From 883e7c256a34b32406dd5c594cd5326e661721e6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Wed, 31 Aug 2022 19:19:29 -0400 Subject: [PATCH] clang format in src/video (#2654) --- src/video/agpgart.c | 46 +- src/video/vid_8514a.c | 3826 +++--- src/video/vid_ati18800.c | 407 +- src/video/vid_ati28800.c | 1009 +- src/video/vid_ati68860_ramdac.c | 323 +- src/video/vid_ati_eeprom.c | 304 +- src/video/vid_ati_mach64.c | 6264 ++++----- src/video/vid_att20c49x_ramdac.c | 228 +- src/video/vid_att2xc498_ramdac.c | 200 +- src/video/vid_av9194.c | 112 +- src/video/vid_bt48x_ramdac.c | 788 +- src/video/vid_cga.c | 758 +- src/video/vid_cga_comp.c | 415 +- src/video/vid_cl54xx.c | 6351 +++++----- src/video/vid_colorplus.c | 649 +- src/video/vid_compaq_cga.c | 646 +- src/video/vid_ddc.c | 234 +- src/video/vid_ega.c | 1694 +-- src/video/vid_ega_render.c | 258 +- src/video/vid_et4000.c | 1146 +- src/video/vid_et4000w32.c | 4051 +++--- src/video/vid_f82c425.c | 847 +- src/video/vid_genius.c | 872 +- src/video/vid_hercules.c | 736 +- src/video/vid_herculesplus.c | 792 +- src/video/vid_ht216.c | 2064 ++- src/video/vid_ibm_rgb528_ramdac.c | 1494 ++- src/video/vid_icd2061.c | 144 +- src/video/vid_ics2494.c | 75 +- src/video/vid_ics2595.c | 90 +- src/video/vid_im1024.c | 813 +- src/video/vid_incolor.c | 1519 ++- src/video/vid_mda.c | 555 +- src/video/vid_mga.c | 7982 ++++++------ src/video/vid_nga.c | 893 +- src/video/vid_oak_oti.c | 700 +- src/video/vid_ogc.c | 925 +- src/video/vid_paradise.c | 1303 +- src/video/vid_pgc.c | 2218 ++-- src/video/vid_rtg310x.c | 446 +- src/video/vid_s3.c | 15340 ++++++++++++----------- src/video/vid_s3_virge.c | 7444 +++++------ src/video/vid_sc1148x_ramdac.c | 208 +- src/video/vid_sc1502x_ramdac.c | 169 +- src/video/vid_sdac_ramdac.c | 380 +- src/video/vid_sigma.c | 994 +- src/video/vid_stg_ramdac.c | 311 +- src/video/vid_svga.c | 2139 ++-- src/video/vid_svga_render.c | 2571 ++-- src/video/vid_table.c | 113 +- src/video/vid_tgui9440.c | 5767 +++++---- src/video/vid_ti_cf62011.c | 207 +- src/video/vid_tkd8001_ramdac.c | 106 +- src/video/vid_tvga.c | 705 +- src/video/vid_tvp3026_ramdac.c | 919 +- src/video/vid_vga.c | 255 +- src/video/vid_voodoo.c | 1890 ++- src/video/vid_voodoo_banshee.c | 5044 ++++---- src/video/vid_voodoo_banshee_blitter.c | 2551 ++-- src/video/vid_voodoo_blitter.c | 816 +- src/video/vid_voodoo_display.c | 1070 +- src/video/vid_voodoo_fb.c | 676 +- src/video/vid_voodoo_fifo.c | 869 +- src/video/vid_voodoo_reg.c | 2489 ++-- src/video/vid_voodoo_render.c | 2766 ++-- src/video/vid_voodoo_setup.c | 348 +- src/video/vid_voodoo_texture.c | 963 +- src/video/vid_wy700.c | 1583 ++- src/video/vid_xga.c | 1069 +- src/video/video.c | 921 +- 70 files changed, 58560 insertions(+), 56300 deletions(-) diff --git a/src/video/agpgart.c b/src/video/agpgart.c index a1374cb10..cf4fcd7a8 100644 --- a/src/video/agpgart.c +++ b/src/video/agpgart.c @@ -25,7 +25,6 @@ #include <86box/mem.h> #include <86box/agpgart.h> - #ifdef ENABLE_AGPGART_LOG int agpgart_do_log = ENABLE_AGPGART_LOG; @@ -35,16 +34,15 @@ agpgart_log(const char *fmt, ...) va_list ap; if (agpgart_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define agpgart_log(fmt, ...) +# define agpgart_log(fmt, ...) #endif - void agpgart_set_aperture(agpgart_t *dev, uint32_t base, uint32_t size, int enable) { @@ -60,12 +58,11 @@ agpgart_set_aperture(agpgart_t *dev, uint32_t base, uint32_t size, int enable) /* Enable new aperture mapping if requested. */ if (dev->aperture_base && dev->aperture_size && dev->aperture_enable) { - mem_mapping_set_addr(&dev->aperture_mapping, dev->aperture_base, dev->aperture_size); - mem_mapping_enable(&dev->aperture_mapping); + mem_mapping_set_addr(&dev->aperture_mapping, dev->aperture_base, dev->aperture_size); + mem_mapping_enable(&dev->aperture_mapping); } } - void agpgart_set_gart(agpgart_t *dev, uint32_t base) { @@ -75,7 +72,6 @@ agpgart_set_gart(agpgart_t *dev, uint32_t base) dev->gart_base = base; } - static uint32_t agpgart_translate(uint32_t addr, agpgart_t *dev) { @@ -89,7 +85,6 @@ agpgart_translate(uint32_t addr, agpgart_t *dev) return gart_ptr | (addr & 0x00000fff); } - static uint8_t agpgart_aperture_readb(uint32_t addr, void *priv) { @@ -97,7 +92,6 @@ agpgart_aperture_readb(uint32_t addr, void *priv) return mem_readb_phys(agpgart_translate(addr, dev)); } - static uint16_t agpgart_aperture_readw(uint32_t addr, void *priv) { @@ -105,7 +99,6 @@ agpgart_aperture_readw(uint32_t addr, void *priv) return mem_readw_phys(agpgart_translate(addr, dev)); } - static uint32_t agpgart_aperture_readl(uint32_t addr, void *priv) { @@ -113,7 +106,6 @@ agpgart_aperture_readl(uint32_t addr, void *priv) return mem_readl_phys(agpgart_translate(addr, dev)); } - static void agpgart_aperture_writeb(uint32_t addr, uint8_t val, void *priv) { @@ -121,7 +113,6 @@ agpgart_aperture_writeb(uint32_t addr, uint8_t val, void *priv) mem_writeb_phys(agpgart_translate(addr, dev), val); } - static void agpgart_aperture_writew(uint32_t addr, uint16_t val, void *priv) { @@ -129,7 +120,6 @@ agpgart_aperture_writew(uint32_t addr, uint16_t val, void *priv) mem_writew_phys(agpgart_translate(addr, dev), val); } - static void agpgart_aperture_writel(uint32_t addr, uint32_t val, void *priv) { @@ -137,7 +127,6 @@ agpgart_aperture_writel(uint32_t addr, uint32_t val, void *priv) mem_writel_phys(agpgart_translate(addr, dev), val); } - static void * agpgart_init(const device_t *info) { @@ -148,14 +137,13 @@ agpgart_init(const device_t *info) /* Create aperture mapping. */ mem_mapping_add(&dev->aperture_mapping, 0, 0, - agpgart_aperture_readb, agpgart_aperture_readw, agpgart_aperture_readl, - agpgart_aperture_writeb, agpgart_aperture_writew, agpgart_aperture_writel, - NULL, MEM_MAPPING_EXTERNAL, dev); + agpgart_aperture_readb, agpgart_aperture_readw, agpgart_aperture_readl, + agpgart_aperture_writeb, agpgart_aperture_writew, agpgart_aperture_writel, + NULL, MEM_MAPPING_EXTERNAL, dev); return dev; } - static void agpgart_close(void *priv) { @@ -170,15 +158,15 @@ agpgart_close(void *priv) } const device_t agpgart_device = { - .name = "AGP Graphics Address Remapping Table", + .name = "AGP Graphics Address Remapping Table", .internal_name = "agpgart", - .flags = DEVICE_PCI, - .local = 0, - .init = agpgart_init, - .close = agpgart_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = agpgart_init, + .close = agpgart_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 1cb0a5407..88dcee020 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -37,69 +37,133 @@ #include <86box/vid_svga_render.h> #include "cpu.h" -static void ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len); -static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *p); -static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *p); -static uint8_t ibm8514_accel_inb(uint16_t port, void *p); +static void ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len); +static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *p); +static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *p); +static uint8_t ibm8514_accel_inb(uint16_t port, void *p); static uint16_t ibm8514_accel_inw(uint16_t port, void *p); static void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, uint8_t ssv, int len); static void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, int len); -#define READ_PIXTRANS_WORD(cx, n) \ - if (cmd <= 1 || (cmd == 5)) { \ - temp = dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } else { \ - temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ - } +#define READ_PIXTRANS_WORD(cx, n) \ + if (cmd <= 1 || (cmd == 5)) { \ + temp = dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.cy * dev->h_disp) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } else { \ + temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } #define READ(addr, dat) \ - dat = dev->vram[(addr) & (dev->vram_mask)]; + dat = dev->vram[(addr) & (dev->vram_mask)]; -#define MIX(mixmode, dest_dat, src_dat) { \ - switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ - case 0x00: dest_dat = ~dest_dat; break; \ - case 0x01: dest_dat = 0; break; \ - case 0x02: dest_dat = ~0; break; \ - case 0x03: dest_dat = dest_dat; break; \ - case 0x04: dest_dat = ~src_dat; break; \ - case 0x05: dest_dat = src_dat ^ dest_dat; break; \ - case 0x06: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x07: dest_dat = src_dat; break; \ - case 0x08: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x09: dest_dat = ~src_dat | dest_dat; break; \ - case 0x0a: dest_dat = src_dat | ~dest_dat; break; \ - case 0x0b: dest_dat = src_dat | dest_dat; break; \ - case 0x0c: dest_dat = src_dat & dest_dat; break; \ - case 0x0d: dest_dat = src_dat & ~dest_dat; break; \ - case 0x0e: dest_dat = ~src_dat & dest_dat; break; \ - case 0x0f: dest_dat = ~(src_dat | dest_dat); break; \ - case 0x10: dest_dat = MIN(src_dat, dest_dat); break; \ - case 0x11: dest_dat = dest_dat - src_dat; break; \ - case 0x12: dest_dat = src_dat - dest_dat; break; \ - case 0x13: dest_dat = src_dat + dest_dat; break; \ - case 0x14: dest_dat = MAX(src_dat, dest_dat); break; \ - case 0x15: dest_dat = (dest_dat - src_dat) / 2; break; \ - case 0x16: dest_dat = (src_dat - dest_dat) / 2; break; \ - case 0x17: dest_dat = (dest_dat + src_dat) / 2; break; \ - case 0x18: dest_dat = MAX(0, (dest_dat - src_dat)); break; \ - case 0x19: dest_dat = MAX(0, (dest_dat - src_dat)); break; \ - case 0x1a: dest_dat = MAX(0, (src_dat - dest_dat)); break; \ - case 0x1b: dest_dat = MIN(0xff, (dest_dat + src_dat)); break; \ - case 0x1c: dest_dat = MAX(0, (dest_dat - src_dat)) / 2; break; \ - case 0x1d: dest_dat = MAX(0, (dest_dat - src_dat)) / 2; break; \ - case 0x1e: dest_dat = MAX(0, (src_dat - dest_dat)) / 2; break; \ - case 0x1f: dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); break; \ - } \ - } +#define MIX(mixmode, dest_dat, src_dat) \ + { \ + switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ + case 0x00: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x01: \ + dest_dat = 0; \ + break; \ + case 0x02: \ + dest_dat = ~0; \ + break; \ + case 0x03: \ + dest_dat = dest_dat; \ + break; \ + case 0x04: \ + dest_dat = ~src_dat; \ + break; \ + case 0x05: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x06: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x07: \ + dest_dat = src_dat; \ + break; \ + case 0x08: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x09: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0x0a: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0x0b: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0x0c: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0x0d: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0x0e: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0x0f: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + case 0x10: \ + dest_dat = MIN(src_dat, dest_dat); \ + break; \ + case 0x11: \ + dest_dat = dest_dat - src_dat; \ + break; \ + case 0x12: \ + dest_dat = src_dat - dest_dat; \ + break; \ + case 0x13: \ + dest_dat = src_dat + dest_dat; \ + break; \ + case 0x14: \ + dest_dat = MAX(src_dat, dest_dat); \ + break; \ + case 0x15: \ + dest_dat = (dest_dat - src_dat) / 2; \ + break; \ + case 0x16: \ + dest_dat = (src_dat - dest_dat) / 2; \ + break; \ + case 0x17: \ + dest_dat = (dest_dat + src_dat) / 2; \ + break; \ + case 0x18: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x19: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x1a: \ + dest_dat = MAX(0, (src_dat - dest_dat)); \ + break; \ + case 0x1b: \ + dest_dat = MIN(0xff, (dest_dat + src_dat)); \ + break; \ + case 0x1c: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1d: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1e: \ + dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ + break; \ + case 0x1f: \ + dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \ + break; \ + } \ + } -#define WRITE(addr, dat) \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ +#define WRITE(addr, dat) \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; - static int ibm8514_cpu_src(ibm8514_t *dev) { @@ -124,18 +188,17 @@ ibm8514_cpu_dest(ibm8514_t *dev) return 1; } - static void ibm8514_accel_out_pixtrans(ibm8514_t *dev, uint16_t port, uint16_t val, int len) { - uint8_t nibble = 0; + uint8_t nibble = 0; uint32_t pixelxfer = 0, monoxfer = 0xffffffff; - int pixcnt = 0; - int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; - int frgd_mix = (dev->accel.frgd_mix >> 5) & 3; - int bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; - int cmd = dev->accel.cmd >> 13; - int and3 = dev->accel.cur_x & 3; + int pixcnt = 0; + int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; + int frgd_mix = (dev->accel.frgd_mix >> 5) & 3; + int bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; + int cmd = dev->accel.cmd >> 13; + int and3 = dev->accel.cur_x & 3; if (dev->accel.cmd & 0x100) { if (len != 1) { @@ -459,9 +522,9 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) if (len == 1) dev->accel.cmd = (dev->accel.cmd & 0xff00) | val; else { - dev->data_available = 0; + dev->data_available = 0; dev->data_available2 = 0; - dev->accel.cmd = val; + dev->accel.cmd = val; if (dev->accel.cmd & 0x100) dev->accel.cmd_back = 0; ibm8514_accel_start(-1, 0, -1, 0, dev, len); @@ -470,9 +533,9 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) case 0x9ae9: case 0xdae9: if (len == 1) { - dev->data_available = 0; + dev->data_available = 0; dev->data_available2 = 0; - dev->accel.cmd = (dev->accel.cmd & 0xff) | (val << 8); + dev->accel.cmd = (dev->accel.cmd & 0xff) | (val << 8); if (port == 0xdae9) { if (dev->accel.cmd & 0x100) dev->accel.cmd_back = 0; @@ -488,8 +551,8 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) dev->accel.short_stroke = (dev->accel.short_stroke & 0xff00) | val; else { dev->accel.short_stroke = val; - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_x & 0x400) dev->accel.cx |= ~0x3ff; if (dev->accel.cur_y & 0x400) @@ -507,8 +570,8 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) case 0xdee9: if (len == 1) { dev->accel.short_stroke = (dev->accel.short_stroke & 0xff) | (val << 8); - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; if (dev->accel.cur_x & 0x400) dev->accel.cx |= ~0x3ff; if (dev->accel.cur_y & 0x400) @@ -630,7 +693,7 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) if (len == 1) dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff00) | val; else { - dev->accel.multifunc_cntl = val; + dev->accel.multifunc_cntl = val; dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; if ((dev->accel.multifunc_cntl >> 12) == 1) { dev->accel.clip_top = val & 0x3ff; @@ -647,7 +710,7 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) case 0xbee9: case 0xfee9: if (len == 1) { - dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); + dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; if (port == 0xfee9) dev->accel.cmd_back = 1; @@ -661,7 +724,7 @@ ibm8514_accel_out_fifo(ibm8514_t *dev, uint16_t port, uint32_t val, int len) static void ibm8514_ramdac_out(uint16_t port, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; switch (port) { case 0x2ea: @@ -682,8 +745,8 @@ ibm8514_ramdac_out(uint16_t port, uint8_t val, void *p) static uint8_t ibm8514_ramdac_in(uint16_t port, void *p) { - svga_t *svga = (svga_t *)p; - uint8_t ret = 0xff; + svga_t *svga = (svga_t *) p; + uint8_t ret = 0xff; switch (port) { case 0x2ea: @@ -698,7 +761,6 @@ ibm8514_ramdac_in(uint16_t port, void *p) case 0x2ed: ret = svga_in(0x3c9, svga); break; - } return ret; } @@ -779,24 +841,24 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x2e9: if (len != 1) { dev->htotal = (dev->htotal & 0xff) | (val << 8); - //pclog("IBM 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); + // pclog("IBM 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); svga_recalctimings(svga); } break; case 0x6e8: dev->hdisp = val; - //pclog("IBM 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); + // pclog("IBM 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); svga_recalctimings(svga); break; case 0xae8: - //pclog("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + // pclog("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); svga_recalctimings(svga); break; case 0xee8: - //pclog("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + // pclog("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); svga_recalctimings(svga); break; @@ -811,7 +873,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x12e9: if (len == 1) { dev->vtotal = (dev->vtotal & 0xff) | ((val & 0x1f) << 8); - //pclog("IBM 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); + // pclog("IBM 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); svga_recalctimings(svga); } break; @@ -827,7 +889,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x16e9: if (len == 1) { dev->vdisp = (dev->vdisp & 0xff) | ((val & 0x1f) << 8); - //pclog("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + // pclog("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); svga_recalctimings(svga); } break; @@ -843,21 +905,21 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x1ae9: if (len == 1) { dev->vsyncstart = (dev->vsyncstart & 0xff) | ((val & 0x1f) << 8); - //pclog("IBM 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); + // pclog("IBM 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); svga_recalctimings(svga); } break; case 0x1ee8: dev->vsyncwidth = val; - //pclog("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + // pclog("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); svga_recalctimings(svga); break; case 0x22e8: dev->disp_cntl = val & 0x7e; dev->interlace = !!(val & 0x10); - //pclog("IBM 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); + // pclog("IBM 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); svga_recalctimings(svga); break; @@ -877,9 +939,9 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x4ae8: dev->accel.advfunc_cntl = val & 7; - vga_on = ((dev->accel.advfunc_cntl & 1) == 0) ? 1 : 0; - ibm8514_on = !vga_on; - //pclog("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); + vga_on = ((dev->accel.advfunc_cntl & 1) == 0) ? 1 : 0; + ibm8514_on = !vga_on; + // pclog("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); svga_recalctimings(svga); break; } @@ -889,23 +951,23 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) static void ibm8514_accel_outb(uint16_t port, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; ibm8514_accel_out(port, val, svga, 1); } static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; ibm8514_accel_out(port, val, svga, 2); } static uint32_t ibm8514_accel_in(uint16_t port, svga_t *svga, int len) { - ibm8514_t *dev = &svga->dev8514; - uint32_t temp = 0; - int cmd; + ibm8514_t *dev = &svga->dev8514; + uint32_t temp = 0; + int cmd; switch (port) { case 0x6e8: @@ -980,7 +1042,7 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) case 0xe6e8: if (ibm8514_cpu_dest(dev)) { if (len == 1) { - ;//READ_PIXTRANS_BYTE_IO(0) + ; // READ_PIXTRANS_BYTE_IO(0) } else { cmd = (dev->accel.cmd >> 13); READ_PIXTRANS_WORD(dev->accel.cx, 0) @@ -996,7 +1058,7 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) case 0xe6e9: if (ibm8514_cpu_dest(dev)) { if (len == 1) { - ;//READ_PIXTRANS_BYTE_IO(1) + ; // READ_PIXTRANS_BYTE_IO(1) ibm8514_accel_out_pixtrans(dev, port, temp, len); } } @@ -1005,28 +1067,26 @@ ibm8514_accel_in(uint16_t port, svga_t *svga, int len) return temp; } - static uint8_t ibm8514_accel_inb(uint16_t port, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; return ibm8514_accel_in(port, svga, 1); } static uint16_t ibm8514_accel_inw(uint16_t port, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; return ibm8514_accel_in(port, svga, 2); } - static void ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, uint8_t ssv, int len) { if (!cpu_input) { - dev->accel.ssv_len = ssv & 0x0f; - dev->accel.ssv_dir = ssv & 0xe0; + dev->accel.ssv_len = ssv & 0x0f; + dev->accel.ssv_dir = ssv & 0xe0; dev->accel.ssv_draw = ssv & 0x10; if (ibm8514_cpu_src(dev)) { @@ -1040,28 +1100,28 @@ ibm8514_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t static void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, ibm8514_t *dev, int len) { - uint8_t src_dat = 0, dest_dat, old_dest_dat; - int frgd_mix, bkgd_mix; - uint16_t clip_b = dev->accel.multifunc[3] & 0x7ff; - uint16_t clip_r = dev->accel.multifunc[4] & 0x7ff; - int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; - uint8_t mix_mask = 0x80; - uint8_t compare = dev->accel.color_cmp & 0xff; - int compare_mode = dev->accel.multifunc[0x0a] & 0x38; - int cmd = dev->accel.cmd >> 13; - uint8_t wrt_mask = dev->accel.wrt_mask & 0xff; - uint8_t rd_mask = ((dev->accel.rd_mask & 0x01) << 7) | ((dev->accel.rd_mask & 0xfe) >> 1); - uint8_t rd_mask_polygon = dev->accel.rd_mask & 0xff; - uint8_t frgd_color = dev->accel.frgd_color; - uint8_t bkgd_color = dev->accel.bkgd_color; - uint32_t old_mix_dat; - int and3 = dev->accel.cur_x & 3; - uint8_t poly_src = 0; + uint8_t src_dat = 0, dest_dat, old_dest_dat; + int frgd_mix, bkgd_mix; + uint16_t clip_b = dev->accel.multifunc[3] & 0x7ff; + uint16_t clip_r = dev->accel.multifunc[4] & 0x7ff; + int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; + uint8_t mix_mask = 0x80; + uint8_t compare = dev->accel.color_cmp & 0xff; + int compare_mode = dev->accel.multifunc[0x0a] & 0x38; + int cmd = dev->accel.cmd >> 13; + uint8_t wrt_mask = dev->accel.wrt_mask & 0xff; + uint8_t rd_mask = ((dev->accel.rd_mask & 0x01) << 7) | ((dev->accel.rd_mask & 0xfe) >> 1); + uint8_t rd_mask_polygon = dev->accel.rd_mask & 0xff; + uint8_t frgd_color = dev->accel.frgd_color; + uint8_t bkgd_color = dev->accel.bkgd_color; + uint32_t old_mix_dat; + int and3 = dev->accel.cur_x & 3; + uint8_t poly_src = 0; - if (dev->accel.cmd & 0x100) { - dev->force_busy = 1; + if (dev->accel.cmd & 0x100) { + dev->force_busy = 1; dev->force_busy2 = 1; - } + } frgd_mix = (dev->accel.frgd_mix >> 5) & 3; bkgd_mix = (dev->accel.bkgd_mix >> 5) & 3; @@ -1159,335 +1219,149 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat old_mix_dat = mix_dat; - /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. - When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on - the NOP command)*/ + /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. + When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on + the NOP command)*/ switch (cmd) { case 0: /*NOP (Short Stroke Vectors)*/ - if (dev->accel.ssv_state == 0) - break; + if (dev->accel.ssv_state == 0) + break; - if (dev->accel.cmd & 8) { - while (count-- && dev->accel.ssv_len >= 0) { - if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - MIX(mix_dat & mix_mask, dest_dat, src_dat); - - if (dev->accel.ssv_draw) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + if (dev->accel.cmd & 8) { + while (count-- && dev->accel.ssv_len >= 0) { + if (dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (!dev->accel.ssv_len) - break; - - switch (dev->accel.ssv_dir & 0xe0) { - case 0x00: dev->accel.cx++; break; - case 0x20: dev->accel.cx++; dev->accel.cy--; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cx--; dev->accel.cy--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx--; dev->accel.cy++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cx++; dev->accel.cy++; break; - } - - dev->accel.ssv_len--; - } - - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - } - break; - - case 1: /*Draw line*/ - if (!cpu_input) { - dev->accel.xx_count = 0; - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; - - if (dev->accel.cur_x & 0x400) { - dev->accel.cx |= ~0x3ff; - } - if (dev->accel.cur_y & 0x400) { - dev->accel.cy |= ~0x3ff; - } - - dev->accel.sy = dev->accel.maj_axis_pcnt; - - if (ibm8514_cpu_src(dev)) { - if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 8) { - if (and3 == 1) { - dev->accel.sy += 4; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 4; - else - dev->accel.cx -= 4; - } else if (and3 == 2) { - dev->accel.sy += 5; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 5; - else - dev->accel.cx -= 5; - } else if (and3 == 3) { - dev->accel.sy += 6; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 6; - else - dev->accel.cx -= 6; - } else { - dev->accel.sy += 3; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 3; - else - dev->accel.cx -= 3; - } - } - } - dev->data_available = 0; - dev->data_available2 = 0; - return; /*Wait for data from CPU*/ - } else if (ibm8514_cpu_dest(dev)) { - dev->data_available = 1; - dev->data_available2 = 1; - return; - } - } - - if (dev->accel.cmd & 8) { /*Vector Line*/ - if (ibm8514_cpu_dest(dev) && cpu_input && (dev->accel.cmd & 2)) - count >>= 1; - dev->accel.xx_count++; - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - - if (ibm8514_cpu_dest(dev)) { - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } - - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 2) && ibm8514_cpu_src(dev)) { - if (and3 == 1) { - if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 2) { - if (dev->accel.xx_count == 2) { - if (count <= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 3) { - if (dev->accel.xx_count == 2) { - if (count <= 1) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } else { - if (dev->accel.xx_count == 1) { - if (!count) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } - } else { - if (ibm8514_cpu_src(dev) || !cpu_input) { - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.sy == 0) { - break; - } - - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cx++; break; - case 0x20: dev->accel.cx++; dev->accel.cy--; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cx--; dev->accel.cy--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx--; dev->accel.cy++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cx++; dev->accel.cy++; break; - } - - dev->accel.sy--; - } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - } else { /*Bresenham*/ - if (pixcntl == 1) { - dev->accel.temp_cnt = 8; - while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.temp_cnt == 0) { - dev->accel.temp_cnt = 8; - mix_dat = old_mix_dat; - } - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - if (ibm8514_cpu_dest(dev)) { - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); - } else switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + + if (dev->accel.ssv_draw) { WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); } } } - dev->accel.temp_cnt--; - mix_dat >>= 1; + mix_dat <<= 1; + mix_dat |= 1; cpu_dat >>= 8; - if (dev->accel.sy == 0) { + if (!dev->accel.ssv_len) break; + + switch (dev->accel.ssv_dir & 0xe0) { + case 0x00: + dev->accel.cx++; + break; + case 0x20: + dev->accel.cx++; + dev->accel.cy--; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cx--; + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx--; + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cx++; + dev->accel.cy++; + break; } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cy--; break; - case 0x20: dev->accel.cy--; break; - case 0x40: dev->accel.cx--; break; - case 0x60: dev->accel.cx++; break; - case 0x80: dev->accel.cy++; break; - case 0xa0: dev->accel.cy++; break; - case 0xc0: dev->accel.cx--; break; - case 0xe0: dev->accel.cx++; break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; - - /*Step major axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cx--; break; - case 0x20: dev->accel.cx++; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cy--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cy++; break; - } - - dev->accel.sy--; + dev->accel.ssv_len--; } - } else { + + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } + break; + + case 1: /*Draw line*/ + if (!cpu_input) { + dev->accel.xx_count = 0; + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + + if (dev->accel.cur_x & 0x400) { + dev->accel.cx |= ~0x3ff; + } + if (dev->accel.cur_y & 0x400) { + dev->accel.cy |= ~0x3ff; + } + + dev->accel.sy = dev->accel.maj_axis_pcnt; + + if (ibm8514_cpu_src(dev)) { + if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 8) { + if (and3 == 1) { + dev->accel.sy += 4; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 4; + else + dev->accel.cx -= 4; + } else if (and3 == 2) { + dev->accel.sy += 5; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 5; + else + dev->accel.cx -= 5; + } else if (and3 == 3) { + dev->accel.sy += 6; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 6; + else + dev->accel.cx -= 6; + } else { + dev->accel.sy += 3; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 3; + else + dev->accel.cx -= 3; + } + } + } + dev->data_available = 0; + dev->data_available2 = 0; + return; /*Wait for data from CPU*/ + } else if (ibm8514_cpu_dest(dev)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + + if (dev->accel.cmd & 8) { /*Vector Line*/ + if (ibm8514_cpu_dest(dev) && cpu_input && (dev->accel.cmd & 2)) + count >>= 1; + dev->accel.xx_count++; while (count-- && (dev->accel.sy >= 0)) { - if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx) <= clip_r && - (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { @@ -1501,29 +1375,94 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); if (pixcntl == 3) src_dat = ((src_dat & rd_mask) == rd_mask); - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } + } else + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; + } READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + if ((dev->accel.cmd & 2) && ibm8514_cpu_src(dev)) { + if (and3 == 1) { + if (dev->accel.xx_count >= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (and3 == 2) { + if (dev->accel.xx_count == 2) { + if (count <= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 3) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (and3 == 3) { + if (dev->accel.xx_count == 2) { + if (count <= 1) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 3) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else { + if (dev->accel.xx_count == 1) { + if (!count) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } + } else { + if (ibm8514_cpu_src(dev) || !cpu_input) { + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } } } } @@ -1536,311 +1475,195 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat break; } - if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { - dev->accel.err_term += dev->accel.destx_distp; - /*Step minor axis*/ - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cy--; break; - case 0x20: dev->accel.cy--; break; - case 0x40: dev->accel.cx--; break; - case 0x60: dev->accel.cx++; break; - case 0x80: dev->accel.cy++; break; - case 0xa0: dev->accel.cy++; break; - case 0xc0: dev->accel.cx--; break; - case 0xe0: dev->accel.cx++; break; - } - } else - dev->accel.err_term += dev->accel.desty_axstp; - - /*Step major axis*/ switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cx--; break; - case 0x20: dev->accel.cx++; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cy--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cy++; break; + case 0x00: + dev->accel.cx++; + break; + case 0x20: + dev->accel.cx++; + dev->accel.cy--; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cx--; + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx--; + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cx++; + dev->accel.cy++; + break; } dev->accel.sy--; } - } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - } - break; - - case 2: /*Rectangle fill (X direction)*/ - case 3: /*Rectangle fill (Y direction)*/ - case 4: /*Rectangle fill (Y direction using nibbles)*/ - if (!cpu_input) { - dev->accel.x_count = 0; - dev->accel.xx_count = 0; - dev->accel.odd_out = 0; - dev->accel.odd_in = 0; - dev->accel.input = 0; - dev->accel.output = 0; - dev->accel.newdest_out = 0; - dev->accel.newdest_in = 0; - - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; - - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - dev->accel.cy = dev->accel.cur_y & 0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; - - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.fill_state = 0; - - if (cmd == 4) - dev->accel.cmd |= 2; - else if (cmd == 3) - dev->accel.cmd &= ~2; - - if (ibm8514_cpu_src(dev)) { - if (dev->accel.cmd & 2) { - if (!(dev->accel.cmd & 0x1000)) { - if (!(dev->accel.cmd & 8)) { - dev->accel.sx += and3; - dev->accel.nibbleset = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.writemono = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; - } else { - if (and3 == 1) { - dev->accel.sx += 4; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 4; - else - dev->accel.cx -= 4; - } else if (and3 == 2) { - dev->accel.sx += 5; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 5; - else - dev->accel.cx -= 5; - } else if (and3 == 3) { - dev->accel.sx += 6; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 6; - else - dev->accel.cx -= 6; - } else { - dev->accel.sx += 3; - if (dev->accel.cmd & 0x20) - dev->accel.cx += 3; - else - dev->accel.cx -= 3; - } - } - } - } else { - if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { - if (!(dev->accel.sx & 1)) { - dev->accel.output = 1; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->h_disp; - } - } - } - dev->data_available = 0; - dev->data_available2 = 0; - return; /*Wait for data from CPU*/ - } else if (ibm8514_cpu_dest(dev)) { - if (!(dev->accel.cmd & 2) && (frgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { - if (!(dev->accel.sx & 1)) { - dev->accel.input = 1; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp; - } - } else if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 8) { - dev->accel.sx += and3; - dev->accel.nibbleset = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.writemono = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; - } - } - dev->data_available = 1; - dev->data_available2 = 1; - return; /*Wait for data from CPU*/ - } - } - - if (dev->accel.cmd & 2) { - if (cpu_input) { -rect_fill_pix: - if ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev)) { - dev->accel.xx_count++; + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } else { /*Bresenham*/ + if (pixcntl == 1) { + dev->accel.temp_cnt = 8; while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat = old_mix_dat; + } + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + if (ibm8514_cpu_dest(dev)) { + READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); + } else + switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; + } - READ(dev->accel.dest + dev->accel.cx, dest_dat); + READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); + MIX(mix_dat & 1, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (and3 == 1) { - if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 2) { - if (dev->accel.xx_count == 2) { - if (count <= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (and3 == 3) { - if (dev->accel.xx_count == 2) { - if (count <= 1) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 3) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else { - if (dev->accel.xx_count == 1) { - if (!count) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } else if (dev->accel.xx_count >= 2) { - if ((dev->accel.cmd & 4) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 4)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); } } } - mix_dat <<= 1; - mix_dat |= 1; + dev->accel.temp_cnt--; + mix_dat >>= 1; cpu_dat >>= 8; - switch (dev->accel.cmd & 0xe0) { - case 0x00: dev->accel.cx++; break; - case 0x20: dev->accel.cx++; break; - case 0x60: dev->accel.cx--; break; - case 0x80: dev->accel.cx--; break; - case 0xa0: dev->accel.cx--; break; - case 0xe0: dev->accel.cx++; break; + if (dev->accel.sy == 0) { + break; } - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (and3 == 1) { - dev->accel.sx += 4; - } else if (and3 == 2) { - dev->accel.sx += 5; - } else if (and3 == 3) { - dev->accel.sx += 6; - } else { - dev->accel.sx += 3; - } - - if (dev->accel.cmd & 0x20) - dev->accel.cx -= (dev->accel.sx + 1); - else - dev->accel.cx += (dev->accel.sx + 1); - + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { + dev->accel.err_term += dev->accel.destx_distp; + /*Step minor axis*/ switch (dev->accel.cmd & 0xe0) { - case 0x20: dev->accel.cy--; break; - case 0x40: dev->accel.cy--; break; - case 0x60: dev->accel.cy--; break; - case 0xa0: dev->accel.cy++; break; - case 0xc0: dev->accel.cy++; break; - case 0xe0: dev->accel.cy++; break; + case 0x00: + dev->accel.cy--; + break; + case 0x20: + dev->accel.cy--; + break; + case 0x40: + dev->accel.cx--; + break; + case 0x60: + dev->accel.cx++; + break; + case 0x80: + dev->accel.cy++; + break; + case 0xa0: + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cx--; + break; + case 0xe0: + dev->accel.cx++; + break; } + } else + dev->accel.err_term += dev->accel.desty_axstp; - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - return; + /*Step major axis*/ + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx--; + break; + case 0x20: + dev->accel.cx++; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cy++; + break; } + + dev->accel.sy--; } - break; - } - if (count < 8) { + } else { while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx) <= clip_r && (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) { if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { /* Mix data = current video memory value. */ - READ(dev->accel.dest + dev->accel.cx, mix_dat); + READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, mix_dat); mix_dat = ((mix_dat & rd_mask) == rd_mask); mix_dat = mix_dat ? mix_mask : 0; } if (ibm8514_cpu_dest(dev)) { - READ(dev->accel.dest + dev->accel.cx, src_dat); + READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, src_dat); if (pixcntl == 3) src_dat = ((src_dat & rd_mask) == rd_mask); - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } + } else + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; + } - READ(dev->accel.dest + dev->accel.cx, dest_dat); + READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + if ((dev->accel.cmd & 4) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } } } @@ -1848,276 +1671,338 @@ rect_fill_pix: mix_dat |= 1; cpu_dat >>= 8; - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; + if (dev->accel.sy == 0) { + break; + } - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - dev->accel.sx += (dev->accel.cur_x & 3); + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { + dev->accel.err_term += dev->accel.destx_distp; + /*Step minor axis*/ + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cy--; + break; + case 0x20: + dev->accel.cy--; + break; + case 0x40: + dev->accel.cx--; + break; + case 0x60: + dev->accel.cx++; + break; + case 0x80: + dev->accel.cy++; + break; + case 0xa0: + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cx--; + break; + case 0xe0: + dev->accel.cx++; + break; } + } else + dev->accel.err_term += dev->accel.desty_axstp; - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else + /*Step major axis*/ + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx--; + break; + case 0x20: + dev->accel.cx++; + break; + case 0x40: dev->accel.cy--; - - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - return; - } - } - } else { - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { - mix_dat = 1; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ(dev->accel.dest + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? 1 : 0; - } - - if (ibm8514_cpu_dest(dev)) { - READ(dev->accel.dest + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else { - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } - } - - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - mix_dat >>= 1; - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - if (!(dev->accel.cmd & 0x1000)) - dev->accel.sx += (dev->accel.cur_x & 3); - } - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - } - } - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else + break; + case 0x60: dev->accel.cy--; - - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - return; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cy++; + break; } + + dev->accel.sy--; } } - } else { - goto rect_fill; + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; } - } else { - if (cpu_input) { - if (pixcntl == 2) { - goto rect_fill_pix; - } else { - if (dev->accel.input && !dev->accel.output) { - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - if (!dev->accel.odd_in && !dev->accel.sx) { - READ(dev->accel.newdest_in + dev->accel.cur_x, src_dat); - READ(dev->accel.newdest_in + dev->accel.cur_x, dest_dat); - } else { - READ(dev->accel.dest + dev->accel.cx, src_dat); - READ(dev->accel.dest + dev->accel.cx, dest_dat); - } - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (!dev->accel.odd_in && !dev->accel.sx) { - WRITE(dev->accel.newdest_in + dev->accel.cur_x, dest_dat); - } else { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } - mix_dat <<= 1; - mix_dat |= 1; + break; - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; + case 2: /*Rectangle fill (X direction)*/ + case 3: /*Rectangle fill (Y direction)*/ + case 4: /*Rectangle fill (Y direction using nibbles)*/ + if (!cpu_input) { + dev->accel.x_count = 0; + dev->accel.xx_count = 0; + dev->accel.odd_out = 0; + dev->accel.odd_in = 0; + dev->accel.input = 0; + dev->accel.output = 0; + dev->accel.newdest_out = 0; + dev->accel.newdest_in = 0; - dev->accel.sx--; - if (dev->accel.odd_in) { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.odd_in = 0; - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp; - dev->accel.sy--; - return; - } + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; + + dev->accel.cx = dev->accel.cur_x & 0x3ff; + if (dev->accel.cur_x & 0x400) + dev->accel.cx |= ~0x3ff; + dev->accel.cy = dev->accel.cur_y & 0x3ff; + if (dev->accel.cur_y & 0x400) + dev->accel.cy |= ~0x3ff; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.fill_state = 0; + + if (cmd == 4) + dev->accel.cmd |= 2; + else if (cmd == 3) + dev->accel.cmd &= ~2; + + if (ibm8514_cpu_src(dev)) { + if (dev->accel.cmd & 2) { + if (!(dev->accel.cmd & 0x1000)) { + if (!(dev->accel.cmd & 8)) { + dev->accel.sx += and3; + dev->accel.nibbleset = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.writemono = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; } else { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.sx--; - dev->accel.cx = dev->accel.cur_x; - dev->accel.odd_in = 1; + if (and3 == 1) { + dev->accel.sx += 4; if (dev->accel.cmd & 0x20) - dev->accel.cx++; + dev->accel.cx += 4; else - dev->accel.cx--; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; + dev->accel.cx -= 4; + } else if (and3 == 2) { + dev->accel.sx += 5; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 5; else - dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp; - dev->accel.sy--; - return; - } - } - } - } else if (dev->accel.output && !dev->accel.input) { - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - src_dat = cpu_dat; - if (!dev->accel.odd_out && !dev->accel.sx) { - READ(dev->accel.newdest_out + dev->accel.cur_x, dest_dat); + dev->accel.cx -= 5; + } else if (and3 == 3) { + dev->accel.sx += 6; + if (dev->accel.cmd & 0x20) + dev->accel.cx += 6; + else + dev->accel.cx -= 6; } else { - READ(dev->accel.dest + dev->accel.cx, dest_dat); - } - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (!dev->accel.odd_out && !dev->accel.sx) { - WRITE(dev->accel.newdest_out + dev->accel.cur_x, dest_dat); - } else { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - } - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.odd_out) { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.odd_out = 0; - dev->accel.cx = dev->accel.cur_x; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->h_disp; - dev->accel.sy--; - return; - } - } else { - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.odd_out = 1; - dev->accel.sx--; - dev->accel.cx = dev->accel.cur_x; + dev->accel.sx += 3; if (dev->accel.cmd & 0x20) - dev->accel.cx++; + dev->accel.cx += 3; else - dev->accel.cx--; - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->h_disp; - dev->accel.sy--; - return; + dev->accel.cx -= 3; } } } } else { + if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { + if (!(dev->accel.sx & 1)) { + dev->accel.output = 1; + dev->accel.newdest_out = (dev->accel.cy + 1) * dev->h_disp; + } + } + } + dev->data_available = 0; + dev->data_available2 = 0; + return; /*Wait for data from CPU*/ + } else if (ibm8514_cpu_dest(dev)) { + if (!(dev->accel.cmd & 2) && (frgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { + if (!(dev->accel.sx & 1)) { + dev->accel.input = 1; + dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp; + } + } else if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 8) { + dev->accel.sx += and3; + dev->accel.nibbleset = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.writemono = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; + } + } + dev->data_available = 1; + dev->data_available2 = 1; + return; /*Wait for data from CPU*/ + } + } + + if (dev->accel.cmd & 2) { + if (cpu_input) { +rect_fill_pix: + if ((dev->accel.cmd & 8) && ibm8514_cpu_src(dev)) { + dev->accel.xx_count++; while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; + } + + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if (and3 == 1) { + if (dev->accel.xx_count >= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } else if (and3 == 2) { + if (dev->accel.xx_count == 2) { + if (count <= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 3) { + if ((dev->accel.cmd & 4) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } else if (and3 == 3) { + if (dev->accel.xx_count == 2) { + if (count <= 1) { + if ((dev->accel.cmd & 4) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 3) { + if ((dev->accel.cmd & 4) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } else { + if (dev->accel.xx_count == 1) { + if (!count) { + if ((dev->accel.cmd & 4) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } else if (dev->accel.xx_count >= 2) { + if ((dev->accel.cmd & 4) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 8; + + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx++; + break; + case 0x20: + dev->accel.cx++; + break; + case 0x60: + dev->accel.cx--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx--; + break; + case 0xe0: + dev->accel.cx++; + break; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + if (and3 == 1) { + dev->accel.sx += 4; + } else if (and3 == 2) { + dev->accel.sx += 5; + } else if (and3 == 3) { + dev->accel.sx += 6; + } else { + dev->accel.sx += 3; + } + + if (dev->accel.cmd & 0x20) + dev->accel.cx -= (dev->accel.sx + 1); + else + dev->accel.cx += (dev->accel.sx + 1); + + switch (dev->accel.cmd & 0xe0) { + case 0x20: + dev->accel.cy--; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cy--; + break; + case 0xa0: + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cy++; + break; + } + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + return; + } + } + break; + } + if (count < 8) { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { mix_dat = mix_mask; /* Mix data = forced to foreground register. */ } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { @@ -2129,33 +2014,29 @@ rect_fill_pix: if (ibm8514_cpu_dest(dev)) { READ(dev->accel.dest + dev->accel.cx, src_dat); - if (pixcntl == 3) { + if (pixcntl == 3) src_dat = ((src_dat & rd_mask) == rd_mask); + } else + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; } - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } READ(dev->accel.dest + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - if (ibm8514_cpu_dest(dev)) { - if (pixcntl == 3) { - MIX(mix_dat & mix_mask, dest_dat, src_dat); - } - } else { - MIX(mix_dat & mix_mask, dest_dat, src_dat); - } + MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } @@ -2174,11 +2055,97 @@ rect_fill_pix: if (dev->accel.sx < 0) { dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + if (dev->accel.cmd & 2) { + dev->accel.sx += (dev->accel.cur_x & 3); + } + if (dev->accel.cmd & 0x20) { dev->accel.cx -= (dev->accel.sx) + 1; } else dev->accel.cx += (dev->accel.sx) + 1; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + return; + } + } + } else { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { + mix_dat = 1; /* Mix data = forced to foreground register. */ + } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { + /* Mix data = current video memory value. */ + READ(dev->accel.dest + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? 1 : 0; + } + + if (ibm8514_cpu_dest(dev)) { + READ(dev->accel.dest + dev->accel.cx, src_dat); + if (pixcntl == 3) + src_dat = ((src_dat & rd_mask) == rd_mask); + } else { + switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; + } + } + + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & 1, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + mix_dat >>= 1; + cpu_dat >>= 8; + + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 2) { + if (!(dev->accel.cmd & 0x1000)) + dev->accel.sx += (dev->accel.cur_x & 3); + } + + if (dev->accel.cmd & 0x20) { + dev->accel.cx -= (dev->accel.sx) + 1; + } else + dev->accel.cx += (dev->accel.sx) + 1; + + if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 0x1000) { + dev->accel.cx = dev->accel.cur_x & 0x3ff; + if (dev->accel.cur_x & 0x400) + dev->accel.cx |= ~0x3ff; + } + } + if (dev->accel.cmd & 0x80) dev->accel.cy++; else @@ -2190,248 +2157,694 @@ rect_fill_pix: } } } + } else { + goto rect_fill; } } else { -rect_fill: - if (pixcntl == 1) { - if (dev->accel.cmd & 0x40) { - count = dev->accel.maj_axis_pcnt + 1; - dev->accel.temp_cnt = 8; - while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { - mix_dat >>= 8; - dev->accel.temp_cnt = 8; - } - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = 0; break; - case 3: src_dat = 0; break; + if (cpu_input) { + if (pixcntl == 2) { + goto rect_fill_pix; + } else { + if (dev->accel.input && !dev->accel.output) { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + mix_dat = mix_mask; /* Mix data = forced to foreground register. */ + if (!dev->accel.odd_in && !dev->accel.sx) { + READ(dev->accel.newdest_in + dev->accel.cur_x, src_dat); + READ(dev->accel.newdest_in + dev->accel.cur_x, dest_dat); + } else { + READ(dev->accel.dest + dev->accel.cx, src_dat); + READ(dev->accel.dest + dev->accel.cx, dest_dat); + } + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if (!dev->accel.odd_in && !dev->accel.sx) { + WRITE(dev->accel.newdest_in + dev->accel.cur_x, dest_dat); + } else { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } } - - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } - - if (dev->accel.temp_cnt > 0) { - dev->accel.temp_cnt--; mix_dat <<= 1; mix_dat |= 1; - } - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; else - dev->accel.cy--; + dev->accel.cx--; - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - return; - } - } - } else { - dev->accel.temp_cnt = 8; - while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { - dev->accel.temp_cnt = 8; - mix_dat = old_mix_dat; - } - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = 0; break; - case 3: src_dat = 0; break; - } - - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + dev->accel.sx--; + if (dev->accel.odd_in) { + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.odd_in = 0; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp; + dev->accel.sy--; + return; + } + } else { + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.sx--; + dev->accel.cx = dev->accel.cur_x; + dev->accel.odd_in = 1; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.newdest_in = (dev->accel.cy + 1) * dev->h_disp; + dev->accel.sy--; + return; + } } } + } else if (dev->accel.output && !dev->accel.input) { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + src_dat = cpu_dat; + if (!dev->accel.odd_out && !dev->accel.sx) { + READ(dev->accel.newdest_out + dev->accel.cur_x, dest_dat); + } else { + READ(dev->accel.dest + dev->accel.cx, dest_dat); + } - dev->accel.temp_cnt--; - mix_dat >>= 1; + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if (!dev->accel.odd_out && !dev->accel.sx) { + WRITE(dev->accel.newdest_out + dev->accel.cur_x, dest_dat); + } else { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 8; - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; else - dev->accel.cy--; + dev->accel.cx--; - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.sy--; + dev->accel.sx--; + if (dev->accel.odd_out) { + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.odd_out = 0; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; - if (dev->accel.sy < 0) { - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.newdest_out = (dev->accel.cy + 1) * dev->h_disp; + dev->accel.sy--; + return; + } + } else { + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.odd_out = 1; + dev->accel.sx--; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.newdest_out = (dev->accel.cy + 1) * dev->h_disp; + dev->accel.sy--; + return; + } + } + } + } else { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + if (ibm8514_cpu_dest(dev) && (pixcntl == 0)) { + mix_dat = mix_mask; /* Mix data = forced to foreground register. */ + } else if (ibm8514_cpu_dest(dev) && (pixcntl == 3)) { + /* Mix data = current video memory value. */ + READ(dev->accel.dest + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + + if (ibm8514_cpu_dest(dev)) { + READ(dev->accel.dest + dev->accel.cx, src_dat); + if (pixcntl == 3) { + src_dat = ((src_dat & rd_mask) == rd_mask); + } + } else + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; + } + + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + if (ibm8514_cpu_dest(dev)) { + if (pixcntl == 3) { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + } + } else { + MIX(mix_dat & mix_mask, dest_dat, src_dat); + } + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 8; + + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.cx -= (dev->accel.sx) + 1; + } else + dev->accel.cx += (dev->accel.sx) + 1; + + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.sy--; return; } } } } } else { - if (dev->accel.multifunc[0x0a] & 6) { - while (count-- && dev->accel.sy >= 0) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = 0; break; - case 3: src_dat = 0; break; +rect_fill: + if (pixcntl == 1) { + if (dev->accel.cmd & 0x40) { + count = dev->accel.maj_axis_pcnt + 1; + dev->accel.temp_cnt = 8; + while (count-- && dev->accel.sy >= 0) { + if (dev->accel.temp_cnt == 0) { + mix_dat >>= 8; + dev->accel.temp_cnt = 8; } + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + src_dat = 0; + break; + } - READ(dev->accel.dest + dev->accel.cx, poly_src); - if (dev->accel.multifunc[0x0a] & 2) { - poly_src = ((poly_src & wrt_mask) == wrt_mask); - } else { - poly_src = ((poly_src & rd_mask_polygon) == rd_mask_polygon); - } - - if (poly_src) { - dev->accel.fill_state = !dev->accel.fill_state; - } - - if (dev->accel.fill_state) { READ(dev->accel.dest + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + + if (dev->accel.temp_cnt > 0) { + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.cx -= (dev->accel.sx) + 1; + } else + dev->accel.cx += (dev->accel.sx) + 1; + + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + return; + } + } + } else { + dev->accel.temp_cnt = 8; + while (count-- && dev->accel.sy >= 0) { + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat = old_mix_dat; + } + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + src_dat = 0; + break; + } + + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & 1, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + + dev->accel.temp_cnt--; + mix_dat >>= 1; + + if (dev->accel.cmd & 0x20) + dev->accel.cx++; + else + dev->accel.cx--; + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.cx -= (dev->accel.sx) + 1; + } else + dev->accel.cx += (dev->accel.sx) + 1; + + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + + if (dev->accel.sy < 0) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + return; + } + } + } + } + } else { + if (dev->accel.multifunc[0x0a] & 6) { + while (count-- && dev->accel.sy >= 0) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + src_dat = 0; + break; + } + + READ(dev->accel.dest + dev->accel.cx, poly_src); + if (dev->accel.multifunc[0x0a] & 2) { + poly_src = ((poly_src & wrt_mask) == wrt_mask); + } else { + poly_src = ((poly_src & rd_mask_polygon) == rd_mask_polygon); + } + + if (poly_src) { + dev->accel.fill_state = !dev->accel.fill_state; + } + + if (dev->accel.fill_state) { + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + + if (dev->accel.cmd & 0x20) { + dev->accel.cx++; + } else { + dev->accel.cx--; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.fill_state = 0; + + if (dev->accel.cmd & 0x20) { + dev->accel.cx -= (dev->accel.sx) + 1; + } else { + dev->accel.cx += (dev->accel.sx) + 1; + } + + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + + if (dev->accel.sy < 0) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + return; + } + } + } + } else { + while (count-- && dev->accel.sy >= 0) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + src_dat = 0; + break; + } + + READ(dev->accel.dest + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dev->accel.cx, dest_dat); } } - } - mix_dat <<= 1; - mix_dat |= 1; + mix_dat <<= 1; + mix_dat |= 1; - if (dev->accel.cmd & 0x20) { - dev->accel.cx++; - } else { - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.fill_state = 0; - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; + if (dev->accel.cmd & 0x20) + dev->accel.cx++; else - dev->accel.cy--; + dev->accel.cx--; - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.sy--; + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - if (dev->accel.sy < 0) { - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - return; + if (dev->accel.cmd & 0x20) { + dev->accel.cx -= (dev->accel.sx) + 1; + } else + dev->accel.cx += (dev->accel.sx) + 1; + + if (dev->accel.cmd & 0x80) + dev->accel.cy++; + else + dev->accel.cy--; + + dev->accel.dest = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + + if (dev->accel.sy < 0) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + return; + } } } } + } + } + } + break; + + case 5: /*Draw Polygon Boundary Line*/ + if (!cpu_input) { + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + dev->accel.oldcy = dev->accel.cy; + + dev->accel.xdir = (dev->accel.cmd & 0x20) ? 1 : -1; + dev->accel.ydir = (dev->accel.cmd & 0x80) ? 1 : -1; + + dev->accel.sy = 0; + + if (ibm8514_cpu_src(dev)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; /*Wait for data from CPU*/ + } else if (ibm8514_cpu_dest(dev)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + + while (count-- && (dev->accel.sy >= 0)) { + if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx <= clip_r) && (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + src_dat = 0; + break; + } + + READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if ((dev->accel.cmd & 4) && (dev->accel.sy < dev->accel.maj_axis_pcnt)) { + if (!dev->accel.sy) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if ((dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.cy == dev->accel.oldcy + 1)) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.err_term >= 0) && (dev->accel.cy == (dev->accel.oldcy + 1))) { + WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 8; + + if (dev->accel.sy == dev->accel.maj_axis_pcnt) { + return; + } + + if (dev->accel.cmd & 0x40) { + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy += dev->accel.ydir; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.cx += dev->accel.xdir; } else { - while (count-- && dev->accel.sy >= 0) { - if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && - dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + dev->accel.err_term += dev->accel.desty_axstp; + } + } else { + dev->accel.cx += dev->accel.xdir; + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.oldcy = dev->accel.cy; + dev->accel.cy += dev->accel.ydir; + } else { + dev->accel.err_term += dev->accel.desty_axstp; + } + } + + dev->accel.sy++; + } + break; + + case 6: /*BitBlt*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + dev->accel.x_count = 0; + dev->accel.output = 0; + + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; + + dev->accel.dx = dev->accel.destx_distp & 0x3ff; + dev->accel.dy = dev->accel.desty_axstp & 0x3ff; + + if (dev->accel.destx_distp & 0x400) + dev->accel.dx |= ~0x3ff; + if (dev->accel.desty_axstp & 0x400) + dev->accel.dy |= ~0x3ff; + + dev->accel.cx = dev->accel.cur_x & 0x3ff; + dev->accel.cy = dev->accel.cur_y & 0x3ff; + + if (dev->accel.cur_x & 0x400) + dev->accel.cx |= ~0x3ff; + if (dev->accel.cur_y & 0x400) + dev->accel.cy |= ~0x3ff; + + dev->accel.src = dev->accel.cy * dev->h_disp; + dev->accel.dest = dev->accel.dy * dev->h_disp; + + if (ibm8514_cpu_src(dev)) { + if (dev->accel.cmd & 2) { + if (!(dev->accel.cmd & 0x1000)) { + dev->accel.sx += (dev->accel.cur_x & 3); + dev->accel.nibbleset = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.writemono = (uint8_t *) calloc(1, (dev->accel.sx >> 3) + 1); + dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; + } + } + dev->data_available = 0; + dev->data_available2 = 0; + return; /*Wait for data from CPU*/ + } else if (ibm8514_cpu_dest(dev)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; /*Wait for data from CPU*/ + } + } + + if (dev->accel.cmd & 2) { + if (cpu_input) { +bitblt_pix: + if (count < 8) { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { + if (pixcntl == 3) { + if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } else if (dev->accel.cmd & 0x10) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = 0; break; - case 3: src_dat = 0; break; + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + if (pixcntl == 3) { + if (dev->accel.cmd & 0x10) { + src_dat = ((src_dat & rd_mask) == rd_mask); + } + } + break; } - READ(dev->accel.dest + dev->accel.cx, dest_dat); + READ(dev->accel.dest + dev->accel.dx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } mix_dat <<= 1; mix_dat |= 1; + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2442,6 +2855,10 @@ rect_fill: if (dev->accel.sx < 0) { dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + if (dev->accel.cmd & 2) { + dev->accel.sx += (dev->accel.cur_x & 3); + } + if (dev->accel.cmd & 0x20) { dev->accel.cx -= (dev->accel.sx) + 1; } else @@ -2454,450 +2871,384 @@ rect_fill: dev->accel.dest = dev->accel.cy * dev->h_disp; dev->accel.sy--; - - if (dev->accel.sy < 0) { - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - return; - } + return; } } - } - } - } - } - break; - - case 5: /*Draw Polygon Boundary Line*/ - if (!cpu_input) { - dev->accel.cx = dev->accel.cur_x; - dev->accel.cy = dev->accel.cur_y; - dev->accel.oldcy = dev->accel.cy; - - dev->accel.xdir = (dev->accel.cmd & 0x20) ? 1 : -1; - dev->accel.ydir = (dev->accel.cmd & 0x80) ? 1 : -1; - - dev->accel.sy = 0; - - if (ibm8514_cpu_src(dev)) { - dev->data_available = 0; - dev->data_available2 = 0; - return; /*Wait for data from CPU*/ - } else if (ibm8514_cpu_dest(dev)) { - dev->data_available = 1; - dev->data_available2 = 1; - return; - } - } - - while (count-- && (dev->accel.sy >= 0)) { - if (((dev->accel.cx) >= dev->accel.clip_left && (dev->accel.cx <= clip_r) && - (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b)) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: src_dat = 0; break; - } - - READ((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 4) && (dev->accel.sy < dev->accel.maj_axis_pcnt)) { - if (!dev->accel.sy) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if ((dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.cy == dev->accel.oldcy + 1)) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 0x40) && dev->accel.sy && (dev->accel.err_term >= 0) && (dev->accel.cy == (dev->accel.oldcy + 1))) { - WRITE((dev->accel.cy * dev->h_disp) + dev->accel.cx, dest_dat); - } - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.sy == dev->accel.maj_axis_pcnt) { - return; - } - - if (dev->accel.cmd & 0x40) { - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy += dev->accel.ydir; - if (dev->accel.err_term >= 0) { - dev->accel.err_term += dev->accel.destx_distp; - dev->accel.cx += dev->accel.xdir; - } else { - dev->accel.err_term += dev->accel.desty_axstp; - } - } else { - dev->accel.cx += dev->accel.xdir; - if (dev->accel.err_term >= 0) { - dev->accel.err_term += dev->accel.destx_distp; - dev->accel.oldcy = dev->accel.cy; - dev->accel.cy += dev->accel.ydir; - } else { - dev->accel.err_term += dev->accel.desty_axstp; - } - } - - dev->accel.sy++; - } - break; - - case 6: /*BitBlt*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - dev->accel.x_count = 0; - dev->accel.output = 0; - - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; - - dev->accel.dx = dev->accel.destx_distp & 0x3ff; - dev->accel.dy = dev->accel.desty_axstp & 0x3ff; - - if (dev->accel.destx_distp & 0x400) - dev->accel.dx |= ~0x3ff; - if (dev->accel.desty_axstp & 0x400) - dev->accel.dy |= ~0x3ff; - - dev->accel.cx = dev->accel.cur_x & 0x3ff; - dev->accel.cy = dev->accel.cur_y & 0x3ff; - - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; - - dev->accel.src = dev->accel.cy * dev->h_disp; - dev->accel.dest = dev->accel.dy * dev->h_disp; - - if (ibm8514_cpu_src(dev)) { - if (dev->accel.cmd & 2) { - if (!(dev->accel.cmd & 0x1000)) { - dev->accel.sx += (dev->accel.cur_x & 3); - dev->accel.nibbleset = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.writemono = (uint8_t *)calloc(1, (dev->accel.sx >> 3) + 1); - dev->accel.sys_cnt = (dev->accel.sx >> 3) + 1; - } - } - dev->data_available = 0; - dev->data_available2 = 0; - return; /*Wait for data from CPU*/ - } else if (ibm8514_cpu_dest(dev)) { - dev->data_available = 1; - dev->data_available2 = 1; - return; /*Wait for data from CPU*/ - } - } - - if (dev->accel.cmd & 2) { - if (cpu_input) { -bitblt_pix: - if (count < 8) { - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && - dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { - if (pixcntl == 3) { - if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } else if (dev->accel.cmd & 0x10) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { - src_dat = ((src_dat & rd_mask) == rd_mask); - } + } else { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { + if (pixcntl == 3) { + if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? 1 : 0; + } else if (dev->accel.cmd & 0x10) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? 1 : 0; } - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; - else - dev->accel.cx--; - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - dev->accel.sx += (dev->accel.cur_x & 3); - } - - if (dev->accel.cmd & 0x20) { - dev->accel.cx -= (dev->accel.sx) + 1; - } else - dev->accel.cx += (dev->accel.sx) + 1; - - if (dev->accel.cmd & 0x80) - dev->accel.cy++; - else - dev->accel.cy--; - - dev->accel.dest = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - return; - } - } - } else { - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && - dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { - if (pixcntl == 3) { - if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? 1 : 0; - } else if (dev->accel.cmd & 0x10) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? 1 : 0; } - } - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { - src_dat = ((src_dat & rd_mask) == rd_mask); + switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + if (pixcntl == 3) { + if (dev->accel.cmd & 0x10) { + src_dat = ((src_dat & rd_mask) == rd_mask); + } } - } - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - mix_dat >>= 1; - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 2) { - if (!(dev->accel.cmd & 0x1000)) - dev->accel.sx += (dev->accel.cur_x & 3); - } - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 2) { - if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - dev->accel.dx = dev->accel.destx_distp & 0x3ff; - if (dev->accel.destx_distp & 0x400) - dev->accel.dx |= ~0x3ff; - } - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->h_disp; - dev->accel.src = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - return; - } - } - } - } else { - goto bitblt; - } - } else { - if (cpu_input) { - if (pixcntl == 2) { - goto bitblt_pix; - } else { - while (count-- && (dev->accel.sy >= 0)) { - if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && - dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { - if (pixcntl == 3) { - if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } else if (dev->accel.cmd & 0x10) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = cpu_dat & 0xff; break; - case 3: READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { - src_dat = ((src_dat & rd_mask) == rd_mask); - } - } - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - mix_dat <<= 1; - mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->h_disp; - dev->accel.src = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - return; - } - } - } - } else { -bitblt: - if (pixcntl == 1) { - if (dev->accel.cmd & 0x40) { - count = dev->accel.maj_axis_pcnt + 1; - dev->accel.temp_cnt = 8; - while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { - mix_dat >>= 8; - dev->accel.temp_cnt = 8; - } - if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && - dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = 0; break; - case 3: READ(dev->accel.src + dev->accel.cx, src_dat); - break; + break; } READ(dev->accel.dest + dev->accel.dx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & 1, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } + mix_dat >>= 1; + cpu_dat >>= 8; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; + dev->accel.cx--; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 2) { + if (!(dev->accel.cmd & 0x1000)) + dev->accel.sx += (dev->accel.cur_x & 3); + } + + if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx) + 1; + dev->accel.cx -= (dev->accel.sx) + 1; + } else { + dev->accel.dx += (dev->accel.sx) + 1; + dev->accel.cx += (dev->accel.sx) + 1; + } + + if (dev->accel.cmd & 2) { + if (dev->accel.cmd & 0x1000) { + dev->accel.cx = dev->accel.cur_x & 0x3ff; + if (dev->accel.cur_x & 0x400) + dev->accel.cx |= ~0x3ff; + dev->accel.dx = dev->accel.destx_distp & 0x3ff; + if (dev->accel.destx_distp & 0x400) + dev->accel.dx |= ~0x3ff; + } + } + + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; + dev->accel.cy++; + } else { + dev->accel.dy--; + dev->accel.cy--; + } + + dev->accel.dest = dev->accel.dy * dev->h_disp; + dev->accel.src = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + return; + } + } + } + } else { + goto bitblt; + } + } else { + if (cpu_input) { + if (pixcntl == 2) { + goto bitblt_pix; + } else { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { + if (pixcntl == 3) { + if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } else if (dev->accel.cmd & 0x10) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat & 0xff; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + if (pixcntl == 3) { + if (dev->accel.cmd & 0x10) { + src_dat = ((src_dat & rd_mask) == rd_mask); + } + } + break; + } + + READ(dev->accel.dest + dev->accel.dx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } + mix_dat <<= 1; + mix_dat |= 1; + cpu_dat >>= 8; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; + dev->accel.cx--; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx) + 1; + dev->accel.cx -= (dev->accel.sx) + 1; + } else { + dev->accel.dx += (dev->accel.sx) + 1; + dev->accel.cx += (dev->accel.sx) + 1; + } + + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; + dev->accel.cy++; + } else { + dev->accel.dy--; + dev->accel.cy--; + } + + dev->accel.dest = dev->accel.dy * dev->h_disp; + dev->accel.src = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + return; + } + } + } + } else { +bitblt: + if (pixcntl == 1) { + if (dev->accel.cmd & 0x40) { + count = dev->accel.maj_axis_pcnt + 1; + dev->accel.temp_cnt = 8; + while (count-- && dev->accel.sy >= 0) { + if (dev->accel.temp_cnt == 0) { + mix_dat >>= 8; + dev->accel.temp_cnt = 8; + } + if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + break; + } + + READ(dev->accel.dest + dev->accel.dx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } + + if (dev->accel.temp_cnt > 0) { + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; + dev->accel.cx--; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx) + 1; + dev->accel.cx -= (dev->accel.sx) + 1; + } else { + dev->accel.dx += (dev->accel.sx) + 1; + dev->accel.cx += (dev->accel.sx) + 1; + } + + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; + dev->accel.cy++; + } else { + dev->accel.dy--; + dev->accel.cy--; + } + + dev->accel.dest = dev->accel.dy * dev->h_disp; + dev->accel.src = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + return; + } + } + } else { + dev->accel.temp_cnt = 8; + while (count-- && dev->accel.sy >= 0) { + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat = old_mix_dat; + } + if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { + switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + break; + } + + READ(dev->accel.dest + dev->accel.dx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & 1, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } + dev->accel.temp_cnt--; + mix_dat >>= 1; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; + dev->accel.cx--; + } + + dev->accel.sx--; + if (dev->accel.sx < 0) { + dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx) + 1; + dev->accel.cx -= (dev->accel.sx) + 1; + } else { + dev->accel.dx += (dev->accel.sx) + 1; + dev->accel.cx += (dev->accel.sx) + 1; + } + + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; + dev->accel.cy++; + } else { + dev->accel.dy--; + dev->accel.cy--; + } + + dev->accel.dest = dev->accel.dy * dev->h_disp; + dev->accel.src = dev->accel.cy * dev->h_disp; + dev->accel.sy--; + + if (dev->accel.sy < 0) { + return; + } + } + } + } + } else { + while (count-- && dev->accel.sy >= 0) { + if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { + if (pixcntl == 3) { + if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } else if (dev->accel.cmd & 0x10) { + READ(dev->accel.src + dev->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = 0; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + if (pixcntl == 3) { + if (dev->accel.cmd & 0x10) { + src_dat = ((src_dat & rd_mask) == rd_mask); + } + } + break; + } + + READ(dev->accel.dest + dev->accel.dx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); @@ -2905,12 +3256,8 @@ bitblt: WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } - - if (dev->accel.temp_cnt > 0) { - dev->accel.temp_cnt--; - mix_dat <<= 1; - mix_dat |= 1; - } + mix_dat <<= 1; + mix_dat |= 1; if (dev->accel.cmd & 0x20) { dev->accel.dx++; @@ -2941,77 +3288,7 @@ bitblt: } dev->accel.dest = dev->accel.dy * dev->h_disp; - dev->accel.src = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - return; - } - } - } else { - dev->accel.temp_cnt = 8; - while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { - dev->accel.temp_cnt = 8; - mix_dat = old_mix_dat; - } - if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && - dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { - switch ((mix_dat & 1) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = 0; break; - case 3: READ(dev->accel.src + dev->accel.cx, src_dat); - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & 1, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - dev->accel.temp_cnt--; - mix_dat >>= 1; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->h_disp; - dev->accel.src = dev->accel.cy * dev->h_disp; + dev->accel.src = dev->accel.cy * dev->h_disp; dev->accel.sy--; if (dev->accel.sy < 0) { @@ -3020,104 +3297,19 @@ bitblt: } } } - } else { - while (count-- && dev->accel.sy >= 0) { - if ((dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && - dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b)) { - if (pixcntl == 3) { - if (!(dev->accel.cmd & 0x10) && ((frgd_mix != 3) || (bkgd_mix != 3))) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } else if (dev->accel.cmd & 0x10) { - READ(dev->accel.src + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: src_dat = bkgd_color; break; - case 1: src_dat = frgd_color; break; - case 2: src_dat = 0; break; - case 3: READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) { - src_dat = ((src_dat & rd_mask) == rd_mask); - } - } - break; - } - - READ(dev->accel.dest + dev->accel.dx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - } - } - mix_dat <<= 1; - mix_dat |= 1; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx++; - dev->accel.cx++; - } else { - dev->accel.dx--; - dev->accel.cx--; - } - - dev->accel.sx--; - if (dev->accel.sx < 0) { - dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; - - if (dev->accel.cmd & 0x20) { - dev->accel.dx -= (dev->accel.sx) + 1; - dev->accel.cx -= (dev->accel.sx) + 1; - } else { - dev->accel.dx += (dev->accel.sx) + 1; - dev->accel.cx += (dev->accel.sx) + 1; - } - - if (dev->accel.cmd & 0x80) { - dev->accel.dy++; - dev->accel.cy++; - } else { - dev->accel.dy--; - dev->accel.cy--; - } - - dev->accel.dest = dev->accel.dy * dev->h_disp; - dev->accel.src = dev->accel.cy * dev->h_disp; - dev->accel.sy--; - - if (dev->accel.sy < 0) { - return; - } - } - } } } - } - break; - } + break; + } } static void ibm8514_render_8bpp(svga_t *svga) { ibm8514_t *dev = &svga->dev8514; - int x; - uint32_t *p; - uint32_t dat; + int x; + uint32_t *p; + uint32_t dat; if ((dev->displine + svga->y_add) < 0) { return; @@ -3131,13 +3323,13 @@ ibm8514_render_8bpp(svga_t *svga) dev->lastline_draw = dev->displine; for (x = 0; x <= dev->h_disp; x += 8) { - dat = *(uint32_t *)(&dev->vram[dev->ma & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[dev->ma & dev->vram_mask]); p[0] = dev->map8[dat & 0xff]; p[1] = dev->map8[(dat >> 8) & 0xff]; p[2] = dev->map8[(dat >> 16) & 0xff]; p[3] = dev->map8[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&dev->vram[(dev->ma + 4) & dev->vram_mask]); + dat = *(uint32_t *) (&dev->vram[(dev->ma + 4) & dev->vram_mask]); p[4] = dev->map8[dat & 0xff]; p[5] = dev->map8[(dat >> 8) & 0xff]; p[6] = dev->map8[(dat >> 16) & 0xff]; @@ -3165,7 +3357,6 @@ ibm8514_render_overscan_left(ibm8514_t *dev, svga_t *svga) buffer32->line[dev->displine + svga->y_add][i] = svga->overscan_color; } - static void ibm8514_render_overscan_right(ibm8514_t *dev, svga_t *svga) { @@ -3186,7 +3377,7 @@ void ibm8514_poll(ibm8514_t *dev, svga_t *svga) { uint32_t x; - int wx, wy; + int wx, wy; if (!dev->linepos) { timer_advance_u64(&svga->timer, svga->dispofftime); @@ -3226,7 +3417,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) if (dev->dispon) { if (dev->sc == dev->rowcount) { dev->linecountff = 0; - dev->sc = 0; + dev->sc = 0; dev->maback += (dev->rowoffset << 3); if (dev->interlace) @@ -3257,7 +3448,7 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) } if (dev->vc == dev->v_syncstart) { dev->dispon = 0; - x = dev->h_disp; + x = dev->h_disp; if (dev->interlace && !dev->oddeven) dev->lastline++; @@ -3270,10 +3461,10 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) svga_doblit(wx, wy, svga); dev->firstline = 2000; - dev->lastline = 0; + dev->lastline = 0; dev->firstline_draw = 2000; - dev->lastline_draw = 0; + dev->lastline_draw = 0; dev->oddeven ^= 1; @@ -3284,13 +3475,13 @@ ibm8514_poll(ibm8514_t *dev, svga_t *svga) else dev->ma = dev->maback = 0; - dev->ma = (dev->ma << 2); + dev->ma = (dev->ma << 2); dev->maback = (dev->maback << 2); } if (dev->vc == dev->v_total) { - dev->vc = 0; - dev->sc = 0; - dev->dispon = 1; + dev->vc = 0; + dev->sc = 0; + dev->dispon = 1; dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; svga->x_add = (overscan_x >> 1); @@ -3306,16 +3497,16 @@ ibm8514_recalctimings(svga_t *svga) ibm8514_t *dev = &svga->dev8514; dev->h_disp_time = dev->h_disp = (dev->hdisp + 1) << 3; - dev->rowoffset = (dev->hdisp + 1); - dev->h_total = (dev->htotal + 1); - dev->v_total = (dev->vtotal + 1); - dev->v_syncstart = (dev->vsyncstart + 1); - dev->rowcount = !!(dev->disp_cntl & 0x08); + dev->rowoffset = (dev->hdisp + 1); + dev->h_total = (dev->htotal + 1); + dev->v_total = (dev->vtotal + 1); + dev->v_syncstart = (dev->vsyncstart + 1); + dev->rowcount = !!(dev->disp_cntl & 0x08); if (dev->accel.advfunc_cntl & 4) { if (dev->hdisp == 0) { dev->rowoffset = 128; - dev->h_disp = 1024; + dev->h_disp = 1024; } if (dev->vtotal == 0) @@ -3333,63 +3524,62 @@ ibm8514_recalctimings(svga_t *svga) dev->v_total >>= 1; dev->v_syncstart >>= 1; } - //pclog("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); - svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; + // pclog("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; } else { - //pclog("640x480 clock mode\n"); + // pclog("640x480 clock mode\n"); dev->dispend = 480; dev->v_total >>= 1; dev->v_syncstart >>= 1; - svga->clock = (cpuclock * (double)(1ull << 32)) / 25175000.0; + svga->clock = (cpuclock * (double) (1ull << 32)) / 25175000.0; } - //pclog("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); + // pclog("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); } static uint8_t ibm8514_mca_read(int port, void *priv) { - svga_t *svga = (svga_t *)priv; - ibm8514_t *dev = &svga->dev8514; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = &svga->dev8514; - return(dev->pos_regs[port & 7]); + return (dev->pos_regs[port & 7]); } - static void ibm8514_mca_write(int port, uint8_t val, void *priv) { - svga_t *svga = (svga_t *)priv; - ibm8514_t *dev = &svga->dev8514; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = &svga->dev8514; /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; + if (port < 0x0102) + return; /* Save the MCA register value. */ dev->pos_regs[port & 7] = val; } - static uint8_t ibm8514_mca_feedb(void *priv) { - svga_t *svga = (svga_t *)priv; - ibm8514_t *dev = &svga->dev8514; + svga_t *svga = (svga_t *) priv; + ibm8514_t *dev = &svga->dev8514; return dev->pos_regs[2] & 1; } - static void -*ibm8514_init(const device_t *info) + * + ibm8514_init(const device_t *info) { - svga_t *svga = svga_get_pri(); - ibm8514_t *dev = &svga->dev8514; + svga_t *svga = svga_get_pri(); + ibm8514_t *dev = &svga->dev8514; - dev->vram_size = 1024 << 10; - dev->vram = calloc(dev->vram_size, 1); + dev->vram_size = 1024 << 10; + dev->vram = calloc(dev->vram_size, 1); dev->changedvram = calloc(dev->vram_size >> 12, 1); - dev->vram_mask = dev->vram_size - 1; - dev->map8 = svga->pallook; + dev->vram_mask = dev->vram_size - 1; + dev->map8 = svga->pallook; dev->type = info->flags; @@ -3407,8 +3597,8 @@ static void static void ibm8514_close(void *p) { - svga_t *svga = (svga_t *)p; - ibm8514_t *dev = &svga->dev8514; + svga_t *svga = (svga_t *) p; + ibm8514_t *dev = &svga->dev8514; if (dev) { free(dev->vram); @@ -3419,7 +3609,7 @@ ibm8514_close(void *p) static void ibm8514_speed_changed(void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; svga_recalctimings(svga); } @@ -3427,9 +3617,9 @@ ibm8514_speed_changed(void *p) static void ibm8514_force_redraw(void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - svga->fullchange = changeframecount; + svga->fullchange = changeframecount; } // clang-format off diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 4c5f8cb24..2fb58aa5b 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -32,296 +32,293 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> - #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) -#define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" +# define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin" #endif -#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" -#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" +#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin" +#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi" enum { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - ATI18800_WONDER = 0, - ATI18800_VGA88, - ATI18800_EDGE16 + ATI18800_WONDER = 0, + ATI18800_VGA88, + ATI18800_EDGE16 #else - ATI18800_VGA88 = 0, - ATI18800_EDGE16 + ATI18800_VGA88 = 0, + ATI18800_EDGE16 #endif }; +typedef struct ati18800_t { + svga_t svga; + ati_eeprom_t eeprom; -typedef struct ati18800_t -{ - svga_t svga; - ati_eeprom_t eeprom; + rom_t bios_rom; - rom_t bios_rom; - - uint8_t regs[256]; - int index; + uint8_t regs[256]; + int index; } ati18800_t; -static video_timings_t timing_ati18800 = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +static video_timings_t timing_ati18800 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; - -static void ati18800_out(uint16_t addr, uint8_t val, void *p) +static void +ati18800_out(uint16_t addr, uint8_t val, void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; - svga_t *svga = &ati18800->svga; - uint8_t old; + ati18800_t *ati18800 = (ati18800_t *) p; + svga_t *svga = &ati18800->svga; + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x1ce: - ati18800->index = val; - break; - case 0x1cf: - ati18800->regs[ati18800->index] = val; - switch (ati18800->index) - { - case 0xb0: - svga_recalctimings(svga); - break; - case 0xb2: - case 0xbe: - if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ - { - svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; - } - else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; - break; - case 0xb3: - ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); - break; - } - break; + switch (addr) { + case 0x1ce: + ati18800->index = val; + break; + case 0x1cf: + ati18800->regs[ati18800->index] = val; + switch (ati18800->index) { + case 0xb0: + svga_recalctimings(svga); + break; + case 0xb2: + case 0xbe: + if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/ + { + svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000; + svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + } else /*Single bank mode*/ + svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000; + break; + case 0xb3: + ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1); + break; + } + break; - case 0x3D4: - svga->crtcreg = val & 0x3f; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } - break; - } - svga_out(addr, val, svga); + } + break; + } + svga_out(addr, val, svga); } -static uint8_t ati18800_in(uint16_t addr, void *p) +static uint8_t +ati18800_in(uint16_t addr, void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; - svga_t *svga = &ati18800->svga; - uint8_t temp = 0xff; + ati18800_t *ati18800 = (ati18800_t *) p; + svga_t *svga = &ati18800->svga; + uint8_t temp = 0xff; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x1ce: - temp = ati18800->index; - break; - case 0x1cf: - switch (ati18800->index) - { - case 0xb7: - temp = ati18800->regs[ati18800->index] & ~8; - if (ati_eeprom_read(&ati18800->eeprom)) - temp |= 8; - break; - default: - temp = ati18800->regs[ati18800->index]; - break; - } - break; - - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - break; + switch (addr) { + case 0x1ce: + temp = ati18800->index; + break; + case 0x1cf: + switch (ati18800->index) { + case 0xb7: + temp = ati18800->regs[ati18800->index] & ~8; + if (ati_eeprom_read(&ati18800->eeprom)) + temp |= 8; + break; default: - temp = svga_in(addr, svga); - break; - } - return temp; + temp = ati18800->regs[ati18800->index]; + break; + } + break; + + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + return temp; } -static void ati18800_recalctimings(svga_t *svga) +static void +ati18800_recalctimings(svga_t *svga) { - ati18800_t *ati18800 = (ati18800_t *)svga->p; + ati18800_t *ati18800 = (ati18800_t *) svga->p; - if(svga->crtc[0x17] & 4) - { - svga->vtotal <<= 1; - svga->dispend <<= 1; - svga->vsyncstart <<= 1; - svga->split <<= 1; - svga->vblankstart <<= 1; - } + if (svga->crtc[0x17] & 4) { + svga->vtotal <<= 1; + svga->dispend <<= 1; + svga->vsyncstart <<= 1; + svga->split <<= 1; + svga->vblankstart <<= 1; + } - if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/ - { - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - svga->rowoffset <<= 1; - svga->ma <<= 1; - } + if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/ + { + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + svga->rowoffset <<= 1; + svga->ma <<= 1; + } } -static void *ati18800_init(const device_t *info) +static void * +ati18800_init(const device_t *info) { - ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); - memset(ati18800, 0, sizeof(ati18800_t)); + ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); + memset(ati18800, 0, sizeof(ati18800_t)); - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800); - switch (info->local) { + switch (info->local) { #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - case ATI18800_WONDER: + case ATI18800_WONDER: #endif - default: + default: #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; + rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; #endif - case ATI18800_VGA88: - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case ATI18800_EDGE16: - rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - }; + case ATI18800_VGA88: + rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case ATI18800_EDGE16: + rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + }; - if (info->local == ATI18800_EDGE16) { - svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } else { - svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/ - ati18800_recalctimings, - ati18800_in, ati18800_out, - NULL, - NULL); - } + if (info->local == ATI18800_EDGE16) { + svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/ + ati18800_recalctimings, + ati18800_in, ati18800_out, + NULL, + NULL); + } else { + svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/ + ati18800_recalctimings, + ati18800_in, ati18800_out, + NULL, + NULL); + } - io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); + io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800); - ati18800->svga.miscout = 1; + ati18800->svga.miscout = 1; - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); - return ati18800; + return ati18800; } #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) -static int ati18800_wonder_available(void) +static int +ati18800_wonder_available(void) { - return rom_present(BIOS_ROM_PATH_WONDER); + return rom_present(BIOS_ROM_PATH_WONDER); } #endif -static int ati18800_vga88_available(void) +static int +ati18800_vga88_available(void) { - return rom_present(BIOS_ROM_PATH_VGA88); + return rom_present(BIOS_ROM_PATH_VGA88); } -static int ati18800_available(void) +static int +ati18800_available(void) { - return rom_present(BIOS_ROM_PATH_EDGE16); + return rom_present(BIOS_ROM_PATH_EDGE16); } -static void ati18800_close(void *p) +static void +ati18800_close(void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; + ati18800_t *ati18800 = (ati18800_t *) p; - svga_close(&ati18800->svga); + svga_close(&ati18800->svga); - free(ati18800); + free(ati18800); } -static void ati18800_speed_changed(void *p) +static void +ati18800_speed_changed(void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; + ati18800_t *ati18800 = (ati18800_t *) p; - svga_recalctimings(&ati18800->svga); + svga_recalctimings(&ati18800->svga); } -static void ati18800_force_redraw(void *p) +static void +ati18800_force_redraw(void *p) { - ati18800_t *ati18800 = (ati18800_t *)p; + ati18800_t *ati18800 = (ati18800_t *) p; - ati18800->svga.fullchange = changeframecount; + ati18800->svga.fullchange = changeframecount; } #if defined(DEV_BRANCH) && defined(USE_VGAWONDER) const device_t ati18800_wonder_device = { - .name = "ATI-18800", + .name = "ATI-18800", .internal_name = "ati18800w", - .flags = DEVICE_ISA, - .local = ATI18800_WONDER, - .init = ati18800_init, - .close = ati18800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = ATI18800_WONDER, + .init = ati18800_init, + .close = ati18800_close, + .reset = NULL, { .available = ati18800_wonder_available }, .speed_changed = ati18800_speed_changed, - .force_redraw = ati18800_force_redraw, - .config = NULL + .force_redraw = ati18800_force_redraw, + .config = NULL }; #endif -const device_t ati18800_vga88_device = -{ - .name = "ATI-18800-1", +const device_t ati18800_vga88_device = { + .name = "ATI-18800-1", .internal_name = "ati18800v", - .flags = DEVICE_ISA, - .local = ATI18800_VGA88, - .init = ati18800_init, - .close = ati18800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = ATI18800_VGA88, + .init = ati18800_init, + .close = ati18800_close, + .reset = NULL, { .available = ati18800_vga88_available }, .speed_changed = ati18800_speed_changed, - .force_redraw = ati18800_force_redraw, - .config = NULL + .force_redraw = ati18800_force_redraw, + .config = NULL }; -const device_t ati18800_device = -{ - .name = "ATI-18800-5", +const device_t ati18800_device = { + .name = "ATI-18800-5", .internal_name = "ati18800", - .flags = DEVICE_ISA, - .local = ATI18800_EDGE16, - .init = ati18800_init, - .close = ati18800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = ATI18800_EDGE16, + .init = ati18800_init, + .close = ati18800_close, + .reset = NULL, { .available = ati18800_available }, .speed_changed = ati18800_speed_changed, - .force_redraw = ati18800_force_redraw, - .config = NULL + .force_redraw = ati18800_force_redraw, + .config = NULL }; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index 87abb7da8..06b61d41f 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -36,461 +36,484 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> - -#define VGAWONDERXL 1 +#define VGAWONDERXL 1 #if defined(DEV_BRANCH) && defined(USE_XL24) -#define VGAWONDERXL24 2 +# define VGAWONDERXL24 2 #endif -#define BIOS_ATIKOR_PATH "roms/video/ati28800/atikorvga.bin" +#define BIOS_ATIKOR_PATH "roms/video/ati28800/atikorvga.bin" #define BIOS_ATIKOR_4620P_PATH_L "roms/machines/spc4620p/31005h.u8" #define BIOS_ATIKOR_4620P_PATH_H "roms/machines/spc4620p/31005h.u10" -#define BIOS_ATIKOR_6033P_PATH "roms/machines/spc6033p/phoenix.BIN" -#define FONT_ATIKOR_PATH "roms/video/ati28800/ati_ksc5601.rom" -#define FONT_ATIKOR_4620P_PATH "roms/machines/spc4620p/svb6120a_font.rom" -#define FONT_ATIKOR_6033P_PATH "roms/machines/spc6033p/svb6120a_font.rom" +#define BIOS_ATIKOR_6033P_PATH "roms/machines/spc6033p/phoenix.BIN" +#define FONT_ATIKOR_PATH "roms/video/ati28800/ati_ksc5601.rom" +#define FONT_ATIKOR_4620P_PATH "roms/machines/spc4620p/svb6120a_font.rom" +#define FONT_ATIKOR_6033P_PATH "roms/machines/spc6033p/svb6120a_font.rom" -#define BIOS_VGAXL_EVEN_PATH "roms/video/ati28800/xleven.bin" -#define BIOS_VGAXL_ODD_PATH "roms/video/ati28800/xlodd.bin" +#define BIOS_VGAXL_EVEN_PATH "roms/video/ati28800/xleven.bin" +#define BIOS_VGAXL_ODD_PATH "roms/video/ati28800/xlodd.bin" #if defined(DEV_BRANCH) && defined(USE_XL24) -#define BIOS_XL24_EVEN_PATH "roms/video/ati28800/112-14318-102.bin" -#define BIOS_XL24_ODD_PATH "roms/video/ati28800/112-14319-102.bin" +# define BIOS_XL24_EVEN_PATH "roms/video/ati28800/112-14318-102.bin" +# define BIOS_XL24_ODD_PATH "roms/video/ati28800/112-14319-102.bin" #endif -#define BIOS_ROM_PATH "roms/video/ati28800/bios.bin" +#define BIOS_ROM_PATH "roms/video/ati28800/bios.bin" #define BIOS_VGAXL_ROM_PATH "roms/video/ati28800/ATI_VGAWonder_XL.bin" +typedef struct ati28800_t { + svga_t svga; + ati_eeprom_t eeprom; -typedef struct ati28800_t -{ - svga_t svga; - ati_eeprom_t eeprom; + rom_t bios_rom; - rom_t bios_rom; + uint8_t regs[256]; + int index; + uint16_t vtotal; - uint8_t regs[256]; - int index; - uint16_t vtotal; + uint32_t memory; + uint8_t id; - uint32_t memory; - uint8_t id; + uint8_t port_03dd_val; + uint16_t get_korean_font_kind; + int in_get_korean_font_kind_set; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; + int ksc5601_mode_enabled; - uint8_t port_03dd_val; - uint16_t get_korean_font_kind; - int in_get_korean_font_kind_set; - int get_korean_font_enabled; - int get_korean_font_index; - uint16_t get_korean_font_base; - int ksc5601_mode_enabled; - - int type, type_korean; + int type, type_korean; } ati28800_t; - -static video_timings_t timing_ati28800 = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; -static video_timings_t timing_ati28800_spc = {VIDEO_ISA, 2, 2, 4, 4, 4, 8}; - +static video_timings_t timing_ati28800 = { .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_ati28800_spc = { .type = VIDEO_ISA, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 4, .read_w = 4, .read_l = 8 }; #ifdef ENABLE_ATI28800_LOG int ati28800_do_log = ENABLE_ATI28800_LOG; - static void ati28800_log(const char *fmt, ...) { va_list ap; if (ati28800_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ati28800_log(fmt, ...) +# define ati28800_log(fmt, ...) #endif - static void ati28800_recalctimings(svga_t *svga); static void ati28800_out(uint16_t addr, uint8_t val, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t old; + ati28800_t *ati28800 = (ati28800_t *) p; + svga_t *svga = &ati28800->svga; + uint8_t old; ati28800_log("ati28800_out : %04X %02X\n", addr, val); if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x1ce: - ati28800->index = val; - break; - case 0x1cf: - old = ati28800->regs[ati28800->index]; - ati28800->regs[ati28800->index] = val; - ati28800_log("ATI 28800 write reg=0x%02X, val=0x%02X\n", ati28800->index, val); - switch (ati28800->index) { - case 0xa3: - if ((old ^ val) & 0x10) - svga_recalctimings(svga); - break; - case 0xa7: - if ((old ^ val) & 0x80) - svga_recalctimings(svga); - break; - case 0xb0: - if ((old ^ val) & 0x60) - svga_recalctimings(svga); - break; - case 0xb2: - case 0xbe: - if (ati28800->regs[0xbe] & 0x08) { /* Read/write bank mode */ - svga->read_bank = (((ati28800->regs[0xb2] & 0x01) << 3) | ((ati28800->regs[0xb2] & 0xe0) >> 5)) * 0x10000; - svga->write_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; - } else { /* Single bank mode */ - svga->read_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; - svga->write_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; - } - if (ati28800->index == 0xbe) { - if ((old ^ val) & 0x10) - svga_recalctimings(svga); - } - break; - case 0xb3: - ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); - break; - case 0xb6: - if ((old ^ val) & 0x10) - svga_recalctimings(svga); - break; - case 0xb8: - if ((old ^ val) & 0x40) - svga_recalctimings(svga); - break; - case 0xb9: - if ((old ^ val) & 2) - svga_recalctimings(svga); - break; - } - break; + case 0x1ce: + ati28800->index = val; + break; + case 0x1cf: + old = ati28800->regs[ati28800->index]; + ati28800->regs[ati28800->index] = val; + ati28800_log("ATI 28800 write reg=0x%02X, val=0x%02X\n", ati28800->index, val); + switch (ati28800->index) { + case 0xa3: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xa7: + if ((old ^ val) & 0x80) + svga_recalctimings(svga); + break; + case 0xb0: + if ((old ^ val) & 0x60) + svga_recalctimings(svga); + break; + case 0xb2: + case 0xbe: + if (ati28800->regs[0xbe] & 0x08) { /* Read/write bank mode */ + svga->read_bank = (((ati28800->regs[0xb2] & 0x01) << 3) | ((ati28800->regs[0xb2] & 0xe0) >> 5)) * 0x10000; + svga->write_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; + } else { /* Single bank mode */ + svga->read_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; + svga->write_bank = ((ati28800->regs[0xb2] & 0x1e) >> 1) * 0x10000; + } + if (ati28800->index == 0xbe) { + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + } + break; + case 0xb3: + ati_eeprom_write(&ati28800->eeprom, val & 8, val & 2, val & 1); + break; + case 0xb6: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xb8: + if ((old ^ val) & 0x40) + svga_recalctimings(svga); + break; + case 0xb9: + if ((old ^ val) & 2) + svga_recalctimings(svga); + break; + } + break; - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (ati28800->type == 1) - sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); - else - svga_out(addr, val, svga); - return; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (ati28800->type == 1) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + return; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } - break; + } + break; } svga_out(addr, val, svga); } - static void ati28800k_out(uint16_t addr, uint8_t val, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; + ati28800_t *ati28800 = (ati28800_t *) p; + svga_t *svga = &ati28800->svga; + uint16_t oldaddr = addr; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x1CF: - if (ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) { - ati28800->ksc5601_mode_enabled = val & 0x20; - svga_recalctimings(svga); - } - ati28800_out(oldaddr, val, p); - break; - case 0x3DD: - ati28800->port_03dd_val = val; - if (val == 1) - ati28800->get_korean_font_enabled = 0; - if (ati28800->in_get_korean_font_kind_set) { - ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); - ati28800->get_korean_font_enabled = 1; - ati28800->get_korean_font_index = 0; - ati28800->in_get_korean_font_kind_set = 0; - } - break; - case 0x3DE: - ati28800->in_get_korean_font_kind_set = 0; - if (ati28800->get_korean_font_enabled) { - if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) { - fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + - (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index] = val; - } - ati28800->get_korean_font_index++; - ati28800->get_korean_font_index &= 0x1F; - } else { - switch (ati28800->port_03dd_val) { - case 0x10: - ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); - break; - case 8: - ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); - break; - case 1: - ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; - if (val & 2) - ati28800->in_get_korean_font_kind_set = 1; - break; - } - break; - } - break; - default: - ati28800_out(oldaddr, val, p); - break; + case 0x1CF: + if (ati28800->index == 0xBF && ((ati28800->regs[0xBF] ^ val) & 0x20)) { + ati28800->ksc5601_mode_enabled = val & 0x20; + svga_recalctimings(svga); + } + ati28800_out(oldaddr, val, p); + break; + case 0x3DD: + ati28800->port_03dd_val = val; + if (val == 1) + ati28800->get_korean_font_enabled = 0; + if (ati28800->in_get_korean_font_kind_set) { + ati28800->get_korean_font_kind = (val << 8) | (ati28800->get_korean_font_kind & 0xFF); + ati28800->get_korean_font_enabled = 1; + ati28800->get_korean_font_index = 0; + ati28800->in_get_korean_font_kind_set = 0; + } + break; + case 0x3DE: + ati28800->in_get_korean_font_kind_set = 0; + if (ati28800->get_korean_font_enabled) { + if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) { + fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index] = val; + } + ati28800->get_korean_font_index++; + ati28800->get_korean_font_index &= 0x1F; + } else { + switch (ati28800->port_03dd_val) { + case 0x10: + ati28800->get_korean_font_base = ((val & 0x7F) << 7) | (ati28800->get_korean_font_base & 0x7F); + break; + case 8: + ati28800->get_korean_font_base = (ati28800->get_korean_font_base & 0x3F80) | (val & 0x7F); + break; + case 1: + ati28800->get_korean_font_kind = (ati28800->get_korean_font_kind & 0xFF00) | val; + if (val & 2) + ati28800->in_get_korean_font_kind_set = 1; + break; + } + break; + } + break; + default: + ati28800_out(oldaddr, val, p); + break; } } - static uint8_t ati28800_in(uint16_t addr, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint8_t temp; + ati28800_t *ati28800 = (ati28800_t *) p; + svga_t *svga = &ati28800->svga; + uint8_t temp; if (addr != 0x3da) - ati28800_log("ati28800_in : %04X ", addr); + ati28800_log("ati28800_in : %04X ", addr); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x1ce: - temp = ati28800->index; - break; - case 0x1cf: - switch (ati28800->index) { - case 0xaa: - temp = ati28800->id; - break; - case 0xb0: - temp = ati28800->regs[0xb0] | 0x80; - if (ati28800->memory == 1024) { - temp &= ~0x10; - temp |= 0x08; - } else if (ati28800->memory == 512) { - temp |= 0x10; - temp &= ~0x08; - } else { - temp &= ~0x18; - } - break; - case 0xb7: - temp = ati28800->regs[0xb7] & ~8; - if (ati_eeprom_read(&ati28800->eeprom)) - temp |= 8; - break; + case 0x1ce: + temp = ati28800->index; + break; + case 0x1cf: + switch (ati28800->index) { + case 0xaa: + temp = ati28800->id; + break; + case 0xb0: + temp = ati28800->regs[0xb0] | 0x80; + if (ati28800->memory == 1024) { + temp &= ~0x10; + temp |= 0x08; + } else if (ati28800->memory == 512) { + temp |= 0x10; + temp &= ~0x08; + } else { + temp &= ~0x18; + } + break; + case 0xb7: + temp = ati28800->regs[0xb7] & ~8; + if (ati_eeprom_read(&ati28800->eeprom)) + temp |= 8; + break; - default: - temp = ati28800->regs[ati28800->index]; - break; - } - break; + default: + temp = ati28800->regs[ati28800->index]; + break; + } + break; - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) - temp = 0; - else - temp = 0x10; - break; + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) + temp = 0; + else + temp = 0x10; + break; - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (ati28800->type == 1) - return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); - return svga_in(addr, svga); + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (ati28800->type == 1) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - break; - default: - temp = svga_in(addr, svga); - break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; } if (addr != 0x3da) - ati28800_log("%02X\n", temp); + ati28800_log("%02X\n", temp); return temp; } - static uint8_t ati28800k_in(uint16_t addr, void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; - svga_t *svga = &ati28800->svga; - uint16_t oldaddr = addr; - uint8_t temp = 0xFF; + ati28800_t *ati28800 = (ati28800_t *) p; + svga_t *svga = &ati28800->svga; + uint16_t oldaddr = addr; + uint8_t temp = 0xFF; if (addr != 0x3da) - ati28800_log("ati28800k_in : %04X ", addr); + ati28800_log("ati28800k_in : %04X ", addr); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3DE: - if (ati28800->get_korean_font_enabled) { - switch (ati28800->get_korean_font_kind >> 8) { - case 4: /* ROM font */ - temp = fontdatksc5601[ati28800->get_korean_font_base].chr[ati28800->get_korean_font_index++]; - break; - case 2: /* User defined font */ - if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) { - temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + - (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index]; - } else - temp = 0xFF; - ati28800->get_korean_font_index++; - break; - default: - break; - } - ati28800->get_korean_font_index &= 0x1F; - } - break; - default: - temp = ati28800_in(oldaddr, p); - break; + case 0x3DE: + if (ati28800->get_korean_font_enabled) { + switch (ati28800->get_korean_font_kind >> 8) { + case 4: /* ROM font */ + temp = fontdatksc5601[ati28800->get_korean_font_base].chr[ati28800->get_korean_font_index++]; + break; + case 2: /* User defined font */ + if ((ati28800->get_korean_font_base & 0x7F) > 0x20 && (ati28800->get_korean_font_base & 0x7F) < 0x7F) { + temp = fontdatksc5601_user[(ati28800->get_korean_font_kind & 4) * 24 + (ati28800->get_korean_font_base & 0x7F) - 0x20].chr[ati28800->get_korean_font_index]; + } else + temp = 0xFF; + ati28800->get_korean_font_index++; + break; + default: + break; + } + ati28800->get_korean_font_index &= 0x1F; + } + break; + default: + temp = ati28800_in(oldaddr, p); + break; } if (addr != 0x3da) - ati28800_log("%02X\n", temp); + ati28800_log("%02X\n", temp); return temp; } - static void ati28800_recalctimings(svga_t *svga) { - ati28800_t *ati28800 = (ati28800_t *)svga->p; + ati28800_t *ati28800 = (ati28800_t *) svga->p; - if (ati28800->regs[0xa3] & 0x10) - svga->ma_latch |= 0x10000; + if (ati28800->regs[0xa3] & 0x10) + svga->ma_latch |= 0x10000; - if (ati28800->regs[0xb0] & 0x40) - svga->ma_latch |= 0x20000; + if (ati28800->regs[0xb0] & 0x40) + svga->ma_latch |= 0x20000; - switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | - ((svga->miscout & 0x0C) >> 2)) { - case 0x00: svga->clock = (cpuclock * (double)(1ull << 32)) / 42954000.0; break; - case 0x01: svga->clock = (cpuclock * (double)(1ull << 32)) / 48771000.0; break; - case 0x02: ati28800_log ("clock 2\n"); break; - case 0x03: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; - case 0x04: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; - case 0x05: svga->clock = (cpuclock * (double)(1ull << 32)) / 56640000.0; break; - case 0x06: ati28800_log ("clock 2\n"); break; - case 0x07: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; - case 0x08: svga->clock = (cpuclock * (double)(1ull << 32)) / 30240000.0; break; - case 0x09: svga->clock = (cpuclock * (double)(1ull << 32)) / 32000000.0; break; - case 0x0A: svga->clock = (cpuclock * (double)(1ull << 32)) / 37500000.0; break; - case 0x0B: svga->clock = (cpuclock * (double)(1ull << 32)) / 39000000.0; break; - case 0x0C: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; - case 0x0D: svga->clock = (cpuclock * (double)(1ull << 32)) / 56644000.0; break; - case 0x0E: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; - case 0x0F: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; - default: break; - } + switch (((ati28800->regs[0xbe] & 0x10) >> 1) | ((ati28800->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0C) >> 2)) { + case 0x00: + svga->clock = (cpuclock * (double) (1ull << 32)) / 42954000.0; + break; + case 0x01: + svga->clock = (cpuclock * (double) (1ull << 32)) / 48771000.0; + break; + case 0x02: + ati28800_log("clock 2\n"); + break; + case 0x03: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + case 0x04: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0; + break; + case 0x05: + svga->clock = (cpuclock * (double) (1ull << 32)) / 56640000.0; + break; + case 0x06: + ati28800_log("clock 2\n"); + break; + case 0x07: + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; + break; + case 0x08: + svga->clock = (cpuclock * (double) (1ull << 32)) / 30240000.0; + break; + case 0x09: + svga->clock = (cpuclock * (double) (1ull << 32)) / 32000000.0; + break; + case 0x0A: + svga->clock = (cpuclock * (double) (1ull << 32)) / 37500000.0; + break; + case 0x0B: + svga->clock = (cpuclock * (double) (1ull << 32)) / 39000000.0; + break; + case 0x0C: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0; + break; + case 0x0D: + svga->clock = (cpuclock * (double) (1ull << 32)) / 56644000.0; + break; + case 0x0E: + svga->clock = (cpuclock * (double) (1ull << 32)) / 75000000.0; + break; + case 0x0F: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0; + break; + default: + break; + } - if (ati28800->regs[0xb8] & 0x40) - svga->clock *= 2; + if (ati28800->regs[0xb8] & 0x40) + svga->clock *= 2; - if (ati28800->regs[0xa7] & 0x80) - svga->clock *= 3; + if (ati28800->regs[0xa7] & 0x80) + svga->clock *= 3; - if (ati28800->regs[0xb6] & 0x10) { - svga->hdisp <<= 1; - svga->htotal <<= 1; - svga->rowoffset <<= 1; - svga->gdcreg[5] &= ~0x40; - } + if (ati28800->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->rowoffset <<= 1; + svga->gdcreg[5] &= ~0x40; + } - if (ati28800->regs[0xb0] & 0x20) { - svga->gdcreg[5] |= 0x40; - } + if (ati28800->regs[0xb0] & 0x20) { + svga->gdcreg[5] |= 0x40; + } - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: case 0x60: /*256+ colours*/ - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } - break; - case 15: - if (svga->lowres) - svga->render = svga_render_15bpp_lowres; - else { - svga->render = svga_render_15bpp_highres; - svga->hdisp >>= 1; - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } - break; - } - break; - } - } - } + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + break; + case 15: + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; + else { + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + break; + } + break; + } + } + } } - static void ati28800k_recalctimings(svga_t *svga) { @@ -499,7 +522,7 @@ ati28800k_recalctimings(svga_t *svga) ati28800_recalctimings(svga); if (svga->render == svga_render_text_80 && ati28800->ksc5601_mode_enabled) - svga->render = svga_render_text_80_ksc5601; + svga->render = svga_render_text_80_ksc5601; } void * @@ -508,57 +531,57 @@ ati28800k_init(const device_t *info) ati28800_t *ati28800 = (ati28800_t *) malloc(sizeof(ati28800_t)); memset(ati28800, 0, sizeof(ati28800_t)); - ati28800->type_korean = info->local; + ati28800->type_korean = info->local; if (ati28800->type_korean == 0) { - ati28800->memory = device_get_config_int("memory"); - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800); + ati28800->memory = device_get_config_int("memory"); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800); } else { - ati28800->memory = 512; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800_spc); + ati28800->memory = 512; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati28800_spc); } - ati28800->port_03dd_val = 0; - ati28800->get_korean_font_base = 0; - ati28800->get_korean_font_index = 0; - ati28800->get_korean_font_enabled = 0; - ati28800->get_korean_font_kind = 0; + ati28800->port_03dd_val = 0; + ati28800->get_korean_font_base = 0; + ati28800->get_korean_font_index = 0; + ati28800->get_korean_font_enabled = 0; + ati28800->get_korean_font_kind = 0; ati28800->in_get_korean_font_kind_set = 0; - ati28800->ksc5601_mode_enabled = 0; + ati28800->ksc5601_mode_enabled = 0; - switch(ati28800->type_korean) { - case 0: - default: - rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont(FONT_ATIKOR_PATH, 6); - break; - case 1: - rom_init_interleaved(&ati28800->bios_rom, BIOS_ATIKOR_4620P_PATH_L, BIOS_ATIKOR_4620P_PATH_H, 0xc0000, - 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont(FONT_ATIKOR_4620P_PATH, 6); - break; - case 2: - rom_init(&ati28800->bios_rom, BIOS_ATIKOR_6033P_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - loadfont(FONT_ATIKOR_6033P_PATH, 6); - break; + switch (ati28800->type_korean) { + case 0: + default: + rom_init(&ati28800->bios_rom, BIOS_ATIKOR_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_PATH, 6); + break; + case 1: + rom_init_interleaved(&ati28800->bios_rom, BIOS_ATIKOR_4620P_PATH_L, BIOS_ATIKOR_4620P_PATH_H, 0xc0000, + 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_4620P_PATH, 6); + break; + case 2: + rom_init(&ati28800->bios_rom, BIOS_ATIKOR_6033P_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + loadfont(FONT_ATIKOR_6033P_PATH, 6); + break; } svga_init(info, &ati28800->svga, ati28800, ati28800->memory << 10, /*Memory size, default 512KB*/ - ati28800k_recalctimings, - ati28800k_in, ati28800k_out, - NULL, - NULL); + ati28800k_recalctimings, + ati28800k_in, ati28800k_out, + NULL, + NULL); io_sethandler(0x01ce, 0x0002, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); io_sethandler(0x03c0, 0x0020, ati28800k_in, NULL, NULL, ati28800k_out, NULL, NULL, ati28800); - ati28800->svga.miscout = 1; - ati28800->svga.bpp = 8; - ati28800->svga.packed_chain4 = 1; - ati28800->svga.ksc5601_sbyte_mask = 0; - ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; - ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; - ati28800->svga.ksc5601_swap_mode = 0; + ati28800->svga.miscout = 1; + ati28800->svga.bpp = 8; + ati28800->svga.packed_chain4 = 1; + ati28800->svga.ksc5601_sbyte_mask = 0; + ati28800->svga.ksc5601_udc_area_msb[0] = 0xC9; + ati28800->svga.ksc5601_udc_area_msb[1] = 0xFE; + ati28800->svga.ksc5601_swap_mode = 0; ati28800->svga.ksc5601_english_font_type = 0; ati_eeprom_load(&ati28800->eeprom, "atikorvga.nvr", 0); @@ -566,7 +589,6 @@ ati28800k_init(const device_t *info) return ati28800; } - static void * ati28800_init(const device_t *info) { @@ -578,129 +600,122 @@ ati28800_init(const device_t *info) ati28800->memory = device_get_config_int("memory"); - ati28800->type = info->local; + ati28800->type = info->local; - switch(ati28800->type) { - case VGAWONDERXL: - ati28800->id = 5; - rom_init(&ati28800->bios_rom, - BIOS_VGAXL_ROM_PATH, - 0xc0000, 0x8000, 0x7fff, - 0, MEM_MAPPING_EXTERNAL); - ati28800->svga.ramdac = device_add(&sc11486_ramdac_device); - break; + switch (ati28800->type) { + case VGAWONDERXL: + ati28800->id = 5; + rom_init(&ati28800->bios_rom, + BIOS_VGAXL_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + ati28800->svga.ramdac = device_add(&sc11486_ramdac_device); + break; #if defined(DEV_BRANCH) && defined(USE_XL24) - case VGAWONDERXL24: - ati28800->id = 6; - rom_init_interleaved(&ati28800->bios_rom, - BIOS_XL24_EVEN_PATH, - BIOS_XL24_ODD_PATH, - 0xc0000, 0x10000, 0xffff, - 0, MEM_MAPPING_EXTERNAL); - break; + case VGAWONDERXL24: + ati28800->id = 6; + rom_init_interleaved(&ati28800->bios_rom, + BIOS_XL24_EVEN_PATH, + BIOS_XL24_ODD_PATH, + 0xc0000, 0x10000, 0xffff, + 0, MEM_MAPPING_EXTERNAL); + break; #endif - default: - ati28800->id = 5; - rom_init(&ati28800->bios_rom, - BIOS_ROM_PATH, - 0xc0000, 0x8000, 0x7fff, - 0, MEM_MAPPING_EXTERNAL); - break; + default: + ati28800->id = 5; + rom_init(&ati28800->bios_rom, + BIOS_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + break; } svga_init(info, &ati28800->svga, ati28800, ati28800->memory << 10, /*default: 512kb*/ - ati28800_recalctimings, - ati28800_in, ati28800_out, - NULL, - NULL); + ati28800_recalctimings, + ati28800_in, ati28800_out, + NULL, + NULL); io_sethandler(0x01ce, 2, - ati28800_in, NULL, NULL, - ati28800_out, NULL, NULL, ati28800); + ati28800_in, NULL, NULL, + ati28800_out, NULL, NULL, ati28800); io_sethandler(0x03c0, 32, - ati28800_in, NULL, NULL, - ati28800_out, NULL, NULL, ati28800); + ati28800_in, NULL, NULL, + ati28800_out, NULL, NULL, ati28800); - ati28800->svga.miscout = 1; - ati28800->svga.bpp = 8; - ati28800->svga.packed_chain4 = 1; + ati28800->svga.miscout = 1; + ati28800->svga.bpp = 8; + ati28800->svga.packed_chain4 = 1; switch (ati28800->type) { - case VGAWONDERXL: - ati_eeprom_load(&ati28800->eeprom, "ati28800xl.nvr", 0); - break; + case VGAWONDERXL: + ati_eeprom_load(&ati28800->eeprom, "ati28800xl.nvr", 0); + break; #if defined(DEV_BRANCH) && defined(USE_XL24) - case VGAWONDERXL24: - ati_eeprom_load(&ati28800->eeprom, "ati28800xl24.nvr", 0); - break; + case VGAWONDERXL24: + ati_eeprom_load(&ati28800->eeprom, "ati28800xl24.nvr", 0); + break; #endif - default: - ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); - break; + default: + ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); + break; } - return(ati28800); + return (ati28800); } - static int ati28800_available(void) { - return(rom_present(BIOS_ROM_PATH)); + return (rom_present(BIOS_ROM_PATH)); } - static int ati28800k_available(void) { return ((rom_present(BIOS_ATIKOR_PATH) && rom_present(FONT_ATIKOR_PATH))); } - static int compaq_ati28800_available(void) { - return((rom_present(BIOS_VGAXL_ROM_PATH))); + return ((rom_present(BIOS_VGAXL_ROM_PATH))); } - #if defined(DEV_BRANCH) && defined(USE_XL24) static int ati28800_wonderxl24_available(void) { - return((rom_present(BIOS_XL24_EVEN_PATH) && rom_present(BIOS_XL24_ODD_PATH))); + return ((rom_present(BIOS_XL24_EVEN_PATH) && rom_present(BIOS_XL24_ODD_PATH))); } #endif - static void ati28800_close(void *priv) { - ati28800_t *ati28800 = (ati28800_t *)priv; + ati28800_t *ati28800 = (ati28800_t *) priv; svga_close(&ati28800->svga); free(ati28800); } - static void ati28800_speed_changed(void *p) { - ati28800_t *ati28800 = (ati28800_t *)p; + ati28800_t *ati28800 = (ati28800_t *) p; - svga_recalctimings(&ati28800->svga); + svga_recalctimings(&ati28800->svga); } - static void ati28800_force_redraw(void *priv) { - ati28800_t *ati28800 = (ati28800_t *)priv; + ati28800_t *ati28800 = (ati28800_t *) priv; ati28800->svga.fullchange = changeframecount; } @@ -768,87 +783,87 @@ static const device_config_t ati28800_wonderxl_config[] = { // clang-format on const device_t ati28800_device = { - .name = "ATI 28800-5 (ATI VGA Charger)", + .name = "ATI 28800-5 (ATI VGA Charger)", .internal_name = "ati28800", - .flags = DEVICE_ISA, - .local = 0, - .init = ati28800_init, - .close = ati28800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = ati28800_init, + .close = ati28800_close, + .reset = NULL, { .available = ati28800_available }, .speed_changed = ati28800_speed_changed, - .force_redraw = ati28800_force_redraw, - .config = ati28800_config + .force_redraw = ati28800_force_redraw, + .config = ati28800_config }; const device_t ati28800k_device = { - .name = "ATI Korean VGA", + .name = "ATI Korean VGA", .internal_name = "ati28800k", - .flags = DEVICE_ISA, - .local = 0, - .init = ati28800k_init, - .close = ati28800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = ati28800k_init, + .close = ati28800_close, + .reset = NULL, { .available = ati28800k_available }, .speed_changed = ati28800_speed_changed, - .force_redraw = ati28800_force_redraw, - .config = ati28800_config + .force_redraw = ati28800_force_redraw, + .config = ati28800_config }; const device_t ati28800k_spc4620p_device = { - .name = "ATI Korean VGA On-Board SPC-4620P", + .name = "ATI Korean VGA On-Board SPC-4620P", .internal_name = "ati28800k_spc4620p", - .flags = DEVICE_ISA, - .local = 1, - .init = ati28800k_init, - .close = ati28800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 1, + .init = ati28800k_init, + .close = ati28800_close, + .reset = NULL, { .available = NULL }, .speed_changed = ati28800_speed_changed, - .force_redraw = ati28800_force_redraw, - .config = NULL + .force_redraw = ati28800_force_redraw, + .config = NULL }; const device_t ati28800k_spc6033p_device = { - .name = "ATI Korean VGA On-Board SPC-6033P", + .name = "ATI Korean VGA On-Board SPC-6033P", .internal_name = "ati28800k_spc6033p", - .flags = DEVICE_ISA, - .local = 2, - .init = ati28800k_init, - .close = ati28800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 2, + .init = ati28800k_init, + .close = ati28800_close, + .reset = NULL, { .available = NULL }, .speed_changed = ati28800_speed_changed, - .force_redraw = ati28800_force_redraw, - .config = NULL + .force_redraw = ati28800_force_redraw, + .config = NULL }; const device_t compaq_ati28800_device = { - .name = "ATI 28800-5 (ATI VGA Wonder XL)", + .name = "ATI 28800-5 (ATI VGA Wonder XL)", .internal_name = "compaq_ati28800", - .flags = DEVICE_ISA, - .local = VGAWONDERXL, - .init = ati28800_init, - .close = ati28800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = VGAWONDERXL, + .init = ati28800_init, + .close = ati28800_close, + .reset = NULL, { .available = compaq_ati28800_available }, .speed_changed = ati28800_speed_changed, - .force_redraw = ati28800_force_redraw, - .config = ati28800_config + .force_redraw = ati28800_force_redraw, + .config = ati28800_config }; #if defined(DEV_BRANCH) && defined(USE_XL24) const device_t ati28800_wonderxl24_device = { - .name = "ATI-28800 (VGA Wonder XL24)", + .name = "ATI-28800 (VGA Wonder XL24)", .internal_name = "ati28800w", - .flags = DEVICE_ISA, - .local = VGAWONDERXL24, - .init = ati28800_init, - .close = ati28800_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = VGAWONDERXL24, + .init = ati28800_init, + .close = ati28800_close, + .reset = NULL, { .available = ati28800_wonderxl24_available }, .speed_changed = ati28800_speed_changed, - .force_redraw = ati28800_force_redraw, - .config = ati28800_wonderxl_config + .force_redraw = ati28800_force_redraw, + .config = ati28800_wonderxl_config }; #endif diff --git a/src/video/vid_ati68860_ramdac.c b/src/video/vid_ati68860_ramdac.c index 46967ce3d..1bf74067a 100644 --- a/src/video/vid_ati68860_ramdac.c +++ b/src/video/vid_ati68860_ramdac.c @@ -49,111 +49,112 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> - -typedef struct ati68860_ramdac_t -{ +typedef struct ati68860_ramdac_t { uint8_t regs[16]; void (*render)(struct svga_t *svga); - int dac_addr, dac_pos; - int dac_r, dac_g; - PALETTE pal; + int dac_addr, dac_pos; + int dac_r, dac_g; + PALETTE pal; uint32_t pallook[2]; int ramdac_type; } ati68860_ramdac_t; - void ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; switch (addr) { - case 0: - svga_out(0x3c8, val, svga); - break; - case 1: - svga_out(0x3c9, val, svga); - break; - case 2: - svga_out(0x3c6, val, svga); - break; - case 3: - svga_out(0x3c7, val, svga); - break; - default: - ramdac->regs[addr & 0xf] = val; - switch (addr & 0xf) { - case 0x4: - ramdac->dac_addr = val; - ramdac->dac_pos = 0; - break; - case 0x5: - switch (ramdac->dac_pos) { - case 0: - ramdac->dac_r = val; - ramdac->dac_pos++; - break; - case 1: - ramdac->dac_g = val; - ramdac->dac_pos++; - break; - case 2: - if (ramdac->dac_addr > 1) - break; - ramdac->pal[ramdac->dac_addr].r = ramdac->dac_r; - ramdac->pal[ramdac->dac_addr].g = ramdac->dac_g; - ramdac->pal[ramdac->dac_addr].b = val; - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[ramdac->dac_addr] = makecol32(ramdac->pal[ramdac->dac_addr].r, - ramdac->pal[ramdac->dac_addr].g, - ramdac->pal[ramdac->dac_addr].b); - else - ramdac->pallook[ramdac->dac_addr] = makecol32(video_6to8[ramdac->pal[ramdac->dac_addr].r & 0x3f], - video_6to8[ramdac->pal[ramdac->dac_addr].g & 0x3f], - video_6to8[ramdac->pal[ramdac->dac_addr].b & 0x3f]); - ramdac->dac_pos = 0; - ramdac->dac_addr = (ramdac->dac_addr + 1) & 255; - break; - } - break; - case 0xb: - switch (val) { - case 0x82: - ramdac->render = svga_render_4bpp_highres; - break; - case 0x83: - ramdac->render = svga_render_8bpp_highres; - break; - case 0xa0: case 0xb0: - ramdac->render = svga_render_15bpp_highres; - break; - case 0xa1: case 0xb1: - ramdac->render = svga_render_16bpp_highres; - break; - case 0xc0: case 0xd0: - ramdac->render = svga_render_24bpp_highres; - break; - case 0xe2: case 0xf7: - ramdac->render = svga_render_32bpp_highres; - break; - case 0xe3: - ramdac->render = svga_render_ABGR8888_highres; - break; - case 0xf2: - ramdac->render = svga_render_RGBA8888_highres; - break; - default: - ramdac->render = svga_render_8bpp_highres; - break; - } - break; - case 0xc: - svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); - break; - } - break; + case 0: + svga_out(0x3c8, val, svga); + break; + case 1: + svga_out(0x3c9, val, svga); + break; + case 2: + svga_out(0x3c6, val, svga); + break; + case 3: + svga_out(0x3c7, val, svga); + break; + default: + ramdac->regs[addr & 0xf] = val; + switch (addr & 0xf) { + case 0x4: + ramdac->dac_addr = val; + ramdac->dac_pos = 0; + break; + case 0x5: + switch (ramdac->dac_pos) { + case 0: + ramdac->dac_r = val; + ramdac->dac_pos++; + break; + case 1: + ramdac->dac_g = val; + ramdac->dac_pos++; + break; + case 2: + if (ramdac->dac_addr > 1) + break; + ramdac->pal[ramdac->dac_addr].r = ramdac->dac_r; + ramdac->pal[ramdac->dac_addr].g = ramdac->dac_g; + ramdac->pal[ramdac->dac_addr].b = val; + if (ramdac->ramdac_type == RAMDAC_8BIT) + ramdac->pallook[ramdac->dac_addr] = makecol32(ramdac->pal[ramdac->dac_addr].r, + ramdac->pal[ramdac->dac_addr].g, + ramdac->pal[ramdac->dac_addr].b); + else + ramdac->pallook[ramdac->dac_addr] = makecol32(video_6to8[ramdac->pal[ramdac->dac_addr].r & 0x3f], + video_6to8[ramdac->pal[ramdac->dac_addr].g & 0x3f], + video_6to8[ramdac->pal[ramdac->dac_addr].b & 0x3f]); + ramdac->dac_pos = 0; + ramdac->dac_addr = (ramdac->dac_addr + 1) & 255; + break; + } + break; + case 0xb: + switch (val) { + case 0x82: + ramdac->render = svga_render_4bpp_highres; + break; + case 0x83: + ramdac->render = svga_render_8bpp_highres; + break; + case 0xa0: + case 0xb0: + ramdac->render = svga_render_15bpp_highres; + break; + case 0xa1: + case 0xb1: + ramdac->render = svga_render_16bpp_highres; + break; + case 0xc0: + case 0xd0: + ramdac->render = svga_render_24bpp_highres; + break; + case 0xe2: + case 0xf7: + ramdac->render = svga_render_32bpp_highres; + break; + case 0xe3: + ramdac->render = svga_render_ABGR8888_highres; + break; + case 0xf2: + ramdac->render = svga_render_RGBA8888_highres; + break; + default: + ramdac->render = svga_render_8bpp_highres; + break; + } + break; + case 0xc: + svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT); + break; + } + break; } } @@ -161,61 +162,61 @@ uint8_t ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga) { ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; - uint8_t temp = 0; + uint8_t temp = 0; switch (addr) { - case 0: - temp = svga_in(0x3c8, svga); - break; - case 1: - temp = svga_in(0x3c9, svga); - break; - case 2: - temp = svga_in(0x3c6, svga); - break; - case 3: - temp = svga_in(0x3c7, svga); - break; - case 4: case 8: - temp = 2; - break; - case 6: case 0xa: - temp = 0x1d; - break; - case 0xf: - temp = 0xd0; - break; + case 0: + temp = svga_in(0x3c8, svga); + break; + case 1: + temp = svga_in(0x3c9, svga); + break; + case 2: + temp = svga_in(0x3c6, svga); + break; + case 3: + temp = svga_in(0x3c7, svga); + break; + case 4: + case 8: + temp = 2; + break; + case 6: + case 0xa: + temp = 0x1d; + break; + case 0xf: + temp = 0xd0; + break; - default: - temp = ramdac->regs[addr & 0xf]; - break; + default: + temp = ramdac->regs[addr & 0xf]; + break; } return temp; } - void ati68860_set_ramdac_type(void *p, int type) { ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p; - int c; + int c; if (ramdac->ramdac_type != type) { - ramdac->ramdac_type = type; + ramdac->ramdac_type = type; - for (c = 0; c < 2; c++) { - if (ramdac->ramdac_type == RAMDAC_8BIT) - ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, - ramdac->pal[c].b); - else - ramdac->pallook[c] = makecol32(video_6to8[ramdac->pal[c].r & 0x3f], video_6to8[ramdac->pal[c].g & 0x3f], - video_6to8[ramdac->pal[c].b & 0x3f]); - } + for (c = 0; c < 2; c++) { + if (ramdac->ramdac_type == RAMDAC_8BIT) + ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g, + ramdac->pal[c].b); + else + ramdac->pallook[c] = makecol32(video_6to8[ramdac->pal[c].r & 0x3f], video_6to8[ramdac->pal[c].g & 0x3f], + video_6to8[ramdac->pal[c].b & 0x3f]); + } } } - static void * ati68860_ramdac_init(const device_t *info) { @@ -227,7 +228,6 @@ ati68860_ramdac_init(const device_t *info) return ramdac; } - void ati68860_ramdac_set_render(void *p, svga_t *svga) { @@ -236,7 +236,6 @@ ati68860_ramdac_set_render(void *p, svga_t *svga) svga->render = ramdac->render; } - void ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) { @@ -245,57 +244,63 @@ ati68860_ramdac_set_pallook(void *p, int i, uint32_t col) ramdac->pallook[i] = col; } - void ati68860_hwcursor_draw(svga_t *svga, int displine) { ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac; - int x, offset; - uint8_t dat; - uint32_t col0 = ramdac->pallook[0]; - uint32_t col1 = ramdac->pallook[1]; + int x, offset; + uint8_t dat; + uint32_t col0 = ramdac->pallook[0]; + uint32_t col1 = ramdac->pallook[1]; offset = svga->dac_hwcursor_latch.xoff; for (x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) { - dat = svga->vram[svga->dac_hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF; - dat >>= 2; - if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF; - dat >>= 2; - offset += 4; + dat = svga->vram[svga->dac_hwcursor_latch.addr + (offset >> 2)]; + if (!(dat & 2)) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF; + dat >>= 2; + if (!(dat & 2)) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) + buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF; + dat >>= 2; + offset += 4; } svga->dac_hwcursor_latch.addr += 16; } - static void ati68860_ramdac_close(void *priv) { ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t ati68860_ramdac_device = { - .name = "ATI-68860 RAMDAC", + .name = "ATI-68860 RAMDAC", .internal_name = "ati68860_ramdac", - .flags = 0, - .local = 0, - .init = ati68860_ramdac_init, - .close = ati68860_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = ati68860_ramdac_init, + .close = ati68860_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 561f6229b..15696be63 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -27,184 +27,168 @@ #include <86box/nvr.h> #include <86box/vid_ati_eeprom.h> - -void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) +void +ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) { - FILE *f; - int size; - eeprom->type = type; - strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); - f = nvr_fopen(eeprom->fn, "rb"); - size = eeprom->type ? 512 : 128; - if (!f) { - memset(eeprom->data, 0xff, size); - return; - } - if (fread(eeprom->data, 1, size, f) != size) - memset(eeprom->data, 0, size); - fclose(f); + FILE *f; + int size; + eeprom->type = type; + strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); + f = nvr_fopen(eeprom->fn, "rb"); + size = eeprom->type ? 512 : 128; + if (!f) { + memset(eeprom->data, 0xff, size); + return; + } + if (fread(eeprom->data, 1, size, f) != size) + memset(eeprom->data, 0, size); + fclose(f); } -void ati_eeprom_save(ati_eeprom_t *eeprom) +void +ati_eeprom_save(ati_eeprom_t *eeprom) { - FILE *f = nvr_fopen(eeprom->fn, "wb"); - if (!f) return; - fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); - fclose(f); + FILE *f = nvr_fopen(eeprom->fn, "wb"); + if (!f) + return; + fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); + fclose(f); } -void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) +void +ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) { - int c; - if (!ena) - { - eeprom->out = 1; - } - if (clk && !eeprom->oldclk) - { - if (ena && !eeprom->oldena) - { - eeprom->state = EEPROM_WAIT; - eeprom->opcode = 0; - eeprom->count = 3; - eeprom->out = 1; - } - else if (ena) - { - switch (eeprom->state) - { - case EEPROM_WAIT: - if (!dat) + int c; + if (!ena) { + eeprom->out = 1; + } + if (clk && !eeprom->oldclk) { + if (ena && !eeprom->oldena) { + eeprom->state = EEPROM_WAIT; + eeprom->opcode = 0; + eeprom->count = 3; + eeprom->out = 1; + } else if (ena) { + switch (eeprom->state) { + case EEPROM_WAIT: + if (!dat) + break; + eeprom->state = EEPROM_OPCODE; + /* fall through */ + case EEPROM_OPCODE: + eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); + eeprom->count--; + if (!eeprom->count) { + switch (eeprom->opcode) { + case EEPROM_OP_WRITE: + eeprom->count = eeprom->type ? 24 : 22; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + case EEPROM_OP_READ: + eeprom->count = eeprom->type ? 8 : 6; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + case EEPROM_OP_EW: + eeprom->count = 2; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + case EEPROM_OP_ERASE: + eeprom->count = eeprom->type ? 8 : 6; + eeprom->state = EEPROM_INPUT; + eeprom->dat = 0; + break; + } + } + break; + + case EEPROM_INPUT: + eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0); + eeprom->count--; + if (!eeprom->count) { + switch (eeprom->opcode) { + case EEPROM_OP_WRITE: + if (!eeprom->wp) { + eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff; + ati_eeprom_save(eeprom); + } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; + break; + + case EEPROM_OP_READ: + eeprom->count = 17; + eeprom->state = EEPROM_OUTPUT; + eeprom->dat = eeprom->data[eeprom->dat]; + break; + case EEPROM_OP_EW: + switch (eeprom->dat) { + case EEPROM_OP_EWDS: + eeprom->wp = 1; break; - eeprom->state = EEPROM_OPCODE; - /* fall through */ - case EEPROM_OPCODE: - eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0); - eeprom->count--; - if (!eeprom->count) - { - switch (eeprom->opcode) - { - case EEPROM_OP_WRITE: - eeprom->count = eeprom->type ? 24 : 22; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_READ: - eeprom->count = eeprom->type ? 8 : 6; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_EW: - eeprom->count = 2; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; - case EEPROM_OP_ERASE: - eeprom->count = eeprom->type ? 8 : 6; - eeprom->state = EEPROM_INPUT; - eeprom->dat = 0; - break; + case EEPROM_OP_WRAL: + eeprom->opcode = EEPROM_OP_WRALMAIN; + eeprom->count = 20; + break; + case EEPROM_OP_ERAL: + if (!eeprom->wp) { + memset(eeprom->data, 0xff, 128); + ati_eeprom_save(eeprom); } + break; + case EEPROM_OP_EWEN: + eeprom->wp = 0; + break; } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; break; - case EEPROM_INPUT: - eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0); - eeprom->count--; - if (!eeprom->count) - { - switch (eeprom->opcode) - { - case EEPROM_OP_WRITE: - if (!eeprom->wp) - { - eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - - case EEPROM_OP_READ: - eeprom->count = 17; - eeprom->state = EEPROM_OUTPUT; - eeprom->dat = eeprom->data[eeprom->dat]; - break; - case EEPROM_OP_EW: - switch (eeprom->dat) - { - case EEPROM_OP_EWDS: - eeprom->wp = 1; - break; - case EEPROM_OP_WRAL: - eeprom->opcode = EEPROM_OP_WRALMAIN; - eeprom->count = 20; - break; - case EEPROM_OP_ERAL: - if (!eeprom->wp) - { - memset(eeprom->data, 0xff, 128); - ati_eeprom_save(eeprom); - } - break; - case EEPROM_OP_EWEN: - eeprom->wp = 0; - break; - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - - case EEPROM_OP_ERASE: - if (!eeprom->wp) - { - eeprom->data[eeprom->dat] = 0xffff; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - - case EEPROM_OP_WRALMAIN: - if (!eeprom->wp) - { - for (c = 0; c < 256; c++) - eeprom->data[c] = eeprom->dat; - ati_eeprom_save(eeprom); - } - eeprom->state = EEPROM_IDLE; - eeprom->out = 1; - break; - } + case EEPROM_OP_ERASE: + if (!eeprom->wp) { + eeprom->data[eeprom->dat] = 0xffff; + ati_eeprom_save(eeprom); } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; + break; + + case EEPROM_OP_WRALMAIN: + if (!eeprom->wp) { + for (c = 0; c < 256; c++) + eeprom->data[c] = eeprom->dat; + ati_eeprom_save(eeprom); + } + eeprom->state = EEPROM_IDLE; + eeprom->out = 1; break; } - } - eeprom->oldena = ena; + } + break; + } } - else if (!clk && eeprom->oldclk) - { - if (ena) - { - switch (eeprom->state) - { - case EEPROM_OUTPUT: - eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0; - eeprom->dat <<= 1; - eeprom->count--; - if (!eeprom->count) - { - eeprom->state = EEPROM_IDLE; - } - break; - } - } + eeprom->oldena = ena; + } else if (!clk && eeprom->oldclk) { + if (ena) { + switch (eeprom->state) { + case EEPROM_OUTPUT: + eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0; + eeprom->dat <<= 1; + eeprom->count--; + if (!eeprom->count) { + eeprom->state = EEPROM_IDLE; + } + break; + } } - eeprom->oldclk = clk; + } + eeprom->oldclk = clk; } -int ati_eeprom_read(ati_eeprom_t *eeprom) +int +ati_eeprom_read(ati_eeprom_t *eeprom) { - return eeprom->out; + return eeprom->out; } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 7f4e2c7c9..46663af51 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -40,311 +40,299 @@ #include <86box/vid_ati_eeprom.h> #ifdef CLAMP -#undef CLAMP +# undef CLAMP #endif -#define BIOS_ROM_PATH "roms/video/mach64/bios.bin" -#define BIOS_ISA_ROM_PATH "roms/video/mach64/M64-1994.VBI" -#define BIOS_VLB_ROM_PATH "roms/video/mach64/mach64_vlb_vram.bin" -#define BIOS_ROMVT2_PATH "roms/video/mach64/atimach64vt2pci.bin" +#define BIOS_ROM_PATH "roms/video/mach64/bios.bin" +#define BIOS_ISA_ROM_PATH "roms/video/mach64/M64-1994.VBI" +#define BIOS_VLB_ROM_PATH "roms/video/mach64/mach64_vlb_vram.bin" +#define BIOS_ROMVT2_PATH "roms/video/mach64/atimach64vt2pci.bin" +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) +#define FIFO_ENTRIES (mach64->fifo_write_idx - mach64->fifo_read_idx) +#define FIFO_FULL ((mach64->fifo_write_idx - mach64->fifo_read_idx) >= FIFO_SIZE) +#define FIFO_EMPTY (mach64->fifo_read_idx == mach64->fifo_write_idx) -#define FIFO_ENTRIES (mach64->fifo_write_idx - mach64->fifo_read_idx) -#define FIFO_FULL ((mach64->fifo_write_idx - mach64->fifo_read_idx) >= FIFO_SIZE) -#define FIFO_EMPTY (mach64->fifo_read_idx == mach64->fifo_write_idx) +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff - -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24) +enum { + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), + FIFO_WRITE_DWORD = (0x03 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; -enum -{ - MACH64_GX = 0, - MACH64_VT2 +enum { + MACH64_GX = 0, + MACH64_VT2 }; -typedef struct mach64_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - mem_mapping_t mmio_linear_mapping; - mem_mapping_t mmio_linear_mapping_2; +typedef struct mach64_t { + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + mem_mapping_t mmio_linear_mapping; + mem_mapping_t mmio_linear_mapping_2; - ati_eeprom_t eeprom; - svga_t svga; + ati_eeprom_t eeprom; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - uint8_t regs[256]; - int index; + uint8_t regs[256]; + int index; - int type, pci; + int type, pci; - uint8_t pci_regs[256]; - uint8_t int_line; - int card; + uint8_t pci_regs[256]; + uint8_t int_line; + int card; - int bank_r[2]; - int bank_w[2]; + int bank_r[2]; + int bank_w[2]; - uint32_t vram_size; - uint32_t vram_mask; + uint32_t vram_size; + uint32_t vram_mask; - uint32_t config_cntl; + uint32_t config_cntl; - uint32_t context_load_cntl; - uint32_t context_mask; + uint32_t context_load_cntl; + uint32_t context_mask; - uint32_t crtc_gen_cntl; - uint8_t crtc_int_cntl; - uint32_t crtc_h_total_disp; - uint32_t crtc_v_sync_strt_wid; - uint32_t crtc_v_total_disp; - uint32_t crtc_off_pitch; + uint32_t crtc_gen_cntl; + uint8_t crtc_int_cntl; + uint32_t crtc_h_total_disp; + uint32_t crtc_v_sync_strt_wid; + uint32_t crtc_v_total_disp; + uint32_t crtc_off_pitch; - uint32_t clock_cntl; + uint32_t clock_cntl; - uint32_t clr_cmp_clr; - uint32_t clr_cmp_cntl; - uint32_t clr_cmp_mask; + uint32_t clr_cmp_clr; + uint32_t clr_cmp_cntl; + uint32_t clr_cmp_mask; - uint32_t cur_horz_vert_off; - uint32_t cur_horz_vert_posn; - uint32_t cur_offset; + uint32_t cur_horz_vert_off; + uint32_t cur_horz_vert_posn; + uint32_t cur_offset; - uint32_t dac_cntl; + uint32_t dac_cntl; + + uint32_t dp_bkgd_clr; + uint32_t dp_frgd_clr; + uint32_t dp_mix; + uint32_t dp_pix_width; + uint32_t dp_src; + + uint32_t dst_bres_lnth; + uint32_t dst_bres_dec; + uint32_t dst_bres_err; + uint32_t dst_bres_inc; + + uint32_t dst_cntl; + uint32_t dst_height_width; + uint32_t dst_off_pitch; + uint32_t dst_y_x; + + uint32_t gen_test_cntl; + + uint32_t gui_traj_cntl; + + uint32_t host_cntl; + + uint32_t mem_cntl; + + uint32_t ovr_clr; + uint32_t ovr_wid_left_right; + uint32_t ovr_wid_top_bottom; + + uint32_t pat_cntl; + uint32_t pat_reg0, pat_reg1; + + uint32_t sc_left_right, sc_top_bottom; + + uint32_t scratch_reg0, scratch_reg1; + + uint32_t src_cntl; + uint32_t src_off_pitch; + uint32_t src_y_x; + uint32_t src_y_x_start; + uint32_t src_height1_width1, src_height2_width2; + + uint32_t write_mask; + uint32_t chain_mask; + + uint32_t linear_base, old_linear_base; + uint32_t io_base; + + struct + { + int op; + + int dst_x, dst_y; + int dst_x_start, dst_y_start; + int src_x, src_y; + int src_x_start, src_y_start; + int xinc, yinc; + int x_count, y_count; + int src_x_count, src_y_count; + int src_width1, src_height1; + int src_width2, src_height2; + uint32_t src_offset, src_pitch; + uint32_t dst_offset, dst_pitch; + int mix_bg, mix_fg; + int source_bg, source_fg, source_mix; + int source_host; + int dst_width, dst_height; + int busy; + int pattern[8][8]; + uint8_t pattern_clr4x2[2][4]; + uint8_t pattern_clr8x1[8]; + int sc_left, sc_right, sc_top, sc_bottom; + int dst_pix_width, src_pix_width, host_pix_width; + int dst_size, src_size, host_size; uint32_t dp_bkgd_clr; uint32_t dp_frgd_clr; - uint32_t dp_mix; - uint32_t dp_pix_width; - uint32_t dp_src; - - uint32_t dst_bres_lnth; - uint32_t dst_bres_dec; - uint32_t dst_bres_err; - uint32_t dst_bres_inc; - - uint32_t dst_cntl; - uint32_t dst_height_width; - uint32_t dst_off_pitch; - uint32_t dst_y_x; - - uint32_t gen_test_cntl; - - uint32_t gui_traj_cntl; - - uint32_t host_cntl; - - uint32_t mem_cntl; - - uint32_t ovr_clr; - uint32_t ovr_wid_left_right; - uint32_t ovr_wid_top_bottom; - - uint32_t pat_cntl; - uint32_t pat_reg0, pat_reg1; - - uint32_t sc_left_right, sc_top_bottom; - - uint32_t scratch_reg0, scratch_reg1; - - uint32_t src_cntl; - uint32_t src_off_pitch; - uint32_t src_y_x; - uint32_t src_y_x_start; - uint32_t src_height1_width1, src_height2_width2; - uint32_t write_mask; - uint32_t chain_mask; - uint32_t linear_base, old_linear_base; - uint32_t io_base; + uint32_t clr_cmp_clr; + uint32_t clr_cmp_mask; + int clr_cmp_fn; + int clr_cmp_src; - struct - { - int op; + int err; + int poly_draw; + } accel; - int dst_x, dst_y; - int dst_x_start, dst_y_start; - int src_x, src_y; - int src_x_start, src_y_start; - int xinc, yinc; - int x_count, y_count; - int src_x_count, src_y_count; - int src_width1, src_height1; - int src_width2, src_height2; - uint32_t src_offset, src_pitch; - uint32_t dst_offset, dst_pitch; - int mix_bg, mix_fg; - int source_bg, source_fg, source_mix; - int source_host; - int dst_width, dst_height; - int busy; - int pattern[8][8]; - uint8_t pattern_clr4x2[2][4]; - uint8_t pattern_clr8x1[8]; - int sc_left, sc_right, sc_top, sc_bottom; - int dst_pix_width, src_pix_width, host_pix_width; - int dst_size, src_size, host_size; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - uint32_t dp_bkgd_clr; - uint32_t dp_frgd_clr; - uint32_t write_mask; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - uint32_t clr_cmp_clr; - uint32_t clr_cmp_mask; - int clr_cmp_fn; - int clr_cmp_src; + int blitter_busy; + uint64_t blitter_time; + uint64_t status_time; - int err; - int poly_draw; - } accel; + uint16_t pci_id; + uint32_t config_chip_id; + uint32_t block_decoded_io; + int use_block_decoded_io; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + int pll_addr; + uint8_t pll_regs[16]; + double pll_freq[4]; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + uint32_t config_stat0; - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; + uint32_t cur_clr0, cur_clr1; - uint16_t pci_id; - uint32_t config_chip_id; - uint32_t block_decoded_io; - int use_block_decoded_io; + uint32_t overlay_dat[1024]; + uint32_t overlay_graphics_key_clr, overlay_graphics_key_msk; + uint32_t overlay_video_key_clr, overlay_video_key_msk; + uint32_t overlay_key_cntl; + uint32_t overlay_scale_inc; + uint32_t overlay_scale_cntl; + uint32_t overlay_y_x_start, overlay_y_x_end; - int pll_addr; - uint8_t pll_regs[16]; - double pll_freq[4]; + uint32_t scaler_height_width; + int scaler_format; + int scaler_update; - uint32_t config_stat0; + uint32_t buf_offset[2], buf_pitch[2]; - uint32_t cur_clr0, cur_clr1; + int overlay_v_acc; - uint32_t overlay_dat[1024]; - uint32_t overlay_graphics_key_clr, overlay_graphics_key_msk; - uint32_t overlay_video_key_clr, overlay_video_key_msk; - uint32_t overlay_key_cntl; - uint32_t overlay_scale_inc; - uint32_t overlay_scale_cntl; - uint32_t overlay_y_x_start, overlay_y_x_end; - - uint32_t scaler_height_width; - int scaler_format; - int scaler_update; - - uint32_t buf_offset[2], buf_pitch[2]; - - int overlay_v_acc; - - uint8_t thread_run; - void *i2c, *ddc; + uint8_t thread_run; + void *i2c, *ddc; } mach64_t; -static video_timings_t timing_mach64_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; -static video_timings_t timing_mach64_vlb = {VIDEO_BUS, 2, 2, 1, 20, 20, 21}; -static video_timings_t timing_mach64_pci = {VIDEO_PCI, 2, 2, 1, 20, 20, 21}; +static video_timings_t timing_mach64_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_mach64_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; +static video_timings_t timing_mach64_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; -enum -{ - SRC_BG = 0, - SRC_FG = 1, - SRC_HOST = 2, - SRC_BLITSRC = 3, - SRC_PAT = 4 +enum { + SRC_BG = 0, + SRC_FG = 1, + SRC_HOST = 2, + SRC_BLITSRC = 3, + SRC_PAT = 4 }; -enum -{ - MONO_SRC_1 = 0, - MONO_SRC_PAT = 1, - MONO_SRC_HOST = 2, - MONO_SRC_BLITSRC = 3 +enum { + MONO_SRC_1 = 0, + MONO_SRC_PAT = 1, + MONO_SRC_HOST = 2, + MONO_SRC_BLITSRC = 3 }; -enum -{ - BPP_1 = 0, - BPP_4 = 1, - BPP_8 = 2, - BPP_15 = 3, - BPP_16 = 4, - BPP_24 = 5, - BPP_32 = 6 +enum { + BPP_1 = 0, + BPP_4 = 1, + BPP_8 = 2, + BPP_15 = 3, + BPP_16 = 4, + BPP_24 = 5, + BPP_32 = 6 }; -enum -{ - OP_RECT, - OP_LINE +enum { + OP_RECT, + OP_LINE }; -enum -{ - SRC_PATT_EN = 1, - SRC_PATT_ROT_EN = 2, - SRC_LINEAR_EN = 4 +enum { + SRC_PATT_EN = 1, + SRC_PATT_ROT_EN = 2, + SRC_LINEAR_EN = 4 }; -enum -{ - DP_BYTE_PIX_ORDER = (1 << 24) +enum { + DP_BYTE_PIX_ORDER = (1 << 24) }; #define WIDTH_1BIT 3 -static int mach64_width[8] = {WIDTH_1BIT, 0, 0, 1, 1, 2, 2, 0}; +static int mach64_width[8] = { WIDTH_1BIT, 0, 0, 1, 1, 2, 2, 0 }; -enum -{ - DST_X_DIR = 0x01, - DST_Y_DIR = 0x02, - DST_Y_MAJOR = 0x04, - DST_X_TILE = 0x08, - DST_Y_TILE = 0x10, - DST_LAST_PEL = 0x20, - DST_POLYGON_EN = 0x40, - DST_24_ROT_EN = 0x80 +enum { + DST_X_DIR = 0x01, + DST_Y_DIR = 0x02, + DST_Y_MAJOR = 0x04, + DST_X_TILE = 0x08, + DST_Y_TILE = 0x10, + DST_LAST_PEL = 0x20, + DST_POLYGON_EN = 0x40, + DST_24_ROT_EN = 0x80 }; -enum -{ - HOST_BYTE_ALIGN = (1 << 0) +enum { + HOST_BYTE_ALIGN = (1 << 0) }; -void mach64_write(uint32_t addr, uint8_t val, void *priv); -void mach64_writew(uint32_t addr, uint16_t val, void *priv); -void mach64_writel(uint32_t addr, uint32_t val, void *priv); -uint8_t mach64_read(uint32_t addr, void *priv); +void mach64_write(uint32_t addr, uint8_t val, void *priv); +void mach64_writew(uint32_t addr, uint16_t val, void *priv); +void mach64_writel(uint32_t addr, uint32_t val, void *priv); +uint8_t mach64_read(uint32_t addr, void *priv); uint16_t mach64_readw(uint32_t addr, void *priv); uint32_t mach64_readl(uint32_t addr, void *priv); -void mach64_updatemapping(mach64_t *mach64); -void mach64_recalctimings(svga_t *svga); -void mach64_start_fill(mach64_t *mach64); -void mach64_start_line(mach64_t *mach64); -void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64); -void mach64_load_context(mach64_t *mach64); +void mach64_updatemapping(mach64_t *mach64); +void mach64_recalctimings(svga_t *svga); +void mach64_start_fill(mach64_t *mach64); +void mach64_start_line(mach64_t *mach64); +void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64); +void mach64_load_context(mach64_t *mach64); uint8_t mach64_ext_readb(uint32_t addr, void *priv); uint16_t mach64_ext_readw(uint32_t addr, void *priv); @@ -353,3336 +341,4030 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *priv); void mach64_ext_writew(uint32_t addr, uint16_t val, void *priv); void mach64_ext_writel(uint32_t addr, uint32_t val, void *priv); - #ifdef ENABLE_MACH64_LOG int mach64_do_log = ENABLE_MACH64_LOG; - static void mach64_log(const char *fmt, ...) { va_list ap; if (mach64_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define mach64_log(fmt, ...) +# define mach64_log(fmt, ...) #endif - -void mach64_out(uint16_t addr, uint8_t val, void *p) +void +mach64_out(uint16_t addr, uint8_t val, void *p) { - mach64_t *mach64 = p; - svga_t *svga = &mach64->svga; - uint8_t old; + mach64_t *mach64 = p; + svga_t *svga = &mach64->svga; + uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x1ce: - mach64->index = val; - break; - case 0x1cf: - mach64->regs[mach64->index & 0x3f] = val; - if ((mach64->index & 0x3f) == 0x36) + switch (addr) { + case 0x1ce: + mach64->index = val; + break; + case 0x1cf: + mach64->regs[mach64->index & 0x3f] = val; + if ((mach64->index & 0x3f) == 0x36) + svga_recalctimings(svga); + break; + + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, svga); + else + svga_out(addr, val, svga); + return; + + case 0x3cf: + if (svga->gdcaddr == 6) { + uint8_t old_val = svga->gdcreg[6]; + svga->gdcreg[6] = val; + if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) + mach64_updatemapping(mach64); + return; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if (svga->crtcreg > 0x18) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; svga_recalctimings(svga); - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, svga); - else - svga_out(addr, val, svga); - return; - - case 0x3cf: - if (svga->gdcaddr == 6) - { - uint8_t old_val = svga->gdcreg[6]; - svga->gdcreg[6] = val; - if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) - mach64_updatemapping(mach64); - return; + } } - break; - - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x18) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - break; - } - svga_out(addr, val, svga); + } + break; + } + svga_out(addr, val, svga); } -uint8_t mach64_in(uint16_t addr, void *p) +uint8_t +mach64_in(uint16_t addr, void *p) { - mach64_t *mach64 = p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = p; + svga_t *svga = &mach64->svga; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) - addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x1ce: - return mach64->index; - case 0x1cf: - return mach64->regs[mach64->index & 0x3f]; + switch (addr) { + case 0x1ce: + return mach64->index; + case 0x1cf: + return mach64->regs[mach64->index & 0x3f]; - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (mach64->type == MACH64_GX) - return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, svga); - return svga_in(addr, svga); + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (mach64->type == MACH64_GX) + return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, svga); + return svga_in(addr, svga); - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg > 0x18) - return 0xff; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if (svga->crtcreg > 0x18) + return 0xff; + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } -void mach64_recalctimings(svga_t *svga) +void +mach64_recalctimings(svga_t *svga) { - mach64_t *mach64 = (mach64_t *)svga->p; + mach64_t *mach64 = (mach64_t *) svga->p; - if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) - { - svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; - svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; - svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; - svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; - svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; - svga->rowoffset = (mach64->crtc_off_pitch >> 22); - svga->clock = (cpuclock * (double)(1ull << 32)) / ics2595_getclock(svga->clock_gen); - svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; - svga->linedbl = svga->rowcount = 0; - svga->split = 0xffffff; - svga->vblankstart = svga->dispend; - svga->rowcount = mach64->crtc_gen_cntl & 1; - svga->rowoffset <<= 1; - if (mach64->type == MACH64_GX) - ati68860_ramdac_set_render(svga->ramdac, svga); - switch ((mach64->crtc_gen_cntl >> 8) & 7) - { - case BPP_4: - if (mach64->type != MACH64_GX) - svga->render = svga_render_4bpp_highres; - svga->hdisp *= 8; - break; - case BPP_8: - if (mach64->type != MACH64_GX) - svga->render = svga_render_8bpp_highres; - svga->hdisp *= 8; - svga->rowoffset /= 2; - break; - case BPP_15: - if (mach64->type != MACH64_GX) - svga->render = svga_render_15bpp_highres; - svga->hdisp *= 8; - break; - case BPP_16: - if (mach64->type != MACH64_GX) - svga->render = svga_render_16bpp_highres; - svga->hdisp *= 8; - break; - case BPP_24: - if (mach64->type != MACH64_GX) - svga->render = svga_render_24bpp_highres; - svga->hdisp *= 8; - svga->rowoffset = (svga->rowoffset * 3) / 2; - break; - case BPP_32: - if (mach64->type != MACH64_GX) - svga->render = svga_render_32bpp_highres; - svga->hdisp *= 8; - svga->rowoffset *= 2; - break; - } + if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) { + svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; + svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; + svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; + svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; + svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; + svga->rowoffset = (mach64->crtc_off_pitch >> 22); + svga->clock = (cpuclock * (double) (1ull << 32)) / ics2595_getclock(svga->clock_gen); + svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; + svga->linedbl = svga->rowcount = 0; + svga->split = 0xffffff; + svga->vblankstart = svga->dispend; + svga->rowcount = mach64->crtc_gen_cntl & 1; + svga->rowoffset <<= 1; + if (mach64->type == MACH64_GX) + ati68860_ramdac_set_render(svga->ramdac, svga); + switch ((mach64->crtc_gen_cntl >> 8) & 7) { + case BPP_4: + if (mach64->type != MACH64_GX) + svga->render = svga_render_4bpp_highres; + svga->hdisp *= 8; + break; + case BPP_8: + if (mach64->type != MACH64_GX) + svga->render = svga_render_8bpp_highres; + svga->hdisp *= 8; + svga->rowoffset /= 2; + break; + case BPP_15: + if (mach64->type != MACH64_GX) + svga->render = svga_render_15bpp_highres; + svga->hdisp *= 8; + break; + case BPP_16: + if (mach64->type != MACH64_GX) + svga->render = svga_render_16bpp_highres; + svga->hdisp *= 8; + break; + case BPP_24: + if (mach64->type != MACH64_GX) + svga->render = svga_render_24bpp_highres; + svga->hdisp *= 8; + svga->rowoffset = (svga->rowoffset * 3) / 2; + break; + case BPP_32: + if (mach64->type != MACH64_GX) + svga->render = svga_render_32bpp_highres; + svga->hdisp *= 8; + svga->rowoffset *= 2; + break; + } - svga->vram_display_mask = mach64->vram_mask; - } - else - { - svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; - } + svga->vram_display_mask = mach64->vram_mask; + } else { + svga->vram_display_mask = (mach64->regs[0x36] & 0x01) ? mach64->vram_mask : 0x3ffff; + } } -void mach64_updatemapping(mach64_t *mach64) +void +mach64_updatemapping(mach64_t *mach64) { - svga_t *svga = &mach64->svga; - - if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mach64_log("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping_2); - return; - } + svga_t *svga = &mach64->svga; + if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + mach64_log("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mach64->linear_mapping); mem_mapping_disable(&mach64->mmio_mapping); - switch (svga->gdcreg[6] & 0xc) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - mem_mapping_enable(&mach64->mmio_mapping); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - if (mach64->linear_base) - { - if (mach64->type == MACH64_GX) - { - if ((mach64->config_cntl & 3) == 2) - { - /*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - } - else - { - /*4 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); - } - } - else - { - /*2*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); - } - } - else - { - mem_mapping_disable(&mach64->linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping); - mem_mapping_disable(&mach64->mmio_linear_mapping_2); + mem_mapping_disable(&mach64->mmio_linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping_2); + return; + } + + mem_mapping_disable(&mach64->mmio_mapping); + switch (svga->gdcreg[6] & 0xc) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); + mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + mem_mapping_enable(&mach64->mmio_mapping); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); + mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + if (mach64->linear_base) { + if (mach64->type == MACH64_GX) { + if ((mach64->config_cntl & 3) == 2) { + /*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + } else { + /*4 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); + } + } else { + /*2*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); } + } else { + mem_mapping_disable(&mach64->linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping_2); + } } -static void mach64_update_irqs(mach64_t *mach64) +static void +mach64_update_irqs(mach64_t *mach64) { - if (!mach64->pci) - { - return; - } + if (!mach64->pci) { + return; + } - if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) - pci_set_irq(mach64->card, PCI_INTA); - else - pci_clear_irq(mach64->card, PCI_INTA); + if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) + pci_set_irq(mach64->card, PCI_INTA); + else + pci_clear_irq(mach64->card, PCI_INTA); } -static __inline void wake_fifo_thread(mach64_t *mach64) +static __inline void +wake_fifo_thread(mach64_t *mach64) { - thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } -static void mach64_wait_fifo_idle(mach64_t *mach64) +static void +mach64_wait_fifo_idle(mach64_t *mach64) { - while (!FIFO_EMPTY) - { - wake_fifo_thread(mach64); - thread_wait_event(mach64->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread(mach64); + thread_wait_event(mach64->fifo_not_full_event, 1); + } } -#define READ8(addr, var) switch ((addr) & 3) \ - { \ - case 0: ret = (var) & 0xff; break; \ - case 1: ret = ((var) >> 8) & 0xff; break; \ - case 2: ret = ((var) >> 16) & 0xff; break; \ - case 3: ret = ((var) >> 24) & 0xff; break; \ - } +#define READ8(addr, var) \ + switch ((addr) &3) { \ + case 0: \ + ret = (var) &0xff; \ + break; \ + case 1: \ + ret = ((var) >> 8) & 0xff; \ + break; \ + case 2: \ + ret = ((var) >> 16) & 0xff; \ + break; \ + case 3: \ + ret = ((var) >> 24) & 0xff; \ + break; \ + } -#define WRITE8(addr, var, val) switch ((addr) & 3) \ - { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } +#define WRITE8(addr, var, val) \ + switch ((addr) &3) { \ + case 0: \ + var = (var & 0xffffff00) | (val); \ + break; \ + case 1: \ + var = (var & 0xffff00ff) | ((val) << 8); \ + break; \ + case 2: \ + var = (var & 0xff00ffff) | ((val) << 16); \ + break; \ + case 3: \ + var = (var & 0x00ffffff) | ((val) << 24); \ + break; \ + } -static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) +static void +mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) { - switch (addr & 0x3ff) - { - case 0x100: case 0x101: case 0x102: case 0x103: - WRITE8(addr, mach64->dst_off_pitch, val); - break; - case 0x104: case 0x105: case 0x11c: case 0x11d: - WRITE8(addr + 2, mach64->dst_y_x, val); - break; - case 0x108: case 0x109: - WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x10c: case 0x10d: case 0x10e: case 0x10f: - WRITE8(addr, mach64->dst_y_x, val); - break; - case 0x110: case 0x111: - WRITE8(addr + 2, mach64->dst_height_width, val); - break; - case 0x114: case 0x115: - case 0x118: case 0x119: case 0x11a: case 0x11b: - case 0x11e: case 0x11f: - WRITE8(addr, mach64->dst_height_width, val); - /*FALLTHROUGH*/ - case 0x113: - if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || - (addr & 0x3ff) == 0x113) && !(val & 0x80)) - { - mach64_start_fill(mach64); - mach64_log("%i %i %i %i %i %08x\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), - ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST), mach64->dp_src); - if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; + switch (addr & 0x3ff) { + case 0x100: + case 0x101: + case 0x102: + case 0x103: + WRITE8(addr, mach64->dst_off_pitch, val); + break; + case 0x104: + case 0x105: + case 0x11c: + case 0x11d: + WRITE8(addr + 2, mach64->dst_y_x, val); + break; + case 0x108: + case 0x109: + WRITE8(addr, mach64->dst_y_x, val); + break; + case 0x10c: + case 0x10d: + case 0x10e: + case 0x10f: + WRITE8(addr, mach64->dst_y_x, val); + break; + case 0x110: + case 0x111: + WRITE8(addr + 2, mach64->dst_height_width, val); + break; + case 0x114: + case 0x115: + case 0x118: + case 0x119: + case 0x11a: + case 0x11b: + case 0x11e: + case 0x11f: + WRITE8(addr, mach64->dst_height_width, val); + /*FALLTHROUGH*/ + case 0x113: + if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || (addr & 0x3ff) == 0x113) && !(val & 0x80)) { + mach64_start_fill(mach64); + mach64_log("%i %i %i %i %i %08x\n", (mach64->dst_height_width & 0x7ff), (mach64->dst_height_width & 0x7ff0000), + ((mach64->dp_src & 7) != SRC_HOST), (((mach64->dp_src >> 8) & 7) != SRC_HOST), + (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST), mach64->dp_src); + if ((mach64->dst_height_width & 0x7ff) && (mach64->dst_height_width & 0x7ff0000) && ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); + } + break; - case 0x120: case 0x121: case 0x122: case 0x123: - WRITE8(addr, mach64->dst_bres_lnth, val); - if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) - { - mach64_start_line(mach64); + case 0x120: + case 0x121: + case 0x122: + case 0x123: + WRITE8(addr, mach64->dst_bres_lnth, val); + if ((addr & 0x3ff) == 0x123 && !(val & 0x80)) { + mach64_start_line(mach64); - if ((mach64->dst_bres_lnth & 0x7fff) && - ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && - (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) - mach64_blit(0, -1, mach64); - } - break; - case 0x124: case 0x125: case 0x126: case 0x127: - WRITE8(addr, mach64->dst_bres_err, val); - break; - case 0x128: case 0x129: case 0x12a: case 0x12b: - WRITE8(addr, mach64->dst_bres_inc, val); - break; - case 0x12c: case 0x12d: case 0x12e: case 0x12f: - WRITE8(addr, mach64->dst_bres_dec, val); - break; + if ((mach64->dst_bres_lnth & 0x7fff) && ((mach64->dp_src & 7) != SRC_HOST) && (((mach64->dp_src >> 8) & 7) != SRC_HOST) && (((mach64->dp_src >> 16) & 3) != MONO_SRC_HOST)) + mach64_blit(0, -1, mach64); + } + break; + case 0x124: + case 0x125: + case 0x126: + case 0x127: + WRITE8(addr, mach64->dst_bres_err, val); + break; + case 0x128: + case 0x129: + case 0x12a: + case 0x12b: + WRITE8(addr, mach64->dst_bres_inc, val); + break; + case 0x12c: + case 0x12d: + case 0x12e: + case 0x12f: + WRITE8(addr, mach64->dst_bres_dec, val); + break; - case 0x130: case 0x131: case 0x132: case 0x133: - WRITE8(addr, mach64->dst_cntl, val); - break; + case 0x130: + case 0x131: + case 0x132: + case 0x133: + WRITE8(addr, mach64->dst_cntl, val); + break; - case 0x180: case 0x181: case 0x182: case 0x183: - WRITE8(addr, mach64->src_off_pitch, val); - break; - case 0x184: case 0x185: - WRITE8(addr, mach64->src_y_x, val); - break; - case 0x188: case 0x189: - WRITE8(addr + 2, mach64->src_y_x, val); - break; - case 0x18c: case 0x18d: case 0x18e: case 0x18f: - WRITE8(addr, mach64->src_y_x, val); - break; - case 0x190: case 0x191: - WRITE8(addr + 2, mach64->src_height1_width1, val); - break; - case 0x194: case 0x195: - WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x198: case 0x199: case 0x19a: case 0x19b: - WRITE8(addr, mach64->src_height1_width1, val); - break; - case 0x19c: case 0x19d: - WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a0: case 0x1a1: - WRITE8(addr + 2, mach64->src_y_x_start, val); - break; - case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: - WRITE8(addr, mach64->src_y_x_start, val); - break; - case 0x1a8: case 0x1a9: - WRITE8(addr + 2, mach64->src_height2_width2, val); - break; - case 0x1ac: case 0x1ad: - WRITE8(addr, mach64->src_height2_width2, val); - break; - case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: - WRITE8(addr, mach64->src_height2_width2, val); - break; + case 0x180: + case 0x181: + case 0x182: + case 0x183: + WRITE8(addr, mach64->src_off_pitch, val); + break; + case 0x184: + case 0x185: + WRITE8(addr, mach64->src_y_x, val); + break; + case 0x188: + case 0x189: + WRITE8(addr + 2, mach64->src_y_x, val); + break; + case 0x18c: + case 0x18d: + case 0x18e: + case 0x18f: + WRITE8(addr, mach64->src_y_x, val); + break; + case 0x190: + case 0x191: + WRITE8(addr + 2, mach64->src_height1_width1, val); + break; + case 0x194: + case 0x195: + WRITE8(addr, mach64->src_height1_width1, val); + break; + case 0x198: + case 0x199: + case 0x19a: + case 0x19b: + WRITE8(addr, mach64->src_height1_width1, val); + break; + case 0x19c: + case 0x19d: + WRITE8(addr, mach64->src_y_x_start, val); + break; + case 0x1a0: + case 0x1a1: + WRITE8(addr + 2, mach64->src_y_x_start, val); + break; + case 0x1a4: + case 0x1a5: + case 0x1a6: + case 0x1a7: + WRITE8(addr, mach64->src_y_x_start, val); + break; + case 0x1a8: + case 0x1a9: + WRITE8(addr + 2, mach64->src_height2_width2, val); + break; + case 0x1ac: + case 0x1ad: + WRITE8(addr, mach64->src_height2_width2, val); + break; + case 0x1b0: + case 0x1b1: + case 0x1b2: + case 0x1b3: + WRITE8(addr, mach64->src_height2_width2, val); + break; - case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: - WRITE8(addr, mach64->src_cntl, val); - break; + case 0x1b4: + case 0x1b5: + case 0x1b6: + case 0x1b7: + WRITE8(addr, mach64->src_cntl, val); + break; - case 0x200: case 0x201: case 0x202: case 0x203: - case 0x204: case 0x205: case 0x206: case 0x207: - case 0x208: case 0x209: case 0x20a: case 0x20b: - case 0x20c: case 0x20d: case 0x20e: case 0x20f: - case 0x210: case 0x211: case 0x212: case 0x213: - case 0x214: case 0x215: case 0x216: case 0x217: - case 0x218: case 0x219: case 0x21a: case 0x21b: - case 0x21c: case 0x21d: case 0x21e: case 0x21f: - case 0x220: case 0x221: case 0x222: case 0x223: - case 0x224: case 0x225: case 0x226: case 0x227: - case 0x228: case 0x229: case 0x22a: case 0x22b: - case 0x22c: case 0x22d: case 0x22e: case 0x22f: - case 0x230: case 0x231: case 0x232: case 0x233: - case 0x234: case 0x235: case 0x236: case 0x237: - case 0x238: case 0x239: case 0x23a: case 0x23b: - case 0x23c: case 0x23d: case 0x23e: case 0x23f: - mach64_blit(val, 8, mach64); - break; + case 0x200: + case 0x201: + case 0x202: + case 0x203: + case 0x204: + case 0x205: + case 0x206: + case 0x207: + case 0x208: + case 0x209: + case 0x20a: + case 0x20b: + case 0x20c: + case 0x20d: + case 0x20e: + case 0x20f: + case 0x210: + case 0x211: + case 0x212: + case 0x213: + case 0x214: + case 0x215: + case 0x216: + case 0x217: + case 0x218: + case 0x219: + case 0x21a: + case 0x21b: + case 0x21c: + case 0x21d: + case 0x21e: + case 0x21f: + case 0x220: + case 0x221: + case 0x222: + case 0x223: + case 0x224: + case 0x225: + case 0x226: + case 0x227: + case 0x228: + case 0x229: + case 0x22a: + case 0x22b: + case 0x22c: + case 0x22d: + case 0x22e: + case 0x22f: + case 0x230: + case 0x231: + case 0x232: + case 0x233: + case 0x234: + case 0x235: + case 0x236: + case 0x237: + case 0x238: + case 0x239: + case 0x23a: + case 0x23b: + case 0x23c: + case 0x23d: + case 0x23e: + case 0x23f: + mach64_blit(val, 8, mach64); + break; - case 0x240: case 0x241: case 0x242: case 0x243: - WRITE8(addr, mach64->host_cntl, val); - break; + case 0x240: + case 0x241: + case 0x242: + case 0x243: + WRITE8(addr, mach64->host_cntl, val); + break; - case 0x280: case 0x281: case 0x282: case 0x283: - WRITE8(addr, mach64->pat_reg0, val); - break; - case 0x284: case 0x285: case 0x286: case 0x287: - WRITE8(addr, mach64->pat_reg1, val); - break; + case 0x280: + case 0x281: + case 0x282: + case 0x283: + WRITE8(addr, mach64->pat_reg0, val); + break; + case 0x284: + case 0x285: + case 0x286: + case 0x287: + WRITE8(addr, mach64->pat_reg1, val); + break; - case 0x288: case 0x289: case 0x28a: case 0x28b: - WRITE8(addr, mach64->pat_cntl, val); - break; + case 0x288: + case 0x289: + case 0x28a: + case 0x28b: + WRITE8(addr, mach64->pat_cntl, val); + break; - case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: - WRITE8(addr, mach64->sc_left_right, val); - break; - case 0x2a4: case 0x2a5: - addr += 2; - /*FALLTHROUGH*/ - case 0x2aa: case 0x2ab: - WRITE8(addr, mach64->sc_left_right, val); - break; + case 0x2a0: + case 0x2a1: + case 0x2a8: + case 0x2a9: + WRITE8(addr, mach64->sc_left_right, val); + break; + case 0x2a4: + case 0x2a5: + addr += 2; + /*FALLTHROUGH*/ + case 0x2aa: + case 0x2ab: + WRITE8(addr, mach64->sc_left_right, val); + break; - case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: - WRITE8(addr, mach64->sc_top_bottom, val); - break; - case 0x2b0: case 0x2b1: - addr += 2; - /*FALLTHROUGH*/ - case 0x2b6: case 0x2b7: - WRITE8(addr, mach64->sc_top_bottom, val); - break; + case 0x2ac: + case 0x2ad: + case 0x2b4: + case 0x2b5: + WRITE8(addr, mach64->sc_top_bottom, val); + break; + case 0x2b0: + case 0x2b1: + addr += 2; + /*FALLTHROUGH*/ + case 0x2b6: + case 0x2b7: + WRITE8(addr, mach64->sc_top_bottom, val); + break; - case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: - WRITE8(addr, mach64->dp_bkgd_clr, val); - break; - case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: - WRITE8(addr, mach64->dp_frgd_clr, val); - break; - case 0x2c8: case 0x2c9: case 0x2ca: case 0x2cb: - WRITE8(addr, mach64->write_mask, val); - break; - case 0x2cc: case 0x2cd: case 0x2ce: case 0x2cf: - WRITE8(addr, mach64->chain_mask, val); - break; + case 0x2c0: + case 0x2c1: + case 0x2c2: + case 0x2c3: + WRITE8(addr, mach64->dp_bkgd_clr, val); + break; + case 0x2c4: + case 0x2c5: + case 0x2c6: + case 0x2c7: + WRITE8(addr, mach64->dp_frgd_clr, val); + break; + case 0x2c8: + case 0x2c9: + case 0x2ca: + case 0x2cb: + WRITE8(addr, mach64->write_mask, val); + break; + case 0x2cc: + case 0x2cd: + case 0x2ce: + case 0x2cf: + WRITE8(addr, mach64->chain_mask, val); + break; - case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: - WRITE8(addr, mach64->dp_pix_width, val); - break; - case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: - WRITE8(addr, mach64->dp_mix, val); - break; - case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: - WRITE8(addr, mach64->dp_src, val); - break; + case 0x2d0: + case 0x2d1: + case 0x2d2: + case 0x2d3: + WRITE8(addr, mach64->dp_pix_width, val); + break; + case 0x2d4: + case 0x2d5: + case 0x2d6: + case 0x2d7: + WRITE8(addr, mach64->dp_mix, val); + break; + case 0x2d8: + case 0x2d9: + case 0x2da: + case 0x2db: + WRITE8(addr, mach64->dp_src, val); + break; - case 0x300: case 0x301: case 0x302: case 0x303: - WRITE8(addr, mach64->clr_cmp_clr, val); - break; - case 0x304: case 0x305: case 0x306: case 0x307: - WRITE8(addr, mach64->clr_cmp_mask, val); - break; - case 0x308: case 0x309: case 0x30a: case 0x30b: - WRITE8(addr, mach64->clr_cmp_cntl, val); - break; + case 0x300: + case 0x301: + case 0x302: + case 0x303: + WRITE8(addr, mach64->clr_cmp_clr, val); + break; + case 0x304: + case 0x305: + case 0x306: + case 0x307: + WRITE8(addr, mach64->clr_cmp_mask, val); + break; + case 0x308: + case 0x309: + case 0x30a: + case 0x30b: + WRITE8(addr, mach64->clr_cmp_cntl, val); + break; - case 0x320: case 0x321: case 0x322: case 0x323: - WRITE8(addr, mach64->context_mask, val); - break; + case 0x320: + case 0x321: + case 0x322: + case 0x323: + WRITE8(addr, mach64->context_mask, val); + break; - case 0x330: case 0x331: - WRITE8(addr, mach64->dst_cntl, val); - break; - case 0x332: - WRITE8(addr - 2, mach64->src_cntl, val); - break; - case 0x333: - WRITE8(addr - 3, mach64->pat_cntl, val & 7); - if (val & 0x10) - mach64->host_cntl |= HOST_BYTE_ALIGN; - else - mach64->host_cntl &= ~HOST_BYTE_ALIGN; - break; - } + case 0x330: + case 0x331: + WRITE8(addr, mach64->dst_cntl, val); + break; + case 0x332: + WRITE8(addr - 2, mach64->src_cntl, val); + break; + case 0x333: + WRITE8(addr - 3, mach64->pat_cntl, val & 7); + if (val & 0x10) + mach64->host_cntl |= HOST_BYTE_ALIGN; + else + mach64->host_cntl &= ~HOST_BYTE_ALIGN; + break; + } } -static void mach64_accel_write_fifo_w(mach64_t *mach64, uint32_t addr, uint16_t val) +static void +mach64_accel_write_fifo_w(mach64_t *mach64, uint32_t addr, uint16_t val) { - switch (addr & 0x3fe) - { - case 0x200: case 0x202: case 0x204: case 0x206: - case 0x208: case 0x20a: case 0x20c: case 0x20e: - case 0x210: case 0x212: case 0x214: case 0x216: - case 0x218: case 0x21a: case 0x21c: case 0x21e: - case 0x220: case 0x222: case 0x224: case 0x226: - case 0x228: case 0x22a: case 0x22c: case 0x22e: - case 0x230: case 0x232: case 0x234: case 0x236: - case 0x238: case 0x23a: case 0x23c: case 0x23e: - mach64_blit(val, 16, mach64); - break; + switch (addr & 0x3fe) { + case 0x200: + case 0x202: + case 0x204: + case 0x206: + case 0x208: + case 0x20a: + case 0x20c: + case 0x20e: + case 0x210: + case 0x212: + case 0x214: + case 0x216: + case 0x218: + case 0x21a: + case 0x21c: + case 0x21e: + case 0x220: + case 0x222: + case 0x224: + case 0x226: + case 0x228: + case 0x22a: + case 0x22c: + case 0x22e: + case 0x230: + case 0x232: + case 0x234: + case 0x236: + case 0x238: + case 0x23a: + case 0x23c: + case 0x23e: + mach64_blit(val, 16, mach64); + break; - case 0x32c: - mach64->context_load_cntl = (mach64->context_load_cntl & 0xffff0000) | val; - break; + case 0x32c: + mach64->context_load_cntl = (mach64->context_load_cntl & 0xffff0000) | val; + break; - case 0x32e: - mach64->context_load_cntl = (mach64->context_load_cntl & 0x0000ffff) | (val << 16); - if (val & 0x30000) - mach64_load_context(mach64); - break; + case 0x32e: + mach64->context_load_cntl = (mach64->context_load_cntl & 0x0000ffff) | (val << 16); + if (val & 0x30000) + mach64_load_context(mach64); + break; - default: - mach64_accel_write_fifo(mach64, addr, val); - mach64_accel_write_fifo(mach64, addr + 1, val >> 8); - break; - } + default: + mach64_accel_write_fifo(mach64, addr, val); + mach64_accel_write_fifo(mach64, addr + 1, val >> 8); + break; + } } -static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) +static void +mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) { - switch (addr & 0x3fc) - { - case 0x32c: - mach64->context_load_cntl = val; - if (val & 0x30000) - mach64_load_context(mach64); - break; + switch (addr & 0x3fc) { + case 0x32c: + mach64->context_load_cntl = val; + if (val & 0x30000) + mach64_load_context(mach64); + break; - case 0x200: case 0x204: case 0x208: case 0x20c: - case 0x210: case 0x214: case 0x218: case 0x21c: - case 0x220: case 0x224: case 0x228: case 0x22c: - case 0x230: case 0x234: case 0x238: case 0x23c: - if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)) - mach64_blit(val, 32, mach64); - else - mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64); - break; + case 0x200: + case 0x204: + case 0x208: + case 0x20c: + case 0x210: + case 0x214: + case 0x218: + case 0x21c: + case 0x220: + case 0x224: + case 0x228: + case 0x22c: + case 0x230: + case 0x234: + case 0x238: + case 0x23c: + if (mach64->accel.source_host || (mach64->dp_pix_width & DP_BYTE_PIX_ORDER)) + mach64_blit(val, 32, mach64); + else + mach64_blit(((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), 32, mach64); + break; - default: - mach64_accel_write_fifo_w(mach64, addr, val); - mach64_accel_write_fifo_w(mach64, addr + 2, val >> 16); - break; - } + default: + mach64_accel_write_fifo_w(mach64, addr, val); + mach64_accel_write_fifo_w(mach64, addr + 2, val >> 16); + break; + } } -static void fifo_thread(void *param) +static void +fifo_thread(void *param) { - mach64_t *mach64 = (mach64_t *)param; + mach64_t *mach64 = (mach64_t *) param; - while (mach64->thread_run) - { + while (mach64->thread_run) { + thread_set_event(mach64->fifo_not_full_event); + thread_wait_event(mach64->wake_fifo_thread, -1); + thread_reset_event(mach64->wake_fifo_thread); + mach64->blitter_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; + + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + mach64_accel_write_fifo(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_WORD: + mach64_accel_write_fifo_w(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_DWORD: + mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } + + mach64->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; + + if (FIFO_ENTRIES > 0xe000) thread_set_event(mach64->fifo_not_full_event); - thread_wait_event(mach64->wake_fifo_thread, -1); - thread_reset_event(mach64->wake_fifo_thread); - mach64->blitter_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITE_BYTE: - mach64_accel_write_fifo(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD: - mach64_accel_write_fifo_w(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD: - mach64_accel_write_fifo_l(mach64, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } - - mach64->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(mach64->fifo_not_full_event); - - end_time = plat_timer_read(); - mach64->blitter_time += end_time - start_time; - } - mach64->blitter_busy = 0; + end_time = plat_timer_read(); + mach64->blitter_time += end_time - start_time; } + mach64->blitter_busy = 0; + } } -static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) +static void +mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) - { - thread_reset_event(mach64->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } + if (FIFO_FULL) { + thread_reset_event(mach64->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(mach64->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - mach64->fifo_write_idx++; + mach64->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(mach64); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(mach64); } - -void mach64_start_fill(mach64_t *mach64) +void +mach64_start_fill(mach64_t *mach64) { - int x, y; + int x, y; - mach64->accel.dst_x = 0; - mach64->accel.dst_y = 0; - mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff; + mach64->accel.dst_x = 0; + mach64->accel.dst_y = 0; + mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff; + mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff; - mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; - mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; + mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; + mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; - if (((mach64->dp_src >> 16) & 7) == MONO_SRC_BLITSRC) - { - if (mach64->accel.dst_width & 7) - mach64->accel.dst_width = (mach64->accel.dst_width & ~7) + 8; - } + if (((mach64->dp_src >> 16) & 7) == MONO_SRC_BLITSRC) { + if (mach64->accel.dst_width & 7) + mach64->accel.dst_width = (mach64->accel.dst_width & ~7) + 8; + } - mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.src_x = 0; - mach64->accel.src_y = 0; - mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y_start = mach64->src_y_x & 0xfff; - if (mach64->src_cntl & SRC_LINEAR_EN) - mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/ - else - mach64->accel.src_x_count = (mach64->src_height1_width1 >> 16) & 0x7fff; - if (!(mach64->src_cntl & SRC_PATT_EN)) - mach64->accel.src_y_count = 0x7ffffff; /*Essentially infinite*/ - else - mach64->accel.src_y_count = mach64->src_height1_width1 & 0x1fff; + mach64->accel.src_x = 0; + mach64->accel.src_y = 0; + mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_y_start = mach64->src_y_x & 0xfff; + if (mach64->src_cntl & SRC_LINEAR_EN) + mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/ + else + mach64->accel.src_x_count = (mach64->src_height1_width1 >> 16) & 0x7fff; + if (!(mach64->src_cntl & SRC_PATT_EN)) + mach64->accel.src_y_count = 0x7ffffff; /*Essentially infinite*/ + else + mach64->accel.src_y_count = mach64->src_height1_width1 & 0x1fff; - mach64->accel.src_width1 = (mach64->src_height1_width1 >> 16) & 0x7fff; - mach64->accel.src_height1 = mach64->src_height1_width1 & 0x1fff; - mach64->accel.src_width2 = (mach64->src_height2_width2 >> 16) & 0x7fff; - mach64->accel.src_height2 = mach64->src_height2_width2 & 0x1fff; + mach64->accel.src_width1 = (mach64->src_height1_width1 >> 16) & 0x7fff; + mach64->accel.src_height1 = mach64->src_height1_width1 & 0x1fff; + mach64->accel.src_width2 = (mach64->src_height2_width2 >> 16) & 0x7fff; + mach64->accel.src_height2 = mach64->src_height2_width2 & 0x1fff; - mach64_log("src %i %i %i %i %08X %08X\n", mach64->accel.src_x_count, - mach64->accel.src_y_count, - mach64->accel.src_width1, - mach64->accel.src_height1, - mach64->src_height1_width1, - mach64->src_height2_width2); + mach64_log("src %i %i %i %i %08X %08X\n", mach64->accel.src_x_count, + mach64->accel.src_y_count, + mach64->accel.src_width1, + mach64->accel.src_height1, + mach64->src_height1_width1, + mach64->src_height2_width2); - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; - mach64->accel.mix_bg = mach64->dp_mix & 0x1f; + mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; + mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - mach64->accel.source_bg = mach64->dp_src & 7; - mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; - mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; + mach64->accel.source_bg = mach64->dp_src & 7; + mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; + mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; - mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; - mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; + mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; + mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; + mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; - mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; + mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; + mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; + mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - if (mach64->accel.src_size == WIDTH_1BIT) - mach64->accel.src_offset <<= 3; - else - mach64->accel.src_offset >>= mach64->accel.src_size; + if (mach64->accel.src_size == WIDTH_1BIT) + mach64->accel.src_offset <<= 3; + else + mach64->accel.src_offset >>= mach64->accel.src_size; - if (mach64->accel.dst_size == WIDTH_1BIT) - mach64->accel.dst_offset <<= 3; - else - mach64->accel.dst_offset >>= mach64->accel.dst_size; + if (mach64->accel.dst_size == WIDTH_1BIT) + mach64->accel.dst_offset <<= 3; + else + mach64->accel.dst_offset >>= mach64->accel.dst_size; - mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; - mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; + mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; + mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); + mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; - } + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; } + } - if (mach64->pat_cntl & 2) { - mach64->accel.pattern_clr4x2[0][0] = (mach64->pat_reg0 & 0xff); - mach64->accel.pattern_clr4x2[0][1] = ((mach64->pat_reg0 >> 8) & 0xff); - mach64->accel.pattern_clr4x2[0][2] = ((mach64->pat_reg0 >> 16) & 0xff); - mach64->accel.pattern_clr4x2[0][3] = ((mach64->pat_reg0 >> 24) & 0xff); - mach64->accel.pattern_clr4x2[1][0] = (mach64->pat_reg1 & 0xff); - mach64->accel.pattern_clr4x2[1][1] = ((mach64->pat_reg1 >> 8) & 0xff); - mach64->accel.pattern_clr4x2[1][2] = ((mach64->pat_reg1 >> 16) & 0xff); - mach64->accel.pattern_clr4x2[1][3] = ((mach64->pat_reg1 >> 24) & 0xff); - } else if (mach64->pat_cntl & 4) { - mach64->accel.pattern_clr8x1[0] = (mach64->pat_reg0 & 0xff); - mach64->accel.pattern_clr8x1[1] = ((mach64->pat_reg0 >> 8) & 0xff); - mach64->accel.pattern_clr8x1[2] = ((mach64->pat_reg0 >> 16) & 0xff); - mach64->accel.pattern_clr8x1[3] = ((mach64->pat_reg0 >> 24) & 0xff); - mach64->accel.pattern_clr8x1[4] = (mach64->pat_reg1 & 0xff); - mach64->accel.pattern_clr8x1[5] = ((mach64->pat_reg1 >> 8) & 0xff); - mach64->accel.pattern_clr8x1[6] = ((mach64->pat_reg1 >> 16) & 0xff); - mach64->accel.pattern_clr8x1[7] = ((mach64->pat_reg1 >> 24) & 0xff); - } + if (mach64->pat_cntl & 2) { + mach64->accel.pattern_clr4x2[0][0] = (mach64->pat_reg0 & 0xff); + mach64->accel.pattern_clr4x2[0][1] = ((mach64->pat_reg0 >> 8) & 0xff); + mach64->accel.pattern_clr4x2[0][2] = ((mach64->pat_reg0 >> 16) & 0xff); + mach64->accel.pattern_clr4x2[0][3] = ((mach64->pat_reg0 >> 24) & 0xff); + mach64->accel.pattern_clr4x2[1][0] = (mach64->pat_reg1 & 0xff); + mach64->accel.pattern_clr4x2[1][1] = ((mach64->pat_reg1 >> 8) & 0xff); + mach64->accel.pattern_clr4x2[1][2] = ((mach64->pat_reg1 >> 16) & 0xff); + mach64->accel.pattern_clr4x2[1][3] = ((mach64->pat_reg1 >> 24) & 0xff); + } else if (mach64->pat_cntl & 4) { + mach64->accel.pattern_clr8x1[0] = (mach64->pat_reg0 & 0xff); + mach64->accel.pattern_clr8x1[1] = ((mach64->pat_reg0 >> 8) & 0xff); + mach64->accel.pattern_clr8x1[2] = ((mach64->pat_reg0 >> 16) & 0xff); + mach64->accel.pattern_clr8x1[3] = ((mach64->pat_reg0 >> 24) & 0xff); + mach64->accel.pattern_clr8x1[4] = (mach64->pat_reg1 & 0xff); + mach64->accel.pattern_clr8x1[5] = ((mach64->pat_reg1 >> 8) & 0xff); + mach64->accel.pattern_clr8x1[6] = ((mach64->pat_reg1 >> 16) & 0xff); + mach64->accel.pattern_clr8x1[7] = ((mach64->pat_reg1 >> 24) & 0xff); + } - mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; - mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; - mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; - mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; + mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; + mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; + mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; + mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; - mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - mach64->accel.write_mask = mach64->write_mask; + mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; + mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; + mach64->accel.write_mask = mach64->write_mask; - mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; - mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; - mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; - mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); + mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; + mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; + mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; + mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); - mach64->accel.poly_draw = 0; + mach64->accel.poly_draw = 0; - mach64->accel.busy = 1; - mach64_log("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i mix %02X %02X\n", mach64->accel.dst_x_start, mach64->accel.dst_y_start, mach64->accel.src_x_start, mach64->accel.src_y_start, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg, mach64->accel.mix_fg, mach64->accel.mix_bg); + mach64->accel.busy = 1; + mach64_log("mach64_start_fill : dst %i, %i src %i, %i size %i, %i src pitch %i offset %X dst pitch %i offset %X scissor %i %i %i %i src_fg %i mix %02X %02X\n", mach64->accel.dst_x_start, mach64->accel.dst_y_start, mach64->accel.src_x_start, mach64->accel.src_y_start, mach64->accel.dst_width, mach64->accel.dst_height, mach64->accel.src_pitch, mach64->accel.src_offset, mach64->accel.dst_pitch, mach64->accel.dst_offset, mach64->accel.sc_left, mach64->accel.sc_right, mach64->accel.sc_top, mach64->accel.sc_bottom, mach64->accel.source_fg, mach64->accel.mix_fg, mach64->accel.mix_bg); - mach64->accel.op = OP_RECT; + mach64->accel.op = OP_RECT; } -void mach64_start_line(mach64_t *mach64) +void +mach64_start_line(mach64_t *mach64) { - int x, y; + int x, y; - mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y = mach64->dst_y_x & 0xfff; + mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; + mach64->accel.dst_y = mach64->dst_y_x & 0xfff; - mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y = mach64->src_y_x & 0xfff; + mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_y = mach64->src_y_x & 0xfff; - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; - mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; - mach64->accel.mix_bg = mach64->dp_mix & 0x1f; + mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; + mach64->accel.mix_bg = mach64->dp_mix & 0x1f; - mach64->accel.source_bg = mach64->dp_src & 7; - mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; - mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; + mach64->accel.source_bg = mach64->dp_src & 7; + mach64->accel.source_fg = (mach64->dp_src >> 8) & 7; + mach64->accel.source_mix = (mach64->dp_src >> 16) & 7; - mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; - mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; - mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; + mach64->accel.dst_pix_width = mach64->dp_pix_width & 7; + mach64->accel.src_pix_width = (mach64->dp_pix_width >> 8) & 7; + mach64->accel.host_pix_width = (mach64->dp_pix_width >> 16) & 7; - mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; - mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; - mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; + mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; + mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; + mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - if (mach64->accel.src_size == WIDTH_1BIT) - mach64->accel.src_offset <<= 3; - else - mach64->accel.src_offset >>= mach64->accel.src_size; + if (mach64->accel.src_size == WIDTH_1BIT) + mach64->accel.src_offset <<= 3; + else + mach64->accel.src_offset >>= mach64->accel.src_size; - if (mach64->accel.dst_size == WIDTH_1BIT) - mach64->accel.dst_offset <<= 3; - else - mach64->accel.dst_offset >>= mach64->accel.dst_size; + if (mach64->accel.dst_size == WIDTH_1BIT) + mach64->accel.dst_offset <<= 3; + else + mach64->accel.dst_offset >>= mach64->accel.dst_size; -/* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ + /* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; + mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); + mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; - mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; - } + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; + mach64->accel.pattern[y][7 - x] = (temp >> (x + ((y & 3) * 8))) & 1; } + } - mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; - mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; - mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; - mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; + mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; + mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; + mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; + mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; - mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; - mach64->accel.write_mask = mach64->write_mask; + mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; + mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; + mach64->accel.write_mask = mach64->write_mask; - mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff; - mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0); + mach64->accel.x_count = mach64->dst_bres_lnth & 0x7fff; + mach64->accel.err = (mach64->dst_bres_err & 0x3ffff) | ((mach64->dst_bres_err & 0x40000) ? 0xfffc0000 : 0); - mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; - mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; - mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; - mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); + mach64->accel.clr_cmp_clr = mach64->clr_cmp_clr & mach64->clr_cmp_mask; + mach64->accel.clr_cmp_mask = mach64->clr_cmp_mask; + mach64->accel.clr_cmp_fn = mach64->clr_cmp_cntl & 7; + mach64->accel.clr_cmp_src = mach64->clr_cmp_cntl & (1 << 24); - mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; - mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; + mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; + mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; - mach64->accel.busy = 1; - mach64_log("mach64_start_line\n"); + mach64->accel.busy = 1; + mach64_log("mach64_start_line\n"); - mach64->accel.op = OP_LINE; + mach64->accel.op = OP_LINE; } -#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \ - else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \ - else if (width == 2) dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask]; \ - else if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr) & 7)) & 1; \ - else dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> (7 - ((addr) & 7))) & 1; +#define READ(addr, dat, width) \ + if (width == 0) \ + dat = svga->vram[((addr)) & mach64->vram_mask]; \ + else if (width == 1) \ + dat = *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask]; \ + else if (width == 2) \ + dat = *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask]; \ + else if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ + dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr) &7)) & 1; \ + else \ + dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> (7 - ((addr) &7))) & 1; -#define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \ - { \ - case 0x0: dest_dat = ~dest_dat; break; \ - case 0x1: dest_dat = 0; break; \ - case 0x2: dest_dat = 0xffffffff; break; \ - case 0x3: dest_dat = dest_dat; break; \ - case 0x4: dest_dat = ~src_dat; break; \ - case 0x5: dest_dat = src_dat ^ dest_dat; break; \ - case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x7: dest_dat = src_dat; break; \ - case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x9: dest_dat = ~src_dat | dest_dat; break; \ - case 0xa: dest_dat = src_dat | ~dest_dat; break; \ - case 0xb: dest_dat = src_dat | dest_dat; break; \ - case 0xc: dest_dat = src_dat & dest_dat; break; \ - case 0xd: dest_dat = src_dat & ~dest_dat; break; \ - case 0xe: dest_dat = ~src_dat & dest_dat; break; \ - case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ - case 0x17: dest_dat = (dest_dat + src_dat) >> 1; \ +#define MIX \ + switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) { \ + case 0x0: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x1: \ + dest_dat = 0; \ + break; \ + case 0x2: \ + dest_dat = 0xffffffff; \ + break; \ + case 0x3: \ + dest_dat = dest_dat; \ + break; \ + case 0x4: \ + dest_dat = ~src_dat; \ + break; \ + case 0x5: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x6: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x7: \ + dest_dat = src_dat; \ + break; \ + case 0x8: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x9: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0xa: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0xb: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0xc: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0xd: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0xe: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0xf: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + case 0x17: \ + dest_dat = (dest_dat + src_dat) >> 1; \ + } + +#define WRITE(addr, width) \ + if (width == 0) { \ + svga->vram[(addr) &mach64->vram_mask] = dest_dat; \ + svga->changedvram[((addr) &mach64->vram_mask) >> 12] = changeframecount; \ + } else if (width == 1) { \ + *(uint16_t *) &svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ + } else if (width == 2) { \ + *(uint32_t *) &svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ + } else { \ + if (dest_dat & 1) { \ + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ + svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr) &7); \ + else \ + svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << (7 - ((addr) &7)); \ + } else { \ + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ + svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr) &7)); \ + else \ + svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) &7))); \ + } \ + svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ + } + +void +mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) +{ + svga_t *svga = &mach64->svga; + int cmp_clr = 0; + + if (!mach64->accel.busy) { + mach64_log("mach64_blit : return as not busy\n"); + return; + } + switch (mach64->accel.op) { + case OP_RECT: + while (count) { + uint32_t src_dat = 0, dest_dat; + uint32_t host_dat = 0; + uint32_t old_dest_dat; + int mix = 0; + int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; + int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; + int src_x; + int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff; + + if (mach64->src_cntl & SRC_LINEAR_EN) + src_x = mach64->accel.src_x; + else + src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff; + + if (mach64->accel.source_host) { + host_dat = cpu_dat; + switch (mach64->accel.host_size) { + case 0: + cpu_dat >>= 8; + count -= 8; + break; + case 1: + cpu_dat >>= 16; + count -= 16; + break; + case 2: + count -= 32; + break; + } + } else + count--; + + switch (mach64->accel.source_mix) { + case MONO_SRC_HOST: + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) { + mix = cpu_dat & 1; + cpu_dat >>= 1; + } else { + mix = cpu_dat >> 31; + cpu_dat <<= 1; + } + break; + case MONO_SRC_PAT: + mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + break; + case MONO_SRC_1: + mix = 1; + break; + case MONO_SRC_BLITSRC: + if (mach64->src_cntl & SRC_LINEAR_EN) { + READ(mach64->accel.src_offset + src_x, mix, WIDTH_1BIT); + } else { + READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, mix, WIDTH_1BIT); + } + break; } -#define WRITE(addr, width) if (width == 0) \ - { \ - svga->vram[(addr) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else if (width == 1) \ - { \ - *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else if (width == 2) \ - { \ - *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ - svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ - } \ - else \ - { \ - if (dest_dat & 1) { \ - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ - svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr) & 7); \ - else \ - svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << (7 - ((addr) & 7)); \ - } else { \ - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) \ - svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr) & 7)); \ - else \ - svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << (7 - ((addr) & 7)));\ - } \ - svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ - } - -void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) -{ - svga_t *svga = &mach64->svga; - int cmp_clr = 0; - - if (!mach64->accel.busy) - { - mach64_log("mach64_blit : return as not busy\n"); - return; - } - switch (mach64->accel.op) - { - case OP_RECT: - while (count) - { - uint32_t src_dat = 0, dest_dat; - uint32_t host_dat = 0; - uint32_t old_dest_dat; - int mix = 0; - int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; - int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; - int src_x; - int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff; - - if (mach64->src_cntl & SRC_LINEAR_EN) - src_x = mach64->accel.src_x; - else - src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff; - - if (mach64->accel.source_host) - { - host_dat = cpu_dat; - switch (mach64->accel.host_size) - { - case 0: - cpu_dat >>= 8; - count -= 8; - break; - case 1: - cpu_dat >>= 16; - count -= 16; - break; - case 2: - count -= 32; - break; - } - } - else - count--; - - switch (mach64->accel.source_mix) - { - case MONO_SRC_HOST: - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) - { - mix = cpu_dat & 1; - cpu_dat >>= 1; - } - else - { - mix = cpu_dat >> 31; - cpu_dat <<= 1; - } + if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom) { + switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { + case SRC_HOST: + src_dat = host_dat; + break; + case SRC_BLITSRC: + READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); + break; + case SRC_FG: + if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { + if ((mach64->accel.x_count % 3) == 2) + src_dat = mach64->accel.dp_frgd_clr & 0xff; + else if ((mach64->accel.x_count % 3) == 1) + src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; + else if ((mach64->accel.x_count % 3) == 0) + src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; + } else + src_dat = mach64->accel.dp_frgd_clr; + break; + case SRC_BG: + if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { + if ((mach64->accel.x_count % 3) == 2) + src_dat = mach64->accel.dp_bkgd_clr & 0xff; + else if ((mach64->accel.x_count % 3) == 1) + src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; + else if ((mach64->accel.x_count % 3) == 0) + src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; + } else + src_dat = mach64->accel.dp_bkgd_clr; + break; + case SRC_PAT: + if (mach64->pat_cntl & 2) { + src_dat = mach64->accel.pattern_clr4x2[dst_y & 1][dst_x & 3]; break; - case MONO_SRC_PAT: - mix = mach64->accel.pattern[dst_y & 7][dst_x & 7]; + } else if (mach64->pat_cntl & 4) { + src_dat = mach64->accel.pattern_clr8x1[dst_x & 7]; break; - case MONO_SRC_1: - mix = 1; - break; - case MONO_SRC_BLITSRC: - if (mach64->src_cntl & SRC_LINEAR_EN) - { - READ(mach64->accel.src_offset + src_x, mix, WIDTH_1BIT); - } - else - { - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, mix, WIDTH_1BIT); - } - break; - } - - if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && - dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom) - { - switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) - { - case SRC_HOST: - src_dat = host_dat; - break; - case SRC_BLITSRC: - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); - break; - case SRC_FG: - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - if ((mach64->accel.x_count % 3) == 2) - src_dat = mach64->accel.dp_frgd_clr & 0xff; - else if ((mach64->accel.x_count % 3) == 1) - src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; - else if ((mach64->accel.x_count % 3) == 0) - src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; - } else - src_dat = mach64->accel.dp_frgd_clr; - break; - case SRC_BG: - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - if ((mach64->accel.x_count % 3) == 2) - src_dat = mach64->accel.dp_bkgd_clr & 0xff; - else if ((mach64->accel.x_count % 3) == 1) - src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; - else if ((mach64->accel.x_count % 3) == 0) - src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; - } else - src_dat = mach64->accel.dp_bkgd_clr; - break; - case SRC_PAT: - if (mach64->pat_cntl & 2) { - src_dat = mach64->accel.pattern_clr4x2[dst_y & 1][dst_x & 3]; - break; - } else if (mach64->pat_cntl & 4) { - src_dat = mach64->accel.pattern_clr8x1[dst_x & 7]; - break; - } - default: - src_dat = 0; - break; - } - - if (mach64->dst_cntl & DST_POLYGON_EN) - { - int poly_src; - READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, poly_src, mach64->accel.src_size); - if (poly_src) - mach64->accel.poly_draw = !mach64->accel.poly_draw; - } - - if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) - { - READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size); - - switch (mach64->accel.clr_cmp_fn) - { - case 1: /*TRUE*/ - cmp_clr = 1; - break; - case 4: /*DST_CLR != CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; - break; - case 5: /*DST_CLR == CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; - break; - } - - if (!cmp_clr) { - old_dest_dat = dest_dat; - MIX - dest_dat = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); - } - - WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size); - } - } - - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) != (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); - mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); - mach64->accel.write_mask = ((mach64->accel.write_mask >> 8) & 0xffff) | (mach64->accel.write_mask << 16); } - } + default: + src_dat = 0; + break; + } - mach64->accel.src_x += mach64->accel.xinc; - mach64->accel.dst_x += mach64->accel.xinc; - if (!(mach64->src_cntl & SRC_LINEAR_EN)) - { - mach64->accel.src_x_count--; - if (mach64->accel.src_x_count <= 0) - { - mach64->accel.src_x = 0; - if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) - { - mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff; - mach64->accel.src_x_count = mach64->accel.src_width2; - } - else - mach64->accel.src_x_count = mach64->accel.src_width1; - } - } + if (mach64->dst_cntl & DST_POLYGON_EN) { + int poly_src; + READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, poly_src, mach64->accel.src_size); + if (poly_src) + mach64->accel.poly_draw = !mach64->accel.poly_draw; + } - mach64->accel.x_count--; - if (mach64->accel.x_count <= 0) - { - mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.dst_x = 0; - mach64->accel.dst_y += mach64->accel.yinc; - mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_x_count = mach64->accel.src_width1; + if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) { + READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size); - if (!(mach64->src_cntl & SRC_LINEAR_EN)) - { - mach64->accel.src_x = 0; - mach64->accel.src_y += mach64->accel.yinc; - mach64->accel.src_y_count--; - if (mach64->accel.src_y_count <= 0) - { - mach64->accel.src_y = 0; - if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) - { - mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff; - mach64->accel.src_y_count = mach64->accel.src_height2; - } - else - mach64->accel.src_y_count = mach64->accel.src_height1; - } - } - - mach64->accel.poly_draw = 0; - - mach64->accel.dst_height--; - - if (mach64->accel.dst_height <= 0) - { - /*Blit finished*/ - mach64_log("mach64 blit finished\n"); - mach64->accel.busy = 0; - if (mach64->dst_cntl & DST_X_TILE) - mach64->dst_y_x = (mach64->dst_y_x & 0xfff) | ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000); - if (mach64->dst_cntl & DST_Y_TILE) - mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + (mach64->dst_height_width & 0x1fff)) & 0xfff); - return; - } - if (mach64->host_cntl & HOST_BYTE_ALIGN) - { - if (mach64->accel.source_mix == MONO_SRC_HOST) - { - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) - cpu_dat >>= (count & 7); - else - cpu_dat <<= (count & 7); - count &= ~7; - } - } - } - } - break; - - case OP_LINE: - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { - int x = 0; - while (count) { - uint32_t src_dat = 0, dest_dat; - uint32_t host_dat = 0; - int mix = 0; - - if (mach64->accel.source_host) - { - host_dat = cpu_dat; - switch (mach64->accel.src_size) - { - case 0: - cpu_dat >>= 8; - count -= 8; - break; - case 1: - cpu_dat >>= 16; - count -= 16; - break; - case 2: - count -= 32; - break; - } - } - else - count--; - - switch (mach64->accel.source_mix) - { - case MONO_SRC_HOST: - if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) - { - mix = cpu_dat & 1; - cpu_dat >>= 1; - } - else - { - mix = cpu_dat >> 31; - cpu_dat <<= 1; - } - break; - case MONO_SRC_PAT: - mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; - break; - case MONO_SRC_1: - mix = 1; - break; - case MONO_SRC_BLITSRC: - READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, mix, WIDTH_1BIT); - break; - } - - if ((mach64->accel.dst_x >= mach64->accel.sc_left) && (mach64->accel.dst_x <= mach64->accel.sc_right) && - (mach64->accel.dst_y >= mach64->accel.sc_top) && (mach64->accel.dst_y <= mach64->accel.sc_bottom)) { - switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) - { - case SRC_HOST: - src_dat = host_dat; - break; - case SRC_BLITSRC: - READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); - break; - case SRC_FG: - src_dat = mach64->accel.dp_frgd_clr; - break; - case SRC_BG: - src_dat = mach64->accel.dp_bkgd_clr; - break; - case SRC_PAT: - if (mach64->pat_cntl & 2) { - src_dat = mach64->accel.pattern_clr4x2[mach64->accel.dst_y & 1][mach64->accel.dst_x & 3]; - break; - } else if (mach64->pat_cntl & 4) { - src_dat = mach64->accel.pattern_clr8x1[mach64->accel.dst_x & 7]; - break; - } - default: - src_dat = 0; - break; - } - - READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); - - switch (mach64->accel.clr_cmp_fn) { - case 1: /*TRUE*/ + switch (mach64->accel.clr_cmp_fn) { + case 1: /*TRUE*/ cmp_clr = 1; break; - case 4: /*DST_CLR != CLR_CMP_CLR*/ + case 4: /*DST_CLR != CLR_CMP_CLR*/ cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; break; - case 5: /*DST_CLR == CLR_CMP_CLR*/ + case 5: /*DST_CLR == CLR_CMP_CLR*/ cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; break; - } - - if (!cmp_clr) - MIX - - if (!(mach64->dst_cntl & DST_Y_MAJOR)) { - if (x == 0) - dest_dat &= ~1; - } else { - if (x == (mach64->accel.x_count - 1)) - dest_dat &= ~1; - } - - WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); } - x++; - if (x >= mach64->accel.x_count) { - mach64->accel.busy = 0; - mach64_log("mach64 line24 finished\n"); - return; + if (!cmp_clr) { + old_dest_dat = dest_dat; + MIX + dest_dat + = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); } - if (mach64->dst_cntl & DST_Y_MAJOR) { - mach64->accel.dst_y += mach64->accel.yinc; - if (mach64->accel.err >= 0) { - mach64->accel.err += mach64->dst_bres_dec; - mach64->accel.dst_x += mach64->accel.xinc; - } else { - mach64->accel.err += mach64->dst_bres_inc; - } - } else { - mach64->accel.dst_x += mach64->accel.xinc; - if (mach64->accel.err >= 0) { - mach64->accel.err += mach64->dst_bres_dec; - mach64->accel.dst_y += mach64->accel.yinc; - } else { - mach64->accel.err += mach64->dst_bres_inc; - } - } - } - } else { - while (count) - { - uint32_t src_dat = 0, dest_dat; - uint32_t host_dat = 0; - int mix = 0; - int draw_pixel = !(mach64->dst_cntl & DST_POLYGON_EN); - - if (mach64->accel.source_host) - { - host_dat = cpu_dat; - switch (mach64->accel.src_size) - { - case 0: - cpu_dat >>= 8; - count -= 8; - break; - case 1: - cpu_dat >>= 16; - count -= 16; - break; - case 2: - count -= 32; - break; - } - } - else - count--; - - switch (mach64->accel.source_mix) - { - case MONO_SRC_HOST: - mix = cpu_dat >> 31; - cpu_dat <<= 1; - break; - case MONO_SRC_PAT: - mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; - break; - case MONO_SRC_1: - default: - mix = 1; - break; - } - - if (mach64->dst_cntl & DST_POLYGON_EN) - { - if (mach64->dst_cntl & DST_Y_MAJOR) - draw_pixel = 1; - else if ((mach64->dst_cntl & DST_X_DIR) && mach64->accel.err < (mach64->dst_bres_dec + mach64->dst_bres_inc)) /*X+*/ - draw_pixel = 1; - else if (!(mach64->dst_cntl & DST_X_DIR) && mach64->accel.err >= 0) /*X-*/ - draw_pixel = 1; - } - - if (mach64->accel.x_count == 1 && !(mach64->dst_cntl & DST_LAST_PEL)) - draw_pixel = 0; - - if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right && - mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom && draw_pixel) - { - switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) - { - case SRC_HOST: - src_dat = host_dat; - break; - case SRC_BLITSRC: - READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); - break; - case SRC_FG: - src_dat = mach64->accel.dp_frgd_clr; - break; - case SRC_BG: - src_dat = mach64->accel.dp_bkgd_clr; - break; - default: - src_dat = 0; - break; - } - - READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); - - switch (mach64->accel.clr_cmp_fn) - { - case 1: /*TRUE*/ - cmp_clr = 1; - break; - case 4: /*DST_CLR != CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; - break; - case 5: /*DST_CLR == CLR_CMP_CLR*/ - cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; - break; - } - - if (!cmp_clr) - MIX - - WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); - } - - mach64->accel.x_count--; - if (mach64->accel.x_count <= 0) - { - /*Blit finished*/ - mach64_log("mach64 blit finished\n"); - mach64->accel.busy = 0; - return; - } - - switch (mach64->dst_cntl & 7) - { - case 0: case 2: - mach64->accel.src_x--; - mach64->accel.dst_x--; - break; - case 1: case 3: - mach64->accel.src_x++; - mach64->accel.dst_x++; - break; - case 4: case 5: - mach64->accel.src_y--; - mach64->accel.dst_y--; - break; - case 6: case 7: - mach64->accel.src_y++; - mach64->accel.dst_y++; - break; - } - mach64_log("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, mach64->dst_bres_inc, mach64->dst_bres_dec); - if (mach64->accel.err >= 0) - { - mach64->accel.err += mach64->dst_bres_dec; - - switch (mach64->dst_cntl & 7) - { - case 0: case 1: - mach64->accel.src_y--; - mach64->accel.dst_y--; - break; - case 2: case 3: - mach64->accel.src_y++; - mach64->accel.dst_y++; - break; - case 4: case 6: - mach64->accel.src_x--; - mach64->accel.dst_x--; - break; - case 5: case 7: - mach64->accel.src_x++; - mach64->accel.dst_x++; - break; - } - } - else - mach64->accel.err += mach64->dst_bres_inc; + WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size); } } - break; - } + + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) != (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { + mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); + mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); + mach64->accel.write_mask = ((mach64->accel.write_mask >> 8) & 0xffff) | (mach64->accel.write_mask << 16); + } + } + + mach64->accel.src_x += mach64->accel.xinc; + mach64->accel.dst_x += mach64->accel.xinc; + if (!(mach64->src_cntl & SRC_LINEAR_EN)) { + mach64->accel.src_x_count--; + if (mach64->accel.src_x_count <= 0) { + mach64->accel.src_x = 0; + if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { + mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff; + mach64->accel.src_x_count = mach64->accel.src_width2; + } else + mach64->accel.src_x_count = mach64->accel.src_width1; + } + } + + mach64->accel.x_count--; + if (mach64->accel.x_count <= 0) { + mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.dst_x = 0; + mach64->accel.dst_y += mach64->accel.yinc; + mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; + mach64->accel.src_x_count = mach64->accel.src_width1; + + if (!(mach64->src_cntl & SRC_LINEAR_EN)) { + mach64->accel.src_x = 0; + mach64->accel.src_y += mach64->accel.yinc; + mach64->accel.src_y_count--; + if (mach64->accel.src_y_count <= 0) { + mach64->accel.src_y = 0; + if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { + mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff; + mach64->accel.src_y_count = mach64->accel.src_height2; + } else + mach64->accel.src_y_count = mach64->accel.src_height1; + } + } + + mach64->accel.poly_draw = 0; + + mach64->accel.dst_height--; + + if (mach64->accel.dst_height <= 0) { + /*Blit finished*/ + mach64_log("mach64 blit finished\n"); + mach64->accel.busy = 0; + if (mach64->dst_cntl & DST_X_TILE) + mach64->dst_y_x = (mach64->dst_y_x & 0xfff) | ((mach64->dst_y_x + (mach64->accel.dst_width << 16)) & 0xfff0000); + if (mach64->dst_cntl & DST_Y_TILE) + mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + (mach64->dst_height_width & 0x1fff)) & 0xfff); + return; + } + if (mach64->host_cntl & HOST_BYTE_ALIGN) { + if (mach64->accel.source_mix == MONO_SRC_HOST) { + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) + cpu_dat >>= (count & 7); + else + cpu_dat <<= (count & 7); + count &= ~7; + } + } + } + } + break; + + case OP_LINE: + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + int x = 0; + while (count) { + uint32_t src_dat = 0, dest_dat; + uint32_t host_dat = 0; + int mix = 0; + + if (mach64->accel.source_host) { + host_dat = cpu_dat; + switch (mach64->accel.src_size) { + case 0: + cpu_dat >>= 8; + count -= 8; + break; + case 1: + cpu_dat >>= 16; + count -= 16; + break; + case 2: + count -= 32; + break; + } + } else + count--; + + switch (mach64->accel.source_mix) { + case MONO_SRC_HOST: + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) { + mix = cpu_dat & 1; + cpu_dat >>= 1; + } else { + mix = cpu_dat >> 31; + cpu_dat <<= 1; + } + break; + case MONO_SRC_PAT: + mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; + break; + case MONO_SRC_1: + mix = 1; + break; + case MONO_SRC_BLITSRC: + READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, mix, WIDTH_1BIT); + break; + } + + if ((mach64->accel.dst_x >= mach64->accel.sc_left) && (mach64->accel.dst_x <= mach64->accel.sc_right) && (mach64->accel.dst_y >= mach64->accel.sc_top) && (mach64->accel.dst_y <= mach64->accel.sc_bottom)) { + switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { + case SRC_HOST: + src_dat = host_dat; + break; + case SRC_BLITSRC: + READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); + break; + case SRC_FG: + src_dat = mach64->accel.dp_frgd_clr; + break; + case SRC_BG: + src_dat = mach64->accel.dp_bkgd_clr; + break; + case SRC_PAT: + if (mach64->pat_cntl & 2) { + src_dat = mach64->accel.pattern_clr4x2[mach64->accel.dst_y & 1][mach64->accel.dst_x & 3]; + break; + } else if (mach64->pat_cntl & 4) { + src_dat = mach64->accel.pattern_clr8x1[mach64->accel.dst_x & 7]; + break; + } + default: + src_dat = 0; + break; + } + + READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); + + switch (mach64->accel.clr_cmp_fn) { + case 1: /*TRUE*/ + cmp_clr = 1; + break; + case 4: /*DST_CLR != CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; + break; + case 5: /*DST_CLR == CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; + break; + } + + if (!cmp_clr) + MIX + + if (!(mach64->dst_cntl & DST_Y_MAJOR)) + { + if (x == 0) + dest_dat &= ~1; + } + else { + if (x == (mach64->accel.x_count - 1)) + dest_dat &= ~1; + } + + WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); + } + + x++; + if (x >= mach64->accel.x_count) { + mach64->accel.busy = 0; + mach64_log("mach64 line24 finished\n"); + return; + } + + if (mach64->dst_cntl & DST_Y_MAJOR) { + mach64->accel.dst_y += mach64->accel.yinc; + if (mach64->accel.err >= 0) { + mach64->accel.err += mach64->dst_bres_dec; + mach64->accel.dst_x += mach64->accel.xinc; + } else { + mach64->accel.err += mach64->dst_bres_inc; + } + } else { + mach64->accel.dst_x += mach64->accel.xinc; + if (mach64->accel.err >= 0) { + mach64->accel.err += mach64->dst_bres_dec; + mach64->accel.dst_y += mach64->accel.yinc; + } else { + mach64->accel.err += mach64->dst_bres_inc; + } + } + } + } else { + while (count) { + uint32_t src_dat = 0, dest_dat; + uint32_t host_dat = 0; + int mix = 0; + int draw_pixel = !(mach64->dst_cntl & DST_POLYGON_EN); + + if (mach64->accel.source_host) { + host_dat = cpu_dat; + switch (mach64->accel.src_size) { + case 0: + cpu_dat >>= 8; + count -= 8; + break; + case 1: + cpu_dat >>= 16; + count -= 16; + break; + case 2: + count -= 32; + break; + } + } else + count--; + + switch (mach64->accel.source_mix) { + case MONO_SRC_HOST: + mix = cpu_dat >> 31; + cpu_dat <<= 1; + break; + case MONO_SRC_PAT: + mix = mach64->accel.pattern[mach64->accel.dst_y & 7][mach64->accel.dst_x & 7]; + break; + case MONO_SRC_1: + default: + mix = 1; + break; + } + + if (mach64->dst_cntl & DST_POLYGON_EN) { + if (mach64->dst_cntl & DST_Y_MAJOR) + draw_pixel = 1; + else if ((mach64->dst_cntl & DST_X_DIR) && mach64->accel.err < (mach64->dst_bres_dec + mach64->dst_bres_inc)) /*X+*/ + draw_pixel = 1; + else if (!(mach64->dst_cntl & DST_X_DIR) && mach64->accel.err >= 0) /*X-*/ + draw_pixel = 1; + } + + if (mach64->accel.x_count == 1 && !(mach64->dst_cntl & DST_LAST_PEL)) + draw_pixel = 0; + + if (mach64->accel.dst_x >= mach64->accel.sc_left && mach64->accel.dst_x <= mach64->accel.sc_right && mach64->accel.dst_y >= mach64->accel.sc_top && mach64->accel.dst_y <= mach64->accel.sc_bottom && draw_pixel) { + switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { + case SRC_HOST: + src_dat = host_dat; + break; + case SRC_BLITSRC: + READ(mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x, src_dat, mach64->accel.src_size); + break; + case SRC_FG: + src_dat = mach64->accel.dp_frgd_clr; + break; + case SRC_BG: + src_dat = mach64->accel.dp_bkgd_clr; + break; + default: + src_dat = 0; + break; + } + + READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); + + switch (mach64->accel.clr_cmp_fn) { + case 1: /*TRUE*/ + cmp_clr = 1; + break; + case 4: /*DST_CLR != CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) != mach64->accel.clr_cmp_clr; + break; + case 5: /*DST_CLR == CLR_CMP_CLR*/ + cmp_clr = (((mach64->accel.clr_cmp_src) ? src_dat : dest_dat) & mach64->accel.clr_cmp_mask) == mach64->accel.clr_cmp_clr; + break; + } + + if (!cmp_clr) + MIX + + WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); + } + + mach64->accel.x_count--; + if (mach64->accel.x_count <= 0) { + /*Blit finished*/ + mach64_log("mach64 blit finished\n"); + mach64->accel.busy = 0; + return; + } + + switch (mach64->dst_cntl & 7) { + case 0: + case 2: + mach64->accel.src_x--; + mach64->accel.dst_x--; + break; + case 1: + case 3: + mach64->accel.src_x++; + mach64->accel.dst_x++; + break; + case 4: + case 5: + mach64->accel.src_y--; + mach64->accel.dst_y--; + break; + case 6: + case 7: + mach64->accel.src_y++; + mach64->accel.dst_y++; + break; + } + mach64_log("x %i y %i err %i inc %i dec %i\n", mach64->accel.dst_x, mach64->accel.dst_y, mach64->accel.err, mach64->dst_bres_inc, mach64->dst_bres_dec); + if (mach64->accel.err >= 0) { + mach64->accel.err += mach64->dst_bres_dec; + + switch (mach64->dst_cntl & 7) { + case 0: + case 1: + mach64->accel.src_y--; + mach64->accel.dst_y--; + break; + case 2: + case 3: + mach64->accel.src_y++; + mach64->accel.dst_y++; + break; + case 4: + case 6: + mach64->accel.src_x--; + mach64->accel.dst_x--; + break; + case 5: + case 7: + mach64->accel.src_x++; + mach64->accel.dst_x++; + break; + } + } else + mach64->accel.err += mach64->dst_bres_inc; + } + } + break; + } } -void mach64_load_context(mach64_t *mach64) +void +mach64_load_context(mach64_t *mach64) { - svga_t *svga = &mach64->svga; - uint32_t addr; + svga_t *svga = &mach64->svga; + uint32_t addr; - while (mach64->context_load_cntl & 0x30000) - { - addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; - mach64->context_mask = *(uint32_t *)&svga->vram[addr]; - mach64_log("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); + while (mach64->context_load_cntl & 0x30000) { + addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; + mach64->context_mask = *(uint32_t *) &svga->vram[addr]; + mach64_log("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); - if (mach64->context_mask & (1 << 2)) - mach64_accel_write_fifo_l(mach64, 0x100, *(uint32_t *)&svga->vram[addr + 0x08]); - if (mach64->context_mask & (1 << 3)) - mach64_accel_write_fifo_l(mach64, 0x10c, *(uint32_t *)&svga->vram[addr + 0x0c]); - if (mach64->context_mask & (1 << 4)) - mach64_accel_write_fifo_l(mach64, 0x118, *(uint32_t *)&svga->vram[addr + 0x10]); - if (mach64->context_mask & (1 << 5)) - mach64_accel_write_fifo_l(mach64, 0x124, *(uint32_t *)&svga->vram[addr + 0x14]); - if (mach64->context_mask & (1 << 6)) - mach64_accel_write_fifo_l(mach64, 0x128, *(uint32_t *)&svga->vram[addr + 0x18]); - if (mach64->context_mask & (1 << 7)) - mach64_accel_write_fifo_l(mach64, 0x12c, *(uint32_t *)&svga->vram[addr + 0x1c]); - if (mach64->context_mask & (1 << 8)) - mach64_accel_write_fifo_l(mach64, 0x180, *(uint32_t *)&svga->vram[addr + 0x20]); - if (mach64->context_mask & (1 << 9)) - mach64_accel_write_fifo_l(mach64, 0x18c, *(uint32_t *)&svga->vram[addr + 0x24]); - if (mach64->context_mask & (1 << 10)) - mach64_accel_write_fifo_l(mach64, 0x198, *(uint32_t *)&svga->vram[addr + 0x28]); - if (mach64->context_mask & (1 << 11)) - mach64_accel_write_fifo_l(mach64, 0x1a4, *(uint32_t *)&svga->vram[addr + 0x2c]); - if (mach64->context_mask & (1 << 12)) - mach64_accel_write_fifo_l(mach64, 0x1b0, *(uint32_t *)&svga->vram[addr + 0x30]); - if (mach64->context_mask & (1 << 13)) - mach64_accel_write_fifo_l(mach64, 0x280, *(uint32_t *)&svga->vram[addr + 0x34]); - if (mach64->context_mask & (1 << 14)) - mach64_accel_write_fifo_l(mach64, 0x284, *(uint32_t *)&svga->vram[addr + 0x38]); - if (mach64->context_mask & (1 << 15)) - mach64_accel_write_fifo_l(mach64, 0x2a8, *(uint32_t *)&svga->vram[addr + 0x3c]); - if (mach64->context_mask & (1 << 16)) - mach64_accel_write_fifo_l(mach64, 0x2b4, *(uint32_t *)&svga->vram[addr + 0x40]); - if (mach64->context_mask & (1 << 17)) - mach64_accel_write_fifo_l(mach64, 0x2c0, *(uint32_t *)&svga->vram[addr + 0x44]); - if (mach64->context_mask & (1 << 18)) - mach64_accel_write_fifo_l(mach64, 0x2c4, *(uint32_t *)&svga->vram[addr + 0x48]); - if (mach64->context_mask & (1 << 19)) - mach64_accel_write_fifo_l(mach64, 0x2c8, *(uint32_t *)&svga->vram[addr + 0x4c]); - if (mach64->context_mask & (1 << 20)) - mach64_accel_write_fifo_l(mach64, 0x2cc, *(uint32_t *)&svga->vram[addr + 0x50]); - if (mach64->context_mask & (1 << 21)) - mach64_accel_write_fifo_l(mach64, 0x2d0, *(uint32_t *)&svga->vram[addr + 0x54]); - if (mach64->context_mask & (1 << 22)) - mach64_accel_write_fifo_l(mach64, 0x2d4, *(uint32_t *)&svga->vram[addr + 0x58]); - if (mach64->context_mask & (1 << 23)) - mach64_accel_write_fifo_l(mach64, 0x2d8, *(uint32_t *)&svga->vram[addr + 0x5c]); - if (mach64->context_mask & (1 << 24)) - mach64_accel_write_fifo_l(mach64, 0x300, *(uint32_t *)&svga->vram[addr + 0x60]); - if (mach64->context_mask & (1 << 25)) - mach64_accel_write_fifo_l(mach64, 0x304, *(uint32_t *)&svga->vram[addr + 0x64]); - if (mach64->context_mask & (1 << 26)) - mach64_accel_write_fifo_l(mach64, 0x308, *(uint32_t *)&svga->vram[addr + 0x68]); - if (mach64->context_mask & (1 << 27)) - mach64_accel_write_fifo_l(mach64, 0x330, *(uint32_t *)&svga->vram[addr + 0x6c]); + if (mach64->context_mask & (1 << 2)) + mach64_accel_write_fifo_l(mach64, 0x100, *(uint32_t *) &svga->vram[addr + 0x08]); + if (mach64->context_mask & (1 << 3)) + mach64_accel_write_fifo_l(mach64, 0x10c, *(uint32_t *) &svga->vram[addr + 0x0c]); + if (mach64->context_mask & (1 << 4)) + mach64_accel_write_fifo_l(mach64, 0x118, *(uint32_t *) &svga->vram[addr + 0x10]); + if (mach64->context_mask & (1 << 5)) + mach64_accel_write_fifo_l(mach64, 0x124, *(uint32_t *) &svga->vram[addr + 0x14]); + if (mach64->context_mask & (1 << 6)) + mach64_accel_write_fifo_l(mach64, 0x128, *(uint32_t *) &svga->vram[addr + 0x18]); + if (mach64->context_mask & (1 << 7)) + mach64_accel_write_fifo_l(mach64, 0x12c, *(uint32_t *) &svga->vram[addr + 0x1c]); + if (mach64->context_mask & (1 << 8)) + mach64_accel_write_fifo_l(mach64, 0x180, *(uint32_t *) &svga->vram[addr + 0x20]); + if (mach64->context_mask & (1 << 9)) + mach64_accel_write_fifo_l(mach64, 0x18c, *(uint32_t *) &svga->vram[addr + 0x24]); + if (mach64->context_mask & (1 << 10)) + mach64_accel_write_fifo_l(mach64, 0x198, *(uint32_t *) &svga->vram[addr + 0x28]); + if (mach64->context_mask & (1 << 11)) + mach64_accel_write_fifo_l(mach64, 0x1a4, *(uint32_t *) &svga->vram[addr + 0x2c]); + if (mach64->context_mask & (1 << 12)) + mach64_accel_write_fifo_l(mach64, 0x1b0, *(uint32_t *) &svga->vram[addr + 0x30]); + if (mach64->context_mask & (1 << 13)) + mach64_accel_write_fifo_l(mach64, 0x280, *(uint32_t *) &svga->vram[addr + 0x34]); + if (mach64->context_mask & (1 << 14)) + mach64_accel_write_fifo_l(mach64, 0x284, *(uint32_t *) &svga->vram[addr + 0x38]); + if (mach64->context_mask & (1 << 15)) + mach64_accel_write_fifo_l(mach64, 0x2a8, *(uint32_t *) &svga->vram[addr + 0x3c]); + if (mach64->context_mask & (1 << 16)) + mach64_accel_write_fifo_l(mach64, 0x2b4, *(uint32_t *) &svga->vram[addr + 0x40]); + if (mach64->context_mask & (1 << 17)) + mach64_accel_write_fifo_l(mach64, 0x2c0, *(uint32_t *) &svga->vram[addr + 0x44]); + if (mach64->context_mask & (1 << 18)) + mach64_accel_write_fifo_l(mach64, 0x2c4, *(uint32_t *) &svga->vram[addr + 0x48]); + if (mach64->context_mask & (1 << 19)) + mach64_accel_write_fifo_l(mach64, 0x2c8, *(uint32_t *) &svga->vram[addr + 0x4c]); + if (mach64->context_mask & (1 << 20)) + mach64_accel_write_fifo_l(mach64, 0x2cc, *(uint32_t *) &svga->vram[addr + 0x50]); + if (mach64->context_mask & (1 << 21)) + mach64_accel_write_fifo_l(mach64, 0x2d0, *(uint32_t *) &svga->vram[addr + 0x54]); + if (mach64->context_mask & (1 << 22)) + mach64_accel_write_fifo_l(mach64, 0x2d4, *(uint32_t *) &svga->vram[addr + 0x58]); + if (mach64->context_mask & (1 << 23)) + mach64_accel_write_fifo_l(mach64, 0x2d8, *(uint32_t *) &svga->vram[addr + 0x5c]); + if (mach64->context_mask & (1 << 24)) + mach64_accel_write_fifo_l(mach64, 0x300, *(uint32_t *) &svga->vram[addr + 0x60]); + if (mach64->context_mask & (1 << 25)) + mach64_accel_write_fifo_l(mach64, 0x304, *(uint32_t *) &svga->vram[addr + 0x64]); + if (mach64->context_mask & (1 << 26)) + mach64_accel_write_fifo_l(mach64, 0x308, *(uint32_t *) &svga->vram[addr + 0x68]); + if (mach64->context_mask & (1 << 27)) + mach64_accel_write_fifo_l(mach64, 0x330, *(uint32_t *) &svga->vram[addr + 0x6c]); - mach64->context_load_cntl = *(uint32_t *)&svga->vram[addr + 0x70]; - } + mach64->context_load_cntl = *(uint32_t *) &svga->vram[addr + 0x70]; + } } #define PLL_REF_DIV 0x2 #define VCLK_POST_DIV 0x6 #define VCLK0_FB_DIV 0x7 -static void pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) +static void +pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) { - int c; + int c; - switch (addr & 3) - { - case 0: /*Clock sel*/ - break; - case 1: /*Addr*/ - mach64->pll_addr = (val >> 2) & 0xf; - break; - case 2: /*Data*/ - mach64->pll_regs[mach64->pll_addr] = val; - mach64_log("pll_write %02x,%02x\n", mach64->pll_addr, val); + switch (addr & 3) { + case 0: /*Clock sel*/ + break; + case 1: /*Addr*/ + mach64->pll_addr = (val >> 2) & 0xf; + break; + case 2: /*Data*/ + mach64->pll_regs[mach64->pll_addr] = val; + mach64_log("pll_write %02x,%02x\n", mach64->pll_addr, val); - for (c = 0; c < 4; c++) - { - double m = (double)mach64->pll_regs[PLL_REF_DIV]; - double n = (double)mach64->pll_regs[VCLK0_FB_DIV+c]; - double r = 14318184.0; - double p = (double)(1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c*2)) & 3)); + for (c = 0; c < 4; c++) { + double m = (double) mach64->pll_regs[PLL_REF_DIV]; + double n = (double) mach64->pll_regs[VCLK0_FB_DIV + c]; + double r = 14318184.0; + double p = (double) (1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c * 2)) & 3)); - mach64_log("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV+c], mach64->pll_regs[VCLK_POST_DIV]); - mach64->pll_freq[c] = (2.0 * r * n) / (m * p); - mach64_log(" %g\n", mach64->pll_freq[c]); - } - break; - } + mach64_log("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV + c], mach64->pll_regs[VCLK_POST_DIV]); + mach64->pll_freq[c] = (2.0 * r * n) / (m * p); + mach64_log(" %g\n", mach64->pll_freq[c]); + } + break; + } } #define OVERLAY_EN (1 << 30) -static void mach64_vblank_start(svga_t *svga) +static void +mach64_vblank_start(svga_t *svga) { - mach64_t *mach64 = (mach64_t *)svga->p; - int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; + mach64_t *mach64 = (mach64_t *) svga->p; + int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - mach64->crtc_int_cntl |= 4; - mach64_update_irqs(mach64); + mach64->crtc_int_cntl |= 4; + mach64_update_irqs(mach64); - svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; - svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; + svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; + svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; - svga->overlay.cur_xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; - svga->overlay.cur_ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; + svga->overlay.cur_xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; + svga->overlay.cur_ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; - svga->overlay.addr = mach64->buf_offset[0] & 0x3ffff8; - svga->overlay.pitch = mach64->buf_pitch[0] & 0xfff; + svga->overlay.addr = mach64->buf_offset[0] & 0x3ffff8; + svga->overlay.pitch = mach64->buf_pitch[0] & 0xfff; - svga->overlay.ena = (mach64->overlay_scale_cntl & OVERLAY_EN) && (overlay_cmp_mix != 1); + svga->overlay.ena = (mach64->overlay_scale_cntl & OVERLAY_EN) && (overlay_cmp_mix != 1); - mach64->overlay_v_acc = 0; - mach64->scaler_update = 1; + mach64->overlay_v_acc = 0; + mach64->scaler_update = 1; } -uint8_t mach64_ext_readb(uint32_t addr, void *p) +uint8_t +mach64_ext_readb(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - uint8_t ret = 0xff; - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_readb: addr=%04x\n", addr); - switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: - READ8(addr, mach64->overlay_y_x_start); - break; - case 0x04: case 0x05: case 0x06: case 0x07: - READ8(addr, mach64->overlay_y_x_end); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - READ8(addr, mach64->overlay_video_key_clr); - break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - READ8(addr, mach64->overlay_video_key_msk); - break; - case 0x10: case 0x11: case 0x12: case 0x13: - READ8(addr, mach64->overlay_graphics_key_clr); - break; - case 0x14: case 0x15: case 0x16: case 0x17: - READ8(addr, mach64->overlay_graphics_key_msk); - break; - case 0x18: case 0x19: case 0x1a: case 0x1b: - READ8(addr, mach64->overlay_key_cntl); - break; + uint8_t ret = 0xff; + if (!(addr & 0x400)) { + mach64_log("nmach64_ext_readb: addr=%04x\n", addr); + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + READ8(addr, mach64->overlay_y_x_start); + break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + READ8(addr, mach64->overlay_y_x_end); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + READ8(addr, mach64->overlay_video_key_clr); + break; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + READ8(addr, mach64->overlay_video_key_msk); + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + READ8(addr, mach64->overlay_graphics_key_clr); + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + READ8(addr, mach64->overlay_graphics_key_msk); + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + READ8(addr, mach64->overlay_key_cntl); + break; - case 0x20: case 0x21: case 0x22: case 0x23: - READ8(addr, mach64->overlay_scale_inc); - break; - case 0x24: case 0x25: case 0x26: case 0x27: - READ8(addr, mach64->overlay_scale_cntl); - break; - case 0x28: case 0x29: case 0x2a: case 0x2b: - READ8(addr, mach64->scaler_height_width); - break; + case 0x20: + case 0x21: + case 0x22: + case 0x23: + READ8(addr, mach64->overlay_scale_inc); + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + READ8(addr, mach64->overlay_scale_cntl); + break; + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + READ8(addr, mach64->scaler_height_width); + break; - case 0x4a: - ret = mach64->scaler_format; - break; + case 0x4a: + ret = mach64->scaler_format; + break; - default: - ret = 0xff; - break; - } + default: + ret = 0xff; + break; } - else switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: + } else + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: READ8(addr, mach64->crtc_h_total_disp); break; - case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: READ8(addr, mach64->crtc_v_total_disp); break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: READ8(addr, mach64->crtc_v_sync_strt_wid); break; - case 0x12: case 0x13: + case 0x12: + case 0x13: READ8(addr - 2, mach64->svga.vc); break; - case 0x14: case 0x15: case 0x16: case 0x17: + case 0x14: + case 0x15: + case 0x16: + case 0x17: READ8(addr, mach64->crtc_off_pitch); break; - case 0x18: + case 0x18: ret = mach64->crtc_int_cntl & ~1; if (mach64->svga.cgastat & 8) - ret |= 1; + ret |= 1; break; - case 0x1c: case 0x1d: case 0x1e: case 0x1f: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: READ8(addr, mach64->crtc_gen_cntl); break; - case 0x40: case 0x41: case 0x42: case 0x43: + case 0x40: + case 0x41: + case 0x42: + case 0x43: READ8(addr, mach64->ovr_clr); break; - case 0x44: case 0x45: case 0x46: case 0x47: + case 0x44: + case 0x45: + case 0x46: + case 0x47: READ8(addr, mach64->ovr_wid_left_right); break; - case 0x48: case 0x49: case 0x4a: case 0x4b: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: READ8(addr, mach64->ovr_wid_top_bottom); break; - case 0x60: case 0x61: case 0x62: case 0x63: + case 0x60: + case 0x61: + case 0x62: + case 0x63: READ8(addr, mach64->cur_clr0); break; - case 0x64: case 0x65: case 0x66: case 0x67: + case 0x64: + case 0x65: + case 0x66: + case 0x67: READ8(addr, mach64->cur_clr1); break; - case 0x68: case 0x69: case 0x6a: case 0x6b: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: READ8(addr, mach64->cur_offset); break; - case 0x6c: case 0x6d: case 0x6e: case 0x6f: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: READ8(addr, mach64->cur_horz_vert_posn); break; - case 0x70: case 0x71: case 0x72: case 0x73: + case 0x70: + case 0x71: + case 0x72: + case 0x73: READ8(addr, mach64->cur_horz_vert_off); break; - case 0x79: + case 0x79: ret = 0x30; break; - case 0x80: case 0x81: case 0x82: case 0x83: + case 0x80: + case 0x81: + case 0x82: + case 0x83: READ8(addr, mach64->scratch_reg0); break; - case 0x84: case 0x85: case 0x86: case 0x87: + case 0x84: + case 0x85: + case 0x86: + case 0x87: READ8(addr, mach64->scratch_reg1); break; - case 0x90: case 0x91: case 0x92: case 0x93: + case 0x90: + case 0x91: + case 0x92: + case 0x93: READ8(addr, mach64->clock_cntl); break; - case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: READ8(addr, mach64->mem_cntl); break; - case 0xc0: case 0xc1: case 0xc2: case 0xc3: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); + ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); else - ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga); + ret = ati68860_ramdac_in(addr & 3, mach64->svga.ramdac, &mach64->svga); break; - case 0xc4: case 0xc5: case 0xc6: + case 0xc4: + case 0xc5: + case 0xc6: READ8(addr, mach64->dac_cntl); break; - case 0xc7: + case 0xc7: READ8(addr, mach64->dac_cntl); if (mach64->type == MACH64_VT2) { - ret &= 0xf9; - if (i2c_gpio_get_scl(mach64->i2c)) - ret |= 0x04; - if (i2c_gpio_get_sda(mach64->i2c)) - ret |= 0x02; + ret &= 0xf9; + if (i2c_gpio_get_scl(mach64->i2c)) + ret |= 0x04; + if (i2c_gpio_get_sda(mach64->i2c)) + ret |= 0x02; } break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: READ8(addr, mach64->gen_test_cntl); break; - case 0xdc: case 0xdd: case 0xde: case 0xdf: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: if (mach64->type == MACH64_GX) - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); else - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); READ8(addr, mach64->config_cntl); break; - case 0xe0: case 0xe1: case 0xe2: case 0xe3: + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: READ8(addr, mach64->config_chip_id); break; - case 0xe4: case 0xe5: case 0xe6: case 0xe7: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: READ8(addr, mach64->config_stat0); break; - case 0x100: case 0x101: case 0x102: case 0x103: + case 0x100: + case 0x101: + case 0x102: + case 0x103: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_off_pitch); break; - case 0x104: case 0x105: + case 0x104: + case 0x105: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; - case 0x108: case 0x109: case 0x11c: case 0x11d: + case 0x108: + case 0x109: + case 0x11c: + case 0x11d: mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->dst_y_x); break; - case 0x10c: case 0x10d: case 0x10e: case 0x10f: + case 0x10c: + case 0x10d: + case 0x10e: + case 0x10f: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_y_x); break; - case 0x110: case 0x111: + case 0x110: + case 0x111: addr += 2; - /*FALLTHROUGH*/ - case 0x114: case 0x115: - case 0x118: case 0x119: case 0x11a: case 0x11b: - case 0x11e: case 0x11f: + /*FALLTHROUGH*/ + case 0x114: + case 0x115: + case 0x118: + case 0x119: + case 0x11a: + case 0x11b: + case 0x11e: + case 0x11f: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_height_width); break; - case 0x120: case 0x121: case 0x122: case 0x123: + case 0x120: + case 0x121: + case 0x122: + case 0x123: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_lnth); break; - case 0x124: case 0x125: case 0x126: case 0x127: + case 0x124: + case 0x125: + case 0x126: + case 0x127: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_err); break; - case 0x128: case 0x129: case 0x12a: case 0x12b: + case 0x128: + case 0x129: + case 0x12a: + case 0x12b: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_inc); break; - case 0x12c: case 0x12d: case 0x12e: case 0x12f: + case 0x12c: + case 0x12d: + case 0x12e: + case 0x12f: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_bres_dec); break; - case 0x130: case 0x131: case 0x132: case 0x133: + case 0x130: + case 0x131: + case 0x132: + case 0x133: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; - case 0x180: case 0x181: case 0x182: case 0x183: + case 0x180: + case 0x181: + case 0x182: + case 0x183: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_off_pitch); break; - case 0x184: case 0x185: + case 0x184: + case 0x185: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; - case 0x188: case 0x189: + case 0x188: + case 0x189: mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x); break; - case 0x18c: case 0x18d: case 0x18e: case 0x18f: + case 0x18c: + case 0x18d: + case 0x18e: + case 0x18f: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x); break; - case 0x190: case 0x191: + case 0x190: + case 0x191: mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height1_width1); break; - case 0x194: case 0x195: + case 0x194: + case 0x195: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; - case 0x198: case 0x199: case 0x19a: case 0x19b: + case 0x198: + case 0x199: + case 0x19a: + case 0x19b: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height1_width1); break; - case 0x19c: case 0x19d: + case 0x19c: + case 0x19d: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; - case 0x1a0: case 0x1a1: + case 0x1a0: + case 0x1a1: mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_y_x_start); break; - case 0x1a4: case 0x1a5: case 0x1a6: case 0x1a7: + case 0x1a4: + case 0x1a5: + case 0x1a6: + case 0x1a7: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_y_x_start); break; - case 0x1a8: case 0x1a9: + case 0x1a8: + case 0x1a9: mach64_wait_fifo_idle(mach64); READ8(addr + 2, mach64->src_height2_width2); break; - case 0x1ac: case 0x1ad: + case 0x1ac: + case 0x1ad: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; - case 0x1b0: case 0x1b1: case 0x1b2: case 0x1b3: + case 0x1b0: + case 0x1b1: + case 0x1b2: + case 0x1b3: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_height2_width2); break; - case 0x1b4: case 0x1b5: case 0x1b6: case 0x1b7: + case 0x1b4: + case 0x1b5: + case 0x1b6: + case 0x1b7: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->src_cntl); break; - case 0x240: case 0x241: case 0x242: case 0x243: + case 0x240: + case 0x241: + case 0x242: + case 0x243: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->host_cntl); break; - case 0x280: case 0x281: case 0x282: case 0x283: + case 0x280: + case 0x281: + case 0x282: + case 0x283: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg0); break; - case 0x284: case 0x285: case 0x286: case 0x287: + case 0x284: + case 0x285: + case 0x286: + case 0x287: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg1); break; - case 0x288: case 0x289: case 0x28a: case 0x28b: + case 0x288: + case 0x289: + case 0x28a: + case 0x28b: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_cntl); break; - case 0x2a0: case 0x2a1: case 0x2a8: case 0x2a9: + case 0x2a0: + case 0x2a1: + case 0x2a8: + case 0x2a9: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; - case 0x2a4: case 0x2a5: + case 0x2a4: + case 0x2a5: addr += 2; - /*FALLTHROUGH*/ - case 0x2aa: case 0x2ab: + /*FALLTHROUGH*/ + case 0x2aa: + case 0x2ab: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_left_right); break; - case 0x2ac: case 0x2ad: case 0x2b4: case 0x2b5: + case 0x2ac: + case 0x2ad: + case 0x2b4: + case 0x2b5: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; - case 0x2b0: case 0x2b1: + case 0x2b0: + case 0x2b1: addr += 2; - /*FALLTHROUGH*/ - case 0x2b6: case 0x2b7: + /*FALLTHROUGH*/ + case 0x2b6: + case 0x2b7: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->sc_top_bottom); break; - case 0x2c0: case 0x2c1: case 0x2c2: case 0x2c3: + case 0x2c0: + case 0x2c1: + case 0x2c2: + case 0x2c3: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_bkgd_clr); break; - case 0x2c4: case 0x2c5: case 0x2c6: case 0x2c7: + case 0x2c4: + case 0x2c5: + case 0x2c6: + case 0x2c7: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_frgd_clr); break; - case 0x2c8: case 0x2c9: case 0x2ca: case 0x2cb: + case 0x2c8: + case 0x2c9: + case 0x2ca: + case 0x2cb: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->write_mask); break; - case 0x2cc: case 0x2cd: case 0x2ce: case 0x2cf: + case 0x2cc: + case 0x2cd: + case 0x2ce: + case 0x2cf: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->chain_mask); break; - case 0x2d0: case 0x2d1: case 0x2d2: case 0x2d3: + case 0x2d0: + case 0x2d1: + case 0x2d2: + case 0x2d3: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_pix_width); break; - case 0x2d4: case 0x2d5: case 0x2d6: case 0x2d7: + case 0x2d4: + case 0x2d5: + case 0x2d6: + case 0x2d7: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_mix); break; - case 0x2d8: case 0x2d9: case 0x2da: case 0x2db: + case 0x2d8: + case 0x2d9: + case 0x2da: + case 0x2db: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dp_src); break; - case 0x300: case 0x301: case 0x302: case 0x303: + case 0x300: + case 0x301: + case 0x302: + case 0x303: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_clr); break; - case 0x304: case 0x305: case 0x306: case 0x307: + case 0x304: + case 0x305: + case 0x306: + case 0x307: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_mask); break; - case 0x308: case 0x309: case 0x30a: case 0x30b: + case 0x308: + case 0x309: + case 0x30a: + case 0x30b: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->clr_cmp_cntl); break; - case 0x310: - case 0x311: + case 0x310: + case 0x311: if (!FIFO_EMPTY) - wake_fifo_thread(mach64); + wake_fifo_thread(mach64); ret = 0; if (FIFO_FULL) - ret = 0xff; + ret = 0xff; break; - case 0x320: case 0x321: case 0x322: case 0x323: + case 0x320: + case 0x321: + case 0x322: + case 0x323: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->context_mask); break; - case 0x330: case 0x331: + case 0x330: + case 0x331: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->dst_cntl); break; - case 0x332: + case 0x332: mach64_wait_fifo_idle(mach64); READ8(addr - 2, mach64->src_cntl); break; - case 0x333: + case 0x333: mach64_wait_fifo_idle(mach64); READ8(addr - 3, mach64->pat_cntl); break; - case 0x338: + case 0x338: ret = FIFO_EMPTY ? 0 : 1; break; - default: + default: ret = 0; break; } - if ((addr & 0x3fc) != 0x018) mach64_log("mach64_ext_readb : addr %08X ret %02X\n", addr, ret); - return ret; + if ((addr & 0x3fc) != 0x018) + mach64_log("mach64_ext_readb : addr %08X ret %02X\n", addr, ret); + return ret; } -uint16_t mach64_ext_readw(uint32_t addr, void *p) +uint16_t +mach64_ext_readw(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint16_t ret; - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_readw: addr=%04x\n", addr); - ret = 0xffff; - } - else switch (addr & 0x3ff) - { - case 0xb4: case 0xb6: + mach64_t *mach64 = (mach64_t *) p; + uint16_t ret; + if (!(addr & 0x400)) { + mach64_log("nmach64_ext_readw: addr=%04x\n", addr); + ret = 0xffff; + } else + switch (addr & 0x3ff) { + case 0xb4: + case 0xb6: ret = (mach64->bank_w[(addr & 2) >> 1] >> 15); break; - case 0xb8: case 0xba: + case 0xb8: + case 0xba: ret = (mach64->bank_r[(addr & 2) >> 1] >> 15); break; - default: + default: ret = mach64_ext_readb(addr, p); ret |= mach64_ext_readb(addr + 1, p) << 8; break; } - if ((addr & 0x3fc) != 0x018) mach64_log("mach64_ext_readw : addr %08X ret %04X\n", addr, ret); - return ret; + if ((addr & 0x3fc) != 0x018) + mach64_log("mach64_ext_readw : addr %08X ret %04X\n", addr, ret); + return ret; } -uint32_t mach64_ext_readl(uint32_t addr, void *p) +uint32_t +mach64_ext_readl(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint32_t ret; - if (!(addr & 0x400)) - { - mach64_log("nmach64_ext_readl: addr=%04x\n", addr); - ret = 0xffffffff; - } - else switch (addr & 0x3ff) - { - case 0x18: + mach64_t *mach64 = (mach64_t *) p; + uint32_t ret; + if (!(addr & 0x400)) { + mach64_log("nmach64_ext_readl: addr=%04x\n", addr); + ret = 0xffffffff; + } else + switch (addr & 0x3ff) { + case 0x18: ret = mach64->crtc_int_cntl & ~1; if (mach64->svga.cgastat & 8) - ret |= 1; + ret |= 1; break; - case 0xb4: + case 0xb4: ret = (mach64->bank_w[0] >> 15) | ((mach64->bank_w[1] >> 15) << 16); break; - case 0xb8: + case 0xb8: ret = (mach64->bank_r[0] >> 15) | ((mach64->bank_r[1] >> 15) << 16); break; - default: + default: ret = mach64_ext_readw(addr, p); ret |= mach64_ext_readw(addr + 2, p) << 16; break; } - if ((addr & 0x3fc) != 0x018) mach64_log("mach64_ext_readl : addr %08X ret %08X\n", addr, ret); - return ret; + if ((addr & 0x3fc) != 0x018) + mach64_log("mach64_ext_readl : addr %08X ret %08X\n", addr, ret); + return ret; } -void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) +void +mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *) p; + svga_t *svga = &mach64->svga; - mach64_log("mach64_ext_writeb : addr %08X val %02X\n", addr, val); + mach64_log("mach64_ext_writeb : addr %08X val %02X\n", addr, val); - if (!(addr & 0x400)) - { - switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: - WRITE8(addr, mach64->overlay_y_x_start, val); - break; - case 0x04: case 0x05: case 0x06: case 0x07: - WRITE8(addr, mach64->overlay_y_x_end, val); - break; - case 0x08: case 0x09: case 0x0a: case 0x0b: - WRITE8(addr, mach64->overlay_video_key_clr, val); - break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: - WRITE8(addr, mach64->overlay_video_key_msk, val); - break; - case 0x10: case 0x11: case 0x12: case 0x13: - WRITE8(addr, mach64->overlay_graphics_key_clr, val); - break; - case 0x14: case 0x15: case 0x16: case 0x17: - WRITE8(addr, mach64->overlay_graphics_key_msk, val); - break; - case 0x18: case 0x19: case 0x1a: case 0x1b: - WRITE8(addr, mach64->overlay_key_cntl, val); - break; + if (!(addr & 0x400)) { + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + WRITE8(addr, mach64->overlay_y_x_start, val); + break; + case 0x04: + case 0x05: + case 0x06: + case 0x07: + WRITE8(addr, mach64->overlay_y_x_end, val); + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + WRITE8(addr, mach64->overlay_video_key_clr, val); + break; + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + WRITE8(addr, mach64->overlay_video_key_msk, val); + break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: + WRITE8(addr, mach64->overlay_graphics_key_clr, val); + break; + case 0x14: + case 0x15: + case 0x16: + case 0x17: + WRITE8(addr, mach64->overlay_graphics_key_msk, val); + break; + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + WRITE8(addr, mach64->overlay_key_cntl, val); + break; - case 0x20: case 0x21: case 0x22: case 0x23: - WRITE8(addr, mach64->overlay_scale_inc, val); - break; - case 0x24: case 0x25: case 0x26: case 0x27: - WRITE8(addr, mach64->overlay_scale_cntl, val); - break; - case 0x28: case 0x29: case 0x2a: case 0x2b: - WRITE8(addr, mach64->scaler_height_width, val); - break; + case 0x20: + case 0x21: + case 0x22: + case 0x23: + WRITE8(addr, mach64->overlay_scale_inc, val); + break; + case 0x24: + case 0x25: + case 0x26: + case 0x27: + WRITE8(addr, mach64->overlay_scale_cntl, val); + break; + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + WRITE8(addr, mach64->scaler_height_width, val); + break; - case 0x4a: - mach64->scaler_format = val & 0xf; - break; + case 0x4a: + mach64->scaler_format = val & 0xf; + break; - case 0x80: case 0x81: case 0x82: case 0x83: - WRITE8(addr, mach64->buf_offset[0], val); - break; + case 0x80: + case 0x81: + case 0x82: + case 0x83: + WRITE8(addr, mach64->buf_offset[0], val); + break; - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - WRITE8(addr, mach64->buf_pitch[0], val); - break; + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + WRITE8(addr, mach64->buf_pitch[0], val); + break; - case 0x98: case 0x99: case 0x9a: case 0x9b: - WRITE8(addr, mach64->buf_offset[1], val); - break; + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + WRITE8(addr, mach64->buf_offset[1], val); + break; - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - WRITE8(addr, mach64->buf_pitch[1], val); - break; - } - - mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + WRITE8(addr, mach64->buf_pitch[1], val); + break; } - else if (addr & 0x300) - { - mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); - } - else switch (addr & 0x3ff) - { - case 0x00: case 0x01: case 0x02: case 0x03: + + mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); + } else if (addr & 0x300) { + mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); + } else + switch (addr & 0x3ff) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: WRITE8(addr, mach64->crtc_h_total_disp, val); svga_recalctimings(&mach64->svga); break; - case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: WRITE8(addr, mach64->crtc_v_total_disp, val); svga_recalctimings(&mach64->svga); break; - case 0x0c: case 0x0d: case 0x0e: case 0x0f: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: WRITE8(addr, mach64->crtc_v_sync_strt_wid, val); svga_recalctimings(&mach64->svga); break; - case 0x14: case 0x15: case 0x16: case 0x17: + case 0x14: + case 0x15: + case 0x16: + case 0x17: WRITE8(addr, mach64->crtc_off_pitch, val); svga_recalctimings(&mach64->svga); svga->fullchange = changeframecount; break; - case 0x18: + case 0x18: mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); if (val & 4) - mach64->crtc_int_cntl &= ~4; + mach64->crtc_int_cntl &= ~4; mach64_update_irqs(mach64); break; - case 0x1c: case 0x1d: case 0x1e: case 0x1f: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: WRITE8(addr, mach64->crtc_gen_cntl, val); if (((mach64->crtc_gen_cntl >> 24) & 3) == 3) - svga->fb_only = 1; + svga->fb_only = 1; else - svga->fb_only = 0; + svga->fb_only = 0; svga->dpms = !!(mach64->crtc_gen_cntl & 0x0c); svga_recalctimings(&mach64->svga); break; - case 0x40: case 0x41: case 0x42: case 0x43: + case 0x40: + case 0x41: + case 0x42: + case 0x43: WRITE8(addr, mach64->ovr_clr, val); break; - case 0x44: case 0x45: case 0x46: case 0x47: + case 0x44: + case 0x45: + case 0x46: + case 0x47: WRITE8(addr, mach64->ovr_wid_left_right, val); break; - case 0x48: case 0x49: case 0x4a: case 0x4b: + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: WRITE8(addr, mach64->ovr_wid_top_bottom, val); break; - case 0x60: case 0x61: case 0x62: case 0x63: + case 0x60: + case 0x61: + case 0x62: + case 0x63: WRITE8(addr, mach64->cur_clr0, val); if (mach64->type == MACH64_VT2) - ati68860_ramdac_set_pallook(mach64->svga.ramdac, 0, makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff)); + ati68860_ramdac_set_pallook(mach64->svga.ramdac, 0, makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff)); break; - case 0x64: case 0x65: case 0x66: case 0x67: + case 0x64: + case 0x65: + case 0x66: + case 0x67: WRITE8(addr, mach64->cur_clr1, val); if (mach64->type == MACH64_VT2) - ati68860_ramdac_set_pallook(mach64->svga.ramdac, 1, makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff)); + ati68860_ramdac_set_pallook(mach64->svga.ramdac, 1, makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff)); break; - case 0x68: case 0x69: case 0x6a: case 0x6b: + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: WRITE8(addr, mach64->cur_offset, val); svga->dac_hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8; break; - case 0x6c: case 0x6d: case 0x6e: case 0x6f: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: WRITE8(addr, mach64->cur_horz_vert_posn, val); svga->dac_hwcursor.x = mach64->cur_horz_vert_posn & 0x7ff; svga->dac_hwcursor.y = (mach64->cur_horz_vert_posn >> 16) & 0x7ff; break; - case 0x70: case 0x71: case 0x72: case 0x73: + case 0x70: + case 0x71: + case 0x72: + case 0x73: WRITE8(addr, mach64->cur_horz_vert_off, val); svga->dac_hwcursor.xoff = mach64->cur_horz_vert_off & 0x3f; svga->dac_hwcursor.yoff = (mach64->cur_horz_vert_off >> 16) & 0x3f; break; - case 0x80: case 0x81: case 0x82: case 0x83: + case 0x80: + case 0x81: + case 0x82: + case 0x83: WRITE8(addr, mach64->scratch_reg0, val); break; - case 0x84: case 0x85: case 0x86: case 0x87: + case 0x84: + case 0x85: + case 0x86: + case 0x87: WRITE8(addr, mach64->scratch_reg1, val); break; - case 0x90: case 0x91: case 0x92: case 0x93: + case 0x90: + case 0x91: + case 0x92: + case 0x93: WRITE8(addr, mach64->clock_cntl, val); if (mach64->type == MACH64_GX) - ics2595_write(svga->clock_gen, val & 0x40, val & 0xf); - else - { - pll_write(mach64, addr, val); - ics2595_setclock(svga->clock_gen, mach64->pll_freq[mach64->clock_cntl & 3]); + ics2595_write(svga->clock_gen, val & 0x40, val & 0xf); + else { + pll_write(mach64, addr, val); + ics2595_setclock(svga->clock_gen, mach64->pll_freq[mach64->clock_cntl & 3]); } svga_recalctimings(&mach64->svga); break; - case 0xb0: case 0xb1: case 0xb2: case 0xb3: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: WRITE8(addr, mach64->mem_cntl, val); break; - case 0xb4: + case 0xb4: mach64->bank_w[0] = val * 32768; mach64_log("mach64 : write bank A0000-A7FFF set to %08X\n", mach64->bank_w[0]); break; - case 0xb5: case 0xb6: + case 0xb5: + case 0xb6: mach64->bank_w[1] = val * 32768; mach64_log("mach64 : write bank A8000-AFFFF set to %08X\n", mach64->bank_w[1]); break; - case 0xb8: + case 0xb8: mach64->bank_r[0] = val * 32768; mach64_log("mach64 : read bank A0000-A7FFF set to %08X\n", mach64->bank_r[0]); break; - case 0xb9: case 0xba: + case 0xb9: + case 0xba: mach64->bank_r[1] = val * 32768; mach64_log("mach64 : read bank A8000-AFFFF set to %08X\n", mach64->bank_r[1]); break; - case 0xc0: case 0xc1: case 0xc2: case 0xc3: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: if (mach64->type == MACH64_GX) - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); else - ati68860_ramdac_out(addr & 3, val, mach64->svga.ramdac, &mach64->svga); + ati68860_ramdac_out(addr & 3, val, mach64->svga.ramdac, &mach64->svga); break; - case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: WRITE8(addr, mach64->dac_cntl, val); svga_set_ramdac_type(svga, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); ati68860_set_ramdac_type(mach64->svga.ramdac, (mach64->dac_cntl & 0x100) ? RAMDAC_8BIT : RAMDAC_6BIT); i2c_gpio_set(mach64->i2c, !(mach64->dac_cntl & 0x20000000) || (mach64->dac_cntl & 0x04000000), !(mach64->dac_cntl & 0x10000000) || (mach64->dac_cntl & 0x02000000)); break; - case 0xd0: case 0xd1: case 0xd2: case 0xd3: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: WRITE8(addr, mach64->gen_test_cntl, val); ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1); - mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); + mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); svga->dac_hwcursor.ena = mach64->gen_test_cntl & 0x80; break; - case 0xdc: case 0xdd: case 0xde: case 0xdf: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: WRITE8(addr, mach64->config_cntl, val); mach64_updatemapping(mach64); break; - case 0xe4: case 0xe5: case 0xe6: case 0xe7: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: if (mach64->type != MACH64_GX) - WRITE8(addr, mach64->config_stat0, val); + WRITE8(addr, mach64->config_stat0, val); break; } } -void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) +void +mach64_ext_writew(uint32_t addr, uint16_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - mach64_log("mach64_ext_writew : addr %08X val %04X\n", addr, val); - if (!(addr & 0x400)) - { - mach64_log("mach64_ext_writew: addr=%04x val=%04x\n", addr, val); + mach64_t *mach64 = (mach64_t *) p; + mach64_log("mach64_ext_writew : addr %08X val %04X\n", addr, val); + if (!(addr & 0x400)) { + mach64_log("mach64_ext_writew: addr=%04x val=%04x\n", addr, val); - mach64_ext_writeb(addr, val, p); - mach64_ext_writeb(addr + 1, val >> 8, p); - } - else if (addr & 0x300) - { - mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); - } - else switch (addr & 0x3fe) - { - default: + mach64_ext_writeb(addr, val, p); + mach64_ext_writeb(addr + 1, val >> 8, p); + } else if (addr & 0x300) { + mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); + } else + switch (addr & 0x3fe) { + default: mach64_ext_writeb(addr, val, p); mach64_ext_writeb(addr + 1, val >> 8, p); break; } } -void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) +void +mach64_ext_writel(uint32_t addr, uint32_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - if ((addr & 0x3c0) != 0x200) - mach64_log("mach64_ext_writel : addr %08X val %08X\n", addr, val); - if (!(addr & 0x400)) - { - mach64_log("mach64_ext_writel: addr=%04x val=%08x\n", addr, val); + mach64_t *mach64 = (mach64_t *) p; + if ((addr & 0x3c0) != 0x200) + mach64_log("mach64_ext_writel : addr %08X val %08X\n", addr, val); + if (!(addr & 0x400)) { + mach64_log("mach64_ext_writel: addr=%04x val=%08x\n", addr, val); - mach64_ext_writew(addr, val, p); - mach64_ext_writew(addr + 2, val >> 16, p); - } - else if (addr & 0x300) - { - mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); - } - else switch (addr & 0x3fc) - { - default: + mach64_ext_writew(addr, val, p); + mach64_ext_writew(addr + 2, val >> 16, p); + } else if (addr & 0x300) { + mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); + } else + switch (addr & 0x3fc) { + default: mach64_ext_writew(addr, val, p); mach64_ext_writew(addr + 2, val >> 16, p); break; } } -uint8_t mach64_ext_inb(uint16_t port, void *p) +uint8_t +mach64_ext_inb(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; + mach64_t *mach64 = (mach64_t *) p; + uint8_t ret; - switch (port) - { - case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: - case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: - ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), p); - break; - case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), p); - break; - case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), p); - break; + switch (port) { + case 0x02ec: + case 0x02ed: + case 0x02ee: + case 0x02ef: + case 0x7eec: + case 0x7eed: + case 0x7eee: + case 0x7eef: + ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), p); + break; + case 0x0aec: + case 0x0aed: + case 0x0aee: + case 0x0aef: + ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), p); + break; + case 0x0eec: + case 0x0eed: + case 0x0eee: + case 0x0eef: + ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), p); + break; - case 0x12ec: case 0x12ed: case 0x12ee: case 0x12ef: - ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), p); - break; + case 0x12ec: + case 0x12ed: + case 0x12ee: + case 0x12ef: + ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), p); + break; - case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), p); - break; + case 0x16ec: + case 0x16ed: + case 0x16ee: + case 0x16ef: + ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), p); + break; - case 0x1aec: - ret = mach64_ext_readb(0x400 | 0x18, p); - break; + case 0x1aec: + ret = mach64_ext_readb(0x400 | 0x18, p); + break; - case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), p); - break; + case 0x1eec: + case 0x1eed: + case 0x1eee: + case 0x1eef: + ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), p); + break; - case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), p); - break; - case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), p); - break; - case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), p); - break; - case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: - ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), p); - break; + case 0x22ec: + case 0x22ed: + case 0x22ee: + case 0x22ef: + ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), p); + break; + case 0x26ec: + case 0x26ed: + case 0x26ee: + case 0x26ef: + ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), p); + break; + case 0x2aec: + case 0x2aed: + case 0x2aee: + case 0x2aef: + ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), p); + break; + case 0x2eec: + case 0x2eed: + case 0x2eee: + case 0x2eef: + ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), p); + break; - case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: - ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), p); - break; - case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), p); - break; - case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), p); - break; - case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), p); - break; + case 0x32ec: + case 0x32ed: + case 0x32ee: + case 0x32ef: + ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), p); + break; + case 0x36ec: + case 0x36ed: + case 0x36ee: + case 0x36ef: + ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), p); + break; + case 0x3aec: + case 0x3aed: + case 0x3aee: + case 0x3aef: + ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), p); + break; + case 0x3eec: + case 0x3eed: + case 0x3eee: + case 0x3eef: + ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), p); + break; - case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), p); - break; - case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), p); - break; - case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), p); - break; + case 0x42ec: + case 0x42ed: + case 0x42ee: + case 0x42ef: + ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), p); + break; + case 0x46ec: + case 0x46ed: + case 0x46ee: + case 0x46ef: + ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), p); + break; + case 0x4aec: + case 0x4aed: + case 0x4aee: + case 0x4aef: + ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), p); + break; - case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), p); - break; + case 0x52ec: + case 0x52ed: + case 0x52ee: + case 0x52ef: + ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), p); + break; - case 0x56ec: - ret = mach64_ext_readb(0x400 | 0xb4, p); - break; - case 0x56ed: case 0x56ee: - ret = mach64_ext_readb(0x400 | 0xb5, p); - break; - case 0x5aec: - ret = mach64_ext_readb(0x400 | 0xb8, p); - break; - case 0x5aed: case 0x5aee: - ret = mach64_ext_readb(0x400 | 0xb9, p); - break; + case 0x56ec: + ret = mach64_ext_readb(0x400 | 0xb4, p); + break; + case 0x56ed: + case 0x56ee: + ret = mach64_ext_readb(0x400 | 0xb5, p); + break; + case 0x5aec: + ret = mach64_ext_readb(0x400 | 0xb8, p); + break; + case 0x5aed: + case 0x5aee: + ret = mach64_ext_readb(0x400 | 0xb9, p); + break; - case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - if (mach64->type == MACH64_GX) - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); - else - ret = ati68860_ramdac_in(port & 3, mach64->svga.ramdac, &mach64->svga); - break; + case 0x5eec: + case 0x5eed: + case 0x5eee: + case 0x5eef: + if (mach64->type == MACH64_GX) + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), mach64->svga.ramdac, &mach64->svga); + else + ret = ati68860_ramdac_in(port & 3, mach64->svga.ramdac, &mach64->svga); + break; - case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), p); - break; + case 0x62ec: + case 0x62ed: + case 0x62ee: + case 0x62ef: + ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), p); + break; - case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), p); - break; + case 0x66ec: + case 0x66ed: + case 0x66ee: + case 0x66ef: + ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), p); + break; - case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: - mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); - READ8(port, mach64->config_cntl); - break; + case 0x6aec: + case 0x6aed: + case 0x6aee: + case 0x6aef: + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); + READ8(port, mach64->config_cntl); + break; - case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef: - ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), p); - break; + case 0x6eec: + case 0x6eed: + case 0x6eee: + case 0x6eef: + ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), p); + break; - case 0x72ec: case 0x72ed: case 0x72ee: case 0x72ef: - ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); - break; + case 0x72ec: + case 0x72ed: + case 0x72ee: + case 0x72ef: + ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); + break; - default: - ret = 0; - break; - } - mach64_log("mach64_ext_inb : port %04X ret %02X\n", port, ret); - return ret; + default: + ret = 0; + break; + } + mach64_log("mach64_ext_inb : port %04X ret %02X\n", port, ret); + return ret; } -uint16_t mach64_ext_inw(uint16_t port, void *p) +uint16_t +mach64_ext_inw(uint16_t port, void *p) { - uint16_t ret; - switch (port) - { - default: - ret = mach64_ext_inb(port, p); - ret |= (mach64_ext_inb(port + 1, p) << 8); - break; - } - mach64_log("mach64_ext_inw : port %04X ret %04X\n", port, ret); - return ret; + uint16_t ret; + switch (port) { + default: + ret = mach64_ext_inb(port, p); + ret |= (mach64_ext_inb(port + 1, p) << 8); + break; + } + mach64_log("mach64_ext_inw : port %04X ret %04X\n", port, ret); + return ret; } -uint32_t mach64_ext_inl(uint16_t port, void *p) +uint32_t +mach64_ext_inl(uint16_t port, void *p) { - uint32_t ret; - switch (port) - { - case 0x56ec: - ret = mach64_ext_readl(0x400 | 0xb4, p); - break; - case 0x5aec: - ret = mach64_ext_readl(0x400 | 0xb8, p); - break; + uint32_t ret; + switch (port) { + case 0x56ec: + ret = mach64_ext_readl(0x400 | 0xb4, p); + break; + case 0x5aec: + ret = mach64_ext_readl(0x400 | 0xb8, p); + break; - default: - ret = mach64_ext_inw(port, p); - ret |= (mach64_ext_inw(port + 2, p) << 16); - break; - } - mach64_log("mach64_ext_inl : port %04X ret %08X\n", port, ret); - return ret; + default: + ret = mach64_ext_inw(port, p); + ret |= (mach64_ext_inw(port + 2, p) << 16); + break; + } + mach64_log("mach64_ext_inl : port %04X ret %08X\n", port, ret); + return ret; } -void mach64_ext_outb(uint16_t port, uint8_t val, void *p) +void +mach64_ext_outb(uint16_t port, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - mach64_log("mach64_ext_outb : port %04X val %02X\n", port, val); - switch (port) - { - case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: - case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: - mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, p); - break; - case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, p); - break; - case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, p); - break; + mach64_log("mach64_ext_outb : port %04X val %02X\n", port, val); + switch (port) { + case 0x02ec: + case 0x02ed: + case 0x02ee: + case 0x02ef: + case 0x7eec: + case 0x7eed: + case 0x7eee: + case 0x7eef: + mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, p); + break; + case 0x0aec: + case 0x0aed: + case 0x0aee: + case 0x0aef: + mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, p); + break; + case 0x0eec: + case 0x0eed: + case 0x0eee: + case 0x0eef: + mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, p); + break; - case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, p); - break; + case 0x16ec: + case 0x16ed: + case 0x16ee: + case 0x16ef: + mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, p); + break; - case 0x1aec: - mach64_ext_writeb(0x400 | 0x18, val, p); - break; + case 0x1aec: + mach64_ext_writeb(0x400 | 0x18, val, p); + break; - case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, p); - break; + case 0x1eec: + case 0x1eed: + case 0x1eee: + case 0x1eef: + mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, p); + break; - case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, p); - break; - case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, p); - break; - case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, p); - break; - case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: - mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, p); - break; + case 0x22ec: + case 0x22ed: + case 0x22ee: + case 0x22ef: + mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, p); + break; + case 0x26ec: + case 0x26ed: + case 0x26ee: + case 0x26ef: + mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, p); + break; + case 0x2aec: + case 0x2aed: + case 0x2aee: + case 0x2aef: + mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, p); + break; + case 0x2eec: + case 0x2eed: + case 0x2eee: + case 0x2eef: + mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, p); + break; - case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: - mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, p); - break; - case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, p); - break; - case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, p); - break; - case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, p); - break; + case 0x32ec: + case 0x32ed: + case 0x32ee: + case 0x32ef: + mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, p); + break; + case 0x36ec: + case 0x36ed: + case 0x36ee: + case 0x36ef: + mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, p); + break; + case 0x3aec: + case 0x3aed: + case 0x3aee: + case 0x3aef: + mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, p); + break; + case 0x3eec: + case 0x3eed: + case 0x3eee: + case 0x3eef: + mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, p); + break; - case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, p); - break; - case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, p); - break; - case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, p); - break; + case 0x42ec: + case 0x42ed: + case 0x42ee: + case 0x42ef: + mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, p); + break; + case 0x46ec: + case 0x46ed: + case 0x46ee: + case 0x46ef: + mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, p); + break; + case 0x4aec: + case 0x4aed: + case 0x4aee: + case 0x4aef: + mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, p); + break; - case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, p); - break; + case 0x52ec: + case 0x52ed: + case 0x52ee: + case 0x52ef: + mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, p); + break; - case 0x56ec: - mach64_ext_writeb(0x400 | 0xb4, val, p); - break; - case 0x56ed: case 0x56ee: - mach64_ext_writeb(0x400 | 0xb5, val, p); - break; - case 0x5aec: - mach64_ext_writeb(0x400 | 0xb8, val, p); - break; - case 0x5aed: case 0x5aee: - mach64_ext_writeb(0x400 | 0xb9, val, p); - break; + case 0x56ec: + mach64_ext_writeb(0x400 | 0xb4, val, p); + break; + case 0x56ed: + case 0x56ee: + mach64_ext_writeb(0x400 | 0xb5, val, p); + break; + case 0x5aec: + mach64_ext_writeb(0x400 | 0xb8, val, p); + break; + case 0x5aed: + case 0x5aee: + mach64_ext_writeb(0x400 | 0xb9, val, p); + break; - case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - if (mach64->type == MACH64_GX) - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); - else - ati68860_ramdac_out(port & 3, val, mach64->svga.ramdac, &mach64->svga); - break; + case 0x5eec: + case 0x5eed: + case 0x5eee: + case 0x5eef: + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, mach64->svga.ramdac, &mach64->svga); + else + ati68860_ramdac_out(port & 3, val, mach64->svga.ramdac, &mach64->svga); + break; - case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, p); - break; + case 0x62ec: + case 0x62ed: + case 0x62ee: + case 0x62ef: + mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, p); + break; - case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, p); - break; + case 0x66ec: + case 0x66ed: + case 0x66ee: + case 0x66ef: + mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, p); + break; - case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: - WRITE8(port, mach64->config_cntl, val); - mach64_updatemapping(mach64); - break; - } + case 0x6aec: + case 0x6aed: + case 0x6aee: + case 0x6aef: + WRITE8(port, mach64->config_cntl, val); + mach64_updatemapping(mach64); + break; + } } -void mach64_ext_outw(uint16_t port, uint16_t val, void *p) +void +mach64_ext_outw(uint16_t port, uint16_t val, void *p) { - mach64_log("mach64_ext_outw : port %04X val %04X\n", port, val); - switch (port) - { - default: - mach64_ext_outb(port, val, p); - mach64_ext_outb(port + 1, val >> 8, p); - break; - } + mach64_log("mach64_ext_outw : port %04X val %04X\n", port, val); + switch (port) { + default: + mach64_ext_outb(port, val, p); + mach64_ext_outb(port + 1, val >> 8, p); + break; + } } -void mach64_ext_outl(uint16_t port, uint32_t val, void *p) +void +mach64_ext_outl(uint16_t port, uint32_t val, void *p) { - mach64_log("mach64_ext_outl : port %04X val %08X\n", port, val); - switch (port) - { - default: - mach64_ext_outw(port, val, p); - mach64_ext_outw(port + 2, val >> 16, p); - break; - } + mach64_log("mach64_ext_outl : port %04X val %08X\n", port, val); + switch (port) { + default: + mach64_ext_outw(port, val, p); + mach64_ext_outw(port + 2, val >> 16, p); + break; + } } -static uint8_t mach64_block_inb(uint16_t port, void *p) +static uint8_t +mach64_block_inb(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint8_t ret; + mach64_t *mach64 = (mach64_t *) p; + uint8_t ret; - ret = mach64_ext_readb(0x400 | (port & 0x3ff), mach64); - mach64_log("mach64_block_inb : port %04X ret %02X\n", port, ret); - return ret; + ret = mach64_ext_readb(0x400 | (port & 0x3ff), mach64); + mach64_log("mach64_block_inb : port %04X ret %02X\n", port, ret); + return ret; } -static uint16_t mach64_block_inw(uint16_t port, void *p) +static uint16_t +mach64_block_inw(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint16_t ret; + mach64_t *mach64 = (mach64_t *) p; + uint16_t ret; - ret = mach64_ext_readw(0x400 | (port & 0x3ff), mach64); - mach64_log("mach64_block_inw : port %04X ret %04X\n", port, ret); - return ret; + ret = mach64_ext_readw(0x400 | (port & 0x3ff), mach64); + mach64_log("mach64_block_inw : port %04X ret %04X\n", port, ret); + return ret; } -static uint32_t mach64_block_inl(uint16_t port, void *p) +static uint32_t +mach64_block_inl(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; - uint32_t ret; + mach64_t *mach64 = (mach64_t *) p; + uint32_t ret; - ret = mach64_ext_readl(0x400 | (port & 0x3ff), mach64); - mach64_log("mach64_block_inl : port %04X ret %08X\n", port, ret); - return ret; + ret = mach64_ext_readl(0x400 | (port & 0x3ff), mach64); + mach64_log("mach64_block_inl : port %04X ret %08X\n", port, ret); + return ret; } -static void mach64_block_outb(uint16_t port, uint8_t val, void *p) +static void +mach64_block_outb(uint16_t port, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - mach64_log("mach64_block_outb : port %04X val %02X\n ", port, val); - mach64_ext_writeb(0x400 | (port & 0x3ff), val, mach64); + mach64_log("mach64_block_outb : port %04X val %02X\n ", port, val); + mach64_ext_writeb(0x400 | (port & 0x3ff), val, mach64); } -static void mach64_block_outw(uint16_t port, uint16_t val, void *p) +static void +mach64_block_outw(uint16_t port, uint16_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - mach64_log("mach64_block_outw : port %04X val %04X\n ", port, val); - mach64_ext_writew(0x400 | (port & 0x3ff), val, mach64); + mach64_log("mach64_block_outw : port %04X val %04X\n ", port, val); + mach64_ext_writew(0x400 | (port & 0x3ff), val, mach64); } -static void mach64_block_outl(uint16_t port, uint32_t val, void *p) +static void +mach64_block_outl(uint16_t port, uint32_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - mach64_log("mach64_block_outl : port %04X val %08X\n ", port, val); - mach64_ext_writel(0x400 | (port & 0x3ff), val, mach64); + mach64_log("mach64_block_outl : port %04X val %08X\n ", port, val); + mach64_ext_writel(0x400 | (port & 0x3ff), val, mach64); } -void mach64_write(uint32_t addr, uint8_t val, void *p) +void +mach64_write(uint32_t addr, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_write_linear(addr, val, svga); + mach64_t *mach64 = (mach64_t *) p; + svga_t *svga = &mach64->svga; + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + svga_write_linear(addr, val, svga); } -void mach64_writew(uint32_t addr, uint16_t val, void *p) +void +mach64_writew(uint32_t addr, uint16_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *) p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_writew_linear(addr, val, svga); + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + svga_writew_linear(addr, val, svga); } -void mach64_writel(uint32_t addr, uint32_t val, void *p) +void +mach64_writel(uint32_t addr, uint32_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *) p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; - svga_writel_linear(addr, val, svga); + addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; + svga_writel_linear(addr, val, svga); } -uint8_t mach64_read(uint32_t addr, void *p) +uint8_t +mach64_read(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - uint8_t ret; - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - ret = svga_read_linear(addr, svga); - return ret; + mach64_t *mach64 = (mach64_t *) p; + svga_t *svga = &mach64->svga; + uint8_t ret; + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + ret = svga_read_linear(addr, svga); + return ret; } -uint16_t mach64_readw(uint32_t addr, void *p) +uint16_t +mach64_readw(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *) p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readw_linear(addr, svga); + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + return svga_readw_linear(addr, svga); } -uint32_t mach64_readl(uint32_t addr, void *p) +uint32_t +mach64_readl(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; + mach64_t *mach64 = (mach64_t *) p; + svga_t *svga = &mach64->svga; - addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; - return svga_readl_linear(addr, svga); + addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; + return svga_readl_linear(addr, svga); } +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) +#define DECODE_ARGB1555() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { \ + uint16_t dat = ((uint16_t *) src)[x]; \ + \ + int b = dat & 0x1f; \ + int g = (dat >> 5) & 0x1f; \ + int r = (dat >> 10) & 0x1f; \ + \ + b = (b << 3) | (b >> 2); \ + g = (g << 3) | (g >> 2); \ + r = (r << 3) | (r >> 2); \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) -#define DECODE_ARGB1555() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) \ - { \ - uint16_t dat = ((uint16_t *)src)[x]; \ +#define DECODE_RGB565() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { \ + uint16_t dat = ((uint16_t *) src)[x]; \ + \ + int b = dat & 0x1f; \ + int g = (dat >> 5) & 0x3f; \ + int r = (dat >> 11) & 0x1f; \ + \ + b = (b << 3) | (b >> 2); \ + g = (g << 2) | (g >> 4); \ + r = (r << 3) | (r >> 2); \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +#define DECODE_ARGB8888() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { \ + int b = src[0]; \ + int g = src[1]; \ + int r = src[2]; \ + src += 4; \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +#define DECODE_VYUY422() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x += 2) { \ + uint8_t y1, y2; \ + int8_t u, v; \ + int dR, dG, dB; \ + int r, g, b; \ \ - int b = dat & 0x1f; \ - int g = (dat >> 5) & 0x1f; \ - int r = (dat >> 10) & 0x1f; \ + y1 = src[0]; \ + u = src[1] - 0x80; \ + y2 = src[2]; \ + v = src[3] - 0x80; \ + src += 4; \ \ - b = (b << 3) | (b >> 2); \ - g = (g << 3) | (g >> 2); \ - r = (r << 3) | (r >> 2); \ + dR = (359 * v) >> 8; \ + dG = (88 * u + 183 * v) >> 8; \ + dB = (453 * u) >> 8; \ \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x + 1] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) -#define DECODE_RGB565() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) \ - { \ - uint16_t dat = ((uint16_t *)src)[x]; \ +#define DECODE_YVYU422() \ + do { \ + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x += 2) { \ + uint8_t y1, y2; \ + int8_t u, v; \ + int dR, dG, dB; \ + int r, g, b; \ \ - int b = dat & 0x1f; \ - int g = (dat >> 5) & 0x3f; \ - int r = (dat >> 11) & 0x1f; \ + u = src[0] - 0x80; \ + y1 = src[1]; \ + v = src[2] - 0x80; \ + y2 = src[3]; \ + src += 4; \ \ - b = (b << 3) | (b >> 2); \ - g = (g << 2) | (g >> 4); \ - r = (r << 3) | (r >> 2); \ + dR = (359 * v) >> 8; \ + dG = (88 * u + 183 * v) >> 8; \ + dB = (453 * u) >> 8; \ \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x + 1] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) -#define DECODE_ARGB8888() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) \ - { \ - int b = src[0]; \ - int g = src[1]; \ - int r = src[2]; \ - src += 4; \ - \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -#define DECODE_VYUY422() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x += 2) \ - { \ - uint8_t y1, y2; \ - int8_t u, v; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - y1 = src[0]; \ - u = src[1] - 0x80; \ - y2 = src[2]; \ - v = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*v) >> 8; \ - dG = (88*u + 183*v) >> 8; \ - dB = (453*u) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -#define DECODE_YVYU422() \ - do \ - { \ - for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x += 2) \ - { \ - uint8_t y1, y2; \ - int8_t u, v; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - u = src[0] - 0x80; \ - y1 = src[1]; \ - v = src[2] - 0x80; \ - y2 = src[3]; \ - src += 4; \ - \ - dR = (359*v) >> 8; \ - dG = (88*u + 183*v) >> 8; \ - dB = (453*u) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ - } \ - } while (0) - -void mach64_overlay_draw(svga_t *svga, int displine) +void +mach64_overlay_draw(svga_t *svga, int displine) { - mach64_t *mach64 = (mach64_t *)svga->p; - int x; - int h_acc = 0; - int h_max = (mach64->scaler_height_width >> 16) & 0x3ff; - int h_inc = mach64->overlay_scale_inc >> 16; - int v_max = mach64->scaler_height_width & 0x3ff; - int v_inc = mach64->overlay_scale_inc & 0xffff; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay.addr]; - int old_y = mach64->overlay_v_acc; - int y_diff; - int video_key_fn = mach64->overlay_key_cntl & 5; - int graphics_key_fn = (mach64->overlay_key_cntl >> 4) & 5; - int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; + mach64_t *mach64 = (mach64_t *) svga->p; + int x; + int h_acc = 0; + int h_max = (mach64->scaler_height_width >> 16) & 0x3ff; + int h_inc = mach64->overlay_scale_inc >> 16; + int v_max = mach64->scaler_height_width & 0x3ff; + int v_inc = mach64->overlay_scale_inc & 0xffff; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay.addr]; + int old_y = mach64->overlay_v_acc; + int y_diff; + int video_key_fn = mach64->overlay_key_cntl & 5; + int graphics_key_fn = (mach64->overlay_key_cntl >> 4) & 5; + int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - p = &buffer32->line[displine][svga->x_add + mach64->svga.overlay_latch.x]; + p = &buffer32->line[displine][svga->x_add + mach64->svga.overlay_latch.x]; - if (mach64->scaler_update) - { - switch (mach64->scaler_format) - { - case 0x3: - DECODE_ARGB1555(); - break; - case 0x4: - DECODE_RGB565(); - break; - case 0x6: - DECODE_ARGB8888(); - break; - case 0xb: - DECODE_VYUY422(); - break; - case 0xc: - DECODE_YVYU422(); - break; + if (mach64->scaler_update) { + switch (mach64->scaler_format) { + case 0x3: + DECODE_ARGB1555(); + break; + case 0x4: + DECODE_RGB565(); + break; + case 0x6: + DECODE_ARGB8888(); + break; + case 0xb: + DECODE_VYUY422(); + break; + case 0xc: + DECODE_YVYU422(); + break; - default: - mach64_log("Unknown Mach64 scaler format %x\n", mach64->scaler_format); - /*Fill buffer with something recognisably wrong*/ - for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) - mach64->overlay_dat[x] = 0xff00ff; - break; - } - } - - if (overlay_cmp_mix == 2) - { + default: + mach64_log("Unknown Mach64 scaler format %x\n", mach64->scaler_format); + /*Fill buffer with something recognisably wrong*/ for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) - { - int h = h_acc >> 12; - - p[x] = mach64->overlay_dat[h]; - - h_acc += h_inc; - if (h_acc > (h_max << 12)) - h_acc = (h_max << 12); - } + mach64->overlay_dat[x] = 0xff00ff; + break; } - else - { - for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) - { - int h = h_acc >> 12; - int gr_cmp = 0, vid_cmp = 0; - int use_video = 0; + } - switch (video_key_fn) - { - case 0: vid_cmp = 0; break; - case 1: vid_cmp = 1; break; - case 4: vid_cmp = ((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); break; - case 5: vid_cmp = !((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); break; - } - switch (graphics_key_fn) - { - case 0: gr_cmp = 0; break; - case 1: gr_cmp = 1; break; - case 4: gr_cmp = (((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); break; - case 5: gr_cmp = !(((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); break; - } - vid_cmp = vid_cmp ? -1 : 0; - gr_cmp = gr_cmp ? -1 : 0; + if (overlay_cmp_mix == 2) { + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { + int h = h_acc >> 12; - switch (overlay_cmp_mix) - { - case 0x0: use_video = gr_cmp; break; - case 0x1: use_video = 0; break; - case 0x2: use_video = ~0; break; - case 0x3: use_video = ~gr_cmp; break; - case 0x4: use_video = ~vid_cmp; break; - case 0x5: use_video = gr_cmp ^ vid_cmp; break; - case 0x6: use_video = ~gr_cmp ^ vid_cmp; break; - case 0x7: use_video = vid_cmp; break; - case 0x8: use_video = ~gr_cmp | ~vid_cmp; break; - case 0x9: use_video = gr_cmp | ~vid_cmp; break; - case 0xa: use_video = ~gr_cmp | vid_cmp; break; - case 0xb: use_video = gr_cmp | vid_cmp; break; - case 0xc: use_video = gr_cmp & vid_cmp; break; - case 0xd: use_video = ~gr_cmp & vid_cmp; break; - case 0xe: use_video = gr_cmp & ~vid_cmp; break; - case 0xf: use_video = ~gr_cmp & ~vid_cmp; break; - } + p[x] = mach64->overlay_dat[h]; - if (use_video) - p[x] = mach64->overlay_dat[h]; - - h_acc += h_inc; - if (h_acc > (h_max << 12)) - h_acc = (h_max << 12); - } + h_acc += h_inc; + if (h_acc > (h_max << 12)) + h_acc = (h_max << 12); } + } else { + for (x = 0; x < mach64->svga.overlay_latch.cur_xsize; x++) { + int h = h_acc >> 12; + int gr_cmp = 0, vid_cmp = 0; + int use_video = 0; - mach64->overlay_v_acc += v_inc; - if (mach64->overlay_v_acc > (v_max << 12)) - mach64->overlay_v_acc = v_max << 12; + switch (video_key_fn) { + case 0: + vid_cmp = 0; + break; + case 1: + vid_cmp = 1; + break; + case 4: + vid_cmp = ((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); + break; + case 5: + vid_cmp = !((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); + break; + } + switch (graphics_key_fn) { + case 0: + gr_cmp = 0; + break; + case 1: + gr_cmp = 1; + break; + case 4: + gr_cmp = (((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); + break; + case 5: + gr_cmp = !(((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); + break; + } + vid_cmp = vid_cmp ? -1 : 0; + gr_cmp = gr_cmp ? -1 : 0; - y_diff = (mach64->overlay_v_acc >> 12) - (old_y >> 12); + switch (overlay_cmp_mix) { + case 0x0: + use_video = gr_cmp; + break; + case 0x1: + use_video = 0; + break; + case 0x2: + use_video = ~0; + break; + case 0x3: + use_video = ~gr_cmp; + break; + case 0x4: + use_video = ~vid_cmp; + break; + case 0x5: + use_video = gr_cmp ^ vid_cmp; + break; + case 0x6: + use_video = ~gr_cmp ^ vid_cmp; + break; + case 0x7: + use_video = vid_cmp; + break; + case 0x8: + use_video = ~gr_cmp | ~vid_cmp; + break; + case 0x9: + use_video = gr_cmp | ~vid_cmp; + break; + case 0xa: + use_video = ~gr_cmp | vid_cmp; + break; + case 0xb: + use_video = gr_cmp | vid_cmp; + break; + case 0xc: + use_video = gr_cmp & vid_cmp; + break; + case 0xd: + use_video = ~gr_cmp & vid_cmp; + break; + case 0xe: + use_video = gr_cmp & ~vid_cmp; + break; + case 0xf: + use_video = ~gr_cmp & ~vid_cmp; + break; + } - if (mach64->scaler_format == 6) - svga->overlay.addr += svga->overlay.pitch*4*y_diff; - else - svga->overlay.addr += svga->overlay.pitch*2*y_diff; + if (use_video) + p[x] = mach64->overlay_dat[h]; - mach64->scaler_update = y_diff; + h_acc += h_inc; + if (h_acc > (h_max << 12)) + h_acc = (h_max << 12); + } + } + + mach64->overlay_v_acc += v_inc; + if (mach64->overlay_v_acc > (v_max << 12)) + mach64->overlay_v_acc = v_max << 12; + + y_diff = (mach64->overlay_v_acc >> 12) - (old_y >> 12); + + if (mach64->scaler_format == 6) + svga->overlay.addr += svga->overlay.pitch * 4 * y_diff; + else + svga->overlay.addr += svga->overlay.pitch * 2 * y_diff; + + mach64->scaler_update = y_diff; } -static void mach64_io_remove(mach64_t *mach64) +static void +mach64_io_remove(mach64_t *mach64) { - int c; - uint16_t io_base = 0x02ec; + int c; + uint16_t io_base = 0x02ec; - switch (mach64->io_base) - { - case 0: - default: - io_base = 0x02ec; - break; - case 1: - io_base = 0x01cc; - break; - case 2: - io_base = 0x01c8; - break; - case 3: - fatal("Attempting to use the reserved value for I/O Base\n"); - return; - } + switch (mach64->io_base) { + case 0: + default: + io_base = 0x02ec; + break; + case 1: + io_base = 0x01cc; + break; + case 2: + io_base = 0x01c8; + break; + case 3: + fatal("Attempting to use the reserved value for I/O Base\n"); + return; + } - io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_removehandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - for (c = 0; c < 8; c++) - { - io_removehandler((c * 0x1000) + 0x0000 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0x0400 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0x0800 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_removehandler((c * 0x1000) + 0x0c00 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } + for (c = 0; c < 8; c++) { + io_removehandler((c * 0x1000) + 0x0000 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0x0400 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0x0800 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_removehandler((c * 0x1000) + 0x0c00 + io_base, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + } - io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) - io_removehandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); + if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + io_removehandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } -static void mach64_io_set(mach64_t *mach64) +static void +mach64_io_set(mach64_t *mach64) { - int c; + int c; - mach64_io_remove(mach64); + mach64_io_remove(mach64); - io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (!mach64->use_block_decoded_io) - { - for (c = 0; c < 8; c++) - { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } + if (!mach64->use_block_decoded_io) { + for (c = 0; c < 8; c++) { + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); } + } - io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) - io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); + if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } -uint8_t mach64_pci_read(int func, int addr, void *p) +uint8_t +mach64_pci_read(int func, int addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - switch (addr) - { - case 0x00: return 0x02; /*ATi*/ - case 0x01: return 0x10; + switch (addr) { + case 0x00: + return 0x02; /*ATi*/ + case 0x01: + return 0x10; - case 0x02: return mach64->pci_id & 0xff; - case 0x03: return mach64->pci_id >> 8; + case 0x02: + return mach64->pci_id & 0xff; + case 0x03: + return mach64->pci_id >> 8; - case PCI_REG_COMMAND: - return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + case PCI_REG_COMMAND: + return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ + case 0x07: + return 1 << 1; /*Medium DEVSEL timing*/ - case 0x08: /*Revision ID*/ - if (mach64->type == MACH64_GX) - return 0; - return 0x40; + case 0x08: /*Revision ID*/ + if (mach64->type == MACH64_GX) + return 0; + return 0x40; - case 0x09: return 0; /*Programming interface*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ - case 0x0b: return 0x03; + case 0x0a: + return 0x01; /*Supports VGA interface, XGA compatible*/ + case 0x0b: + return 0x03; - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return mach64->linear_base >> 16; - case 0x13: return mach64->linear_base >> 24; + case 0x10: + return 0x00; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + return mach64->linear_base >> 16; + case 0x13: + return mach64->linear_base >> 24; - case 0x14: - if (mach64->type == MACH64_VT2) - return 0x01; /*Block decoded IO address*/ - return 0x00; - case 0x15: - if (mach64->type == MACH64_VT2) - return mach64->block_decoded_io >> 8; - return 0x00; - case 0x16: - if (mach64->type == MACH64_VT2) - return mach64->block_decoded_io >> 16; - return 0x00; - case 0x17: - if (mach64->type == MACH64_VT2) - return mach64->block_decoded_io >> 24; - return 0x00; + case 0x14: + if (mach64->type == MACH64_VT2) + return 0x01; /*Block decoded IO address*/ + return 0x00; + case 0x15: + if (mach64->type == MACH64_VT2) + return mach64->block_decoded_io >> 8; + return 0x00; + case 0x16: + if (mach64->type == MACH64_VT2) + return mach64->block_decoded_io >> 16; + return 0x00; + case 0x17: + if (mach64->type == MACH64_VT2) + return mach64->block_decoded_io >> 24; + return 0x00; - case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return mach64->pci_regs[0x32]; - case 0x33: return mach64->pci_regs[0x33]; + case 0x30: + return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return mach64->pci_regs[0x32]; + case 0x33: + return mach64->pci_regs[0x33]; - case 0x3c: return mach64->int_line; - case 0x3d: return PCI_INTA; + case 0x3c: + return mach64->int_line; + case 0x3d: + return PCI_INTA; - case 0x40: return mach64->use_block_decoded_io | mach64->io_base; - } - return 0; + case 0x40: + return mach64->use_block_decoded_io | mach64->io_base; + } + return 0; } -void mach64_pci_write(int func, int addr, uint8_t val, void *p) +void +mach64_pci_write(int func, int addr, uint8_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - switch (addr) - { - case PCI_REG_COMMAND: - mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; - if (val & PCI_COMMAND_IO) - mach64_io_set(mach64); - else - mach64_io_remove(mach64); - mach64_updatemapping(mach64); - break; + switch (addr) { + case PCI_REG_COMMAND: + mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) + mach64_io_set(mach64); + else + mach64_io_remove(mach64); + mach64_updatemapping(mach64); + break; - case 0x12: - if (mach64->type == MACH64_VT2) - val = 0; - mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); - mach64_updatemapping(mach64); - break; - case 0x13: - mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); - mach64_updatemapping(mach64); - break; + case 0x12: + if (mach64->type == MACH64_VT2) + val = 0; + mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); + mach64_updatemapping(mach64); + break; + case 0x13: + mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); + mach64_updatemapping(mach64); + break; - case 0x15: - if (mach64->type == MACH64_VT2) - { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0xffff0000) | ((val & 0xfc) << 8); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - case 0x16: - if (mach64->type == MACH64_VT2) - { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0xff00fc00) | (val << 16); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; - case 0x17: - if (mach64->type == MACH64_VT2) - { - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->block_decoded_io = (mach64->block_decoded_io & 0x00fffc00) | (val << 24); - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - } - break; + case 0x15: + if (mach64->type == MACH64_VT2) { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0xffff0000) | ((val & 0xfc) << 8); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + case 0x16: + if (mach64->type == MACH64_VT2) { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0xff00fc00) | (val << 16); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + case 0x17: + if (mach64->type == MACH64_VT2) { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0x00fffc00) | (val << 24); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; - case 0x30: case 0x32: case 0x33: - mach64->pci_regs[addr] = val; - if (mach64->pci_regs[0x30] & 0x01) - { - uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); - mach64_log("Mach64 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); - } - else - { - mach64_log("Mach64 bios_rom disabled\n"); - mem_mapping_disable(&mach64->bios_rom.mapping); - } - return; + case 0x30: + case 0x32: + case 0x33: + mach64->pci_regs[addr] = val; + if (mach64->pci_regs[0x30] & 0x01) { + uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); + mach64_log("Mach64 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); + } else { + mach64_log("Mach64 bios_rom disabled\n"); + mem_mapping_disable(&mach64->bios_rom.mapping); + } + return; - case 0x3c: - mach64->int_line = val; - break; + case 0x3c: + mach64->int_line = val; + break; - case 0x40: - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_remove(mach64); - mach64->io_base = val & 0x03; - if (mach64->type == MACH64_VT2) - mach64->use_block_decoded_io = val & 0x04; - if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - mach64_io_set(mach64); - break; - } + case 0x40: + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->io_base = val & 0x03; + if (mach64->type == MACH64_VT2) + mach64->use_block_decoded_io = val & 0x04; + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + break; + } } -static void *mach64_common_init(const device_t *info) +static void * +mach64_common_init(const device_t *info) { - mach64_t *mach64 = malloc(sizeof(mach64_t)); - memset(mach64, 0, sizeof(mach64_t)); + mach64_t *mach64 = malloc(sizeof(mach64_t)); + memset(mach64, 0, sizeof(mach64_t)); - mach64->vram_size = device_get_config_int("memory"); - mach64->vram_mask = (mach64->vram_size << 20) - 1; + mach64->vram_size = device_get_config_int("memory"); + mach64->vram_mask = (mach64->vram_size << 20) - 1; - svga_init(info, &mach64->svga, mach64, mach64->vram_size << 20, - mach64_recalctimings, - mach64_in, mach64_out, - NULL, - mach64_overlay_draw); + svga_init(info, &mach64->svga, mach64, mach64->vram_size << 20, + mach64_recalctimings, + mach64_in, mach64_out, + NULL, + mach64_overlay_draw); mach64->svga.dac_hwcursor.cur_ysize = 64; - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &mach64->svga); - mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); - mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); - mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); - mem_mapping_disable(&mach64->mmio_mapping); + mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &mach64->svga); + mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); + mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); + mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, MEM_MAPPING_EXTERNAL, mach64); + mem_mapping_disable(&mach64->mmio_mapping); - mach64_io_set(mach64); + mach64_io_set(mach64); - if (info->flags & DEVICE_PCI) - { - mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64); - } + if (info->flags & DEVICE_PCI) { + mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64); + } - mach64->pci_regs[PCI_REG_COMMAND] = 3; - mach64->pci_regs[0x30] = 0x00; - mach64->pci_regs[0x32] = 0x0c; - mach64->pci_regs[0x33] = 0x00; + mach64->pci_regs[PCI_REG_COMMAND] = 3; + mach64->pci_regs[0x30] = 0x00; + mach64->pci_regs[0x32] = 0x0c; + mach64->pci_regs[0x33] = 0x00; - mach64->svga.ramdac = device_add(&ati68860_ramdac_device); - mach64->svga.dac_hwcursor_draw = ati68860_hwcursor_draw; + mach64->svga.ramdac = device_add(&ati68860_ramdac_device); + mach64->svga.dac_hwcursor_draw = ati68860_hwcursor_draw; - mach64->svga.clock_gen = device_add(&ics2595_device); + mach64->svga.clock_gen = device_add(&ics2595_device); - mach64->dst_cntl = 3; + mach64->dst_cntl = 3; - mach64->i2c = i2c_gpio_init("ddc_ati_mach64"); - mach64->ddc = ddc_init(i2c_gpio_get_bus(mach64->i2c)); + mach64->i2c = i2c_gpio_init("ddc_ati_mach64"); + mach64->ddc = ddc_init(i2c_gpio_get_bus(mach64->i2c)); - mach64->wake_fifo_thread = thread_create_event(); - mach64->fifo_not_full_event = thread_create_event(); - mach64->thread_run = 1; - mach64->fifo_thread = thread_create(fifo_thread, mach64); + mach64->wake_fifo_thread = thread_create_event(); + mach64->fifo_not_full_event = thread_create_event(); + mach64->thread_run = 1; + mach64->fifo_thread = thread_create(fifo_thread, mach64); - return mach64; + return mach64; } -static void *mach64gx_init(const device_t *info) +static void * +mach64gx_init(const device_t *info) { - mach64_t *mach64 = mach64_common_init(info); + mach64_t *mach64 = mach64_common_init(info); - if (info->flags & DEVICE_ISA) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_isa); - else if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb); + if (info->flags & DEVICE_ISA) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_isa); + else if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb); - mach64->type = MACH64_GX; - mach64->pci = !!(info->flags & DEVICE_PCI); - mach64->pci_id = (int)'X' | ((int)'G' << 8); - mach64->config_chip_id = 0x020000d7; - mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ - mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ - if (info->flags & DEVICE_PCI) - mach64->config_stat0 |= 0; /*PCI, 256Kx16 DRAM*/ - else if (info->flags & DEVICE_VLB) - mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ - else if (info->flags & DEVICE_ISA) - mach64->config_stat0 |= 7; /*ISA 16-bit, 256k16 DRAM*/ + mach64->type = MACH64_GX; + mach64->pci = !!(info->flags & DEVICE_PCI); + mach64->pci_id = (int) 'X' | ((int) 'G' << 8); + mach64->config_chip_id = 0x020000d7; + mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ + mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ + if (info->flags & DEVICE_PCI) + mach64->config_stat0 |= 0; /*PCI, 256Kx16 DRAM*/ + else if (info->flags & DEVICE_VLB) + mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ + else if (info->flags & DEVICE_ISA) + mach64->config_stat0 |= 7; /*ISA 16-bit, 256k16 DRAM*/ - ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); + ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); - if (info->flags & DEVICE_PCI) - rom_init(&mach64->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else if (info->flags & DEVICE_VLB) - rom_init(&mach64->bios_rom, BIOS_VLB_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - else if (info->flags & DEVICE_ISA) - rom_init(&mach64->bios_rom, BIOS_ISA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (info->flags & DEVICE_PCI) + rom_init(&mach64->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + else if (info->flags & DEVICE_VLB) + rom_init(&mach64->bios_rom, BIOS_VLB_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + else if (info->flags & DEVICE_ISA) + rom_init(&mach64->bios_rom, BIOS_ISA_ROM_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&mach64->bios_rom.mapping); + if (info->flags & DEVICE_PCI) + mem_mapping_disable(&mach64->bios_rom.mapping); - return mach64; + return mach64; } -static void *mach64vt2_init(const device_t *info) +static void * +mach64vt2_init(const device_t *info) { - mach64_t *mach64 = mach64_common_init(info); - svga_t *svga = &mach64->svga; + mach64_t *mach64 = mach64_common_init(info); + svga_t *svga = &mach64->svga; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb); + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb); - mach64->type = MACH64_VT2; - mach64->pci = 1; - mach64->pci_id = 0x5654; - mach64->config_chip_id = 0x40005654; - mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ - mach64->config_stat0 = 4; - mach64->use_block_decoded_io = 4; + mach64->type = MACH64_VT2; + mach64->pci = 1; + mach64->pci_id = 0x5654; + mach64->config_chip_id = 0x40005654; + mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ + mach64->config_stat0 = 4; + mach64->use_block_decoded_io = 4; - ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); + ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); - rom_init(&mach64->bios_rom, BIOS_ROMVT2_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, BIOS_ROMVT2_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&mach64->bios_rom.mapping); + if (info->flags & DEVICE_PCI) + mem_mapping_disable(&mach64->bios_rom.mapping); - svga->vblank_start = mach64_vblank_start; + svga->vblank_start = mach64_vblank_start; - return mach64; + return mach64; } -int mach64gx_available(void) +int +mach64gx_available(void) { - return rom_present(BIOS_ROM_PATH); + return rom_present(BIOS_ROM_PATH); } -int mach64gx_isa_available(void) +int +mach64gx_isa_available(void) { - return rom_present(BIOS_ISA_ROM_PATH); + return rom_present(BIOS_ISA_ROM_PATH); } -int mach64gx_vlb_available(void) +int +mach64gx_vlb_available(void) { - return rom_present(BIOS_VLB_ROM_PATH); + return rom_present(BIOS_VLB_ROM_PATH); } -int mach64vt2_available(void) +int +mach64vt2_available(void) { - return rom_present(BIOS_ROMVT2_PATH); + return rom_present(BIOS_ROMVT2_PATH); } -void mach64_close(void *p) +void +mach64_close(void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - mach64->thread_run = 0; - thread_set_event(mach64->wake_fifo_thread); - thread_wait(mach64->fifo_thread); - thread_destroy_event(mach64->fifo_not_full_event); - thread_destroy_event(mach64->wake_fifo_thread); + mach64->thread_run = 0; + thread_set_event(mach64->wake_fifo_thread); + thread_wait(mach64->fifo_thread); + thread_destroy_event(mach64->fifo_not_full_event); + thread_destroy_event(mach64->wake_fifo_thread); - svga_close(&mach64->svga); + svga_close(&mach64->svga); - ddc_close(mach64->ddc); - i2c_gpio_close(mach64->i2c); + ddc_close(mach64->ddc); + i2c_gpio_close(mach64->i2c); - free(mach64); + free(mach64); } -void mach64_speed_changed(void *p) +void +mach64_speed_changed(void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - svga_recalctimings(&mach64->svga); + svga_recalctimings(&mach64->svga); } -void mach64_force_redraw(void *p) +void +mach64_force_redraw(void *p) { - mach64_t *mach64 = (mach64_t *)p; + mach64_t *mach64 = (mach64_t *) p; - mach64->svga.fullchange = changeframecount; + mach64->svga.fullchange = changeframecount; } // clang-format off @@ -3742,57 +4424,57 @@ static const device_config_t mach64vt2_config[] = { // clang-format on const device_t mach64gx_isa_device = { - .name = "ATI Mach64GX ISA", + .name = "ATI Mach64GX ISA", .internal_name = "mach64gx_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = 0, - .init = mach64gx_init, - .close = mach64_close, - .reset = NULL, + .flags = DEVICE_AT | DEVICE_ISA, + .local = 0, + .init = mach64gx_init, + .close = mach64_close, + .reset = NULL, { .available = mach64gx_isa_available }, .speed_changed = mach64_speed_changed, - .force_redraw = mach64_force_redraw, - .config = mach64gx_config + .force_redraw = mach64_force_redraw, + .config = mach64gx_config }; const device_t mach64gx_vlb_device = { - .name = "ATI Mach64GX VLB", + .name = "ATI Mach64GX VLB", .internal_name = "mach64gx_vlb", - .flags = DEVICE_VLB, - .local = 0, - .init = mach64gx_init, - .close = mach64_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = 0, + .init = mach64gx_init, + .close = mach64_close, + .reset = NULL, { .available = mach64gx_vlb_available }, .speed_changed = mach64_speed_changed, - .force_redraw = mach64_force_redraw, - .config = mach64gx_config + .force_redraw = mach64_force_redraw, + .config = mach64gx_config }; const device_t mach64gx_pci_device = { - .name = "ATI Mach64GX PCI", + .name = "ATI Mach64GX PCI", .internal_name = "mach64gx_pci", - .flags = DEVICE_PCI, - .local = 0, - .init = mach64gx_init, - .close = mach64_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = mach64gx_init, + .close = mach64_close, + .reset = NULL, { .available = mach64gx_available }, .speed_changed = mach64_speed_changed, - .force_redraw = mach64_force_redraw, - .config = mach64gx_config + .force_redraw = mach64_force_redraw, + .config = mach64gx_config }; const device_t mach64vt2_device = { - .name = "ATI Mach64VT2", + .name = "ATI Mach64VT2", .internal_name = "mach64vt2", - .flags = DEVICE_PCI, - .local = 0, - .init = mach64vt2_init, - .close = mach64_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = mach64vt2_init, + .close = mach64_close, + .reset = NULL, { .available = mach64vt2_available }, .speed_changed = mach64_speed_changed, - .force_redraw = mach64_force_redraw, - .config = mach64vt2_config + .force_redraw = mach64_force_redraw, + .config = mach64vt2_config }; diff --git a/src/video/vid_att20c49x_ramdac.c b/src/video/vid_att20c49x_ramdac.c index 509256f19..81cde31a4 100644 --- a/src/video/vid_att20c49x_ramdac.c +++ b/src/video/vid_att20c49x_ramdac.c @@ -28,131 +28,126 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef struct { - int type; - int state; + int type; + int state; uint8_t ctrl; } att49x_ramdac_t; - -enum -{ - ATT_490 = 0, - ATT_491, - ATT_492 +enum { + ATT_490 = 0, + ATT_491, + ATT_492 }; - static void att49x_ramdac_control(uint8_t val, void *p, svga_t *svga) { - att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; - ramdac->ctrl = val; - switch ((ramdac->ctrl >> 5) & 7) { - case 0: - case 1: - case 2: - case 3: - svga->bpp = 8; - break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 16; - break; - case 7: - svga->bpp = 24; - break; - } - if (ramdac->type == ATT_490 || ramdac->type == ATT_491) - svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); - svga_recalctimings(svga); + att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; + ramdac->ctrl = val; + switch ((ramdac->ctrl >> 5) & 7) { + case 0: + case 1: + case 2: + case 3: + svga->bpp = 8; + break; + case 4: + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; + } + if (ramdac->type == ATT_490 || ramdac->type == ATT_491) + svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); + svga_recalctimings(svga); } void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; - uint8_t rs = (addr & 0x03); + uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); switch (rs) { - case 0x00: - case 0x01: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - svga_out(addr, val, svga); - ramdac->state = 0; - break; - case 0x02: - switch (ramdac->state) { - case 4: - att49x_ramdac_control(val, ramdac, svga); - break; - default: - svga_out(addr, val, svga); - break; - } - break; - case 0x06: - att49x_ramdac_control(val, ramdac, svga); - ramdac->state = 0; - break; + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + ramdac->state = 0; + break; + case 0x02: + switch (ramdac->state) { + case 4: + att49x_ramdac_control(val, ramdac, svga); + break; + default: + svga_out(addr, val, svga); + break; + } + break; + case 0x06: + att49x_ramdac_control(val, ramdac, svga); + ramdac->state = 0; + break; } } - uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p; - uint8_t temp = 0xff; - uint8_t rs = (addr & 0x03); + uint8_t temp = 0xff; + uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); switch (rs) { - case 0x00: - case 0x01: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - temp = svga_in(addr, svga); - ramdac->state = 0; - break; - case 0x02: - switch (ramdac->state) { - case 1: - case 2: case 3: - temp = 0x00; - ramdac->state++; - break; - case 4: - temp = ramdac->ctrl; - ramdac->state = 0; - break; - default: - temp = svga_in(addr, svga); - ramdac->state++; - break; - } - break; - case 0x06: - temp = ramdac->ctrl; - ramdac->state = 0; - break; + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + temp = svga_in(addr, svga); + ramdac->state = 0; + break; + case 0x02: + switch (ramdac->state) { + case 1: + case 2: + case 3: + temp = 0x00; + ramdac->state++; + break; + case 4: + temp = ramdac->ctrl; + ramdac->state = 0; + break; + default: + temp = svga_in(addr, svga); + ramdac->state++; + break; + } + break; + case 0x06: + temp = ramdac->ctrl; + ramdac->state = 0; + break; } return temp; } - static void * att49x_ramdac_init(const device_t *info) { @@ -164,54 +159,53 @@ att49x_ramdac_init(const device_t *info) return ramdac; } - static void att49x_ramdac_close(void *priv) { att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t att490_ramdac_device = { - .name = "AT&T 20c490 RAMDAC", + .name = "AT&T 20c490 RAMDAC", .internal_name = "att490_ramdac", - .flags = 0, - .local = ATT_490, - .init = att49x_ramdac_init, - .close = att49x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = ATT_490, + .init = att49x_ramdac_init, + .close = att49x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t att491_ramdac_device = { - .name = "AT&T 20c491 RAMDAC", + .name = "AT&T 20c491 RAMDAC", .internal_name = "att491_ramdac", - .flags = 0, - .local = ATT_491, - .init = att49x_ramdac_init, - .close = att49x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = ATT_491, + .init = att49x_ramdac_init, + .close = att49x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t att492_ramdac_device = { - .name = "AT&T 20c492 RAMDAC", + .name = "AT&T 20c492 RAMDAC", .internal_name = "att492_ramdac", - .flags = 0, - .local = ATT_492, - .init = att49x_ramdac_init, - .close = att49x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = ATT_492, + .init = att49x_ramdac_init, + .close = att49x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/vid_att2xc498_ramdac.c index 3e4617f8c..5983677db 100644 --- a/src/video/vid_att2xc498_ramdac.c +++ b/src/video/vid_att2xc498_ramdac.c @@ -28,133 +28,130 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef struct { - int type; - int state; - int loop; + int type; + int state; + int loop; uint8_t ctrl; } att498_ramdac_t; static void att498_ramdac_control(uint8_t val, void *p, svga_t *svga) { - att498_ramdac_t *ramdac = (att498_ramdac_t *) p; - ramdac->ctrl = val; + att498_ramdac_t *ramdac = (att498_ramdac_t *) p; + ramdac->ctrl = val; - if (val == 0xff) - return; + if (val == 0xff) + return; - switch ((ramdac->ctrl >> 4) & 0x0f) { - default: - svga->bpp = 8; - break; - case 1: - if (ramdac->ctrl & 4) - svga->bpp = 15; - else - svga->bpp = 8; - break; - case 3: - case 6: - svga->bpp = 16; - break; - case 5: - case 7: - svga->bpp = 32; - break; - case 0x0e: - svga->bpp = 24; - break; - } + switch ((ramdac->ctrl >> 4) & 0x0f) { + default: + svga->bpp = 8; + break; + case 1: + if (ramdac->ctrl & 4) + svga->bpp = 15; + else + svga->bpp = 8; + break; + case 3: + case 6: + svga->bpp = 16; + break; + case 5: + case 7: + svga->bpp = 32; + break; + case 0x0e: + svga->bpp = 24; + break; + } - svga_set_ramdac_type(svga, (ramdac->ctrl & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); - svga_recalctimings(svga); + svga_set_ramdac_type(svga, (ramdac->ctrl & 2) ? RAMDAC_8BIT : RAMDAC_6BIT); + svga_recalctimings(svga); } void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { att498_ramdac_t *ramdac = (att498_ramdac_t *) p; - uint8_t rs = (addr & 0x03); + uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); switch (rs) { - case 0x00: - case 0x01: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - svga_out(addr, val, svga); - ramdac->state = 0; - break; - case 0x02: - switch (ramdac->state) { - case 4: - att498_ramdac_control(val, ramdac, svga); - break; - default: - svga_out(addr, val, svga); - break; - } - break; - case 0x06: - att498_ramdac_control(val, ramdac, svga); - break; + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + ramdac->state = 0; + break; + case 0x02: + switch (ramdac->state) { + case 4: + att498_ramdac_control(val, ramdac, svga); + break; + default: + svga_out(addr, val, svga); + break; + } + break; + case 0x06: + att498_ramdac_control(val, ramdac, svga); + break; } } - uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { att498_ramdac_t *ramdac = (att498_ramdac_t *) p; - uint8_t temp = 0xff; - uint8_t rs = (addr & 0x03); + uint8_t temp = 0xff; + uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); switch (rs) { - case 0x00: - case 0x01: - case 0x03: - case 0x04: - case 0x05: - case 0x07: - temp = svga_in(addr, svga); - ramdac->state = 0; - break; - case 0x02: - switch (ramdac->state) { - case 4: - temp = ramdac->ctrl; - ramdac->state++; - break; - case 5: - temp = 0x84; - ramdac->state++; - break; - case 6: - temp = ramdac->ctrl; - ramdac->state = 0; - break; - default: - temp = svga_in(addr, svga); - ramdac->state++; - break; - } - break; - case 0x06: - temp = ramdac->ctrl; - ramdac->state = 0; - break; + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x07: + temp = svga_in(addr, svga); + ramdac->state = 0; + break; + case 0x02: + switch (ramdac->state) { + case 4: + temp = ramdac->ctrl; + ramdac->state++; + break; + case 5: + temp = 0x84; + ramdac->state++; + break; + case 6: + temp = ramdac->ctrl; + ramdac->state = 0; + break; + default: + temp = svga_in(addr, svga); + ramdac->state++; + break; + } + break; + case 0x06: + temp = ramdac->ctrl; + ramdac->state = 0; + break; } return temp; } - static void * att498_ramdac_init(const device_t *info) { @@ -166,26 +163,25 @@ att498_ramdac_init(const device_t *info) return ramdac; } - static void att498_ramdac_close(void *priv) { att498_ramdac_t *ramdac = (att498_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t att498_ramdac_device = { - .name = "AT&T 22c498 RAMDAC", + .name = "AT&T 22c498 RAMDAC", .internal_name = "att498_ramdac", - .flags = 0, - .local = 0, - .init = att498_ramdac_init, - .close = att498_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = att498_ramdac_init, + .close = att498_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_av9194.c b/src/video/vid_av9194.c index a736effa2..20d39f247 100644 --- a/src/video/vid_av9194.c +++ b/src/video/vid_av9194.c @@ -28,65 +28,62 @@ #include <86box/video.h> #include <86box/vid_svga.h> - float av9194_getclock(int clock, void *p) { float ret = 0.0; - switch (clock & 0x0f) - { - case 0: - ret = 25175000.0; - break; - case 1: - ret = 28322000.0; - break; - case 2: - ret = 40000000.0; - break; - case 4: - ret = 50000000.0; - break; - case 5: - ret = 77000000.0; - break; - case 6: - ret = 36000000.0; - break; - case 7: - ret = 44900000.0; - break; - case 8: - ret = 130000000.0; - break; - case 9: - ret = 120000000.0; - break; - case 0xa: - ret = 80000000.0; - break; - case 0xb: - ret = 31500000.0; - break; - case 0xc: - ret = 110000000.0; - break; - case 0xd: - ret = 65000000.0; - break; - case 0xe: - ret = 75000000.0; - break; - case 0xf: - ret = 94500000.0; - break; + switch (clock & 0x0f) { + case 0: + ret = 25175000.0; + break; + case 1: + ret = 28322000.0; + break; + case 2: + ret = 40000000.0; + break; + case 4: + ret = 50000000.0; + break; + case 5: + ret = 77000000.0; + break; + case 6: + ret = 36000000.0; + break; + case 7: + ret = 44900000.0; + break; + case 8: + ret = 130000000.0; + break; + case 9: + ret = 120000000.0; + break; + case 0xa: + ret = 80000000.0; + break; + case 0xb: + ret = 31500000.0; + break; + case 0xc: + ret = 110000000.0; + break; + case 0xd: + ret = 65000000.0; + break; + case 0xe: + ret = 75000000.0; + break; + case 0xf: + ret = 94500000.0; + break; } return ret; } - static void * av9194_init(const device_t *info) { @@ -94,17 +91,16 @@ av9194_init(const device_t *info) return (void *) &av9194_device; } - const device_t av9194_device = { - .name = "AV9194 Clock Generator", + .name = "AV9194 Clock Generator", .internal_name = "av9194", - .flags = 0, - .local = 0, - .init = av9194_init, - .close = NULL, - .reset = NULL, + .flags = 0, + .local = 0, + .init = av9194_init, + .close = NULL, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_bt48x_ramdac.c b/src/video/vid_bt48x_ramdac.c index 43b02fa6e..05ade0cc3 100644 --- a/src/video/vid_bt48x_ramdac.c +++ b/src/video/vid_bt48x_ramdac.c @@ -29,324 +29,319 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef struct { - PALETTE extpal; - uint32_t extpallook[256]; - uint8_t cursor32_data[256]; - uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; - uint8_t cmd_r0; - uint8_t cmd_r1; - uint8_t cmd_r2; - uint8_t cmd_r3; - uint8_t cmd_r4; - uint8_t status; - uint8_t type; + PALETTE extpal; + uint32_t extpallook[256]; + uint8_t cursor32_data[256]; + uint8_t cursor64_data[1024]; + int hwc_y, hwc_x; + uint8_t cmd_r0; + uint8_t cmd_r1; + uint8_t cmd_r2; + uint8_t cmd_r3; + uint8_t cmd_r4; + uint8_t status; + uint8_t type; } bt48x_ramdac_t; - enum { - BT484 = 0, - ATT20C504, - BT485, - ATT20C505, - BT485A + BT484 = 0, + ATT20C504, + BT485, + ATT20C505, + BT485A }; - static void bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga) { if ((!(ramdac->cmd_r2 & 0x20)) || ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x60))) - svga->bpp = 8; + svga->bpp = 8; else if ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x40)) - svga->bpp = 24; - else switch (ramdac->cmd_r1 & 0x60) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - if (ramdac->cmd_r1 & 0x08) - svga->bpp = 16; - else - svga->bpp = 15; - break; - case 0x40: - svga->bpp = 8; - break; - case 0x60: - svga->bpp = 4; - break; - } + svga->bpp = 24; + else + switch (ramdac->cmd_r1 & 0x60) { + case 0x00: + svga->bpp = 32; + break; + case 0x20: + if (ramdac->cmd_r1 & 0x08) + svga->bpp = 16; + else + svga->bpp = 15; + break; + case 0x40: + svga->bpp = 8; + break; + case 0x60: + svga->bpp = 4; + break; + } svga_recalctimings(svga); } - void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) { bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; - uint32_t o32; - uint8_t *cd; - uint16_t index; - uint8_t rs = (addr & 0x03); - uint16_t da_mask = 0x03ff; + uint32_t o32; + uint8_t *cd; + uint16_t index; + uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; rs |= (!!rs2 << 2); rs |= (!!rs3 << 3); if (ramdac->type < BT485) - da_mask = 0x00ff; + da_mask = 0x00ff; switch (rs) { - case 0x00: /* Palette Write Index Register (RS value = 0000) */ - case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ - case 0x03: - case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ - svga->dac_pos = 0; - svga->dac_status = addr & 0x03; - svga->dac_addr = val; - if (ramdac->type >= BT485) - svga->dac_addr |= ((int) (ramdac->cmd_r3 & 0x03) << 8); - if (svga->dac_status) - svga->dac_addr = (svga->dac_addr + 1) & da_mask; - break; - case 0x01: /* Palette Data Register (RS value = 0001) */ - case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - svga_out(addr, val, svga); - break; - case 0x05: /* Ext Palette Data Register (RS value = 0101) */ - svga->dac_status = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0: - svga->dac_r = val; - svga->dac_pos++; - break; - case 1: - svga->dac_g = val; - svga->dac_pos++; - break; - case 2: - index = svga->dac_addr & 3; - ramdac->extpal[index].r = svga->dac_r; - ramdac->extpal[index].g = svga->dac_g; - ramdac->extpal[index].b = val; - if (svga->ramdac_type == RAMDAC_8BIT) - ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b); - else - ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]); + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + case 0x03: + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + svga->dac_pos = 0; + svga->dac_status = addr & 0x03; + svga->dac_addr = val; + if (ramdac->type >= BT485) + svga->dac_addr |= ((int) (ramdac->cmd_r3 & 0x03) << 8); + if (svga->dac_status) + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + svga_out(addr, val, svga); + break; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 3; + ramdac->extpal[index].r = svga->dac_r; + ramdac->extpal[index].g = svga->dac_g; + ramdac->extpal[index].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b); + else + ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]); - if (svga->ext_overscan && !index) { - o32 = svga->overscan_color; - svga->overscan_color = ramdac->extpallook[0]; - if (o32 != svga->overscan_color) - svga_recalctimings(svga); - } - svga->dac_addr = (svga->dac_addr + 1) & 0xff; - svga->dac_pos = 0; - break; - } - break; - case 0x06: /* Command Register 0 (RS value = 0110) */ - ramdac->cmd_r0 = val; - svga->ramdac_type = (val & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT; - break; - case 0x08: /* Command Register 1 (RS value = 1000) */ - ramdac->cmd_r1 = val; - bt48x_set_bpp(ramdac, svga); - break; - case 0x09: /* Command Register 2 (RS value = 1001) */ - ramdac->cmd_r2 = val; - svga->dac_hwcursor.ena = !!(val & 0x03); - bt48x_set_bpp(ramdac, svga); - break; - case 0x0a: - if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) { - switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) { - case 0x01: - /* Command Register 3 (RS value = 1010) */ - ramdac->cmd_r3 = val; - if (ramdac->type >= BT485A) - bt48x_set_bpp(ramdac, svga); - svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 4) ? 64 : 32; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; - svga->dac_addr = (svga->dac_addr & 0x00ff) | ((val & 0x03) << 8); - svga_recalctimings(svga); - break; - case 0x02: - case 0x20: - case 0x21: - case 0x22: - if (ramdac->type != BT485A) - break; - else if (svga->dac_addr == 2) { - ramdac->cmd_r4 = val; - break; - } - break; - } - } - break; - case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ - index = svga->dac_addr & da_mask; - if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64)) - cd = (uint8_t *) ramdac->cursor64_data; - else { - index &= 0xff; - cd = (uint8_t *) ramdac->cursor32_data; - } + if (svga->ext_overscan && !index) { + o32 = svga->overscan_color; + svga->overscan_color = ramdac->extpallook[0]; + if (o32 != svga->overscan_color) + svga_recalctimings(svga); + } + svga->dac_addr = (svga->dac_addr + 1) & 0xff; + svga->dac_pos = 0; + break; + } + break; + case 0x06: /* Command Register 0 (RS value = 0110) */ + ramdac->cmd_r0 = val; + svga->ramdac_type = (val & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x08: /* Command Register 1 (RS value = 1000) */ + ramdac->cmd_r1 = val; + bt48x_set_bpp(ramdac, svga); + break; + case 0x09: /* Command Register 2 (RS value = 1001) */ + ramdac->cmd_r2 = val; + svga->dac_hwcursor.ena = !!(val & 0x03); + bt48x_set_bpp(ramdac, svga); + break; + case 0x0a: + if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) { + switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) { + case 0x01: + /* Command Register 3 (RS value = 1010) */ + ramdac->cmd_r3 = val; + if (ramdac->type >= BT485A) + bt48x_set_bpp(ramdac, svga); + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 4) ? 64 : 32; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; + svga->dac_addr = (svga->dac_addr & 0x00ff) | ((val & 0x03) << 8); + svga_recalctimings(svga); + break; + case 0x02: + case 0x20: + case 0x21: + case 0x22: + if (ramdac->type != BT485A) + break; + else if (svga->dac_addr == 2) { + ramdac->cmd_r4 = val; + break; + } + break; + } + } + break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + index = svga->dac_addr & da_mask; + if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64)) + cd = (uint8_t *) ramdac->cursor64_data; + else { + index &= 0xff; + cd = (uint8_t *) ramdac->cursor32_data; + } - cd[index] = val; + cd[index] = val; - svga->dac_addr = (svga->dac_addr + 1) & da_mask; - break; - case 0x0c: /* Cursor X Low Register (RS value = 1100) */ - ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - break; - case 0x0d: /* Cursor X High Register (RS value = 1101) */ - ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - break; - case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ - ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; - break; - case 0x0f: /* Cursor Y High Register (RS value = 1111) */ - ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; - break; + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; + break; } return; } - uint8_t bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) { bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p; - uint8_t temp = 0xff; - uint8_t *cd; - uint16_t index; - uint8_t rs = (addr & 0x03); - uint16_t da_mask = 0x03ff; + uint8_t temp = 0xff; + uint8_t *cd; + uint16_t index; + uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; rs |= (!!rs2 << 2); rs |= (!!rs3 << 3); if (ramdac->type < BT485) - da_mask = 0x00ff; + da_mask = 0x00ff; switch (rs) { - case 0x00: /* Palette Write Index Register (RS value = 0000) */ - case 0x01: /* Palette Data Register (RS value = 0001) */ - case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ - temp = svga_in(addr, svga); - break; - case 0x03: /* Palette Read Index Register (RS value = 0011) */ - case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ - temp = svga->dac_addr & 0xff; - break; - case 0x05: /* Ext Palette Data Register (RS value = 0101) */ - index = (svga->dac_addr - 1) & 3; - svga->dac_status = 3; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - temp = ramdac->extpal[index].r; - else - temp = ramdac->extpal[index].r & 0x3f; - break; - case 1: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - temp = ramdac->extpal[index].g; - else - temp = ramdac->extpal[index].g & 0x3f; - break; - case 2: - svga->dac_pos=0; - svga->dac_addr = svga->dac_addr + 1; - if (svga->ramdac_type == RAMDAC_8BIT) - temp = ramdac->extpal[index].b; - else - temp = ramdac->extpal[index].b & 0x3f; - break; - } - break; - case 0x06: /* Command Register 0 (RS value = 0110) */ - temp = ramdac->cmd_r0; - break; - case 0x08: /* Command Register 1 (RS value = 1000) */ - temp = ramdac->cmd_r1; - break; - case 0x09: /* Command Register 2 (RS value = 1001) */ - temp = ramdac->cmd_r2; - break; - case 0x0a: - if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) { - switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) { - case 0x00: - default: - temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00); - break; - case 0x01: - temp = ramdac->cmd_r3 & 0xfc; - temp |= (svga->dac_addr & 0x300) >> 8; - break; - case 0x02: - case 0x20: - case 0x21: - case 0x22: - if (ramdac->type != BT485A) - break; - else if (svga->dac_addr == 2) { - temp = ramdac->cmd_r4; - break; - } else { - /* TODO: Red, Green, and Blue Signature Analysis Registers */ - temp = 0xff; - break; - } - break; - } - } else - temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00); - break; - case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ - index = (svga->dac_addr - 1) & da_mask; - if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64)) - cd = (uint8_t *) ramdac->cursor64_data; - else { - index &= 0xff; - cd = (uint8_t *) ramdac->cursor32_data; - } + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + temp = svga_in(addr, svga); + break; + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + temp = svga->dac_addr & 0xff; + break; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + index = (svga->dac_addr - 1) & 3; + svga->dac_status = 3; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].r; + else + temp = ramdac->extpal[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].g; + else + temp = ramdac->extpal[index].g & 0x3f; + break; + case 2: + svga->dac_pos = 0; + svga->dac_addr = svga->dac_addr + 1; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].b; + else + temp = ramdac->extpal[index].b & 0x3f; + break; + } + break; + case 0x06: /* Command Register 0 (RS value = 0110) */ + temp = ramdac->cmd_r0; + break; + case 0x08: /* Command Register 1 (RS value = 1000) */ + temp = ramdac->cmd_r1; + break; + case 0x09: /* Command Register 2 (RS value = 1001) */ + temp = ramdac->cmd_r2; + break; + case 0x0a: + if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) { + switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) { + case 0x00: + default: + temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00); + break; + case 0x01: + temp = ramdac->cmd_r3 & 0xfc; + temp |= (svga->dac_addr & 0x300) >> 8; + break; + case 0x02: + case 0x20: + case 0x21: + case 0x22: + if (ramdac->type != BT485A) + break; + else if (svga->dac_addr == 2) { + temp = ramdac->cmd_r4; + break; + } else { + /* TODO: Red, Green, and Blue Signature Analysis Registers */ + temp = 0xff; + break; + } + break; + } + } else + temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00); + break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + index = (svga->dac_addr - 1) & da_mask; + if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64)) + cd = (uint8_t *) ramdac->cursor64_data; + else { + index &= 0xff; + cd = (uint8_t *) ramdac->cursor32_data; + } - temp = cd[index]; + temp = cd[index]; - svga->dac_addr = (svga->dac_addr + 1) & da_mask; - break; - case 0x0c: /* Cursor X Low Register (RS value = 1100) */ - temp = ramdac->hwc_x & 0xff; - break; - case 0x0d: /* Cursor X High Register (RS value = 1101) */ - temp = (ramdac->hwc_x >> 8) & 0xff; - break; - case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ - temp = ramdac->hwc_y & 0xff; - break; - case 0x0f: /* Cursor Y High Register (RS value = 1111) */ - temp = (ramdac->hwc_y >> 8) & 0xff; - break; + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + temp = ramdac->hwc_x & 0xff; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + temp = (ramdac->hwc_x >> 8) & 0xff; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + temp = ramdac->hwc_y & 0xff; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + temp = (ramdac->hwc_y >> 8) & 0xff; + break; } return temp; } - void bt48x_recalctimings(void *p, svga_t *svga) { @@ -354,19 +349,18 @@ bt48x_recalctimings(void *p, svga_t *svga) svga->interlace = ramdac->cmd_r2 & 0x08; if (ramdac->cmd_r3 & 0x08) - svga->hdisp *= 2; /* x2 clock multiplier */ + svga->hdisp *= 2; /* x2 clock multiplier */ } - void bt48x_hwcursor_draw(svga_t *svga, int displine) { - int x, xx, comb, b0, b1; - uint16_t dat[2]; - int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; - int pitch, bppl, mode, x_pos, y_pos; - uint32_t clr1, clr2, clr3, *p; - uint8_t *cd; + int x, xx, comb, b0, b1; + uint16_t dat[2]; + int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; + int pitch, bppl, mode, x_pos, y_pos; + uint32_t clr1, clr2, clr3, *p; + uint8_t *cd; bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac; clr1 = ramdac->extpallook[1]; @@ -376,85 +370,82 @@ bt48x_hwcursor_draw(svga_t *svga, int displine) /* The planes come in two parts, and each plane is 1bpp, so a 32x32 cursor has 4 bytes per line, and a 64x64 cursor has 8 bytes per line. */ - pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */ + pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */ /* A 32x32 cursor has 128 bytes per line, and a 64x64 cursor has 512 bytes per line. */ - bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */ + bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */ mode = ramdac->cmd_r2 & 0x03; if (svga->interlace && svga->dac_hwcursor_oddeven) - svga->dac_hwcursor_latch.addr += pitch; + svga->dac_hwcursor_latch.addr += pitch; if (svga->dac_hwcursor_latch.cur_xsize == 64) - cd = (uint8_t *) ramdac->cursor64_data; + cd = (uint8_t *) ramdac->cursor64_data; else - cd = (uint8_t *) ramdac->cursor32_data; + cd = (uint8_t *) ramdac->cursor32_data; for (x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += 16) { - dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | - cd[svga->dac_hwcursor_latch.addr + 1]; - dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | - cd[svga->dac_hwcursor_latch.addr + bppl + 1]; + dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | cd[svga->dac_hwcursor_latch.addr + 1]; + dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | cd[svga->dac_hwcursor_latch.addr + bppl + 1]; - for (xx = 0; xx < 16; xx++) { - b0 = (dat[0] >> (15 - xx)) & 1; - b1 = (dat[1] >> (15 - xx)) & 1; - comb = (b0 | (b1 << 1)); + for (xx = 0; xx < 16; xx++) { + b0 = (dat[0] >> (15 - xx)) & 1; + b1 = (dat[1] >> (15 - xx)) & 1; + comb = (b0 | (b1 << 1)); - y_pos = displine; - x_pos = offset + svga->x_add; - p = buffer32->line[y_pos]; + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; - if (offset >= svga->dac_hwcursor_latch.x) { - switch (mode) { - case 1: /* Three Color */ - switch (comb) { - case 1: - p[x_pos] = clr1; - break; - case 2: - p[x_pos] = clr2; - break; - case 3: - p[x_pos] = clr3; - break; - } - break; - case 2: /* PM/Windows */ - switch (comb) { - case 0: - p[x_pos] = clr1; - break; - case 1: - p[x_pos] = clr2; - break; - case 3: - p[x_pos] ^= 0xffffff; - break; - } - break; - case 3: /* X-Windows */ - switch (comb) { - case 2: - p[x_pos] = clr1; - break; - case 3: - p[x_pos] = clr2; - break; - } - break; - } - } - offset++; - } - svga->dac_hwcursor_latch.addr += 2; + if (offset >= svga->dac_hwcursor_latch.x) { + switch (mode) { + case 1: /* Three Color */ + switch (comb) { + case 1: + p[x_pos] = clr1; + break; + case 2: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] = clr3; + break; + } + break; + case 2: /* PM/Windows */ + switch (comb) { + case 0: + p[x_pos] = clr1; + break; + case 1: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] ^= 0xffffff; + break; + } + break; + case 3: /* X-Windows */ + switch (comb) { + case 2: + p[x_pos] = clr1; + break; + case 3: + p[x_pos] = clr2; + break; + } + break; + } + } + offset++; + } + svga->dac_hwcursor_latch.addr += 2; } if (svga->interlace && !svga->dac_hwcursor_oddeven) - svga->dac_hwcursor_latch.addr += pitch; + svga->dac_hwcursor_latch.addr += pitch; } - void * bt48x_ramdac_init(const device_t *info) { @@ -465,106 +456,105 @@ bt48x_ramdac_init(const device_t *info) /* Set the RAM DAC status byte to the correct ID bits. - Both the BT484 and BT485 datasheets say this: - SR7-SR6: These bits are identification values. SR7=0 and SR6=1. - But all other sources seem to assume SR7=1 and SR6=0. */ + Both the BT484 and BT485 datasheets say this: + SR7-SR6: These bits are identification values. SR7=0 and SR6=1. + But all other sources seem to assume SR7=1 and SR6=0. */ switch (ramdac->type) { - case BT484: - ramdac->status = 0x40; - break; - case ATT20C504: - ramdac->status = 0x40; - break; - case BT485: - ramdac->status = 0x60; - break; - case ATT20C505: - ramdac->status = 0xd0; - break; - case BT485A: - ramdac->status = 0x20; - break; + case BT484: + ramdac->status = 0x40; + break; + case ATT20C504: + ramdac->status = 0x40; + break; + case BT485: + ramdac->status = 0x60; + break; + case ATT20C505: + ramdac->status = 0xd0; + break; + case BT485A: + ramdac->status = 0x20; + break; } return ramdac; } - static void bt48x_ramdac_close(void *priv) { bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t bt484_ramdac_device = { - .name = "Brooktree Bt484 RAMDAC", + .name = "Brooktree Bt484 RAMDAC", .internal_name = "bt484_ramdac", - .flags = 0, - .local = BT484, - .init = bt48x_ramdac_init, - .close = bt48x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = BT484, + .init = bt48x_ramdac_init, + .close = bt48x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t att20c504_ramdac_device = { - .name = "AT&T 20c504 RAMDAC", + .name = "AT&T 20c504 RAMDAC", .internal_name = "att20c504_ramdac", - .flags = 0, - .local = ATT20C504, - .init = bt48x_ramdac_init, - .close = bt48x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = ATT20C504, + .init = bt48x_ramdac_init, + .close = bt48x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t bt485_ramdac_device = { - .name = "Brooktree Bt485 RAMDAC", + .name = "Brooktree Bt485 RAMDAC", .internal_name = "bt485_ramdac", - .flags = 0, - .local = BT485, - .init = bt48x_ramdac_init, - .close = bt48x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = BT485, + .init = bt48x_ramdac_init, + .close = bt48x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t att20c505_ramdac_device = { - .name = "AT&T 20c505 RAMDAC", + .name = "AT&T 20c505 RAMDAC", .internal_name = "att20c505_ramdac", - .flags = 0, - .local = ATT20C505, - .init = bt48x_ramdac_init, - .close = bt48x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = ATT20C505, + .init = bt48x_ramdac_init, + .close = bt48x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t bt485a_ramdac_device = { - .name = "Brooktree Bt485A RAMDAC", + .name = "Brooktree Bt485A RAMDAC", .internal_name = "bt485a_ramdac", - .flags = 0, - .local = BT485A, - .init = bt48x_ramdac_init, - .close = bt48x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = BT485A, + .init = bt48x_ramdac_init, + .close = bt48x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index d7827732d..ee3987fe0 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -34,68 +34,64 @@ #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> - -#define CGA_RGB 0 +#define CGA_RGB 0 #define CGA_COMPOSITE 1 #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 -static uint8_t crtcmask[32] = -{ - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +static uint8_t crtcmask[32] = { + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static video_timings_t timing_cga = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; void cga_recalctimings(cga_t *cga); - void cga_out(uint16_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) p; uint8_t old; if ((addr >= 0x3d0) && (addr <= 0x3d7)) - addr = (addr & 0xff9) | 0x004; + addr = (addr & 0xff9) | 0x004; switch (addr) { - case 0x3D4: - cga->crtcreg = val & 31; - return; - case 0x3D5: - old = cga->crtc[cga->crtcreg]; - cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; - if (old != val) { - if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x10)) { - cga->fullchange = changeframecount; - cga_recalctimings(cga); - } - } - return; - case 0x3D8: - old = cga->cgamode; - cga->cgamode = val; + case 0x3D4: + cga->crtcreg = val & 31; + return; + case 0x3D5: + old = cga->crtc[cga->crtcreg]; + cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg]; + if (old != val) { + if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x10)) { + cga->fullchange = changeframecount; + cga_recalctimings(cga); + } + } + return; + case 0x3D8: + old = cga->cgamode; + cga->cgamode = val; - if (old ^ val) { - if ((old ^ val) & 0x05) - update_cga16_color(val); + if (old ^ val) { + if ((old ^ val) & 0x05) + update_cga16_color(val); - cga_recalctimings(cga); - } - return; - case 0x3D9: - old = cga->cgacol; - cga->cgacol = val; - if (old ^ val) - cga_recalctimings(cga); - return; + cga_recalctimings(cga); + } + return; + case 0x3D9: + old = cga->cgacol; + cga->cgacol = val; + if (old ^ val) + cga_recalctimings(cga); + return; } } - uint8_t cga_in(uint16_t addr, void *p) { @@ -104,35 +100,33 @@ cga_in(uint16_t addr, void *p) uint8_t ret = 0xff; if ((addr >= 0x3d0) && (addr <= 0x3d7)) - addr = (addr & 0xff9) | 0x004; + addr = (addr & 0xff9) | 0x004; switch (addr) { - case 0x3D4: - ret = cga->crtcreg; - break; - case 0x3D5: - ret = cga->crtc[cga->crtcreg]; - break; - case 0x3DA: - ret = cga->cgastat; - break; + case 0x3D4: + ret = cga->crtcreg; + break; + case 0x3D5: + ret = cga->crtc[cga->crtcreg]; + break; + case 0x3DA: + ret = cga->cgastat; + break; } return ret; } - void cga_waitstates(void *p) { - int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8}; + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; ws = ws_array[cycles & 0xf]; cycles -= ws; } - void cga_write(uint32_t addr, uint8_t val, void *p) { @@ -140,14 +134,13 @@ cga_write(uint32_t addr, uint8_t val, void *p) cga->vram[addr & 0x3fff] = val; if (cga->snow_enabled) { - int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; - cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; - cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; + int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; + cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; } cga_waitstates(cga); } - uint8_t cga_read(uint32_t addr, void *p) { @@ -155,14 +148,13 @@ cga_read(uint32_t addr, void *p) cga_waitstates(cga); if (cga->snow_enabled) { - int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; - cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; - cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; + int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc; + cga->charbuffer[offset] = cga->vram[addr & 0x3fff]; + cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff]; } return cga->vram[addr & 0x3fff]; } - void cga_recalctimings(cga_t *cga) { @@ -170,354 +162,331 @@ cga_recalctimings(cga_t *cga) double _dispontime, _dispofftime; if (cga->cgamode & 1) { - disptime = (double) (cga->crtc[0] + 1); - _dispontime = (double) cga->crtc[1]; + disptime = (double) (cga->crtc[0] + 1); + _dispontime = (double) cga->crtc[1]; } else { - disptime = (double) ((cga->crtc[0] + 1) << 1); - _dispontime = (double) (cga->crtc[1] << 1); + disptime = (double) ((cga->crtc[0] + 1) << 1); + _dispontime = (double) (cga->crtc[1] << 1); } - _dispofftime = disptime - _dispontime; - _dispontime = _dispontime * CGACONST; - _dispofftime = _dispofftime * CGACONST; - cga->dispontime = (uint64_t)(_dispontime); - cga->dispofftime = (uint64_t)(_dispofftime); + _dispofftime = disptime - _dispontime; + _dispontime = _dispontime * CGACONST; + _dispofftime = _dispofftime * CGACONST; + cga->dispontime = (uint64_t) (_dispontime); + cga->dispofftime = (uint64_t) (_dispofftime); } - void cga_poll(void *p) { - cga_t *cga = (cga_t *)p; - uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c, xs_temp, ys_temp; - int oldvc; - uint8_t chr, attr; - uint8_t border; + cga_t *cga = (cga_t *) p; + uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c, xs_temp, ys_temp; + int oldvc; + uint8_t chr, attr; + uint8_t border; uint16_t dat; - int cols[4]; - int col; - int oldsc; + int cols[4]; + int col; + int oldsc; if (!cga->linepos) { - timer_advance_u64(&cga->timer, cga->dispofftime); - cga->cgastat |= 1; - cga->linepos = 1; - oldsc = cga->sc; - if ((cga->crtc[8] & 3) == 3) - cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; - if (cga->cgadispon) { - if (cga->displine < cga->firstline) { - cga->firstline = cga->displine; - video_wait_for_buffer(); - } - cga->lastline = cga->displine; - for (c = 0; c < 8; c++) { - if ((cga->cgamode & 0x12) == 0x12) { - buffer32->line[(cga->displine << 1)][c] = - buffer32->line[(cga->displine << 1) + 1][c] = 0; - if (cga->cgamode & 1) { - buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] = - buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0; - } else { - buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] = - buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0; - } - } else { - buffer32->line[(cga->displine << 1)][c] = - buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) { - buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] = - buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; - } else { - buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] = - buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; - } - } - } - if (cga->cgamode & 1) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->charbuffer[x << 1]; - attr = cga->charbuffer[(x << 1) + 1]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) - cols[1] = cols[0]; - } else - cols[0] = (attr >> 4) + 16; - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = - cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - } else { - for (c = 0; c < 8; c++) { - buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = - cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - cga->ma++; - } - } else if (!(cga->cgamode & 2)) { - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) { - chr = cga->vram[((cga->ma << 1) & 0x3fff)]; - attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; - } else - chr = attr = 0; - drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); - cols[1] = (attr & 15) + 16; - if (cga->cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((cga->cgablink & 8) && (attr & 0x80)) - cols[1] = cols[0]; - } else - cols[0] = (attr >> 4) + 16; - cga->ma++; - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = - buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } - } else { - for (c = 0; c < 8; c++) { - buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = - buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - } else if (!(cga->cgamode & 16)) { - cols[0] = (cga->cgacol & 15) | 16; - col = (cga->cgacol & 16) ? 24 : 16; - if (cga->cgamode & 4) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 7; /* White */ - } else if (cga->cgacol & 32) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 5; /* Magenta */ - cols[3] = col | 7; /* White */ - } else { - cols[1] = col | 2; /* Green */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 6; /* Yellow */ - } - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 8; c++) { - buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = - buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = - cols[dat >> 14]; - dat <<= 2; - } - } - } else { - cols[0] = 0; cols[1] = (cga->cgacol & 15) + 16; - for (x = 0; x < cga->crtc[1]; x++) { - if (cga->cgamode & 8) - dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; - else - dat = 0; - cga->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[(cga->displine << 1)][(x << 4) + c + 8] = - buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] = - cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { - cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; - if (cga->cgamode & 1) { - hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]); - hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]); - } else { - hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]); - hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]); - } - } + timer_advance_u64(&cga->timer, cga->dispofftime); + cga->cgastat |= 1; + cga->linepos = 1; + oldsc = cga->sc; + if ((cga->crtc[8] & 3) == 3) + cga->sc = ((cga->sc << 1) + cga->oddeven) & 7; + if (cga->cgadispon) { + if (cga->displine < cga->firstline) { + cga->firstline = cga->displine; + video_wait_for_buffer(); + } + cga->lastline = cga->displine; + for (c = 0; c < 8; c++) { + if ((cga->cgamode & 0x12) == 0x12) { + buffer32->line[(cga->displine << 1)][c] = buffer32->line[(cga->displine << 1) + 1][c] = 0; + if (cga->cgamode & 1) { + buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0; + } else { + buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0; + } + } else { + buffer32->line[(cga->displine << 1)][c] = buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16; + if (cga->cgamode & 1) { + buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16; + } else { + buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16; + } + } + } + if (cga->cgamode & 1) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->charbuffer[x << 1]; + attr = cga->charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + cols[1] = (attr & 15) + 16; + if (cga->cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + cga->ma++; + } + } else if (!(cga->cgamode & 2)) { + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) { + chr = cga->vram[((cga->ma << 1) & 0x3fff)]; + attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)]; + } else + chr = attr = 0; + drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron); + cols[1] = (attr & 15) + 16; + if (cga->cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((cga->cgablink & 8) && (attr & 0x80)) + cols[1] = cols[0]; + } else + cols[0] = (attr >> 4) + 16; + cga->ma++; + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + } else if (!(cga->cgamode & 16)) { + cols[0] = (cga->cgacol & 15) | 16; + col = (cga->cgacol & 16) ? 24 : 16; + if (cga->cgamode & 4) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 7; /* White */ + } else if (cga->cgacol & 32) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 5; /* Magenta */ + cols[3] = col | 7; /* White */ + } else { + cols[1] = col | 2; /* Green */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 6; /* Yellow */ + } + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 8; c++) { + buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14]; + dat <<= 2; + } + } + } else { + cols[0] = 0; + cols[1] = (cga->cgacol & 15) + 16; + for (x = 0; x < cga->crtc[1]; x++) { + if (cga->cgamode & 8) + dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1]; + else + dat = 0; + cga->ma++; + for (c = 0; c < 16; c++) { + buffer32->line[(cga->displine << 1)][(x << 4) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } + } else { + cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16; + if (cga->cgamode & 1) { + hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]); + hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]); + } else { + hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]); + hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]); + } + } - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; - else - x = (cga->crtc[1] << 4) + 16; + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3) + 16; + else + x = (cga->crtc[1] << 4) + 16; - if (cga->composite) { - if (cga->cgamode & 0x10) - border = 0x00; - else - border = cga->cgacol & 0x0f; + if (cga->composite) { + if (cga->cgamode & 0x10) + border = 0x00; + else + border = cga->cgacol & 0x0f; - Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1)]); - Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]); - } + Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1)]); + Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]); + } - cga->sc = oldsc; - if (cga->vc == cga->crtc[7] && !cga->sc) - cga->cgastat |= 8; - cga->displine++; - if (cga->displine >= 360) - cga->displine = 0; + cga->sc = oldsc; + if (cga->vc == cga->crtc[7] && !cga->sc) + cga->cgastat |= 8; + cga->displine++; + if (cga->displine >= 360) + cga->displine = 0; } else { - timer_advance_u64(&cga->timer, cga->dispontime); - cga->linepos = 0; - if (cga->vsynctime) { - cga->vsynctime--; - if (!cga->vsynctime) - cga->cgastat &= ~8; - } - if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { - cga->con = 0; - cga->coff = 1; - } - if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) - cga->maback = cga->ma; - if (cga->vadj) { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - cga->vadj--; - if (!cga->vadj) { - cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - cga->sc = 0; - } - } else if (cga->sc == cga->crtc[9]) { - cga->maback = cga->ma; - cga->sc = 0; - oldvc = cga->vc; - cga->vc++; - cga->vc &= 127; + timer_advance_u64(&cga->timer, cga->dispontime); + cga->linepos = 0; + if (cga->vsynctime) { + cga->vsynctime--; + if (!cga->vsynctime) + cga->cgastat &= ~8; + } + if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) { + cga->con = 0; + cga->coff = 1; + } + if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1)) + cga->maback = cga->ma; + if (cga->vadj) { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + cga->vadj--; + if (!cga->vadj) { + cga->cgadispon = 1; + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + cga->sc = 0; + } + } else if (cga->sc == cga->crtc[9]) { + cga->maback = cga->ma; + cga->sc = 0; + oldvc = cga->vc; + cga->vc++; + cga->vc &= 127; - if (cga->vc == cga->crtc[6]) - cga->cgadispon = 0; + if (cga->vc == cga->crtc[6]) + cga->cgadispon = 0; - if (oldvc == cga->crtc[4]) { - cga->vc = 0; - cga->vadj = cga->crtc[5]; - if (!cga->vadj) { - cga->cgadispon = 1; - cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; - } - switch (cga->crtc[10] & 0x60) { - case 0x20: - cga->cursoron = 0; - break; - case 0x60: - cga->cursoron = cga->cgablink & 0x10; - break; - default: - cga->cursoron = cga->cgablink & 0x08; - break; - } - } + if (oldvc == cga->crtc[4]) { + cga->vc = 0; + cga->vadj = cga->crtc[5]; + if (!cga->vadj) { + cga->cgadispon = 1; + cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff; + } + switch (cga->crtc[10] & 0x60) { + case 0x20: + cga->cursoron = 0; + break; + case 0x60: + cga->cursoron = cga->cgablink & 0x10; + break; + default: + cga->cursoron = cga->cgablink & 0x08; + break; + } + } - if (cga->vc == cga->crtc[7]) { - cga->cgadispon = 0; - cga->displine = 0; - cga->vsynctime = 16; - if (cga->crtc[7]) { - if (cga->cgamode & 1) - x = (cga->crtc[1] << 3) + 16; - else - x = (cga->crtc[1] << 4) + 16; - cga->lastline++; + if (cga->vc == cga->crtc[7]) { + cga->cgadispon = 0; + cga->displine = 0; + cga->vsynctime = 16; + if (cga->crtc[7]) { + if (cga->cgamode & 1) + x = (cga->crtc[1] << 3) + 16; + else + x = (cga->crtc[1] << 4) + 16; + cga->lastline++; - xs_temp = x; - ys_temp = (cga->lastline - cga->firstline) << 1; + xs_temp = x; + ys_temp = (cga->lastline - cga->firstline) << 1; - if ((xs_temp > 0) && (ys_temp > 0)) { - if (xs_temp < 64) xs_temp = 656; - if (ys_temp < 32) ys_temp = 400; - if (!enable_overscan) - xs_temp -= 16; + if ((xs_temp > 0) && (ys_temp > 0)) { + if (xs_temp < 64) + xs_temp = 656; + if (ys_temp < 32) + ys_temp = 400; + if (!enable_overscan) + xs_temp -= 16; - if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - xsize = xs_temp; - ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + xsize = xs_temp; + ysize = ys_temp; + set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); - if (video_force_resize_get()) - video_force_resize_set(0); - } + if (video_force_resize_get()) + video_force_resize_set(0); + } - if (enable_overscan) { - if (cga->composite) - video_blit_memtoscreen(0, (cga->firstline - 4) << 1, - xsize, ((cga->lastline - cga->firstline) + 8) << 1); - else - video_blit_memtoscreen_8(0, (cga->firstline - 4) << 1, - xsize, ((cga->lastline - cga->firstline) + 8) << 1); - } else { - if (cga->composite) - video_blit_memtoscreen(8, cga->firstline << 1, - xsize, (cga->lastline - cga->firstline) << 1); - else - video_blit_memtoscreen_8(8, cga->firstline << 1, - xsize, (cga->lastline - cga->firstline) << 1); - } - } + if (enable_overscan) { + if (cga->composite) + video_blit_memtoscreen(0, (cga->firstline - 4) << 1, + xsize, ((cga->lastline - cga->firstline) + 8) << 1); + else + video_blit_memtoscreen_8(0, (cga->firstline - 4) << 1, + xsize, ((cga->lastline - cga->firstline) + 8) << 1); + } else { + if (cga->composite) + video_blit_memtoscreen(8, cga->firstline << 1, + xsize, (cga->lastline - cga->firstline) << 1); + else + video_blit_memtoscreen_8(8, cga->firstline << 1, + xsize, (cga->lastline - cga->firstline) << 1); + } + } - frames++; + frames++; - video_res_x = xsize; - video_res_y = ysize; - if (cga->cgamode & 1) { - video_res_x /= 8; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } else if (!(cga->cgamode & 2)) { - video_res_x /= 16; - video_res_y /= cga->crtc[9] + 1; - video_bpp = 0; - } else if (!(cga->cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else - video_bpp = 1; - } - cga->firstline = 1000; - cga->lastline = 0; - cga->cgablink++; - cga->oddeven ^= 1; - } - } else { - cga->sc++; - cga->sc &= 31; - cga->ma = cga->maback; - } - if (cga->cgadispon) - cga->cgastat &= ~1; - if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) - cga->con = 1; - if (cga->cgadispon && (cga->cgamode & 1)) { - for (x = 0; x < (cga->crtc[1] << 1); x++) - cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; - } + video_res_x = xsize; + video_res_y = ysize; + if (cga->cgamode & 1) { + video_res_x /= 8; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } else if (!(cga->cgamode & 2)) { + video_res_x /= 16; + video_res_y /= cga->crtc[9] + 1; + video_bpp = 0; + } else if (!(cga->cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else + video_bpp = 1; + } + cga->firstline = 1000; + cga->lastline = 0; + cga->cgablink++; + cga->oddeven ^= 1; + } + } else { + cga->sc++; + cga->sc &= 31; + cga->ma = cga->maback; + } + if (cga->cgadispon) + cga->cgastat &= ~1; + if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1)))) + cga->con = 1; + if (cga->cgadispon && (cga->cgamode & 1)) { + for (x = 0; x < (cga->crtc[1] << 1); x++) + cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)]; + } } } - void cga_init(cga_t *cga) { @@ -525,19 +494,18 @@ cga_init(cga_t *cga) cga->composite = 0; } - void * cga_standalone_init(const device_t *info) { - int display_type; + int display_type; cga_t *cga = malloc(sizeof(cga_t)); memset(cga, 0, sizeof(cga_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_cga); - display_type = device_get_config_int("display_type"); - cga->composite = (display_type != CGA_RGB); - cga->revision = device_get_config_int("composite_type"); + display_type = device_get_config_int("display_type"); + cga->composite = (display_type != CGA_RGB); + cga->revision = device_get_config_int("composite_type"); cga->snow_enabled = device_get_config_int("snow_enabled"); cga->vram = malloc(0x4000); @@ -550,13 +518,12 @@ cga_standalone_init(const device_t *info) overscan_x = overscan_y = 16; cga->rgb_type = device_get_config_int("rgb_type"); - cga_palette = (cga->rgb_type << 1); + cga_palette = (cga->rgb_type << 1); cgapal_rebuild(); return cga; } - void cga_close(void *p) { @@ -566,7 +533,6 @@ cga_close(void *p) free(cga); } - void cga_speed_changed(void *p) { @@ -659,15 +625,15 @@ const device_config_t cga_config[] = { // clang-format on const device_t cga_device = { - .name = "CGA", + .name = "CGA", .internal_name = "cga", - .flags = DEVICE_ISA, - .local = 0, - .init = cga_standalone_init, - .close = cga_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = cga_standalone_init, + .close = cga_close, + .reset = NULL, { .available = NULL }, .speed_changed = cga_speed_changed, - .force_redraw = NULL, - .config = cga_config + .force_redraw = NULL, + .config = cga_config }; diff --git a/src/video/vid_cga_comp.c b/src/video/vid_cga_comp.c index a0b5c08a8..077084000 100644 --- a/src/video/vid_cga_comp.c +++ b/src/video/vid_cga_comp.c @@ -29,14 +29,12 @@ #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> - int CGA_Composite_Table[1024]; - static double brightness = 0; -static double contrast = 100; +static double contrast = 100; static double saturation = 100; -static double sharpness = 0; +static double sharpness = 0; static double hue_offset = 0; /* New algorithm by reenigne @@ -45,6 +43,7 @@ static double hue_offset = 0; static const double tau = 6.28318531; /* == 2*pi */ static unsigned char chroma_multiplexer[256] = { + // clang-format off 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, 133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152, 2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5, @@ -60,12 +59,15 @@ static unsigned char chroma_multiplexer[256] = { 78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37, 252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200, 61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107, - 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252}; + 198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252 + // clang-format on +}; static double intensity[4] = { - 77.175381, 88.654656, 166.564623, 174.228438}; + 77.175381, 88.654656, 166.564623, 174.228438 +}; -#define NEW_CGA(c,i,r,g,b) (((c)/0.72)*0.29 + ((i)/0.28)*0.32 + ((r)/0.28)*0.1 + ((g)/0.28)*0.22 + ((b)/0.28)*0.07) +#define NEW_CGA(c, i, r, g, b) (((c) / 0.72) * 0.29 + ((i) / 0.28) * 0.32 + ((r) / 0.28) * 0.1 + ((g) / 0.28) * 0.22 + ((b) / 0.28) * 0.07) double mode_brightness; double mode_contrast; @@ -74,272 +76,291 @@ double min_v; double max_v; double video_ri, video_rq, video_gi, video_gq, video_bi, video_bq; -int video_sharpness; -int tandy_mode_control = 0; +int video_sharpness; +int tandy_mode_control = 0; static bool new_cga = 0; -void update_cga16_color(uint8_t cgamode) { - int x; - double c, i, v; - double q, a, s, r; - double iq_adjust_i, iq_adjust_q; - double i0, i3, mode_saturation; +void +update_cga16_color(uint8_t cgamode) +{ + int x; + double c, i, v; + double q, a, s, r; + double iq_adjust_i, iq_adjust_q; + double i0, i3, mode_saturation; - static const double ri = 0.9563; - static const double rq = 0.6210; - static const double gi = -0.2721; - static const double gq = -0.6474; - static const double bi = -1.1069; - static const double bq = 1.7046; + static const double ri = 0.9563; + static const double rq = 0.6210; + static const double gi = -0.2721; + static const double gq = -0.6474; + static const double bi = -1.1069; + static const double bq = 1.7046; - if (!new_cga) { - min_v = chroma_multiplexer[0] + intensity[0]; - max_v = chroma_multiplexer[255] + intensity[3]; + if (!new_cga) { + min_v = chroma_multiplexer[0] + intensity[0]; + max_v = chroma_multiplexer[255] + intensity[3]; + } else { + i0 = intensity[0]; + i3 = intensity[3]; + min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); + max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); + } + mode_contrast = 256 / (max_v - min_v); + mode_brightness = -min_v * mode_contrast; + if ((cgamode & 3) == 1) + mode_hue = 14; + else + mode_hue = 4; + + mode_contrast *= contrast * (new_cga ? 1.2 : 1) / 100; /* new CGA: 120% */ + mode_brightness += (new_cga ? brightness - 10 : brightness) * 5; /* new CGA: -10 */ + mode_saturation = (new_cga ? 4.35 : 2.9) * saturation / 100; /* new CGA: 150% */ + + for (x = 0; x < 1024; ++x) { + int phase = x & 3; + int right = (x >> 2) & 15; + int left = (x >> 6) & 15; + int rc = right; + int lc = left; + if ((cgamode & 4) != 0) { + rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); + lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); } + c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; + i = intensity[(left >> 3) | ((right >> 2) & 2)]; + if (!new_cga) + v = c + i; else { - i0 = intensity[0]; - i3 = intensity[3]; - min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); - max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); + double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)]; + double g = intensity[((left >> 1) & 1) | (right & 2)]; + double b = intensity[(left & 1) | ((right << 1) & 2)]; + v = NEW_CGA(c, i, r, g, b); } - mode_contrast = 256/(max_v - min_v); - mode_brightness = -min_v*mode_contrast; - if ((cgamode & 3) == 1) - mode_hue = 14; - else - mode_hue = 4; + CGA_Composite_Table[x] = (int) (v * mode_contrast + mode_brightness); + } - mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; /* new CGA: 120% */ - mode_brightness += (new_cga ? brightness-10 : brightness)*5; /* new CGA: -10 */ - mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; /* new CGA: 150% */ + i = CGA_Composite_Table[6 * 68] - CGA_Composite_Table[6 * 68 + 2]; + q = CGA_Composite_Table[6 * 68 + 1] - CGA_Composite_Table[6 * 68 + 3]; - for (x = 0; x < 1024; ++x) { - int phase = x & 3; - int right = (x >> 2) & 15; - int left = (x >> 6) & 15; - int rc = right; - int lc = left; - if ((cgamode & 4) != 0) { - rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); - lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); - } - c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; - i = intensity[(left >> 3) | ((right >> 2) & 2)]; - if (!new_cga) - v = c + i; - else { - double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)]; - double g = intensity[((left >> 1) & 1) | (right & 2)]; - double b = intensity[(left & 1) | ((right << 1) & 2)]; - v = NEW_CGA(c, i, r, g, b); - } - CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness); - } + a = tau * (33 + 90 + hue_offset + mode_hue) / 360.0; + c = cos(a); + s = sin(a); + r = 256 * mode_saturation / sqrt(i * i + q * q); - i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2]; - q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3]; + iq_adjust_i = -(i * c + q * s) * r; + iq_adjust_q = (q * c - i * s) * r; - a = tau*(33 + 90 + hue_offset + mode_hue)/360.0; - c = cos(a); - s = sin(a); - r = 256*mode_saturation/sqrt(i*i+q*q); - - iq_adjust_i = -(i*c + q*s)*r; - iq_adjust_q = (q*c - i*s)*r; - - video_ri = (int) (ri*iq_adjust_i + rq*iq_adjust_q); - video_rq = (int) (-ri*iq_adjust_q + rq*iq_adjust_i); - video_gi = (int) (gi*iq_adjust_i + gq*iq_adjust_q); - video_gq = (int) (-gi*iq_adjust_q + gq*iq_adjust_i); - video_bi = (int) (bi*iq_adjust_i + bq*iq_adjust_q); - video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i); - video_sharpness = (int) (sharpness*256/100); + video_ri = (int) (ri * iq_adjust_i + rq * iq_adjust_q); + video_rq = (int) (-ri * iq_adjust_q + rq * iq_adjust_i); + video_gi = (int) (gi * iq_adjust_i + gq * iq_adjust_q); + video_gq = (int) (-gi * iq_adjust_q + gq * iq_adjust_i); + video_bi = (int) (bi * iq_adjust_i + bq * iq_adjust_q); + video_bq = (int) (-bi * iq_adjust_q + bq * iq_adjust_i); + video_sharpness = (int) (sharpness * 256 / 100); } -static Bit8u byte_clamp(int v) { - v >>= 13; - return v < 0 ? 0 : (v > 255 ? 255 : v); +static Bit8u +byte_clamp(int v) +{ + v >>= 13; + return v < 0 ? 0 : (v > 255 ? 255 : v); } /* 2048x1536 is the maximum we can possibly support. */ #define SCALER_MAXWIDTH 2048 -static int temp[SCALER_MAXWIDTH + 10]={0}; -static int atemp[SCALER_MAXWIDTH + 2]={0}; -static int btemp[SCALER_MAXWIDTH + 2]={0}; +static int temp[SCALER_MAXWIDTH + 10] = { 0 }; +static int atemp[SCALER_MAXWIDTH + 2] = { 0 }; +static int btemp[SCALER_MAXWIDTH + 2] = { 0 }; -Bit32u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit32u *TempLine) +Bit32u * +Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewidth*/, Bit32u *TempLine) { - int x; - Bit32u x2; + int x; + Bit32u x2; - int w = blocks*4; + int w = blocks * 4; - int *o; - Bit32u *rgbi; - int *b; - int *i; - Bit32u* srgb; - int *ap, *bp; + int *o; + Bit32u *rgbi; + int *b; + int *i; + Bit32u *srgb; + int *ap, *bp; -#define COMPOSITE_CONVERT(I, Q) do { \ - i[1] = (i[1]<<3) - ap[1]; \ - a = ap[0]; \ - b = bp[0]; \ - c = i[0]+i[0]; \ - d = i[-1]+i[1]; \ - y = ((c+d)<<8) + video_sharpness*(c-d); \ - rr = y + video_ri*(I) + video_rq*(Q); \ - gg = y + video_gi*(I) + video_gq*(Q); \ - bb = y + video_bi*(I) + video_bq*(Q); \ - ++i; \ - ++ap; \ - ++bp; \ - *srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \ - ++srgb; \ -} while (0) +#define COMPOSITE_CONVERT(I, Q) \ + do { \ + i[1] = (i[1] << 3) - ap[1]; \ + a = ap[0]; \ + b = bp[0]; \ + c = i[0] + i[0]; \ + d = i[-1] + i[1]; \ + y = ((c + d) << 8) + video_sharpness * (c - d); \ + rr = y + video_ri * (I) + video_rq * (Q); \ + gg = y + video_gi * (I) + video_gq * (Q); \ + bb = y + video_bi * (I) + video_bq * (Q); \ + ++i; \ + ++ap; \ + ++bp; \ + *srgb = (byte_clamp(rr) << 16) | (byte_clamp(gg) << 8) | byte_clamp(bb); \ + ++srgb; \ + } while (0) -#define OUT(v) do { *o = (v); ++o; } while (0) +#define OUT(v) \ + do { \ + *o = (v); \ + ++o; \ + } while (0) - /* Simulate CGA composite output */ - o = temp; - rgbi = TempLine; - b = &CGA_Composite_Table[border*68]; - for (x = 0; x < 4; ++x) - OUT(b[(x+3)&3]); - OUT(CGA_Composite_Table[(border<<6) | ((*rgbi & 0x0f)<<2) | 3]); - for (x = 0; x < w-1; ++x) { - OUT(CGA_Composite_Table[((rgbi[0] & 0x0f)<<6) | ((rgbi[1] & 0x0f)<<2) | (x&3)]); - ++rgbi; + /* Simulate CGA composite output */ + o = temp; + rgbi = TempLine; + b = &CGA_Composite_Table[border * 68]; + for (x = 0; x < 4; ++x) + OUT(b[(x + 3) & 3]); + OUT(CGA_Composite_Table[(border << 6) | ((*rgbi & 0x0f) << 2) | 3]); + for (x = 0; x < w - 1; ++x) { + OUT(CGA_Composite_Table[((rgbi[0] & 0x0f) << 6) | ((rgbi[1] & 0x0f) << 2) | (x & 3)]); + ++rgbi; + } + OUT(CGA_Composite_Table[((*rgbi & 0x0f) << 6) | (border << 2) | 3]); + for (x = 0; x < 5; ++x) + OUT(b[x & 3]); + + if ((cgamode & 4) != 0) { + /* Decode */ + i = temp + 5; + srgb = (Bit32u *) TempLine; + for (x2 = 0; x2 < blocks * 4; ++x2) { + int c = (i[0] + i[0]) << 3; + int d = (i[-1] + i[1]) << 3; + int y = ((c + d) << 8) + video_sharpness * (c - d); + ++i; + *srgb = byte_clamp(y) * 0x10101; + ++srgb; } - OUT(CGA_Composite_Table[((*rgbi & 0x0f)<<6) | (border<<2) | 3]); - for (x = 0; x < 5; ++x) - OUT(b[x&3]); - - if ((cgamode & 4) != 0) { - /* Decode */ - i = temp + 5; - srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks*4; ++x2) { - int c = (i[0]+i[0])<<3; - int d = (i[-1]+i[1])<<3; - int y = ((c+d)<<8) + video_sharpness*(c-d); - ++i; - *srgb = byte_clamp(y)*0x10101; - ++srgb; - } + } else { + /* Store chroma */ + i = temp + 4; + ap = atemp + 1; + bp = btemp + 1; + for (x = -1; x < w + 1; ++x) { + ap[x] = i[-4] - ((i[-2] - i[0] + i[2]) << 1) + i[4]; + bp[x] = (i[-3] - i[-1] + i[1] - i[3]) << 1; + ++i; } - else { - /* Store chroma */ - i = temp + 4; - ap = atemp + 1; - bp = btemp + 1; - for (x = -1; x < w + 1; ++x) { - ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4]; - bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1; - ++i; - } - /* Decode */ - i = temp + 5; - i[-1] = (i[-1]<<3) - ap[-1]; - i[0] = (i[0]<<3) - ap[0]; - srgb = (Bit32u *)TempLine; - for (x2 = 0; x2 < blocks; ++x2) { - int y,a,b,c,d,rr,gg,bb; - COMPOSITE_CONVERT(a, b); - COMPOSITE_CONVERT(-b, a); - COMPOSITE_CONVERT(-a, -b); - COMPOSITE_CONVERT(b, -a); - } + /* Decode */ + i = temp + 5; + i[-1] = (i[-1] << 3) - ap[-1]; + i[0] = (i[0] << 3) - ap[0]; + srgb = (Bit32u *) TempLine; + for (x2 = 0; x2 < blocks; ++x2) { + int y, a, b, c, d, rr, gg, bb; + COMPOSITE_CONVERT(a, b); + COMPOSITE_CONVERT(-b, a); + COMPOSITE_CONVERT(-a, -b); + COMPOSITE_CONVERT(b, -a); } + } #undef COMPOSITE_CONVERT #undef OUT - return TempLine; + return TempLine; } -void IncreaseHue(uint8_t cgamode) +void +IncreaseHue(uint8_t cgamode) { - hue_offset += 5.0; + hue_offset += 5.0; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void DecreaseHue(uint8_t cgamode) +void +DecreaseHue(uint8_t cgamode) { - hue_offset -= 5.0; + hue_offset -= 5.0; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void IncreaseSaturation(uint8_t cgamode) +void +IncreaseSaturation(uint8_t cgamode) { - saturation += 5; + saturation += 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void DecreaseSaturation(uint8_t cgamode) +void +DecreaseSaturation(uint8_t cgamode) { - saturation -= 5; + saturation -= 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void IncreaseContrast(uint8_t cgamode) +void +IncreaseContrast(uint8_t cgamode) { - contrast += 5; + contrast += 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void DecreaseContrast(uint8_t cgamode) +void +DecreaseContrast(uint8_t cgamode) { - contrast -= 5; + contrast -= 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void IncreaseBrightness(uint8_t cgamode) +void +IncreaseBrightness(uint8_t cgamode) { - brightness += 5; + brightness += 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void DecreaseBrightness(uint8_t cgamode) +void +DecreaseBrightness(uint8_t cgamode) { - brightness -= 5; + brightness -= 5; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void IncreaseSharpness(uint8_t cgamode) +void +IncreaseSharpness(uint8_t cgamode) { - sharpness += 10; + sharpness += 10; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void DecreaseSharpness(uint8_t cgamode) +void +DecreaseSharpness(uint8_t cgamode) { - sharpness -= 10; + sharpness -= 10; - update_cga16_color(cgamode); + update_cga16_color(cgamode); } -void cga_comp_init(int revision) +void +cga_comp_init(int revision) { - new_cga = revision; + new_cga = revision; - /* Making sure this gets reset after reset. */ - brightness = 0; - contrast = 100; - saturation = 100; - sharpness = 0; - hue_offset = 0; + /* Making sure this gets reset after reset. */ + brightness = 0; + contrast = 100; + saturation = 100; + sharpness = 0; + hue_offset = 0; - update_cga16_color(0); + update_cga16_color(0); } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index cea6ee807..16839d93a 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -40,63 +40,63 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define BIOS_GD5401_PATH "roms/video/cirruslogic/avga1.rom" -#define BIOS_GD5402_PATH "roms/video/cirruslogic/avga2.rom" -#define BIOS_GD5402_ONBOARD_PATH "roms/machines/cmdsl386sx25/c000.rom" -#define BIOS_GD5420_PATH "roms/video/cirruslogic/5420.vbi" -#define BIOS_GD5422_PATH "roms/video/cirruslogic/cl5422.bin" -#define BIOS_GD5426_DIAMOND_A1_ISA_PATH "roms/video/cirruslogic/diamond5426.vbi" -#define BIOS_GD5426_MCA_PATH "roms/video/cirruslogic/Reply.BIN" -#define BIOS_GD5428_DIAMOND_B1_VLB_PATH "roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" -#define BIOS_GD5428_ISA_PATH "roms/video/cirruslogic/5428.bin" -#define BIOS_GD5428_MCA_PATH "roms/video/cirruslogic/SVGA141.ROM" -#define BIOS_GD5428_PATH "roms/video/cirruslogic/vlbusjapan.BIN" -#define BIOS_GD5428_BOCA_ISA_PATH_1 "roms/video/cirruslogic/boca_gd5428_1.30b_1.bin" -#define BIOS_GD5428_BOCA_ISA_PATH_2 "roms/video/cirruslogic/boca_gd5428_1.30b_2.bin" -#define BIOS_GD5429_PATH "roms/video/cirruslogic/5429.vbi" -#define BIOS_GD5430_DIAMOND_A8_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin" -#define BIOS_GD5430_ORCHID_VLB_PATH "roms/video/cirruslogic/orchidvlbus.bin" -#define BIOS_GD5430_PATH "roms/video/cirruslogic/pci.bin" -#define BIOS_GD5434_DIAMOND_A3_ISA_PATH "roms/video/cirruslogic/Diamond Multimedia SpeedStar 64 v2.02 EPROM Backup from ST M27C256B-12F1.BIN" -#define BIOS_GD5434_PATH "roms/video/cirruslogic/gd5434.BIN" -#define BIOS_GD5436_PATH "roms/video/cirruslogic/5436.vbi" -#define BIOS_GD5440_PATH "roms/video/cirruslogic/BIOS.BIN" -#define BIOS_GD5446_PATH "roms/video/cirruslogic/5446bv.vbi" -#define BIOS_GD5446_STB_PATH "roms/video/cirruslogic/stb nitro64v.BIN" -#define BIOS_GD5480_PATH "roms/video/cirruslogic/clgd5480.rom" +#define BIOS_GD5401_PATH "roms/video/cirruslogic/avga1.rom" +#define BIOS_GD5402_PATH "roms/video/cirruslogic/avga2.rom" +#define BIOS_GD5402_ONBOARD_PATH "roms/machines/cmdsl386sx25/c000.rom" +#define BIOS_GD5420_PATH "roms/video/cirruslogic/5420.vbi" +#define BIOS_GD5422_PATH "roms/video/cirruslogic/cl5422.bin" +#define BIOS_GD5426_DIAMOND_A1_ISA_PATH "roms/video/cirruslogic/diamond5426.vbi" +#define BIOS_GD5426_MCA_PATH "roms/video/cirruslogic/Reply.BIN" +#define BIOS_GD5428_DIAMOND_B1_VLB_PATH "roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin" +#define BIOS_GD5428_ISA_PATH "roms/video/cirruslogic/5428.bin" +#define BIOS_GD5428_MCA_PATH "roms/video/cirruslogic/SVGA141.ROM" +#define BIOS_GD5428_PATH "roms/video/cirruslogic/vlbusjapan.BIN" +#define BIOS_GD5428_BOCA_ISA_PATH_1 "roms/video/cirruslogic/boca_gd5428_1.30b_1.bin" +#define BIOS_GD5428_BOCA_ISA_PATH_2 "roms/video/cirruslogic/boca_gd5428_1.30b_2.bin" +#define BIOS_GD5429_PATH "roms/video/cirruslogic/5429.vbi" +#define BIOS_GD5430_DIAMOND_A8_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin" +#define BIOS_GD5430_ORCHID_VLB_PATH "roms/video/cirruslogic/orchidvlbus.bin" +#define BIOS_GD5430_PATH "roms/video/cirruslogic/pci.bin" +#define BIOS_GD5434_DIAMOND_A3_ISA_PATH "roms/video/cirruslogic/Diamond Multimedia SpeedStar 64 v2.02 EPROM Backup from ST M27C256B-12F1.BIN" +#define BIOS_GD5434_PATH "roms/video/cirruslogic/gd5434.BIN" +#define BIOS_GD5436_PATH "roms/video/cirruslogic/5436.vbi" +#define BIOS_GD5440_PATH "roms/video/cirruslogic/BIOS.BIN" +#define BIOS_GD5446_PATH "roms/video/cirruslogic/5446bv.vbi" +#define BIOS_GD5446_STB_PATH "roms/video/cirruslogic/stb nitro64v.BIN" +#define BIOS_GD5480_PATH "roms/video/cirruslogic/clgd5480.rom" -#define CIRRUS_ID_CLGD5401 0x88 -#define CIRRUS_ID_CLGD5402 0x89 -#define CIRRUS_ID_CLGD5420 0x8a -#define CIRRUS_ID_CLGD5422 0x8c -#define CIRRUS_ID_CLGD5424 0x94 -#define CIRRUS_ID_CLGD5426 0x90 -#define CIRRUS_ID_CLGD5428 0x98 -#define CIRRUS_ID_CLGD5429 0x9c -#define CIRRUS_ID_CLGD5430 0xa0 -#define CIRRUS_ID_CLGD5432 0xa2 -#define CIRRUS_ID_CLGD5434_4 0xa4 -#define CIRRUS_ID_CLGD5434 0xa8 -#define CIRRUS_ID_CLGD5436 0xac -#define CIRRUS_ID_CLGD5440 0xa0 /* Yes, the 5440 has the same ID as the 5430. */ -#define CIRRUS_ID_CLGD5446 0xb8 -#define CIRRUS_ID_CLGD5480 0xbc +#define CIRRUS_ID_CLGD5401 0x88 +#define CIRRUS_ID_CLGD5402 0x89 +#define CIRRUS_ID_CLGD5420 0x8a +#define CIRRUS_ID_CLGD5422 0x8c +#define CIRRUS_ID_CLGD5424 0x94 +#define CIRRUS_ID_CLGD5426 0x90 +#define CIRRUS_ID_CLGD5428 0x98 +#define CIRRUS_ID_CLGD5429 0x9c +#define CIRRUS_ID_CLGD5430 0xa0 +#define CIRRUS_ID_CLGD5432 0xa2 +#define CIRRUS_ID_CLGD5434_4 0xa4 +#define CIRRUS_ID_CLGD5434 0xa8 +#define CIRRUS_ID_CLGD5436 0xac +#define CIRRUS_ID_CLGD5440 0xa0 /* Yes, the 5440 has the same ID as the 5430. */ +#define CIRRUS_ID_CLGD5446 0xb8 +#define CIRRUS_ID_CLGD5480 0xbc /* sequencer 0x07 */ -#define CIRRUS_SR7_BPP_VGA 0x00 -#define CIRRUS_SR7_BPP_SVGA 0x01 -#define CIRRUS_SR7_BPP_MASK 0x0e -#define CIRRUS_SR7_BPP_8 0x00 -#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 -#define CIRRUS_SR7_BPP_24 0x04 -#define CIRRUS_SR7_BPP_16 0x06 -#define CIRRUS_SR7_BPP_32 0x08 -#define CIRRUS_SR7_ISAADDR_MASK 0xe0 +#define CIRRUS_SR7_BPP_VGA 0x00 +#define CIRRUS_SR7_BPP_SVGA 0x01 +#define CIRRUS_SR7_BPP_MASK 0x0e +#define CIRRUS_SR7_BPP_8 0x00 +#define CIRRUS_SR7_BPP_16_DOUBLEVCLK 0x02 +#define CIRRUS_SR7_BPP_24 0x04 +#define CIRRUS_SR7_BPP_16 0x06 +#define CIRRUS_SR7_BPP_32 0x08 +#define CIRRUS_SR7_ISAADDR_MASK 0xe0 /* sequencer 0x12 */ -#define CIRRUS_CURSOR_SHOW 0x01 -#define CIRRUS_CURSOR_HIDDENPEL 0x02 -#define CIRRUS_CURSOR_LARGE 0x04 /* 64x64 if set, 32x32 if clear */ +#define CIRRUS_CURSOR_SHOW 0x01 +#define CIRRUS_CURSOR_HIDDENPEL 0x02 +#define CIRRUS_CURSOR_LARGE 0x04 /* 64x64 if set, 32x32 if clear */ /* sequencer 0x17 */ #define CIRRUS_BUSTYPE_VLBFAST 0x10 @@ -104,34 +104,34 @@ #define CIRRUS_BUSTYPE_VLBSLOW 0x30 #define CIRRUS_BUSTYPE_ISA 0x38 #define CIRRUS_MMIO_ENABLE 0x04 -#define CIRRUS_MMIO_USE_PCIADDR 0x40 /* 0xb8000 if cleared. */ +#define CIRRUS_MMIO_USE_PCIADDR 0x40 /* 0xb8000 if cleared. */ #define CIRRUS_MEMSIZEEXT_DOUBLE 0x80 /* control 0x0b */ -#define CIRRUS_BANKING_DUAL 0x01 -#define CIRRUS_BANKING_GRANULARITY_16K 0x20 /* set:16k, clear:4k */ +#define CIRRUS_BANKING_DUAL 0x01 +#define CIRRUS_BANKING_GRANULARITY_16K 0x20 /* set:16k, clear:4k */ /* control 0x30 */ -#define CIRRUS_BLTMODE_BACKWARDS 0x01 -#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 -#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 -#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 -#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 -#define CIRRUS_BLTMODE_COLOREXPAND 0x80 -#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 -#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 -#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 -#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 -#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 +#define CIRRUS_BLTMODE_BACKWARDS 0x01 +#define CIRRUS_BLTMODE_MEMSYSDEST 0x02 +#define CIRRUS_BLTMODE_MEMSYSSRC 0x04 +#define CIRRUS_BLTMODE_TRANSPARENTCOMP 0x08 +#define CIRRUS_BLTMODE_PATTERNCOPY 0x40 +#define CIRRUS_BLTMODE_COLOREXPAND 0x80 +#define CIRRUS_BLTMODE_PIXELWIDTHMASK 0x30 +#define CIRRUS_BLTMODE_PIXELWIDTH8 0x00 +#define CIRRUS_BLTMODE_PIXELWIDTH16 0x10 +#define CIRRUS_BLTMODE_PIXELWIDTH24 0x20 +#define CIRRUS_BLTMODE_PIXELWIDTH32 0x30 /* control 0x31 */ -#define CIRRUS_BLT_BUSY 0x01 -#define CIRRUS_BLT_START 0x02 -#define CIRRUS_BLT_RESET 0x04 -#define CIRRUS_BLT_FIFOUSED 0x10 -#define CIRRUS_BLT_PAUSED 0x20 -#define CIRRUS_BLT_APERTURE2 0x40 -#define CIRRUS_BLT_AUTOSTART 0x80 +#define CIRRUS_BLT_BUSY 0x01 +#define CIRRUS_BLT_START 0x02 +#define CIRRUS_BLT_RESET 0x04 +#define CIRRUS_BLT_FIFOUSED 0x10 +#define CIRRUS_BLT_PAUSED 0x20 +#define CIRRUS_BLT_APERTURE2 0x40 +#define CIRRUS_BLT_AUTOSTART 0x80 /* control 0x33 */ #define CIRRUS_BLTMODEEXT_BACKGROUNDONLY 0x08 @@ -139,104 +139,101 @@ #define CIRRUS_BLTMODEEXT_COLOREXPINV 0x02 #define CIRRUS_BLTMODEEXT_DWORDGRANULARITY 0x01 -#define CL_GD5428_SYSTEM_BUS_MCA 5 -#define CL_GD5428_SYSTEM_BUS_VESA 6 -#define CL_GD5428_SYSTEM_BUS_ISA 7 +#define CL_GD5428_SYSTEM_BUS_MCA 5 +#define CL_GD5428_SYSTEM_BUS_VESA 6 +#define CL_GD5428_SYSTEM_BUS_ISA 7 -#define CL_GD5429_SYSTEM_BUS_VESA 5 -#define CL_GD5429_SYSTEM_BUS_ISA 7 +#define CL_GD5429_SYSTEM_BUS_VESA 5 +#define CL_GD5429_SYSTEM_BUS_ISA 7 -#define CL_GD543X_SYSTEM_BUS_PCI 4 -#define CL_GD543X_SYSTEM_BUS_VESA 6 -#define CL_GD543X_SYSTEM_BUS_ISA 7 +#define CL_GD543X_SYSTEM_BUS_PCI 4 +#define CL_GD543X_SYSTEM_BUS_VESA 6 +#define CL_GD543X_SYSTEM_BUS_ISA 7 -typedef struct gd54xx_t -{ - mem_mapping_t mmio_mapping; - mem_mapping_t linear_mapping; - mem_mapping_t aperture2_mapping; - mem_mapping_t vgablt_mapping; +typedef struct gd54xx_t { + mem_mapping_t mmio_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t aperture2_mapping; + mem_mapping_t vgablt_mapping; - svga_t svga; + svga_t svga; - int has_bios, rev, - bit32; - rom_t bios_rom; + int has_bios, rev, + bit32; + rom_t bios_rom; - uint32_t vram_size; - uint32_t vram_mask; + uint32_t vram_size; + uint32_t vram_mask; - uint8_t vclk_n[4]; - uint8_t vclk_d[4]; + uint8_t vclk_n[4]; + uint8_t vclk_d[4]; struct { - uint8_t state; - int ctrl; + uint8_t state; + int ctrl; } ramdac; struct { - uint16_t width, height; - uint16_t dst_pitch, src_pitch; - uint16_t trans_col, trans_mask; - uint16_t height_internal; - uint16_t msd_buf_pos, msd_buf_cnt; + uint16_t width, height; + uint16_t dst_pitch, src_pitch; + uint16_t trans_col, trans_mask; + uint16_t height_internal; + uint16_t msd_buf_pos, msd_buf_cnt; - uint8_t status; - uint8_t mask, mode, rop, modeext; - uint8_t ms_is_dest, msd_buf[32]; + uint8_t status; + uint8_t mask, mode, rop, modeext; + uint8_t ms_is_dest, msd_buf[32]; - uint32_t fg_col, bg_col; - uint32_t dst_addr_backup, src_addr_backup; - uint32_t dst_addr, src_addr; - uint32_t sys_src32, sys_cnt; + uint32_t fg_col, bg_col; + uint32_t dst_addr_backup, src_addr_backup; + uint32_t dst_addr, src_addr; + uint32_t sys_src32, sys_cnt; - /* Internal state */ - int pixel_width, pattern_x; - int x_count, y_count; - int xx_count, dir; - int unlock_special; + /* Internal state */ + int pixel_width, pattern_x; + int x_count, y_count; + int xx_count, dir; + int unlock_special; } blt; struct { - int mode; - uint16_t stride, r1sz, r1adjust, r2sz, - r2adjust, r2sdz, wvs, wve, - hzoom, vzoom; - uint8_t occlusion, colorkeycomparemask, - colorkeycompare; - int region1size, region2size, - colorkeymode; - uint32_t ck; + int mode; + uint16_t stride, r1sz, r1adjust, r2sz, + r2adjust, r2sdz, wvs, wve, + hzoom, vzoom; + uint8_t occlusion, colorkeycomparemask, + colorkeycompare; + int region1size, region2size, + colorkeymode; + uint32_t ck; } overlay; - int pci, vlb, mca, countminusone; - int vblank_irq, vportsync; + int pci, vlb, mca, countminusone; + int vblank_irq, vportsync; - uint8_t pci_regs[256]; - uint8_t int_line, unlocked, status, extensions; - uint8_t crtcreg_mask; + uint8_t pci_regs[256]; + uint8_t int_line, unlocked, status, extensions; + uint8_t crtcreg_mask; - uint8_t fc; /* Feature Connector */ + uint8_t fc; /* Feature Connector */ - int card, id; + int card, id; - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; - uint32_t lfb_base, vgablt_base; + uint32_t lfb_base, vgablt_base; - int mmio_vram_overlap; + int mmio_vram_overlap; - uint32_t extpallook[256]; - PALETTE extpal; + uint32_t extpallook[256]; + PALETTE extpal; - void *i2c, *ddc; + void *i2c, *ddc; } gd54xx_t; - -static video_timings_t timing_gd54xx_isa = {VIDEO_ISA, 3, 3, 6, 8, 8, 12}; -static video_timings_t timing_gd54xx_vlb = {VIDEO_BUS, 4, 4, 8, 10, 10, 20}; -static video_timings_t timing_gd54xx_pci = {VIDEO_PCI, 4, 4, 8, 10, 10, 20}; - +static video_timings_t timing_gd54xx_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 }; +static video_timings_t timing_gd54xx_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 8, .read_b = 10, .read_w = 10, .read_l = 20 }; +static video_timings_t timing_gd54xx_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 8, .read_b = 10, .read_w = 10, .read_l = 20 }; static void gd543x_mmio_write(uint32_t addr, uint8_t val, void *p); @@ -264,225 +261,207 @@ gd54xx_reset_blit(gd54xx_t *gd54xx); static void gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *svga); +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) - -#define DECODE_YCbCr() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - \ - y1 = src[0]; \ - Cr = src[1] - 0x80; \ - y2 = src[2]; \ - Cb = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) +#define DECODE_YCbCr() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) /*Both YUV formats are untested*/ -#define DECODE_YUV211() \ - do \ - { \ - uint8_t y1, y2, y3, y4; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - y2 = (298 * (src[2] - 16)) >> 8; \ - V = src[3] - 0x80; \ - y3 = (298 * (src[4] - 16)) >> 8; \ - y4 = (298 * (src[5] - 16)) >> 8; \ - src += 6; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - r[x_write+2] = y3 + dR; \ - CLAMP(r[x_write+2]); \ - g[x_write+2] = y3 - dG; \ - CLAMP(g[x_write+2]); \ - b[x_write+2] = y3 + dB; \ - CLAMP(b[x_write+2]); \ - \ - r[x_write+3] = y4 + dR; \ - CLAMP(r[x_write+3]); \ - g[x_write+3] = y4 - dG; \ - CLAMP(g[x_write+3]); \ - b[x_write+3] = y4 + dB; \ - CLAMP(b[x_write+3]); \ - \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_YUV211() \ + do { \ + uint8_t y1, y2, y3, y4; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + y2 = (298 * (src[2] - 16)) >> 8; \ + V = src[3] - 0x80; \ + y3 = (298 * (src[4] - 16)) >> 8; \ + y4 = (298 * (src[5] - 16)) >> 8; \ + src += 6; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + r[x_write + 2] = y3 + dR; \ + CLAMP(r[x_write + 2]); \ + g[x_write + 2] = y3 - dG; \ + CLAMP(g[x_write + 2]); \ + b[x_write + 2] = y3 + dB; \ + CLAMP(b[x_write + 2]); \ + \ + r[x_write + 3] = y4 + dR; \ + CLAMP(r[x_write + 3]); \ + g[x_write + 3] = y4 - dG; \ + CLAMP(g[x_write + 3]); \ + b[x_write + 3] = y4 + dB; \ + CLAMP(b[x_write + 3]); \ + \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_YUV422() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - V = src[2] - 0x80; \ - y2 = (298 * (src[3] - 16)) >> 8; \ - src += 4; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) +#define DECODE_YUV422() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + V = src[2] - 0x80; \ + y2 = (298 * (src[3] - 16)) >> 8; \ + src += 4; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) -#define DECODE_RGB555() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ - b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB555() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *) src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ + b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_RGB565() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ - b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB565() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *) src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ + b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_CLUT() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint8_t dat; \ - \ - dat = *(uint8_t *)src; \ - src++; \ - \ - r[x_write + c] = svga->pallook[dat] >> 0; \ - g[x_write + c] = svga->pallook[dat] >> 8; \ - b[x_write + c] = svga->pallook[dat] >> 16; \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) - - - -#define OVERLAY_SAMPLE() \ - do \ - { \ - switch (gd54xx->overlay.mode) \ - { \ - case 0: \ - DECODE_YUV422(); \ - break; \ - case 2: \ - DECODE_CLUT(); \ - break; \ - case 3: \ - DECODE_YUV211(); \ - break; \ - case 4: \ - DECODE_RGB555(); \ - break; \ - case 5: \ - DECODE_RGB565(); \ - break; \ - } \ - } while (0) +#define DECODE_CLUT() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint8_t dat; \ + \ + dat = *(uint8_t *) src; \ + src++; \ + \ + r[x_write + c] = svga->pallook[dat] >> 0; \ + g[x_write + c] = svga->pallook[dat] >> 8; \ + b[x_write + c] = svga->pallook[dat] >> 16; \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) +#define OVERLAY_SAMPLE() \ + do { \ + switch (gd54xx->overlay.mode) { \ + case 0: \ + DECODE_YUV422(); \ + break; \ + case 2: \ + DECODE_CLUT(); \ + break; \ + case 3: \ + DECODE_YUV211(); \ + break; \ + case 4: \ + DECODE_RGB555(); \ + break; \ + case 5: \ + DECODE_RGB565(); \ + break; \ + } \ + } while (0) static int gd54xx_interrupt_enabled(gd54xx_t *gd54xx) @@ -490,22 +469,19 @@ gd54xx_interrupt_enabled(gd54xx_t *gd54xx) return !gd54xx->pci || (gd54xx->svga.gdcreg[0x17] & 0x04); } - static int gd54xx_vga_vsync_enabled(gd54xx_t *gd54xx) { - if (!(gd54xx->svga.crtc[0x11] & 0x20) && (gd54xx->svga.crtc[0x11] & 0x10) && - gd54xx_interrupt_enabled(gd54xx)) + if (!(gd54xx->svga.crtc[0x11] & 0x20) && (gd54xx->svga.crtc[0x11] & 0x10) && gd54xx_interrupt_enabled(gd54xx)) return 1; return 0; } - static void gd54xx_update_irqs(gd54xx_t *gd54xx) { if (!gd54xx->pci) - return; + return; if ((gd54xx->vblank_irq > 0) && gd54xx_vga_vsync_enabled(gd54xx)) pci_set_irq(gd54xx->card, PCI_INTA); @@ -513,94 +489,89 @@ gd54xx_update_irqs(gd54xx_t *gd54xx) pci_clear_irq(gd54xx->card, PCI_INTA); } - static void gd54xx_vblank_start(svga_t *svga) { - gd54xx_t *gd54xx = (gd54xx_t*) svga->p; + gd54xx_t *gd54xx = (gd54xx_t *) svga->p; if (gd54xx->vblank_irq >= 0) { gd54xx->vblank_irq = 1; gd54xx_update_irqs(gd54xx); } } - /* Returns 1 if the card is a 5422+ */ static int gd54xx_is_5422(svga_t *svga) { if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) - return 1; + return 1; else - return 0; + return 0; } - static void gd54xx_overlay_draw(svga_t *svga, int displine) { gd54xx_t *gd54xx = (gd54xx_t *) svga->p; - int shift = (svga->crtc[0x27] >= CIRRUS_ID_CLGD5446) ? 2 : 0; - int h_acc = svga->overlay_latch.h_acc; - int r[8], g[8], b[8]; - int x_read = 4, x_write = 4; - int x; + int shift = (svga->crtc[0x27] >= CIRRUS_ID_CLGD5446) ? 2 : 0; + int h_acc = svga->overlay_latch.h_acc; + int r[8], g[8], b[8]; + int x_read = 4, x_write = 4; + int x; uint32_t *p; - uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask]; - int bpp = svga->bpp; - int bytesperpix = (bpp + 7) / 8; - uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; - int occl, ckval; + uint8_t *src = &svga->vram[(svga->overlay_latch.addr << shift) & svga->vram_mask]; + int bpp = svga->bpp; + int bytesperpix = (bpp + 7) / 8; + uint8_t *src2 = &svga->vram[(svga->ma - (svga->hdisp * bytesperpix)) & svga->vram_display_mask]; + int occl, ckval; - p = &((uint32_t *)buffer32->line[displine])[gd54xx->overlay.region1size + svga->x_add]; + p = &((uint32_t *) buffer32->line[displine])[gd54xx->overlay.region1size + svga->x_add]; src2 += gd54xx->overlay.region1size * bytesperpix; OVERLAY_SAMPLE(); - for (x = 0; (x < gd54xx->overlay.region2size) && - ((x + gd54xx->overlay.region1size) < svga->hdisp); x++) { - if (gd54xx->overlay.occlusion) { - occl = 1; - ckval = gd54xx->overlay.ck; - if (bytesperpix == 1) { - if (*src2 == ckval) - occl = 0; - } else if (bytesperpix == 2) { - if (*((uint16_t*)src2) == ckval) - occl = 0; - } else - occl = 0; - if (!occl) - *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - src2 += bytesperpix; - } else - *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); + for (x = 0; (x < gd54xx->overlay.region2size) && ((x + gd54xx->overlay.region1size) < svga->hdisp); x++) { + if (gd54xx->overlay.occlusion) { + occl = 1; + ckval = gd54xx->overlay.ck; + if (bytesperpix == 1) { + if (*src2 == ckval) + occl = 0; + } else if (bytesperpix == 2) { + if (*((uint16_t *) src2) == ckval) + occl = 0; + } else + occl = 0; + if (!occl) + *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); + src2 += bytesperpix; + } else + *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - h_acc += gd54xx->overlay.hzoom; - if (h_acc >= 256) { - if ((x_read ^ (x_read + 1)) & ~3) - OVERLAY_SAMPLE(); - x_read = (x_read + 1) & 7; + h_acc += gd54xx->overlay.hzoom; + if (h_acc >= 256) { + if ((x_read ^ (x_read + 1)) & ~3) + OVERLAY_SAMPLE(); + x_read = (x_read + 1) & 7; - h_acc -= 256; - } + h_acc -= 256; + } } svga->overlay_latch.v_acc += gd54xx->overlay.vzoom; if (svga->overlay_latch.v_acc >= 256) { - svga->overlay_latch.v_acc -= 256; - svga->overlay_latch.addr += svga->overlay.pitch << 1; + svga->overlay_latch.v_acc -= 256; + svga->overlay_latch.addr += svga->overlay.pitch << 1; } } - static void gd54xx_update_overlay(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; - int bpp = svga->bpp; + int bpp = svga->bpp; - svga->overlay.cur_ysize = gd54xx->overlay.wve - gd54xx->overlay.wvs + 1; + svga->overlay.cur_ysize = gd54xx->overlay.wve - gd54xx->overlay.wvs + 1; gd54xx->overlay.region1size = 32 * gd54xx->overlay.r1sz / bpp + (gd54xx->overlay.r1adjust * 8 / bpp); gd54xx->overlay.region2size = 32 * gd54xx->overlay.r2sz / bpp + (gd54xx->overlay.r2adjust * 8 / bpp); @@ -608,1051 +579,1058 @@ gd54xx_update_overlay(gd54xx_t *gd54xx) /* Mask and chroma key ignored. */ if (gd54xx->overlay.colorkeymode == 0) - gd54xx->overlay.ck = gd54xx->overlay.colorkeycompare; + gd54xx->overlay.ck = gd54xx->overlay.colorkeycompare; else if (gd54xx->overlay.colorkeymode == 1) - gd54xx->overlay.ck = gd54xx->overlay.colorkeycompare | (gd54xx->overlay.colorkeycomparemask << 8); + gd54xx->overlay.ck = gd54xx->overlay.colorkeycompare | (gd54xx->overlay.colorkeycomparemask << 8); else - gd54xx->overlay.occlusion = 0; + gd54xx->overlay.occlusion = 0; } - /* Returns 1 if the card supports the 8-bpp/16-bpp transparency color or mask. */ static int gd54xx_has_transp(svga_t *svga, int mask) { - if (((svga->crtc[0x27] == CIRRUS_ID_CLGD5446) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5480)) && - !mask) - return 1; /* 5446 and 5480 have mask but not transparency. */ + if (((svga->crtc[0x27] == CIRRUS_ID_CLGD5446) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5480)) && !mask) + return 1; /* 5446 and 5480 have mask but not transparency. */ if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5426) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5428)) - return 1; /* 5426 and 5428 have both. */ + return 1; /* 5426 and 5428 have both. */ else - return 0; /* The rest have neither. */ + return 0; /* The rest have neither. */ } - /* Returns 1 if the card is a 5434, 5436/46, or 5480. */ static int gd54xx_is_5434(svga_t *svga) { if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5434) - return 1; + return 1; else - return 0; + return 0; } - static void gd54xx_out(uint16_t addr, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint8_t old; - int c; - uint8_t o, index; - uint32_t o32; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint8_t old; + int c; + uint8_t o, index; + uint32_t o32; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x3c0: - case 0x3c1: - if (!svga->attrff) { - svga->attraddr = val & 31; - if ((val & 0x20) != svga->attr_palette_enable) { - svga->fullchange = 3; - svga->attr_palette_enable = val & 0x20; - svga_recalctimings(svga); - } - } else { - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) - svga->fullchange = changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); - else svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); - } - } - /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ - if (svga->attraddr == 0x10) { - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x11) { - if (!(svga->seqregs[0x12] & 0x80)) { - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - if (o != val) svga_recalctimings(svga); - } - } else if (svga->attraddr == 0x12) { - if ((val & 0xf) != svga->plane_mask) - svga->fullchange = changeframecount; - svga->plane_mask = val & 0xf; - } - } - svga->attrff ^= 1; + case 0x3c0: + case 0x3c1: + if (!svga->attrff) { + svga->attraddr = val & 31; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + } else { + o = svga->attrregs[svga->attraddr & 31]; + svga->attrregs[svga->attraddr & 31] = val; + if (svga->attraddr < 16) + svga->fullchange = changeframecount; + if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { + for (c = 0; c < 16; c++) { + if (svga->attrregs[0x10] & 0x80) + svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + else + svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); + } + } + /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ + if (svga->attraddr == 0x10) { + if (o != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x11) { + if (!(svga->seqregs[0x12] & 0x80)) { + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + if (o != val) + svga_recalctimings(svga); + } + } else if (svga->attraddr == 0x12) { + if ((val & 0xf) != svga->plane_mask) + svga->fullchange = changeframecount; + svga->plane_mask = val & 0xf; + } + } + svga->attrff ^= 1; + return; + + case 0x3c4: + svga->seqaddr = val; + break; + case 0x3c5: + if ((svga->seqaddr == 2) && !gd54xx->unlocked) { + o = svga->seqregs[svga->seqaddr & 0x1f]; + svga_out(addr, val, svga); + svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f); + return; + } else if ((svga->seqaddr > 6) && !gd54xx->unlocked) return; - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if ((svga->seqaddr == 2) && !gd54xx->unlocked) { - o = svga->seqregs[svga->seqaddr & 0x1f]; - svga_out(addr, val, svga); - svga->seqregs[svga->seqaddr & 0x1f] = (o & 0xf0) | (val & 0x0f); - return; - } else if ((svga->seqaddr > 6) && !gd54xx->unlocked) - return; + if (svga->seqaddr > 5) { + o = svga->seqregs[svga->seqaddr & 0x1f]; + svga->seqregs[svga->seqaddr & 0x1f] = val; + switch (svga->seqaddr) { + case 6: + val &= 0x17; + if (val == 0x12) + svga->seqregs[6] = 0x12; + else + svga->seqregs[6] = 0x0f; + if (svga->crtc[0x27] < CIRRUS_ID_CLGD5429) + gd54xx->unlocked = (svga->seqregs[6] == 0x12); + break; + case 0x08: + if (gd54xx->i2c) + i2c_gpio_set(gd54xx->i2c, !!(val & 0x01), !!(val & 0x02)); + break; + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: /* VCLK stuff */ + gd54xx->vclk_n[svga->seqaddr - 0x0b] = val; + break; + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: /* VCLK stuff */ + gd54xx->vclk_d[svga->seqaddr - 0x1b] = val; + break; + case 0x10: + case 0x30: + case 0x50: + case 0x70: + case 0x90: + case 0xb0: + case 0xd0: + case 0xf0: + svga->hwcursor.x = (val << 3) | (svga->seqaddr >> 5); + break; + case 0x11: + case 0x31: + case 0x51: + case 0x71: + case 0x91: + case 0xb1: + case 0xd1: + case 0xf1: + svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); + break; + case 0x12: + svga->ext_overscan = !!(val & 0x80); + if (svga->ext_overscan && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426)) + svga->overscan_color = gd54xx->extpallook[2]; + else + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + svga_recalctimings(svga); + svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) ? 64 : 32; + else + svga->hwcursor.cur_xsize = 32; - if (svga->seqaddr > 5) { - o = svga->seqregs[svga->seqaddr & 0x1f]; - svga->seqregs[svga->seqaddr & 0x1f] = val; - switch (svga->seqaddr) { - case 6: - val &= 0x17; - if (val == 0x12) - svga->seqregs[6] = 0x12; - else - svga->seqregs[6] = 0x0f; - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5429) - gd54xx->unlocked = (svga->seqregs[6] == 0x12); - break; - case 0x08: - if (gd54xx->i2c) - i2c_gpio_set(gd54xx->i2c, !!(val & 0x01), !!(val & 0x02)); - break; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: /* VCLK stuff */ - gd54xx->vclk_n[svga->seqaddr-0x0b] = val; - break; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: /* VCLK stuff */ - gd54xx->vclk_d[svga->seqaddr-0x1b] = val; - break; - case 0x10: case 0x30: case 0x50: case 0x70: - case 0x90: case 0xb0: case 0xd0: case 0xf0: - svga->hwcursor.x = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x11: case 0x31: case 0x51: case 0x71: - case 0x91: case 0xb1: case 0xd1: case 0xf1: - svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); - break; - case 0x12: - svga->ext_overscan = !!(val & 0x80); - if (svga->ext_overscan && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426)) - svga->overscan_color = gd54xx->extpallook[2]; - else - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - svga_recalctimings(svga); - svga->hwcursor.ena = val & CIRRUS_CURSOR_SHOW; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422) - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = - ((val & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) ? 64 : 32; - else - svga->hwcursor.cur_xsize = 32; - - if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); - else - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); - break; - case 0x13: - if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3c) * 256)); - else - svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256)); - break; - case 0x07: - svga->packed_chain4 = svga->seqregs[7] & 1; - svga_recalctimings(svga); - if (gd54xx_is_5422(svga)) - gd543x_recalc_mapping(gd54xx); - else - svga->seqregs[svga->seqaddr] &= 0x0f; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) - svga->set_reset_disabled = svga->seqregs[7] & 1; - break; - case 0x17: - if (gd54xx_is_5422(svga)) - gd543x_recalc_mapping(gd54xx); - else - return; - break; - } - return; - } - break; - case 0x3c6: - if (!gd54xx->unlocked) - break; - if (gd54xx->ramdac.state == 4) { - gd54xx->ramdac.state = 0; - gd54xx->ramdac.ctrl = val; - svga_recalctimings(svga); - return; - } - gd54xx->ramdac.state = 0; - break; - case 0x3c7: case 0x3c8: - gd54xx->ramdac.state = 0; - break; - case 0x3c9: - gd54xx->ramdac.state = 0; - svga->dac_status = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0: - svga->dac_r = val; - svga->dac_pos++; - break; - case 1: - svga->dac_g = val; - svga->dac_pos++; - break; - case 2: - index = svga->dac_addr & 0xff; - if (svga->seqregs[0x12] & 2) { - index &= 0x0f; - gd54xx->extpal[index].r = svga->dac_r; - gd54xx->extpal[index].g = svga->dac_g; - gd54xx->extpal[index].b = val; - gd54xx->extpallook[index] = makecol32(video_6to8[gd54xx->extpal[index].r & 0x3f], video_6to8[gd54xx->extpal[index].g & 0x3f], video_6to8[gd54xx->extpal[index].b & 0x3f]); - if (svga->ext_overscan && (index == 2)) { - o32 = svga->overscan_color; - svga->overscan_color = gd54xx->extpallook[2]; - if (o32 != svga->overscan_color) - svga_recalctimings(svga); - } - } else { - svga->vgapal[index].r = svga->dac_r; - svga->vgapal[index].g = svga->dac_g; - svga->vgapal[index].b = val; - svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); - } - svga->dac_addr = (svga->dac_addr + 1) & 255; - svga->dac_pos = 0; + if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3c) * 256)); + else + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((svga->seqregs[0x13] & 0x3f) * 256)); + break; + case 0x13: + if ((svga->seqregs[0x12] & CIRRUS_CURSOR_LARGE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5422)) + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3c) * 256)); + else + svga->hwcursor.addr = ((gd54xx->vram_size - 0x4000) + ((val & 0x3f) * 256)); + break; + case 0x07: + svga->packed_chain4 = svga->seqregs[7] & 1; + svga_recalctimings(svga); + if (gd54xx_is_5422(svga)) + gd543x_recalc_mapping(gd54xx); + else + svga->seqregs[svga->seqaddr] &= 0x0f; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) + svga->set_reset_disabled = svga->seqregs[7] & 1; + break; + case 0x17: + if (gd54xx_is_5422(svga)) + gd543x_recalc_mapping(gd54xx); + else + return; break; } return; - case 0x3ce: - /* Per the CL-GD 5446 manual: bits 0-5 are the GDC register index, bits 6-7 are reserved. */ - svga->gdcaddr = val/* & 0x3f*/; - return; - case 0x3cf: - if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || - (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) - return; - - o = svga->gdcreg[svga->gdcaddr]; - - if ((svga->gdcaddr < 2) && !gd54xx->unlocked) - svga->gdcreg[svga->gdcaddr] = (svga->gdcreg[svga->gdcaddr] & 0xf0) | (val & 0x0f); - else if ((svga->gdcaddr <= 8) || gd54xx->unlocked) - svga->gdcreg[svga->gdcaddr] = val; - - if (svga->gdcaddr <= 8) { - switch (svga->gdcaddr) { - case 0: - gd543x_mmio_write(0xb8000, val, gd54xx); - break; - case 1: - gd543x_mmio_write(0xb8004, val, gd54xx); - break; - case 2: - svga->colourcompare = val; - break; - case 4: - svga->readplane = val & 3; - break; - case 5: - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = val & 7; - else - svga->writemode = val & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - break; - case 6: - if ((o ^ val) & 0x0c) - gd543x_recalc_mapping(gd54xx); - break; - case 7: - svga->colournocare = val; - break; - } - - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424)) - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); /*TODO: needs verification on other Cirrus chips*/ - else - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only); - if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || - ((svga->gdcaddr == 6) && ((val ^ o) & 1))) - svga_recalctimings(svga); - } else { - switch (svga->gdcaddr) { - case 0x09: case 0x0a: case 0x0b: - if (svga->gdcreg[0xb] & 0x04) - svga->writemode = svga->gdcreg[5] & 7; - else - svga->writemode = svga->gdcreg[5] & 3; - svga->adv_flags = 0; - if (svga->gdcreg[0xb] & 0x01) - svga->adv_flags = FLAG_EXTRA_BANKS; - if (svga->gdcreg[0xb] & 0x02) - svga->adv_flags |= FLAG_ADDR_BY8; - if (svga->gdcreg[0xb] & 0x04) - svga->adv_flags |= FLAG_EXT_WRITE; - if (svga->gdcreg[0xb] & 0x08) - svga->adv_flags |= FLAG_LATCH8; - if (svga->gdcreg[0xb] & 0x10) - svga->adv_flags |= FLAG_ADDR_BY16; - gd54xx_recalc_banking(gd54xx); - break; - - case 0x0c: - gd54xx->overlay.colorkeycompare = val; - gd54xx_update_overlay(gd54xx); - break; - case 0x0d: - gd54xx->overlay.colorkeycomparemask = val; - gd54xx_update_overlay(gd54xx); - break; - - case 0x0e: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) { - svga->dpms = (val & 0x06) && ((svga->miscout & ((val & 0x06) << 5)) != 0xc0); - svga_recalctimings(svga); - } - break; - - case 0x10: - gd543x_mmio_write(0xb8001, val, gd54xx); - break; - case 0x11: - gd543x_mmio_write(0xb8005, val, gd54xx); - break; - case 0x12: - gd543x_mmio_write(0xb8002, val, gd54xx); - break; - case 0x13: - gd543x_mmio_write(0xb8006, val, gd54xx); - break; - case 0x14: - gd543x_mmio_write(0xb8003, val, gd54xx); - break; - case 0x15: - gd543x_mmio_write(0xb8007, val, gd54xx); - break; - - case 0x20: - gd543x_mmio_write(0xb8008, val, gd54xx); - break; - case 0x21: - gd543x_mmio_write(0xb8009, val, gd54xx); - break; - case 0x22: - gd543x_mmio_write(0xb800a, val, gd54xx); - break; - case 0x23: - gd543x_mmio_write(0xb800b, val, gd54xx); - break; - case 0x24: - gd543x_mmio_write(0xb800c, val, gd54xx); - break; - case 0x25: - gd543x_mmio_write(0xb800d, val, gd54xx); - break; - case 0x26: - gd543x_mmio_write(0xb800e, val, gd54xx); - break; - case 0x27: - gd543x_mmio_write(0xb800f, val, gd54xx); - break; - - case 0x28: - gd543x_mmio_write(0xb8010, val, gd54xx); - break; - case 0x29: - gd543x_mmio_write(0xb8011, val, gd54xx); - break; - case 0x2a: - gd543x_mmio_write(0xb8012, val, gd54xx); - break; - - case 0x2c: - gd543x_mmio_write(0xb8014, val, gd54xx); - break; - case 0x2d: - gd543x_mmio_write(0xb8015, val, gd54xx); - break; - case 0x2e: - gd543x_mmio_write(0xb8016, val, gd54xx); - break; - - case 0x2f: - gd543x_mmio_write(0xb8017, val, gd54xx); - break; - case 0x30: - gd543x_mmio_write(0xb8018, val, gd54xx); - break; - - case 0x32: - gd543x_mmio_write(0xb801a, val, gd54xx); - break; - - case 0x33: - gd543x_mmio_write(0xb801b, val, gd54xx); - break; - - case 0x31: - gd543x_mmio_write(0xb8040, val, gd54xx); - break; - - case 0x34: - gd543x_mmio_write(0xb801c, val, gd54xx); - break; - - case 0x35: - gd543x_mmio_write(0xb801d, val, gd54xx); - break; - - case 0x38: - gd543x_mmio_write(0xb8020, val, gd54xx); - break; - - case 0x39: - gd543x_mmio_write(0xb8021, val, gd54xx); - break; - } - } - return; - - case 0x3d4: - svga->crtcreg = val & gd54xx->crtcreg_mask; - return; - case 0x3d5: - if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || - (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || - (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && - !gd54xx->unlocked) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (svga->crtcreg == 0x11) { - if (!(val & 0x10)) { - if (gd54xx->vblank_irq > 0) - gd54xx->vblank_irq = -1; - } else if (gd54xx->vblank_irq < 0) - gd54xx->vblank_irq = 0; - gd54xx_update_irqs(gd54xx); - if ((val & ~0x30) == (old & ~0x30)) - old = val; - } - - if (old != val) { - /* Overlay registers */ - switch (svga->crtcreg) { - case 0x1d: - if (((old >> 3) & 7) != ((val >> 3) & 7)) { - gd54xx->overlay.colorkeymode = (val >> 3) & 7; - gd54xx_update_overlay(gd54xx); - } - break; - case 0x31: - gd54xx->overlay.hzoom = val == 0 ? 256 : val; - gd54xx_update_overlay(gd54xx); - break; - case 0x32: - gd54xx->overlay.vzoom = val == 0 ? 256 : val; - gd54xx_update_overlay(gd54xx); - break; - case 0x33: - gd54xx->overlay.r1sz &= ~0xff; - gd54xx->overlay.r1sz |= val; - gd54xx_update_overlay(gd54xx); - break; - case 0x34: - gd54xx->overlay.r2sz &= ~0xff; - gd54xx->overlay.r2sz |= val; - gd54xx_update_overlay(gd54xx); - break; - case 0x35: - gd54xx->overlay.r2sdz &= ~0xff; - gd54xx->overlay.r2sdz |= val; - gd54xx_update_overlay(gd54xx); - break; - case 0x36: - gd54xx->overlay.r1sz &= 0xff; - gd54xx->overlay.r1sz |= (val << 8) & 0x300; - gd54xx->overlay.r2sz &= 0xff; - gd54xx->overlay.r2sz |= (val << 6) & 0x300; - gd54xx->overlay.r2sdz &= 0xff; - gd54xx->overlay.r2sdz |= (val << 4) & 0x300; - gd54xx_update_overlay(gd54xx); - break; - case 0x37: - gd54xx->overlay.wvs &= ~0xff; - gd54xx->overlay.wvs |= val; - svga->overlay.y = gd54xx->overlay.wvs; - break; - case 0x38: - gd54xx->overlay.wve &= ~0xff; - gd54xx->overlay.wve |= val; - gd54xx_update_overlay(gd54xx); - break; - case 0x39: - gd54xx->overlay.wvs &= 0xff; - gd54xx->overlay.wvs |= (val << 8) & 0x300; - gd54xx->overlay.wve &= 0xff; - gd54xx->overlay.wve |= (val << 6) & 0x300; - gd54xx_update_overlay(gd54xx); - break; - case 0x3a: - svga->overlay.addr &= ~0xff; - svga->overlay.addr |= val; - gd54xx_update_overlay(gd54xx); - break; - case 0x3b: - svga->overlay.addr &= ~0xff00; - svga->overlay.addr |= val << 8; - gd54xx_update_overlay(gd54xx); - break; - case 0x3c: - svga->overlay.addr &= ~0x0f0000; - svga->overlay.addr |= (val << 16) & 0x0f0000; - svga->overlay.pitch &= ~0x100; - svga->overlay.pitch |= (val & 0x20) << 3; - gd54xx_update_overlay(gd54xx); - break; - case 0x3d: - svga->overlay.pitch &= ~0xff; - svga->overlay.pitch |= val; - gd54xx_update_overlay(gd54xx); - break; - case 0x3e: - gd54xx->overlay.mode = (val >> 1) & 7; - svga->overlay.ena = (val & 1) != 0; - gd54xx_update_overlay(gd54xx); - break; - } - - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + } + break; + case 0x3c6: + if (!gd54xx->unlocked) + break; + if (gd54xx->ramdac.state == 4) { + gd54xx->ramdac.state = 0; + gd54xx->ramdac.ctrl = val; + svga_recalctimings(svga); + return; + } + gd54xx->ramdac.state = 0; + break; + case 0x3c7: + case 0x3c8: + gd54xx->ramdac.state = 0; + break; + case 0x3c9: + gd54xx->ramdac.state = 0; + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 0xff; + if (svga->seqregs[0x12] & 2) { + index &= 0x0f; + gd54xx->extpal[index].r = svga->dac_r; + gd54xx->extpal[index].g = svga->dac_g; + gd54xx->extpal[index].b = val; + gd54xx->extpallook[index] = makecol32(video_6to8[gd54xx->extpal[index].r & 0x3f], video_6to8[gd54xx->extpal[index].g & 0x3f], video_6to8[gd54xx->extpal[index].b & 0x3f]); + if (svga->ext_overscan && (index == 2)) { + o32 = svga->overscan_color; + svga->overscan_color = gd54xx->extpallook[2]; + if (o32 != svga->overscan_color) + svga_recalctimings(svga); } - } - break; + } else { + svga->vgapal[index].r = svga->dac_r; + svga->vgapal[index].g = svga->dac_g; + svga->vgapal[index].b = val; + svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); + } + svga->dac_addr = (svga->dac_addr + 1) & 255; + svga->dac_pos = 0; + break; + } + return; + case 0x3ce: + /* Per the CL-GD 5446 manual: bits 0-5 are the GDC register index, bits 6-7 are reserved. */ + svga->gdcaddr = val /* & 0x3f*/; + return; + case 0x3cf: + if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) + return; + + o = svga->gdcreg[svga->gdcaddr]; + + if ((svga->gdcaddr < 2) && !gd54xx->unlocked) + svga->gdcreg[svga->gdcaddr] = (svga->gdcreg[svga->gdcaddr] & 0xf0) | (val & 0x0f); + else if ((svga->gdcaddr <= 8) || gd54xx->unlocked) + svga->gdcreg[svga->gdcaddr] = val; + + if (svga->gdcaddr <= 8) { + switch (svga->gdcaddr) { + case 0: + gd543x_mmio_write(0xb8000, val, gd54xx); + break; + case 1: + gd543x_mmio_write(0xb8004, val, gd54xx); + break; + case 2: + svga->colourcompare = val; + break; + case 4: + svga->readplane = val & 3; + break; + case 5: + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = val & 7; + else + svga->writemode = val & 3; + svga->readmode = val & 8; + svga->chain2_read = val & 0x10; + break; + case 6: + if ((o ^ val) & 0x0c) + gd543x_recalc_mapping(gd54xx); + break; + case 7: + svga->colournocare = val; + break; + } + + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424)) + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); /*TODO: needs verification on other Cirrus chips*/ + else + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && svga->packed_chain4) || svga->fb_only); + if (((svga->gdcaddr == 5) && ((val ^ o) & 0x70)) || ((svga->gdcaddr == 6) && ((val ^ o) & 1))) + svga_recalctimings(svga); + } else { + switch (svga->gdcaddr) { + case 0x09: + case 0x0a: + case 0x0b: + if (svga->gdcreg[0xb] & 0x04) + svga->writemode = svga->gdcreg[5] & 7; + else + svga->writemode = svga->gdcreg[5] & 3; + svga->adv_flags = 0; + if (svga->gdcreg[0xb] & 0x01) + svga->adv_flags = FLAG_EXTRA_BANKS; + if (svga->gdcreg[0xb] & 0x02) + svga->adv_flags |= FLAG_ADDR_BY8; + if (svga->gdcreg[0xb] & 0x04) + svga->adv_flags |= FLAG_EXT_WRITE; + if (svga->gdcreg[0xb] & 0x08) + svga->adv_flags |= FLAG_LATCH8; + if (svga->gdcreg[0xb] & 0x10) + svga->adv_flags |= FLAG_ADDR_BY16; + gd54xx_recalc_banking(gd54xx); + break; + + case 0x0c: + gd54xx->overlay.colorkeycompare = val; + gd54xx_update_overlay(gd54xx); + break; + case 0x0d: + gd54xx->overlay.colorkeycomparemask = val; + gd54xx_update_overlay(gd54xx); + break; + + case 0x0e: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) { + svga->dpms = (val & 0x06) && ((svga->miscout & ((val & 0x06) << 5)) != 0xc0); + svga_recalctimings(svga); + } + break; + + case 0x10: + gd543x_mmio_write(0xb8001, val, gd54xx); + break; + case 0x11: + gd543x_mmio_write(0xb8005, val, gd54xx); + break; + case 0x12: + gd543x_mmio_write(0xb8002, val, gd54xx); + break; + case 0x13: + gd543x_mmio_write(0xb8006, val, gd54xx); + break; + case 0x14: + gd543x_mmio_write(0xb8003, val, gd54xx); + break; + case 0x15: + gd543x_mmio_write(0xb8007, val, gd54xx); + break; + + case 0x20: + gd543x_mmio_write(0xb8008, val, gd54xx); + break; + case 0x21: + gd543x_mmio_write(0xb8009, val, gd54xx); + break; + case 0x22: + gd543x_mmio_write(0xb800a, val, gd54xx); + break; + case 0x23: + gd543x_mmio_write(0xb800b, val, gd54xx); + break; + case 0x24: + gd543x_mmio_write(0xb800c, val, gd54xx); + break; + case 0x25: + gd543x_mmio_write(0xb800d, val, gd54xx); + break; + case 0x26: + gd543x_mmio_write(0xb800e, val, gd54xx); + break; + case 0x27: + gd543x_mmio_write(0xb800f, val, gd54xx); + break; + + case 0x28: + gd543x_mmio_write(0xb8010, val, gd54xx); + break; + case 0x29: + gd543x_mmio_write(0xb8011, val, gd54xx); + break; + case 0x2a: + gd543x_mmio_write(0xb8012, val, gd54xx); + break; + + case 0x2c: + gd543x_mmio_write(0xb8014, val, gd54xx); + break; + case 0x2d: + gd543x_mmio_write(0xb8015, val, gd54xx); + break; + case 0x2e: + gd543x_mmio_write(0xb8016, val, gd54xx); + break; + + case 0x2f: + gd543x_mmio_write(0xb8017, val, gd54xx); + break; + case 0x30: + gd543x_mmio_write(0xb8018, val, gd54xx); + break; + + case 0x32: + gd543x_mmio_write(0xb801a, val, gd54xx); + break; + + case 0x33: + gd543x_mmio_write(0xb801b, val, gd54xx); + break; + + case 0x31: + gd543x_mmio_write(0xb8040, val, gd54xx); + break; + + case 0x34: + gd543x_mmio_write(0xb801c, val, gd54xx); + break; + + case 0x35: + gd543x_mmio_write(0xb801d, val, gd54xx); + break; + + case 0x38: + gd543x_mmio_write(0xb8020, val, gd54xx); + break; + + case 0x39: + gd543x_mmio_write(0xb8021, val, gd54xx); + break; + } + } + return; + + case 0x3d4: + svga->crtcreg = val & gd54xx->crtcreg_mask; + return; + case 0x3d5: + if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && !gd54xx->unlocked) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + + if (svga->crtcreg == 0x11) { + if (!(val & 0x10)) { + if (gd54xx->vblank_irq > 0) + gd54xx->vblank_irq = -1; + } else if (gd54xx->vblank_irq < 0) + gd54xx->vblank_irq = 0; + gd54xx_update_irqs(gd54xx); + if ((val & ~0x30) == (old & ~0x30)) + old = val; + } + + if (old != val) { + /* Overlay registers */ + switch (svga->crtcreg) { + case 0x1d: + if (((old >> 3) & 7) != ((val >> 3) & 7)) { + gd54xx->overlay.colorkeymode = (val >> 3) & 7; + gd54xx_update_overlay(gd54xx); + } + break; + case 0x31: + gd54xx->overlay.hzoom = val == 0 ? 256 : val; + gd54xx_update_overlay(gd54xx); + break; + case 0x32: + gd54xx->overlay.vzoom = val == 0 ? 256 : val; + gd54xx_update_overlay(gd54xx); + break; + case 0x33: + gd54xx->overlay.r1sz &= ~0xff; + gd54xx->overlay.r1sz |= val; + gd54xx_update_overlay(gd54xx); + break; + case 0x34: + gd54xx->overlay.r2sz &= ~0xff; + gd54xx->overlay.r2sz |= val; + gd54xx_update_overlay(gd54xx); + break; + case 0x35: + gd54xx->overlay.r2sdz &= ~0xff; + gd54xx->overlay.r2sdz |= val; + gd54xx_update_overlay(gd54xx); + break; + case 0x36: + gd54xx->overlay.r1sz &= 0xff; + gd54xx->overlay.r1sz |= (val << 8) & 0x300; + gd54xx->overlay.r2sz &= 0xff; + gd54xx->overlay.r2sz |= (val << 6) & 0x300; + gd54xx->overlay.r2sdz &= 0xff; + gd54xx->overlay.r2sdz |= (val << 4) & 0x300; + gd54xx_update_overlay(gd54xx); + break; + case 0x37: + gd54xx->overlay.wvs &= ~0xff; + gd54xx->overlay.wvs |= val; + svga->overlay.y = gd54xx->overlay.wvs; + break; + case 0x38: + gd54xx->overlay.wve &= ~0xff; + gd54xx->overlay.wve |= val; + gd54xx_update_overlay(gd54xx); + break; + case 0x39: + gd54xx->overlay.wvs &= 0xff; + gd54xx->overlay.wvs |= (val << 8) & 0x300; + gd54xx->overlay.wve &= 0xff; + gd54xx->overlay.wve |= (val << 6) & 0x300; + gd54xx_update_overlay(gd54xx); + break; + case 0x3a: + svga->overlay.addr &= ~0xff; + svga->overlay.addr |= val; + gd54xx_update_overlay(gd54xx); + break; + case 0x3b: + svga->overlay.addr &= ~0xff00; + svga->overlay.addr |= val << 8; + gd54xx_update_overlay(gd54xx); + break; + case 0x3c: + svga->overlay.addr &= ~0x0f0000; + svga->overlay.addr |= (val << 16) & 0x0f0000; + svga->overlay.pitch &= ~0x100; + svga->overlay.pitch |= (val & 0x20) << 3; + gd54xx_update_overlay(gd54xx); + break; + case 0x3d: + svga->overlay.pitch &= ~0xff; + svga->overlay.pitch |= val; + gd54xx_update_overlay(gd54xx); + break; + case 0x3e: + gd54xx->overlay.mode = (val >> 1) & 7; + svga->overlay.ena = (val & 1) != 0; + gd54xx_update_overlay(gd54xx); + break; + } + + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; } svga_out(addr, val, svga); } - static uint8_t gd54xx_in(uint16_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; uint8_t index, ret = 0xff; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x3c2: - ret = svga_in(addr, svga); - ret |= gd54xx->vblank_irq > 0 ? 0x80 : 0x00; - break; + case 0x3c2: + ret = svga_in(addr, svga); + ret |= gd54xx->vblank_irq > 0 ? 0x80 : 0x00; + break; - case 0x3c4: - if (svga->seqregs[6] == 0x12) { - ret = svga->seqaddr; - if ((ret & 0x1e) == 0x10) { - if (ret & 1) - ret = ((svga->hwcursor.y & 7) << 5) | 0x11; - else - ret = ((svga->hwcursor.x & 7) << 5) | 0x10; - } - } else - ret = svga->seqaddr; - break; + case 0x3c4: + if (svga->seqregs[6] == 0x12) { + ret = svga->seqaddr; + if ((ret & 0x1e) == 0x10) { + if (ret & 1) + ret = ((svga->hwcursor.y & 7) << 5) | 0x11; + else + ret = ((svga->hwcursor.x & 7) << 5) | 0x10; + } + } else + ret = svga->seqaddr; + break; - case 0x3c5: - if ((svga->seqaddr == 2) && !gd54xx->unlocked) - ret = svga_in(addr, svga) & 0x0f; - else if ((svga->seqaddr > 6) && !gd54xx->unlocked) - ret = 0xff; - else if (svga->seqaddr > 5) { - ret = svga->seqregs[svga->seqaddr & 0x3f]; - switch (svga->seqaddr) { - case 6: - ret = svga->seqregs[6]; - break; - case 0x08: - if (gd54xx->i2c) { - ret &= 0x7b; - if (i2c_gpio_get_scl(gd54xx->i2c)) - ret |= 0x04; - if (i2c_gpio_get_sda(gd54xx->i2c)) - ret |= 0x80; - } - break; - case 0x0a: /*Scratch Pad 1 (Memory size for 5402/542x)*/ - ret = svga->seqregs[0x0a] & ~0x1a; - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5402) { - ret |= 0x01; /*512K of memory*/ - } else if (svga->crtc[0x27] > CIRRUS_ID_CLGD5402) { - switch (gd54xx->vram_size >> 10) { - case 512: - ret |= 0x08; - break; - case 1024: - ret |= 0x10; - break; - case 2048: - ret |= 0x18; - break; - } - } - break; - case 0x0b: case 0x0c: case 0x0d: case 0x0e: - ret = gd54xx->vclk_n[svga->seqaddr-0x0b]; - break; - case 0x0f: /*DRAM control*/ - ret = svga->seqregs[0x0f] & ~0x98; - switch (gd54xx->vram_size >> 10) { - case 512: - ret |= 0x08; /*16-bit DRAM data bus width*/ - break; - case 1024: - ret |= 0x10; /*32-bit DRAM data bus width for 1M of memory*/ - break; - case 2048: - ret |= (gd54xx_is_5434(svga)) ? 0x98 : 0x18; /*32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width for 2M of memory*/ - break; - case 4096: - ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/ - break; - } - break; - case 0x15: /*Scratch Pad 3 (Memory size for 543x)*/ - ret = svga->seqregs[0x15] & ~0x0f; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { - switch (gd54xx->vram_size >> 20) { - case 1: - ret |= 0x02; - break; - case 2: - ret |= 0x03; - break; - case 4: - ret |= 0x04; - break; - } - } - break; - case 0x17: - ret = svga->seqregs[0x17] & ~(7 << 3); - if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { - if (gd54xx->vlb) - ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3); - else if (gd54xx->mca) - ret |= (CL_GD5428_SYSTEM_BUS_MCA << 3); - else - ret |= (CL_GD5428_SYSTEM_BUS_ISA << 3); - } else { - if (gd54xx->vlb) - ret |= (CL_GD5429_SYSTEM_BUS_VESA << 3); - else - ret |= (CL_GD5429_SYSTEM_BUS_ISA << 3); - } - } else { - if (gd54xx->pci) - ret |= (CL_GD543X_SYSTEM_BUS_PCI << 3); - else if (gd54xx->vlb) - ret |= (CL_GD543X_SYSTEM_BUS_VESA << 3); - else - ret |= (CL_GD543X_SYSTEM_BUS_ISA << 3); - } - break; - case 0x18: - ret = svga->seqregs[0x18] & 0xfe; - break; - case 0x1b: case 0x1c: case 0x1d: case 0x1e: - ret = gd54xx->vclk_d[svga->seqaddr - 0x1b]; - break; - } - break; - } else - ret = svga_in(addr, svga); - break; - case 0x3c6: - if (!gd54xx->unlocked) - ret = svga_in(addr, svga); - else if (gd54xx->ramdac.state == 4) { - /* CL-GD 5428 does not lock the register when it's read. */ - if (svga->crtc[0x27] != CIRRUS_ID_CLGD5428) - gd54xx->ramdac.state = 0; - ret = gd54xx->ramdac.ctrl; - } else { - gd54xx->ramdac.state++; - if (gd54xx->ramdac.state == 4) - ret = gd54xx->ramdac.ctrl; - else - ret = svga_in(addr, svga); - } - break; - case 0x3c7: case 0x3c8: - gd54xx->ramdac.state = 0; - ret = svga_in(addr, svga); - break; - case 0x3c9: - gd54xx->ramdac.state = 0; - svga->dac_status = 3; - index = (svga->dac_addr - 1) & 0xff; - if (svga->seqregs[0x12] & 2) - index &= 0x0f; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - ret = gd54xx->extpal[index].r & 0x3f; - else - ret = svga->vgapal[index].r & 0x3f; - break; - case 1: - svga->dac_pos++; - if (svga->seqregs[0x12] & 2) - ret = gd54xx->extpal[index].g & 0x3f; - else - ret = svga->vgapal[index].g & 0x3f; - break; - case 2: - svga->dac_pos=0; - svga->dac_addr = (svga->dac_addr + 1) & 255; - if (svga->seqregs[0x12] & 2) - ret = gd54xx->extpal[index].b & 0x3f; - else - ret = svga->vgapal[index].b & 0x3f; - break; + case 0x3c5: + if ((svga->seqaddr == 2) && !gd54xx->unlocked) + ret = svga_in(addr, svga) & 0x0f; + else if ((svga->seqaddr > 6) && !gd54xx->unlocked) + ret = 0xff; + else if (svga->seqaddr > 5) { + ret = svga->seqregs[svga->seqaddr & 0x3f]; + switch (svga->seqaddr) { + case 6: + ret = svga->seqregs[6]; + break; + case 0x08: + if (gd54xx->i2c) { + ret &= 0x7b; + if (i2c_gpio_get_scl(gd54xx->i2c)) + ret |= 0x04; + if (i2c_gpio_get_sda(gd54xx->i2c)) + ret |= 0x80; + } + break; + case 0x0a: /*Scratch Pad 1 (Memory size for 5402/542x)*/ + ret = svga->seqregs[0x0a] & ~0x1a; + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5402) { + ret |= 0x01; /*512K of memory*/ + } else if (svga->crtc[0x27] > CIRRUS_ID_CLGD5402) { + switch (gd54xx->vram_size >> 10) { + case 512: + ret |= 0x08; + break; + case 1024: + ret |= 0x10; + break; + case 2048: + ret |= 0x18; + break; + } + } + break; + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + ret = gd54xx->vclk_n[svga->seqaddr - 0x0b]; + break; + case 0x0f: /*DRAM control*/ + ret = svga->seqregs[0x0f] & ~0x98; + switch (gd54xx->vram_size >> 10) { + case 512: + ret |= 0x08; /*16-bit DRAM data bus width*/ + break; + case 1024: + ret |= 0x10; /*32-bit DRAM data bus width for 1M of memory*/ + break; + case 2048: + ret |= (gd54xx_is_5434(svga)) ? 0x98 : 0x18; /*32-bit (Pre-5434)/64-bit (5434 and up) DRAM data bus width for 2M of memory*/ + break; + case 4096: + ret |= 0x98; /*64-bit (5434 and up) DRAM data bus width for 4M of memory*/ + break; + } + break; + case 0x15: /*Scratch Pad 3 (Memory size for 543x)*/ + ret = svga->seqregs[0x15] & ~0x0f; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { + switch (gd54xx->vram_size >> 20) { + case 1: + ret |= 0x02; + break; + case 2: + ret |= 0x03; + break; + case 4: + ret |= 0x04; + break; + } + } + break; + case 0x17: + ret = svga->seqregs[0x17] & ~(7 << 3); + if (svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) { + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { + if (gd54xx->vlb) + ret |= (CL_GD5428_SYSTEM_BUS_VESA << 3); + else if (gd54xx->mca) + ret |= (CL_GD5428_SYSTEM_BUS_MCA << 3); + else + ret |= (CL_GD5428_SYSTEM_BUS_ISA << 3); + } else { + if (gd54xx->vlb) + ret |= (CL_GD5429_SYSTEM_BUS_VESA << 3); + else + ret |= (CL_GD5429_SYSTEM_BUS_ISA << 3); + } + } else { + if (gd54xx->pci) + ret |= (CL_GD543X_SYSTEM_BUS_PCI << 3); + else if (gd54xx->vlb) + ret |= (CL_GD543X_SYSTEM_BUS_VESA << 3); + else + ret |= (CL_GD543X_SYSTEM_BUS_ISA << 3); + } + break; + case 0x18: + ret = svga->seqregs[0x18] & 0xfe; + break; + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + ret = gd54xx->vclk_d[svga->seqaddr - 0x1b]; + break; } break; - case 0x3ce: - ret = svga->gdcaddr & 0x3f; - break; - case 0x3cf: - if (svga->gdcaddr >= 0x10) { - if ((svga->gdcaddr > 8) && !gd54xx->unlocked) - ret = 0xff; - else if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || - (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) - ret = 0xff; - else switch (svga->gdcaddr) { - case 0x10: - ret = gd543x_mmio_read(0xb8001, gd54xx); - break; - case 0x11: - ret = gd543x_mmio_read(0xb8005, gd54xx); - break; - case 0x12: - ret = gd543x_mmio_read(0xb8002, gd54xx); - break; - case 0x13: - ret = gd543x_mmio_read(0xb8006, gd54xx); - break; - case 0x14: - ret = gd543x_mmio_read(0xb8003, gd54xx); - break; - case 0x15: - ret = gd543x_mmio_read(0xb8007, gd54xx); - break; + } else + ret = svga_in(addr, svga); + break; + case 0x3c6: + if (!gd54xx->unlocked) + ret = svga_in(addr, svga); + else if (gd54xx->ramdac.state == 4) { + /* CL-GD 5428 does not lock the register when it's read. */ + if (svga->crtc[0x27] != CIRRUS_ID_CLGD5428) + gd54xx->ramdac.state = 0; + ret = gd54xx->ramdac.ctrl; + } else { + gd54xx->ramdac.state++; + if (gd54xx->ramdac.state == 4) + ret = gd54xx->ramdac.ctrl; + else + ret = svga_in(addr, svga); + } + break; + case 0x3c7: + case 0x3c8: + gd54xx->ramdac.state = 0; + ret = svga_in(addr, svga); + break; + case 0x3c9: + gd54xx->ramdac.state = 0; + svga->dac_status = 3; + index = (svga->dac_addr - 1) & 0xff; + if (svga->seqregs[0x12] & 2) + index &= 0x0f; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->seqregs[0x12] & 2) + ret = gd54xx->extpal[index].r & 0x3f; + else + ret = svga->vgapal[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->seqregs[0x12] & 2) + ret = gd54xx->extpal[index].g & 0x3f; + else + ret = svga->vgapal[index].g & 0x3f; + break; + case 2: + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + if (svga->seqregs[0x12] & 2) + ret = gd54xx->extpal[index].b & 0x3f; + else + ret = svga->vgapal[index].b & 0x3f; + break; + } + break; + case 0x3ce: + ret = svga->gdcaddr & 0x3f; + break; + case 0x3cf: + if (svga->gdcaddr >= 0x10) { + if ((svga->gdcaddr > 8) && !gd54xx->unlocked) + ret = 0xff; + else if ((svga->gdcaddr > 0x1f) && ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5422) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5424))) + ret = 0xff; + else + switch (svga->gdcaddr) { + case 0x10: + ret = gd543x_mmio_read(0xb8001, gd54xx); + break; + case 0x11: + ret = gd543x_mmio_read(0xb8005, gd54xx); + break; + case 0x12: + ret = gd543x_mmio_read(0xb8002, gd54xx); + break; + case 0x13: + ret = gd543x_mmio_read(0xb8006, gd54xx); + break; + case 0x14: + ret = gd543x_mmio_read(0xb8003, gd54xx); + break; + case 0x15: + ret = gd543x_mmio_read(0xb8007, gd54xx); + break; - case 0x20: - ret = gd543x_mmio_read(0xb8008, gd54xx); - break; - case 0x21: - ret = gd543x_mmio_read(0xb8009, gd54xx); - break; - case 0x22: - ret = gd543x_mmio_read(0xb800a, gd54xx); - break; - case 0x23: - ret = gd543x_mmio_read(0xb800b, gd54xx); - break; - case 0x24: - ret = gd543x_mmio_read(0xb800c, gd54xx); - break; - case 0x25: - ret = gd543x_mmio_read(0xb800d, gd54xx); - break; - case 0x26: - ret = gd543x_mmio_read(0xb800e, gd54xx); - break; - case 0x27: - ret = gd543x_mmio_read(0xb800f, gd54xx); - break; + case 0x20: + ret = gd543x_mmio_read(0xb8008, gd54xx); + break; + case 0x21: + ret = gd543x_mmio_read(0xb8009, gd54xx); + break; + case 0x22: + ret = gd543x_mmio_read(0xb800a, gd54xx); + break; + case 0x23: + ret = gd543x_mmio_read(0xb800b, gd54xx); + break; + case 0x24: + ret = gd543x_mmio_read(0xb800c, gd54xx); + break; + case 0x25: + ret = gd543x_mmio_read(0xb800d, gd54xx); + break; + case 0x26: + ret = gd543x_mmio_read(0xb800e, gd54xx); + break; + case 0x27: + ret = gd543x_mmio_read(0xb800f, gd54xx); + break; - case 0x28: - ret = gd543x_mmio_read(0xb8010, gd54xx); - break; - case 0x29: - ret = gd543x_mmio_read(0xb8011, gd54xx); - break; - case 0x2a: - ret = gd543x_mmio_read(0xb8012, gd54xx); - break; + case 0x28: + ret = gd543x_mmio_read(0xb8010, gd54xx); + break; + case 0x29: + ret = gd543x_mmio_read(0xb8011, gd54xx); + break; + case 0x2a: + ret = gd543x_mmio_read(0xb8012, gd54xx); + break; - case 0x2c: - ret = gd543x_mmio_read(0xb8014, gd54xx); - break; - case 0x2d: - ret = gd543x_mmio_read(0xb8015, gd54xx); - break; - case 0x2e: - ret = gd543x_mmio_read(0xb8016, gd54xx); - break; + case 0x2c: + ret = gd543x_mmio_read(0xb8014, gd54xx); + break; + case 0x2d: + ret = gd543x_mmio_read(0xb8015, gd54xx); + break; + case 0x2e: + ret = gd543x_mmio_read(0xb8016, gd54xx); + break; - case 0x2f: - ret = gd543x_mmio_read(0xb8017, gd54xx); - break; - case 0x30: - ret = gd543x_mmio_read(0xb8018, gd54xx); - break; + case 0x2f: + ret = gd543x_mmio_read(0xb8017, gd54xx); + break; + case 0x30: + ret = gd543x_mmio_read(0xb8018, gd54xx); + break; - case 0x32: - ret = gd543x_mmio_read(0xb801a, gd54xx); - break; + case 0x32: + ret = gd543x_mmio_read(0xb801a, gd54xx); + break; - case 0x33: - ret = gd543x_mmio_read(0xb801b, gd54xx); - break; + case 0x33: + ret = gd543x_mmio_read(0xb801b, gd54xx); + break; - case 0x31: - ret = gd543x_mmio_read(0xb8040, gd54xx); - break; + case 0x31: + ret = gd543x_mmio_read(0xb8040, gd54xx); + break; - case 0x34: - ret = gd543x_mmio_read(0xb801c, gd54xx); - break; + case 0x34: + ret = gd543x_mmio_read(0xb801c, gd54xx); + break; - case 0x35: - ret = gd543x_mmio_read(0xb801d, gd54xx); - break; + case 0x35: + ret = gd543x_mmio_read(0xb801d, gd54xx); + break; - case 0x38: - ret = gd543x_mmio_read(0xb8020, gd54xx); - break; + case 0x38: + ret = gd543x_mmio_read(0xb8020, gd54xx); + break; - case 0x39: - ret = gd543x_mmio_read(0xb8021, gd54xx); - break; + case 0x39: + ret = gd543x_mmio_read(0xb8021, gd54xx); + break; - case 0x3f: - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5446) - gd54xx->vportsync = !gd54xx->vportsync; - ret = gd54xx->vportsync ? 0x80 : 0x00; - break; - } - } else { - if ((svga->gdcaddr < 2) && !gd54xx->unlocked) - ret = (svga->gdcreg[svga->gdcaddr] & 0x0f); - else { - if (svga->gdcaddr == 0) - ret = gd543x_mmio_read(0xb8000, gd54xx); - else if (svga->gdcaddr == 1) - ret = gd543x_mmio_read(0xb8004, gd54xx); - else - ret = svga->gdcreg[svga->gdcaddr]; - } - } - break; - case 0x3d4: - ret = svga->crtcreg; - break; - case 0x3d5: - ret = svga->crtc[svga->crtcreg]; - if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || - (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || - (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && - !gd54xx->unlocked) - ret = 0xff; - else switch (svga->crtcreg) { - case 0x22: /*Graphics Data Latches Readback Register*/ - /*Should this be & 7 if 8 byte latch is enabled? */ - ret = svga->latch.b[svga->gdcreg[4] & 3]; - break; - case 0x24: /*Attribute controller toggle readback (R)*/ - ret = svga->attrff << 7; - break; - case 0x26: /*Attribute controller index readback (R)*/ - ret = svga->attraddr & 0x3f; - break; - case 0x27: /*ID*/ - ret = svga->crtc[0x27]; /*GD542x/GD543x*/ - break; - case 0x28: /*Class ID*/ - if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) - ret = 0xff; /*Standard CL-GD5430/40*/ - break; - } - break; - default: - ret = svga_in(addr, svga); - break; + case 0x3f: + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5446) + gd54xx->vportsync = !gd54xx->vportsync; + ret = gd54xx->vportsync ? 0x80 : 0x00; + break; + } + } else { + if ((svga->gdcaddr < 2) && !gd54xx->unlocked) + ret = (svga->gdcreg[svga->gdcaddr] & 0x0f); + else { + if (svga->gdcaddr == 0) + ret = gd543x_mmio_read(0xb8000, gd54xx); + else if (svga->gdcaddr == 1) + ret = gd543x_mmio_read(0xb8004, gd54xx); + else + ret = svga->gdcreg[svga->gdcaddr]; + } + } + break; + case 0x3d4: + ret = svga->crtcreg; + break; + case 0x3d5: + ret = svga->crtc[svga->crtcreg]; + if (((svga->crtcreg == 0x19) || (svga->crtcreg == 0x1a) || (svga->crtcreg == 0x1b) || (svga->crtcreg == 0x1d) || (svga->crtcreg == 0x25) || (svga->crtcreg == 0x27)) && !gd54xx->unlocked) + ret = 0xff; + else + switch (svga->crtcreg) { + case 0x22: /*Graphics Data Latches Readback Register*/ + /*Should this be & 7 if 8 byte latch is enabled? */ + ret = svga->latch.b[svga->gdcreg[4] & 3]; + break; + case 0x24: /*Attribute controller toggle readback (R)*/ + ret = svga->attrff << 7; + break; + case 0x26: /*Attribute controller index readback (R)*/ + ret = svga->attraddr & 0x3f; + break; + case 0x27: /*ID*/ + ret = svga->crtc[0x27]; /*GD542x/GD543x*/ + break; + case 0x28: /*Class ID*/ + if ((svga->crtc[0x27] == CIRRUS_ID_CLGD5430) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5440)) + ret = 0xff; /*Standard CL-GD5430/40*/ + break; + } + break; + default: + ret = svga_in(addr, svga); + break; } return ret; } - static void gd54xx_recalc_banking(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; if (!gd54xx_is_5422(svga)) { - svga->extra_banks[0] = (svga->gdcreg[0x09] & 0x7f) << 12; + svga->extra_banks[0] = (svga->gdcreg[0x09] & 0x7f) << 12; - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) - svga->extra_banks[1] = (svga->gdcreg[0x0a] & 0x7f) << 12; - else - svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) + svga->extra_banks[1] = (svga->gdcreg[0x0a] & 0x7f) << 12; + else + svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } else { - if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && - (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) - svga->extra_banks[0] = svga->gdcreg[0x09] << 14; - else - svga->extra_banks[0] = svga->gdcreg[0x09] << 12; + if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) + svga->extra_banks[0] = svga->gdcreg[0x09] << 14; + else + svga->extra_banks[0] = svga->gdcreg[0x09] << 12; - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { - if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && - (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) - svga->extra_banks[1] = svga->gdcreg[0x0a] << 14; - else - svga->extra_banks[1] = svga->gdcreg[0x0a] << 12; - } else - svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_DUAL) { + if ((svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5426) && (svga->crtc[0x27] != CIRRUS_ID_CLGD5424)) + svga->extra_banks[1] = svga->gdcreg[0x0a] << 14; + else + svga->extra_banks[1] = svga->gdcreg[0x0a] << 12; + } else + svga->extra_banks[1] = svga->extra_banks[0] + 0x8000; } svga->write_bank = svga->read_bank = svga->extra_banks[0]; } - static void gd543x_recalc_mapping(gd54xx_t *gd54xx) { - svga_t *svga = &gd54xx->svga; + svga_t *svga = &gd54xx->svga; uint32_t base, size; - if ((gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) || - (gd54xx->mca && (!(gd54xx->pos_regs[2] & 1)))) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&gd54xx->linear_mapping); - mem_mapping_disable(&gd54xx->mmio_mapping); - return; + if ((gd54xx->pci && (!(gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))) || (gd54xx->mca && (!(gd54xx->pos_regs[2] & 1)))) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&gd54xx->linear_mapping); + mem_mapping_disable(&gd54xx->mmio_mapping); + return; } gd54xx->mmio_vram_overlap = 0; if (!gd54xx_is_5422(svga) || !(svga->seqregs[7] & 0xf0) || !(svga->seqregs[0x07] & 0x01)) { - mem_mapping_disable(&gd54xx->linear_mapping); - mem_mapping_disable(&gd54xx->aperture2_mapping); - switch (svga->gdcreg[6] & 0x0c) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - gd54xx->mmio_vram_overlap = 1; - break; - } + mem_mapping_disable(&gd54xx->linear_mapping); + mem_mapping_disable(&gd54xx->aperture2_mapping); + switch (svga->gdcreg[6] & 0x0c) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + gd54xx->mmio_vram_overlap = 1; + break; + } - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && - (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { - if (gd54xx->mmio_vram_overlap) { - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); - } else - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - } else - mem_mapping_disable(&gd54xx->mmio_mapping); + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x07] & 0x01) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { + if (gd54xx->mmio_vram_overlap) { + mem_mapping_disable(&svga->mapping); + mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x08000); + } else + mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); + } else + mem_mapping_disable(&gd54xx->mmio_mapping); } else { - if ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) { - if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { - base = (svga->seqregs[7] & 0xf0) << 16; - size = 1 * 1024 * 1024; - } else { - base = (svga->seqregs[7] & 0xe0) << 16; - size = 2 * 1024 * 1024; - } - } else if (gd54xx->pci) { - base = gd54xx->lfb_base; - /* if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - size = 32 * 1024 * 1024; - else */ if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } else { /*VLB/ISA/MCA*/ - base = 128*1024*1024; - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - size = 16 * 1024 * 1024; - else - size = 4 * 1024 * 1024; - } + if ((svga->crtc[0x27] <= CIRRUS_ID_CLGD5429) || (!gd54xx->pci && !gd54xx->vlb)) { + if (svga->gdcreg[0x0b] & CIRRUS_BANKING_GRANULARITY_16K) { + base = (svga->seqregs[7] & 0xf0) << 16; + size = 1 * 1024 * 1024; + } else { + base = (svga->seqregs[7] & 0xe0) << 16; + size = 2 * 1024 * 1024; + } + } else if (gd54xx->pci) { + base = gd54xx->lfb_base; + /* if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) + size = 32 * 1024 * 1024; + else */ + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + size = 16 * 1024 * 1024; + else + size = 4 * 1024 * 1024; + } else { /*VLB/ISA/MCA*/ + base = 128 * 1024 * 1024; + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + size = 16 * 1024 * 1024; + else + size = 4 * 1024 * 1024; + } - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { - if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) - mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ - else - mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); - } else - mem_mapping_disable(&gd54xx->mmio_mapping); + mem_mapping_disable(&svga->mapping); + mem_mapping_set_addr(&gd54xx->linear_mapping, base, size); + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)) { + if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) + mem_mapping_disable(&gd54xx->mmio_mapping); /* MMIO is handled in the linear read/write functions */ + else + mem_mapping_set_addr(&gd54xx->mmio_mapping, 0xb8000, 0x00100); + } else + mem_mapping_disable(&gd54xx->mmio_mapping); - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_APERTURE2) && - ((gd54xx->blt.mode & (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC)) == - (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC))) { - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - mem_mapping_set_addr(&gd54xx->aperture2_mapping, gd54xx->lfb_base + (16777216), 16777216); - else - mem_mapping_set_addr(&gd54xx->aperture2_mapping, 0xbc000, 0x04000); - } else - mem_mapping_disable(&gd54xx->aperture2_mapping); + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_APERTURE2) && ((gd54xx->blt.mode & (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC)) == (CIRRUS_BLTMODE_COLOREXPAND | CIRRUS_BLTMODE_MEMSYSSRC))) { + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) + mem_mapping_set_addr(&gd54xx->aperture2_mapping, gd54xx->lfb_base + (16777216), 16777216); + else + mem_mapping_set_addr(&gd54xx->aperture2_mapping, 0xbc000, 0x04000); + } else + mem_mapping_disable(&gd54xx->aperture2_mapping); } } - static void gd54xx_recalctimings(svga_t *svga) { - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - uint8_t clocksel, rdmask; - uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + gd54xx_t *gd54xx = (gd54xx_t *) svga->p; + uint8_t clocksel, rdmask; + uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; svga->rowoffset = (svga->crtc[0x13]) | (((int) (uint32_t) (svga->crtc[0x1b] & 0x10)) << 4); @@ -1660,290 +1638,318 @@ gd54xx_recalctimings(svga_t *svga) svga->map8 = svga->pallook; if (svga->seqregs[7] & CIRRUS_SR7_BPP_SVGA) { - if (linedbl) - svga->render = svga_render_8bpp_lowres; - else { - svga->render = svga_render_8bpp_highres; - if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) - svga->hdisp <<= 1; - } + if (linedbl) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + if ((svga->dispend == 512) && !svga->interlace && gd54xx_is_5434(svga)) + svga->hdisp <<= 1; + } } else if (svga->gdcreg[5] & 0x40) - svga->render = svga_render_8bpp_lowres; + svga->render = svga_render_8bpp_lowres; svga->ma_latch |= ((svga->crtc[0x1b] & 0x01) << 16) | ((svga->crtc[0x1b] & 0xc) << 15); svga->bpp = 8; - if (gd54xx->ramdac.ctrl & 0x80) { - if (gd54xx->ramdac.ctrl & 0x40) { - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) - rdmask = 0xf; - else - rdmask = 0x7; + if (gd54xx->ramdac.ctrl & 0x80) { + if (gd54xx->ramdac.ctrl & 0x40) { + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) + rdmask = 0xf; + else + rdmask = 0x7; - switch (gd54xx->ramdac.ctrl & rdmask) { - case 0: - svga->bpp = 15; - if (linedbl) { - if (gd54xx->ramdac.ctrl & 0x10) - svga->render = svga_render_15bpp_mix_lowres; - else - svga->render = svga_render_15bpp_lowres; - } else { - if (gd54xx->ramdac.ctrl & 0x10) - svga->render = svga_render_15bpp_mix_highres; - else - svga->render = svga_render_15bpp_highres; - } - break; + switch (gd54xx->ramdac.ctrl & rdmask) { + case 0: + svga->bpp = 15; + if (linedbl) { + if (gd54xx->ramdac.ctrl & 0x10) + svga->render = svga_render_15bpp_mix_lowres; + else + svga->render = svga_render_15bpp_lowres; + } else { + if (gd54xx->ramdac.ctrl & 0x10) + svga->render = svga_render_15bpp_mix_highres; + else + svga->render = svga_render_15bpp_highres; + } + break; - case 1: - svga->bpp = 16; - if (linedbl) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; + case 1: + svga->bpp = 16; + if (linedbl) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; - case 5: - if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) { - svga->bpp = 32; - if (linedbl) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) { - svga->rowoffset *= 2; - } - } else { - svga->bpp = 24; - if (linedbl) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - } - break; + case 5: + if (gd54xx_is_5434(svga) && (svga->seqregs[7] & CIRRUS_SR7_BPP_32)) { + svga->bpp = 32; + if (linedbl) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) { + svga->rowoffset *= 2; + } + } else { + svga->bpp = 24; + if (linedbl) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + } + break; - case 8: - svga->bpp = 8; - svga->map8 = video_8togs; - if (linedbl) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; + case 8: + svga->bpp = 8; + svga->map8 = video_8togs; + if (linedbl) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; - case 9: - svga->bpp = 8; - svga->map8 = video_8to32; - if (linedbl) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; + case 9: + svga->bpp = 8; + svga->map8 = video_8to32; + if (linedbl) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; - case 0xf: - switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { - case CIRRUS_SR7_BPP_32: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { - svga->bpp = 32; - if (linedbl) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - svga->rowoffset *= 2; - } - break; + case 0xf: + switch (svga->seqregs[7] & CIRRUS_SR7_BPP_MASK) { + case CIRRUS_SR7_BPP_32: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5430) { + svga->bpp = 32; + if (linedbl) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + svga->rowoffset *= 2; + } + break; - case CIRRUS_SR7_BPP_24: - svga->bpp = 24; - if (linedbl) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; + case CIRRUS_SR7_BPP_24: + svga->bpp = 24; + if (linedbl) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; - case CIRRUS_SR7_BPP_16: - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { - svga->bpp = 16; - if (linedbl) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - } - break; + case CIRRUS_SR7_BPP_16: + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5428) || (svga->crtc[0x27] == CIRRUS_ID_CLGD5426)) { + svga->bpp = 16; + if (linedbl) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + } + break; - case CIRRUS_SR7_BPP_16_DOUBLEVCLK: - svga->bpp = 16; - if (linedbl) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; + case CIRRUS_SR7_BPP_16_DOUBLEVCLK: + svga->bpp = 16; + if (linedbl) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; - case CIRRUS_SR7_BPP_8: - svga->bpp = 8; - if (linedbl) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - } - break; - } - } else { - svga->bpp = 15; - if (linedbl) { - if (gd54xx->ramdac.ctrl & 0x10) - svga->render = svga_render_15bpp_mix_lowres; - else - svga->render = svga_render_15bpp_lowres; - } else { - if (gd54xx->ramdac.ctrl & 0x10) - svga->render = svga_render_15bpp_mix_highres; - else - svga->render = svga_render_15bpp_highres; - } - } + case CIRRUS_SR7_BPP_8: + svga->bpp = 8; + if (linedbl) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; + } + break; + } + } else { + svga->bpp = 15; + if (linedbl) { + if (gd54xx->ramdac.ctrl & 0x10) + svga->render = svga_render_15bpp_mix_lowres; + else + svga->render = svga_render_15bpp_lowres; + } else { + if (gd54xx->ramdac.ctrl & 0x10) + svga->render = svga_render_15bpp_mix_highres; + else + svga->render = svga_render_15bpp_highres; + } + } } clocksel = (svga->miscout >> 2) & 3; if (!gd54xx->vclk_n[clocksel] || !gd54xx->vclk_d[clocksel]) - svga->clock = (cpuclock * (float)(1ull << 32)) / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); + svga->clock = (cpuclock * (float) (1ull << 32)) / ((svga->miscout & 0xc) ? 28322000.0 : 25175000.0); else { - int n = gd54xx->vclk_n[clocksel] & 0x7f; - int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; - int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; - float freq = (14318184.0 * ((float)n / ((float)d * m))); - if (gd54xx_is_5422(svga)) { - switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { - case 2: - freq /= 2.0; - break; - case 4: - if (!gd54xx_is_5434(svga)) - freq /= 3.0; - break; - } - } - svga->clock = (cpuclock * (double)(1ull << 32)) / freq; + int n = gd54xx->vclk_n[clocksel] & 0x7f; + int d = (gd54xx->vclk_d[clocksel] & 0x3e) >> 1; + int m = gd54xx->vclk_d[clocksel] & 0x01 ? 2 : 1; + float freq = (14318184.0 * ((float) n / ((float) d * m))); + if (gd54xx_is_5422(svga)) { + switch (svga->seqregs[7] & (gd54xx_is_5434(svga) ? 0xe : 6)) { + case 2: + freq /= 2.0; + break; + case 4: + if (!gd54xx_is_5434(svga)) + freq /= 3.0; + break; + } + } + svga->clock = (cpuclock * (double) (1ull << 32)) / freq; } svga->vram_display_mask = (svga->crtc[0x1b] & 2) ? gd54xx->vram_mask : 0x3ffff; } - -static -void gd54xx_hwcursor_draw(svga_t *svga, int displine) +static void +gd54xx_hwcursor_draw(svga_t *svga, int displine) { - gd54xx_t *gd54xx = (gd54xx_t *)svga->p; - int x, xx, comb, b0, b1; - uint8_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int pitch = (svga->hwcursor.cur_xsize == 64) ? 16 : 4; - uint32_t bgcol = gd54xx->extpallook[0x00]; - uint32_t fgcol = gd54xx->extpallook[0x0f]; - uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; + gd54xx_t *gd54xx = (gd54xx_t *) svga->p; + int x, xx, comb, b0, b1; + uint8_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + int pitch = (svga->hwcursor.cur_xsize == 64) ? 16 : 4; + uint32_t bgcol = gd54xx->extpallook[0x00]; + uint32_t fgcol = gd54xx->extpallook[0x0f]; + uint8_t linedbl = svga->dispend * 9 / 10 >= svga->hdisp; offset <<= linedbl; if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; + svga->hwcursor_latch.addr += pitch; for (x = 0; x < svga->hwcursor.cur_xsize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask]; - if (svga->hwcursor.cur_xsize == 64) - dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & svga->vram_display_mask]; - else - dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & svga->vram_display_mask]; - for (xx = 0; xx < 8; xx++) { - b0 = (dat[0] >> (7 - xx)) & 1; - b1 = (dat[1] >> (7 - xx)) & 1; - comb = (b1 | (b0 << 1)); - if (offset >= svga->hwcursor_latch.x) { - switch(comb) { - case 0: - /* The original screen pixel is shown (invisible cursor) */ - break; - case 1: - /* The pixel is shown in the cursor background color */ - ((uint32_t *)buffer32->line[displine])[offset + svga->x_add] = bgcol; - break; - case 2: - /* The pixel is shown as the inverse of the original screen pixel - (XOR cursor) */ - ((uint32_t *)buffer32->line[displine])[offset + svga->x_add] ^= 0xffffff; - break; - case 3: - /* The pixel is shown in the cursor foreground color */ - ((uint32_t *)buffer32->line[displine])[offset + svga->x_add] = fgcol; - break; - } - } + dat[0] = svga->vram[svga->hwcursor_latch.addr & svga->vram_display_mask]; + if (svga->hwcursor.cur_xsize == 64) + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x08) & svga->vram_display_mask]; + else + dat[1] = svga->vram[(svga->hwcursor_latch.addr + 0x80) & svga->vram_display_mask]; + for (xx = 0; xx < 8; xx++) { + b0 = (dat[0] >> (7 - xx)) & 1; + b1 = (dat[1] >> (7 - xx)) & 1; + comb = (b1 | (b0 << 1)); + if (offset >= svga->hwcursor_latch.x) { + switch (comb) { + case 0: + /* The original screen pixel is shown (invisible cursor) */ + break; + case 1: + /* The pixel is shown in the cursor background color */ + ((uint32_t *) buffer32->line[displine])[offset + svga->x_add] = bgcol; + break; + case 2: + /* The pixel is shown as the inverse of the original screen pixel + (XOR cursor) */ + ((uint32_t *) buffer32->line[displine])[offset + svga->x_add] ^= 0xffffff; + break; + case 3: + /* The pixel is shown in the cursor foreground color */ + ((uint32_t *) buffer32->line[displine])[offset + svga->x_add] = fgcol; + break; + } + } - offset++; - } - svga->hwcursor_latch.addr++; + offset++; + } + svga->hwcursor_latch.addr++; } if (svga->hwcursor.cur_xsize == 64) - svga->hwcursor_latch.addr += 8; + svga->hwcursor_latch.addr += 8; if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; + svga->hwcursor_latch.addr += pitch; } - static void -gd54xx_rop(gd54xx_t *gd54xx, uint8_t *res, uint8_t *dst, const uint8_t *src) { +gd54xx_rop(gd54xx_t *gd54xx, uint8_t *res, uint8_t *dst, const uint8_t *src) +{ switch (gd54xx->blt.rop) { - case 0x00: *res = 0x00; break; - case 0x05: *res = *src & *dst; break; - case 0x06: *res = *dst; break; - case 0x09: *res = *src & ~*dst; break; - case 0x0b: *res = ~*dst; break; - case 0x0d: *res = *src; break; - case 0x0e: *res = 0xff; break; - case 0x50: *res = ~*src & *dst; break; - case 0x59: *res = *src ^ *dst; break; - case 0x6d: *res = *src | *dst; break; - case 0x90: *res = ~(*src | *dst); break; - case 0x95: *res = ~(*src ^ *dst); break; - case 0xad: *res = *src | ~*dst; break; - case 0xd0: *res = ~*src; break; - case 0xd6: *res = ~*src | *dst; break; - case 0xda: *res = ~(*src & *dst); break; + case 0x00: + *res = 0x00; + break; + case 0x05: + *res = *src & *dst; + break; + case 0x06: + *res = *dst; + break; + case 0x09: + *res = *src & ~*dst; + break; + case 0x0b: + *res = ~*dst; + break; + case 0x0d: + *res = *src; + break; + case 0x0e: + *res = 0xff; + break; + case 0x50: + *res = ~*src & *dst; + break; + case 0x59: + *res = *src ^ *dst; + break; + case 0x6d: + *res = *src | *dst; + break; + case 0x90: + *res = ~(*src | *dst); + break; + case 0x95: + *res = ~(*src ^ *dst); + break; + case 0xad: + *res = *src | ~*dst; + break; + case 0xd0: + *res = ~*src; + break; + case 0xd6: + *res = ~*src | *dst; + break; + case 0xda: + *res = ~(*src & *dst); + break; } } - static uint8_t gd54xx_mem_sys_dest_read(gd54xx_t *gd54xx) { uint8_t ret = 0xff; if (gd54xx->blt.msd_buf_cnt != 0) { - ret = gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos++]; - gd54xx->blt.msd_buf_cnt--; + ret = gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos++]; + gd54xx->blt.msd_buf_cnt--; - if (gd54xx->blt.msd_buf_cnt == 0) { - if (gd54xx->countminusone == 1) { - gd54xx->blt.msd_buf_pos = 0; - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && - !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) - gd54xx_start_blit(0xff, 8, gd54xx, &gd54xx->svga); - else - gd54xx_start_blit(0xffffffff, 32, gd54xx, &gd54xx->svga); - } else - gd54xx_reset_blit(gd54xx); /* End of blit, do no more. */ - } + if (gd54xx->blt.msd_buf_cnt == 0) { + if (gd54xx->countminusone == 1) { + gd54xx->blt.msd_buf_pos = 0; + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) + gd54xx_start_blit(0xff, 8, gd54xx, &gd54xx->svga); + else + gd54xx_start_blit(0xffffffff, 32, gd54xx, &gd54xx->svga); + } else + gd54xx_reset_blit(gd54xx); /* End of blit, do no more. */ + } } return ret; } - static void gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val) { @@ -1954,31 +1960,28 @@ gd54xx_mem_sys_src_write(gd54xx_t *gd54xx, uint8_t val) gd54xx->blt.sys_cnt = (gd54xx->blt.sys_cnt + 1) & 3; if (gd54xx->blt.sys_cnt == 0) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && - !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { - for (i = 0; i < 32; i += 8) - gd54xx_start_blit((gd54xx->blt.sys_src32 >> i) & 0xff, 8, gd54xx, &gd54xx->svga); - } else - gd54xx_start_blit(gd54xx->blt.sys_src32, 32, gd54xx, &gd54xx->svga); + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && !(gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + for (i = 0; i < 32; i += 8) + gd54xx_start_blit((gd54xx->blt.sys_src32 >> i) & 0xff, 8, gd54xx, &gd54xx->svga); + } else + gd54xx_start_blit(gd54xx->blt.sys_src32, 32, gd54xx, &gd54xx->svga); } } - static void gd54xx_write(uint32_t addr, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); - return; + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd54xx_mem_sys_src_write(gd54xx, val); + return; } if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_write(addr, val, svga); - return; + svga_write(addr, val, svga); + return; } addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -1986,69 +1989,64 @@ gd54xx_write(uint32_t addr, uint8_t val, void *p) svga_write_linear(addr, val, svga); } - static void gd54xx_writew(uint32_t addr, uint16_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr + 1, val >> 8, gd54xx); - return; + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd54xx_write(addr, val, gd54xx); + gd54xx_write(addr + 1, val >> 8, gd54xx); + return; } if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writew(addr, val, svga); - return; + svga_writew(addr, val, svga); + return; } addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) - svga_writew_linear(addr, val, svga); + svga_writew_linear(addr, val, svga); else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr + 1, val >> 8, svga); + svga_write_linear(addr, val, svga); + svga_write_linear(addr + 1, val >> 8, svga); } } - static void gd54xx_writel(uint32_t addr, uint32_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr + 1, val >> 8, gd54xx); - gd54xx_write(addr + 2, val >> 16, gd54xx); - gd54xx_write(addr + 3, val >> 24, gd54xx); - return; + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd54xx_write(addr, val, gd54xx); + gd54xx_write(addr + 1, val >> 8, gd54xx); + gd54xx_write(addr + 2, val >> 16, gd54xx); + gd54xx_write(addr + 3, val >> 24, gd54xx); + return; } if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writel(addr, val, svga); - return; + svga_writel(addr, val, svga); + return; } addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; if (svga->writemode < 4) - svga_writel_linear(addr, val, svga); + svga_writel_linear(addr, val, svga); else { - svga_write_linear(addr, val, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); + svga_write_linear(addr, val, svga); + svga_write_linear(addr + 1, val >> 8, svga); + svga_write_linear(addr + 2, val >> 16, svga); + svga_write_linear(addr + 3, val >> 24, svga); } } - /* This adds write modes 4 and 5 to SVGA. */ static void gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) @@ -2056,57 +2054,54 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr) uint32_t i, j; switch (svga->writemode) { - case 4: - if (svga->adv_flags & FLAG_ADDR_BY16) { - addr &= svga->decode_mask; + case 4: + if (svga->adv_flags & FLAG_ADDR_BY16) { + addr &= svga->decode_mask; - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) { - svga->vram[addr + (i << 1)] = svga->gdcreg[1]; - svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11]; - } - } - } else { - addr <<= 1; - addr &= svga->decode_mask; + for (i = 0; i < 8; i++) { + if (val & svga->seqregs[2] & (0x80 >> i)) { + svga->vram[addr + (i << 1)] = svga->gdcreg[1]; + svga->vram[addr + (i << 1) + 1] = svga->gdcreg[0x11]; + } + } + } else { + addr <<= 1; + addr &= svga->decode_mask; - for (i = 0; i < 8; i++) { - if (val & svga->seqregs[2] & (0x80 >> i)) - svga->vram[addr + i] = svga->gdcreg[1]; - } - } - break; + for (i = 0; i < 8; i++) { + if (val & svga->seqregs[2] & (0x80 >> i)) + svga->vram[addr + i] = svga->gdcreg[1]; + } + } + break; - case 5: - if (svga->adv_flags & FLAG_ADDR_BY16) { - addr &= svga->decode_mask; + case 5: + if (svga->adv_flags & FLAG_ADDR_BY16) { + addr &= svga->decode_mask; - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) { - svga->vram[addr + (i << 1)] = (val & j) ? - svga->gdcreg[1] : svga->gdcreg[0]; - svga->vram[addr + (i << 1) + 1] = (val & j) ? - svga->gdcreg[0x11] : svga->gdcreg[0x10]; - } - } - } else { - addr <<= 1; - addr &= svga->decode_mask; + for (i = 0; i < 8; i++) { + j = (0x80 >> i); + if (svga->seqregs[2] & j) { + svga->vram[addr + (i << 1)] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; + svga->vram[addr + (i << 1) + 1] = (val & j) ? svga->gdcreg[0x11] : svga->gdcreg[0x10]; + } + } + } else { + addr <<= 1; + addr &= svga->decode_mask; - for (i = 0; i < 8; i++) { - j = (0x80 >> i); - if (svga->seqregs[2] & j) - svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; - } - } - break; + for (i = 0; i < 8; i++) { + j = (0x80 >> i); + if (svga->seqregs[2] & j) + svga->vram[addr + i] = (val & j) ? svga->gdcreg[1] : svga->gdcreg[0]; + } + } + break; } svga->changedvram[addr >> 12] = changeframecount; } - static uint8_t gd54xx_get_aperture(uint32_t addr) { @@ -2114,995 +2109,948 @@ gd54xx_get_aperture(uint32_t addr) return (uint8_t) (ap & 0x03); } - static int gd54xx_aperture2_enabled(gd54xx_t *gd54xx) { svga_t *svga = &gd54xx->svga; if (svga->crtc[0x27] < CIRRUS_ID_CLGD5436) - return 0; + return 0; if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) - return 0; + return 0; if (!(gd54xx->blt.status & CIRRUS_BLT_APERTURE2)) - return 0; + return 0; return 1; } - static uint8_t gd54xx_readb_linear(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; uint8_t ap = gd54xx_get_aperture(addr); - addr &= 0x003fffff; /* 4 MB mask */ + addr &= 0x003fffff; /* 4 MB mask */ if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_read_linear(addr, svga); + return svga_read_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) - return gd543x_mmio_read(addr & 0x000000ff, gd54xx); + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) + return gd543x_mmio_read(addr & 0x000000ff, gd54xx); } /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + return gd54xx_mem_sys_dest_read(gd54xx); switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return 0xff; + case 0: + default: + break; + case 1: + /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ + addr ^= 0x00000001; + break; + case 2: + /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ + addr ^= 0x00000003; + break; + case 3: + return 0xff; } return svga_read_linear(addr, svga); } - static uint16_t gd54xx_readw_linear(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(addr); uint16_t temp; - addr &= 0x003fffff; /* 4 MB mask */ + addr &= 0x003fffff; /* 4 MB mask */ if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_readw_linear(addr, svga); + return svga_readw_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - temp = gd543x_mmio_readw(addr & 0x000000ff, gd54xx); - return temp; - } + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + temp = gd543x_mmio_readw(addr & 0x000000ff, gd54xx); + return temp; + } } /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, p); - temp |= gd54xx_readb_linear(addr + 1, p) << 8; - return temp; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + temp = gd54xx_readb_linear(addr, p); + temp |= gd54xx_readb_linear(addr + 1, p) << 8; + return temp; } switch (ap) { - case 0: - default: - return svga_readw_linear(addr, svga); - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000002; - case 1: - temp = svga_readb_linear(addr + 1, svga); - temp |= (svga_readb_linear(addr, svga) << 8); + case 0: + default: + return svga_readw_linear(addr, svga); + case 2: + /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ + addr ^= 0x00000002; + case 1: + temp = svga_readb_linear(addr + 1, svga); + temp |= (svga_readb_linear(addr, svga) << 8); - if (svga->fast) - cycles -= video_timing_read_w; + if (svga->fast) + cycles -= video_timing_read_w; - return temp; - case 3: - return 0xffff; + return temp; + case 3: + return 0xffff; } } - static uint32_t gd54xx_readl_linear(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; - uint8_t ap = gd54xx_get_aperture(addr); + uint8_t ap = gd54xx_get_aperture(addr); uint32_t temp; - addr &= 0x003fffff; /* 4 MB mask */ + addr &= 0x003fffff; /* 4 MB mask */ if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_readl_linear(addr, svga); + return svga_readl_linear(addr, svga); if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - temp = gd543x_mmio_readl(addr & 0x000000ff, gd54xx); - return temp; - } + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + temp = gd543x_mmio_readl(addr & 0x000000ff, gd54xx); + return temp; + } } /* Do mem sys dest reads here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - temp = gd54xx_readb_linear(addr, p); - temp |= gd54xx_readb_linear(addr + 1, p) << 8; - temp |= gd54xx_readb_linear(addr + 2, p) << 16; - temp |= gd54xx_readb_linear(addr + 3, p) << 24; - return temp; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + temp = gd54xx_readb_linear(addr, p); + temp |= gd54xx_readb_linear(addr + 1, p) << 8; + temp |= gd54xx_readb_linear(addr + 2, p) << 16; + temp |= gd54xx_readb_linear(addr + 3, p) << 24; + return temp; } switch (ap) { - case 0: - default: - return svga_readl_linear(addr, svga); - case 1: - temp = svga_readb_linear(addr + 1, svga); - temp |= (svga_readb_linear(addr, svga) << 8); - temp |= (svga_readb_linear(addr + 3, svga) << 16); - temp |= (svga_readb_linear(addr + 2, svga) << 24); + case 0: + default: + return svga_readl_linear(addr, svga); + case 1: + temp = svga_readb_linear(addr + 1, svga); + temp |= (svga_readb_linear(addr, svga) << 8); + temp |= (svga_readb_linear(addr + 3, svga) << 16); + temp |= (svga_readb_linear(addr + 2, svga) << 24); - if (svga->fast) - cycles -= video_timing_read_l; + if (svga->fast) + cycles -= video_timing_read_l; - return temp; - case 2: - temp = svga_readb_linear(addr + 3, svga); - temp |= (svga_readb_linear(addr + 2, svga) << 8); - temp |= (svga_readb_linear(addr + 1, svga) << 16); - temp |= (svga_readb_linear(addr, svga) << 24); + return temp; + case 2: + temp = svga_readb_linear(addr + 3, svga); + temp |= (svga_readb_linear(addr + 2, svga) << 8); + temp |= (svga_readb_linear(addr + 1, svga) << 16); + temp |= (svga_readb_linear(addr, svga) << 24); - if (svga->fast) - cycles -= video_timing_read_l; + if (svga->fast) + cycles -= video_timing_read_l; - return temp; - case 3: - return 0xffffffff; + return temp; + case 3: + return 0xffffffff; } } - static uint8_t gd5436_aperture2_readb(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + return gd54xx_mem_sys_dest_read(gd54xx); return 0xff; } - static uint16_t gd5436_aperture2_readw(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - uint16_t ret = 0xffff; + gd54xx_t *gd54xx = (gd54xx_t *) p; + uint16_t ret = 0xffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd5436_aperture2_readb(addr, p); - ret |= gd5436_aperture2_readb(addr + 1, p) << 8; - return ret; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd5436_aperture2_readb(addr, p); + ret |= gd5436_aperture2_readb(addr + 1, p) << 8; + return ret; } return ret; } - static uint32_t gd5436_aperture2_readl(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - uint32_t ret = 0xffffffff; + gd54xx_t *gd54xx = (gd54xx_t *) p; + uint32_t ret = 0xffffffff; - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd5436_aperture2_readb(addr, p); - ret |= gd5436_aperture2_readb(addr + 1, p) << 8; - ret |= gd5436_aperture2_readb(addr + 2, p) << 16; - ret |= gd5436_aperture2_readb(addr + 3, p) << 24; - return ret; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd5436_aperture2_readb(addr, p); + ret |= gd5436_aperture2_readb(addr + 1, p) << 8; + ret |= gd5436_aperture2_readb(addr + 2, p) << 16; + ret |= gd5436_aperture2_readb(addr + 3, p) << 24; + return ret; } return ret; } - static void gd5436_aperture2_writeb(uint32_t addr, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - gd54xx_mem_sys_src_write(gd54xx, val); + && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + gd54xx_mem_sys_src_write(gd54xx, val); } - static void gd5436_aperture2_writew(uint32_t addr, uint16_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd5436_aperture2_writeb(addr, val, gd54xx); - gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); + && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd5436_aperture2_writeb(addr, val, gd54xx); + gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); } } - static void gd5436_aperture2_writel(uint32_t addr, uint32_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest - && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd5436_aperture2_writeb(addr, val, gd54xx); - gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); - gd5436_aperture2_writeb(addr + 2, val >> 16, gd54xx); - gd5436_aperture2_writeb(addr + 3, val >> 24, gd54xx); + && gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd5436_aperture2_writeb(addr, val, gd54xx); + gd5436_aperture2_writeb(addr + 1, val >> 8, gd54xx); + gd5436_aperture2_writeb(addr + 2, val >> 16, gd54xx); + gd5436_aperture2_writeb(addr + 3, val >> 24, gd54xx); } } - static void gd54xx_writeb_linear(uint32_t addr, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_write_linear(addr, val, svga); - return; + svga_write_linear(addr, val, svga); + return; } - addr &= 0x003fffff; /* 4 MB mask */ + addr &= 0x003fffff; /* 4 MB mask */ if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - gd543x_mmio_write(addr & 0x000000ff, val, gd54xx); - return; - } + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + gd543x_mmio_write(addr & 0x000000ff, val, gd54xx); + return; + } } /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); - return; + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd54xx_mem_sys_src_write(gd54xx, val); + return; } switch (ap) { - case 0: - default: - break; - case 1: - /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ - addr ^= 0x00000001; - break; - case 2: - /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ - addr ^= 0x00000003; - break; - case 3: - return; + case 0: + default: + break; + case 1: + /* 0 -> 1, 1 -> 0, 2 -> 3, 3 -> 2 */ + addr ^= 0x00000001; + break; + case 2: + /* 0 -> 3, 1 -> 2, 2 -> 1, 3 -> 0 */ + addr ^= 0x00000003; + break; + case 3: + return; } svga_write_linear(addr, val, svga); } - static void gd54xx_writew_linear(uint32_t addr, uint16_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writew_linear(addr, val, svga); - return; + svga_writew_linear(addr, val, svga); + return; } - addr &= 0x003fffff; /* 4 MB mask */ + addr &= 0x003fffff; /* 4 MB mask */ if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - gd543x_mmio_writew(addr & 0x000000ff, val, gd54xx); - return; - } + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + gd543x_mmio_writew(addr & 0x000000ff, val, gd54xx); + return; + } } /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); - return; + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd54xx_writeb_linear(addr, val, gd54xx); + gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); + return; } if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writew_linear(addr, val, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); + switch (ap) { + case 0: + default: + svga_writew_linear(addr, val, svga); + return; + case 2: + addr ^= 0x00000002; + case 1: + svga_writeb_linear(addr + 1, val & 0xff, svga); + svga_writeb_linear(addr, val >> 8, svga); - if (svga->fast) - cycles -= video_timing_write_w; - case 3: - return; - } + if (svga->fast) + cycles -= video_timing_write_w; + case 3: + return; + } } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr + 1, val >> 8, svga); - return; - case 2: - addr ^= 0x00000002; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - case 3: - return; - } + switch (ap) { + case 0: + default: + svga_write_linear(addr, val & 0xff, svga); + svga_write_linear(addr + 1, val >> 8, svga); + return; + case 2: + addr ^= 0x00000002; + case 1: + svga_write_linear(addr + 1, val & 0xff, svga); + svga_write_linear(addr, val >> 8, svga); + case 3: + return; + } } } - static void gd54xx_writel_linear(uint32_t addr, uint32_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; uint8_t ap = gd54xx_get_aperture(addr); if ((svga->seqregs[0x07] & 0x01) == 0) { - svga_writel_linear(addr, val, svga); - return; + svga_writel_linear(addr, val, svga); + return; } - addr &= 0x003fffff; /* 4 MB mask */ + addr &= 0x003fffff; /* 4 MB mask */ if ((addr >= (svga->vram_max - 256)) && (addr < svga->vram_max)) { - if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { - gd543x_mmio_writel(addr & 0x000000ff, val, gd54xx); - return; - } + if ((svga->seqregs[0x17] & CIRRUS_MMIO_ENABLE) && (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR)) { + gd543x_mmio_writel(addr & 0x000000ff, val, gd54xx); + return; + } } /* Do mem sys src writes here if the blitter is neither paused, nor is there a second aperture. */ - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_writeb_linear(addr, val, gd54xx); - gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); - gd54xx_writeb_linear(addr + 2, val >> 16, gd54xx); - gd54xx_writeb_linear(addr + 3, val >> 24, gd54xx); - return; + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !gd54xx_aperture2_enabled(gd54xx) && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd54xx_writeb_linear(addr, val, gd54xx); + gd54xx_writeb_linear(addr + 1, val >> 8, gd54xx); + gd54xx_writeb_linear(addr + 2, val >> 16, gd54xx); + gd54xx_writeb_linear(addr + 3, val >> 24, gd54xx); + return; } if (svga->writemode < 4) { - switch(ap) { - case 0: - default: - svga_writel_linear(addr, val, svga); - return; - case 1: - svga_writeb_linear(addr + 1, val & 0xff, svga); - svga_writeb_linear(addr, val >> 8, svga); - svga_writeb_linear(addr + 3, val >> 16, svga); - svga_writeb_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_writeb_linear(addr + 3, val & 0xff, svga); - svga_writeb_linear(addr + 2, val >> 8, svga); - svga_writeb_linear(addr + 1, val >> 16, svga); - svga_writeb_linear(addr, val >> 24, svga); - case 3: - return; - } + switch (ap) { + case 0: + default: + svga_writel_linear(addr, val, svga); + return; + case 1: + svga_writeb_linear(addr + 1, val & 0xff, svga); + svga_writeb_linear(addr, val >> 8, svga); + svga_writeb_linear(addr + 3, val >> 16, svga); + svga_writeb_linear(addr + 2, val >> 24, svga); + return; + case 2: + svga_writeb_linear(addr + 3, val & 0xff, svga); + svga_writeb_linear(addr + 2, val >> 8, svga); + svga_writeb_linear(addr + 1, val >> 16, svga); + svga_writeb_linear(addr, val >> 24, svga); + case 3: + return; + } } else { - switch(ap) { - case 0: - default: - svga_write_linear(addr, val & 0xff, svga); - svga_write_linear(addr+1, val >> 8, svga); - svga_write_linear(addr+2, val >> 16, svga); - svga_write_linear(addr+3, val >> 24, svga); - return; - case 1: - svga_write_linear(addr + 1, val & 0xff, svga); - svga_write_linear(addr, val >> 8, svga); - svga_write_linear(addr + 3, val >> 16, svga); - svga_write_linear(addr + 2, val >> 24, svga); - return; - case 2: - svga_write_linear(addr + 3, val & 0xff, svga); - svga_write_linear(addr + 2, val >> 8, svga); - svga_write_linear(addr + 1, val >> 16, svga); - svga_write_linear(addr, val >> 24, svga); - case 3: - return; - } + switch (ap) { + case 0: + default: + svga_write_linear(addr, val & 0xff, svga); + svga_write_linear(addr + 1, val >> 8, svga); + svga_write_linear(addr + 2, val >> 16, svga); + svga_write_linear(addr + 3, val >> 24, svga); + return; + case 1: + svga_write_linear(addr + 1, val & 0xff, svga); + svga_write_linear(addr, val >> 8, svga); + svga_write_linear(addr + 3, val >> 16, svga); + svga_write_linear(addr + 2, val >> 24, svga); + return; + case 2: + svga_write_linear(addr + 3, val & 0xff, svga); + svga_write_linear(addr + 2, val >> 8, svga); + svga_write_linear(addr + 1, val >> 16, svga); + svga_write_linear(addr, val >> 24, svga); + case 3: + return; + } } } - static uint8_t gd54xx_read(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_read(addr, svga); + return svga_read(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) - return gd54xx_mem_sys_dest_read(gd54xx); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) + return gd54xx_mem_sys_dest_read(gd54xx); addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_read_linear(addr, svga); } - static uint16_t gd54xx_readw(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint16_t ret; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint16_t ret; if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_readw(addr, svga); + return svga_readw(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_read(addr, p); - ret |= gd54xx_read(addr + 1, p) << 8; - return ret; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd54xx_read(addr, p); + ret |= gd54xx_read(addr + 1, p) << 8; + return ret; } addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readw_linear(addr, svga); } - static uint32_t gd54xx_readl(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint32_t ret; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint32_t ret; if ((svga->seqregs[0x07] & 0x01) == 0) - return svga_readl(addr, svga); + return svga_readl(addr, svga); - if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_read(addr, p); - ret |= gd54xx_read(addr + 1, p) << 8; - ret |= gd54xx_read(addr + 2, p) << 16; - ret |= gd54xx_read(addr + 3, p) << 24; - return ret; + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd54xx_read(addr, p); + ret |= gd54xx_read(addr + 1, p) << 8; + ret |= gd54xx_read(addr + 2, p) << 16; + ret |= gd54xx_read(addr + 3, p) << 24; + return ret; } addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; return svga_readl_linear(addr, svga); } - static int gd543x_do_mmio(svga_t *svga, uint32_t addr) { if (svga->seqregs[0x17] & CIRRUS_MMIO_USE_PCIADDR) - return 1; + return 1; else - return ((addr & ~0xff) == 0xb8000); + return ((addr & ~0xff) == 0xb8000); } - static void gd543x_mmio_write(uint32_t addr, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint8_t old; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint8_t old; if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x00: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffffff00) | val; - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; - break; - case 0x01: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); - break; - case 0x02: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x03: - if (gd54xx_is_5434(svga)) - gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ffffff) | (val << 24); - break; + switch (addr & 0xff) { + case 0x00: + if (gd54xx_is_5434(svga)) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffffff00) | val; + else + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00) | val; + break; + case 0x01: + if (gd54xx_is_5434(svga)) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xffff00ff) | (val << 8); + else + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ff) | (val << 8); + break; + case 0x02: + if (gd54xx_is_5434(svga)) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0xff00ffff) | (val << 16); + break; + case 0x03: + if (gd54xx_is_5434(svga)) + gd54xx->blt.bg_col = (gd54xx->blt.bg_col & 0x00ffffff) | (val << 24); + break; - case 0x04: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffffff00) | val; - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; - break; - case 0x05: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffff00ff) | (val << 8); - else - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); - break; - case 0x06: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x07: - if (gd54xx_is_5434(svga)) - gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ffffff) | (val << 24); - break; + case 0x04: + if (gd54xx_is_5434(svga)) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffffff00) | val; + else + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00) | val; + break; + case 0x05: + if (gd54xx_is_5434(svga)) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xffff00ff) | (val << 8); + else + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ff) | (val << 8); + break; + case 0x06: + if (gd54xx_is_5434(svga)) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0xff00ffff) | (val << 16); + break; + case 0x07: + if (gd54xx_is_5434(svga)) + gd54xx->blt.fg_col = (gd54xx->blt.fg_col & 0x00ffffff) | (val << 24); + break; - case 0x08: - gd54xx->blt.width = (gd54xx->blt.width & 0xff00) | val; - break; - case 0x09: - gd54xx->blt.width = (gd54xx->blt.width & 0x00ff) | (val << 8); - if (gd54xx_is_5434(svga)) - gd54xx->blt.width &= 0x1fff; - else - gd54xx->blt.width &= 0x07ff; - break; - case 0x0a: - gd54xx->blt.height = (gd54xx->blt.height & 0xff00) | val; - break; - case 0x0b: - gd54xx->blt.height = (gd54xx->blt.height & 0x00ff) | (val << 8); - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - gd54xx->blt.height &= 0x07ff; - else - gd54xx->blt.height &= 0x03ff; - break; - case 0x0c: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0xff00) | val; - break; - case 0x0d: - gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0x00ff) | (val << 8); - gd54xx->blt.dst_pitch &= 0x1fff; - break; - case 0x0e: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0xff00) | val; - break; - case 0x0f: - gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0x00ff) | (val << 8); - gd54xx->blt.src_pitch &= 0x1fff; - break; + case 0x08: + gd54xx->blt.width = (gd54xx->blt.width & 0xff00) | val; + break; + case 0x09: + gd54xx->blt.width = (gd54xx->blt.width & 0x00ff) | (val << 8); + if (gd54xx_is_5434(svga)) + gd54xx->blt.width &= 0x1fff; + else + gd54xx->blt.width &= 0x07ff; + break; + case 0x0a: + gd54xx->blt.height = (gd54xx->blt.height & 0xff00) | val; + break; + case 0x0b: + gd54xx->blt.height = (gd54xx->blt.height & 0x00ff) | (val << 8); + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + gd54xx->blt.height &= 0x07ff; + else + gd54xx->blt.height &= 0x03ff; + break; + case 0x0c: + gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0xff00) | val; + break; + case 0x0d: + gd54xx->blt.dst_pitch = (gd54xx->blt.dst_pitch & 0x00ff) | (val << 8); + gd54xx->blt.dst_pitch &= 0x1fff; + break; + case 0x0e: + gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0xff00) | val; + break; + case 0x0f: + gd54xx->blt.src_pitch = (gd54xx->blt.src_pitch & 0x00ff) | (val << 8); + gd54xx->blt.src_pitch &= 0x1fff; + break; - case 0x10: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xffff00) | val; - break; - case 0x11: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xff00ff) | (val << 8); - break; - case 0x12: - gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.dst_addr &= 0x3fffff; - else - gd54xx->blt.dst_addr &= 0x1fffff; + case 0x10: + gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xffff00) | val; + break; + case 0x11: + gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0xff00ff) | (val << 8); + break; + case 0x12: + gd54xx->blt.dst_addr = (gd54xx->blt.dst_addr & 0x00ffff) | (val << 16); + if (gd54xx_is_5434(svga)) + gd54xx->blt.dst_addr &= 0x3fffff; + else + gd54xx->blt.dst_addr &= 0x1fffff; - if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART) && - !(gd54xx->blt.status & CIRRUS_BLT_BUSY)) { - gd54xx->blt.status |= CIRRUS_BLT_BUSY; - gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); - } - break; + if ((svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) && (gd54xx->blt.status & CIRRUS_BLT_AUTOSTART) && !(gd54xx->blt.status & CIRRUS_BLT_BUSY)) { + gd54xx->blt.status |= CIRRUS_BLT_BUSY; + gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); + } + break; - case 0x14: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xffff00) | val; - break; - case 0x15: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xff00ff) | (val << 8); - break; - case 0x16: - gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0x00ffff) | (val << 16); - if (gd54xx_is_5434(svga)) - gd54xx->blt.src_addr &= 0x3fffff; - else - gd54xx->blt.src_addr &= 0x1fffff; - break; + case 0x14: + gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xffff00) | val; + break; + case 0x15: + gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0xff00ff) | (val << 8); + break; + case 0x16: + gd54xx->blt.src_addr = (gd54xx->blt.src_addr & 0x00ffff) | (val << 16); + if (gd54xx_is_5434(svga)) + gd54xx->blt.src_addr &= 0x3fffff; + else + gd54xx->blt.src_addr &= 0x1fffff; + break; - case 0x17: - gd54xx->blt.mask = val; - break; - case 0x18: - gd54xx->blt.mode = val; - gd543x_recalc_mapping(gd54xx); - break; + case 0x17: + gd54xx->blt.mask = val; + break; + case 0x18: + gd54xx->blt.mode = val; + gd543x_recalc_mapping(gd54xx); + break; - case 0x1a: - gd54xx->blt.rop = val; - break; + case 0x1a: + gd54xx->blt.rop = val; + break; - case 0x1b: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - gd54xx->blt.modeext = val; - break; + case 0x1b: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + gd54xx->blt.modeext = val; + break; - case 0x1c: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0xff00) | val; - break; - case 0x1d: - gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0x00ff) | (val << 8); - break; + case 0x1c: + gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0xff00) | val; + break; + case 0x1d: + gd54xx->blt.trans_col = (gd54xx->blt.trans_col & 0x00ff) | (val << 8); + break; - case 0x20: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0xff00) | val; - break; - case 0x21: - gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0x00ff) | (val << 8); - break; + case 0x20: + gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0xff00) | val; + break; + case 0x21: + gd54xx->blt.trans_mask = (gd54xx->blt.trans_mask & 0x00ff) | (val << 8); + break; - case 0x40: - old = gd54xx->blt.status; - gd54xx->blt.status = val; - gd543x_recalc_mapping(gd54xx); - if (!(old & CIRRUS_BLT_RESET) && (gd54xx->blt.status & CIRRUS_BLT_RESET)) - gd54xx_reset_blit(gd54xx); - else if (!(old & CIRRUS_BLT_START) && (gd54xx->blt.status & CIRRUS_BLT_START)) { - gd54xx->blt.status |= CIRRUS_BLT_BUSY; - gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); - } - break; - } + case 0x40: + old = gd54xx->blt.status; + gd54xx->blt.status = val; + gd543x_recalc_mapping(gd54xx); + if (!(old & CIRRUS_BLT_RESET) && (gd54xx->blt.status & CIRRUS_BLT_RESET)) + gd54xx_reset_blit(gd54xx); + else if (!(old & CIRRUS_BLT_START) && (gd54xx->blt.status & CIRRUS_BLT_START)) { + gd54xx->blt.status |= CIRRUS_BLT_BUSY; + gd54xx_start_blit(0, 0xffffffff, gd54xx, svga); + } + break; + } } else if (gd54xx->mmio_vram_overlap) - gd54xx_write(addr, val, gd54xx); + gd54xx_write(addr, val, gd54xx); } - static void gd543x_mmio_writeb(uint32_t addr, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; - if (!gd543x_do_mmio(svga, addr) && !gd54xx->blt.ms_is_dest && - gd54xx->countminusone && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd54xx_mem_sys_src_write(gd54xx, val); - return; + if (!gd543x_do_mmio(svga, addr) && !gd54xx->blt.ms_is_dest && gd54xx->countminusone && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd54xx_mem_sys_src_write(gd54xx, val); + return; } gd543x_mmio_write(addr, val, p); } - static void gd543x_mmio_writew(uint32_t addr, uint16_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr + 1, val >> 8, gd54xx); + gd543x_mmio_write(addr, val & 0xff, gd54xx); + gd543x_mmio_write(addr + 1, val >> 8, gd54xx); } else if (gd54xx->mmio_vram_overlap) { - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr + 1, val >> 8, gd54xx); - } else { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr + 1, val >> 8, gd54xx); - } + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd543x_mmio_write(addr, val & 0xff, gd54xx); + gd543x_mmio_write(addr + 1, val >> 8, gd54xx); + } else { + gd54xx_write(addr, val, gd54xx); + gd54xx_write(addr + 1, val >> 8, gd54xx); + } } } - static void gd543x_mmio_writel(uint32_t addr, uint32_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; if (gd543x_do_mmio(svga, addr)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - gd543x_mmio_write(addr+2, val >> 16, gd54xx); - gd543x_mmio_write(addr+3, val >> 24, gd54xx); + gd543x_mmio_write(addr, val & 0xff, gd54xx); + gd543x_mmio_write(addr + 1, val >> 8, gd54xx); + gd543x_mmio_write(addr + 2, val >> 16, gd54xx); + gd543x_mmio_write(addr + 3, val >> 24, gd54xx); } else if (gd54xx->mmio_vram_overlap) { - if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - gd543x_mmio_write(addr, val & 0xff, gd54xx); - gd543x_mmio_write(addr+1, val >> 8, gd54xx); - gd543x_mmio_write(addr+2, val >> 16, gd54xx); - gd543x_mmio_write(addr+3, val >> 24, gd54xx); - } else { - gd54xx_write(addr, val, gd54xx); - gd54xx_write(addr+1, val >> 8, gd54xx); - gd54xx_write(addr+2, val >> 16, gd54xx); - gd54xx_write(addr+3, val >> 24, gd54xx); - } + if (gd54xx->countminusone && !gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + gd543x_mmio_write(addr, val & 0xff, gd54xx); + gd543x_mmio_write(addr + 1, val >> 8, gd54xx); + gd543x_mmio_write(addr + 2, val >> 16, gd54xx); + gd543x_mmio_write(addr + 3, val >> 24, gd54xx); + } else { + gd54xx_write(addr, val, gd54xx); + gd54xx_write(addr + 1, val >> 8, gd54xx); + gd54xx_write(addr + 2, val >> 16, gd54xx); + gd54xx_write(addr + 3, val >> 24, gd54xx); + } } } - static uint8_t gd543x_mmio_read(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint8_t ret = 0xff; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint8_t ret = 0xff; if (gd543x_do_mmio(svga, addr)) { - switch (addr & 0xff) { - case 0x00: - ret = gd54xx->blt.bg_col & 0xff; - break; - case 0x01: - ret = (gd54xx->blt.bg_col >> 8) & 0xff; - break; - case 0x02: - if (gd54xx_is_5434(svga)) - ret = (gd54xx->blt.bg_col >> 16) & 0xff; - break; - case 0x03: - if (gd54xx_is_5434(svga)) - ret = (gd54xx->blt.bg_col >> 24) & 0xff; - break; + switch (addr & 0xff) { + case 0x00: + ret = gd54xx->blt.bg_col & 0xff; + break; + case 0x01: + ret = (gd54xx->blt.bg_col >> 8) & 0xff; + break; + case 0x02: + if (gd54xx_is_5434(svga)) + ret = (gd54xx->blt.bg_col >> 16) & 0xff; + break; + case 0x03: + if (gd54xx_is_5434(svga)) + ret = (gd54xx->blt.bg_col >> 24) & 0xff; + break; - case 0x04: - ret = gd54xx->blt.fg_col & 0xff; - break; - case 0x05: - ret = (gd54xx->blt.fg_col >> 8) & 0xff; - break; - case 0x06: - if (gd54xx_is_5434(svga)) - ret = (gd54xx->blt.fg_col >> 16) & 0xff; - break; - case 0x07: - if (gd54xx_is_5434(svga)) - ret = (gd54xx->blt.fg_col >> 24) & 0xff; - break; + case 0x04: + ret = gd54xx->blt.fg_col & 0xff; + break; + case 0x05: + ret = (gd54xx->blt.fg_col >> 8) & 0xff; + break; + case 0x06: + if (gd54xx_is_5434(svga)) + ret = (gd54xx->blt.fg_col >> 16) & 0xff; + break; + case 0x07: + if (gd54xx_is_5434(svga)) + ret = (gd54xx->blt.fg_col >> 24) & 0xff; + break; - case 0x08: - ret = gd54xx->blt.width & 0xff; - break; - case 0x09: - if (gd54xx_is_5434(svga)) - ret = (gd54xx->blt.width >> 8) & 0x1f; - else - ret = (gd54xx->blt.width >> 8) & 0x07; - break; - case 0x0a: - ret = gd54xx->blt.height & 0xff; - break; - case 0x0b: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - ret = (gd54xx->blt.height >> 8) & 0x07; - else - ret = (gd54xx->blt.height >> 8) & 0x03; - break; - case 0x0c: - ret = gd54xx->blt.dst_pitch & 0xff; - break; - case 0x0d: - ret = (gd54xx->blt.dst_pitch >> 8) & 0x1f; - break; - case 0x0e: - ret = gd54xx->blt.src_pitch & 0xff; - break; - case 0x0f: - ret = (gd54xx->blt.src_pitch >> 8) & 0x1f; - break; + case 0x08: + ret = gd54xx->blt.width & 0xff; + break; + case 0x09: + if (gd54xx_is_5434(svga)) + ret = (gd54xx->blt.width >> 8) & 0x1f; + else + ret = (gd54xx->blt.width >> 8) & 0x07; + break; + case 0x0a: + ret = gd54xx->blt.height & 0xff; + break; + case 0x0b: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + ret = (gd54xx->blt.height >> 8) & 0x07; + else + ret = (gd54xx->blt.height >> 8) & 0x03; + break; + case 0x0c: + ret = gd54xx->blt.dst_pitch & 0xff; + break; + case 0x0d: + ret = (gd54xx->blt.dst_pitch >> 8) & 0x1f; + break; + case 0x0e: + ret = gd54xx->blt.src_pitch & 0xff; + break; + case 0x0f: + ret = (gd54xx->blt.src_pitch >> 8) & 0x1f; + break; - case 0x10: - ret = gd54xx->blt.dst_addr & 0xff; - break; - case 0x11: - ret = (gd54xx->blt.dst_addr >> 8) & 0xff; - break; - case 0x12: - if (gd54xx_is_5434(svga)) - ret = (gd54xx->blt.dst_addr >> 16) & 0x3f; - else - ret = (gd54xx->blt.dst_addr >> 16) & 0x1f; - break; + case 0x10: + ret = gd54xx->blt.dst_addr & 0xff; + break; + case 0x11: + ret = (gd54xx->blt.dst_addr >> 8) & 0xff; + break; + case 0x12: + if (gd54xx_is_5434(svga)) + ret = (gd54xx->blt.dst_addr >> 16) & 0x3f; + else + ret = (gd54xx->blt.dst_addr >> 16) & 0x1f; + break; - case 0x14: - ret = gd54xx->blt.src_addr & 0xff; - break; - case 0x15: - ret = (gd54xx->blt.src_addr >> 8) & 0xff; - break; - case 0x16: - if (gd54xx_is_5434(svga)) - ret = (gd54xx->blt.src_addr >> 16) & 0x3f; - else - ret = (gd54xx->blt.src_addr >> 16) & 0x1f; - break; + case 0x14: + ret = gd54xx->blt.src_addr & 0xff; + break; + case 0x15: + ret = (gd54xx->blt.src_addr >> 8) & 0xff; + break; + case 0x16: + if (gd54xx_is_5434(svga)) + ret = (gd54xx->blt.src_addr >> 16) & 0x3f; + else + ret = (gd54xx->blt.src_addr >> 16) & 0x1f; + break; - case 0x17: - ret = gd54xx->blt.mask; - break; - case 0x18: - ret = gd54xx->blt.mode; - break; + case 0x17: + ret = gd54xx->blt.mask; + break; + case 0x18: + ret = gd54xx->blt.mode; + break; - case 0x1a: - ret = gd54xx->blt.rop; - break; + case 0x1a: + ret = gd54xx->blt.rop; + break; - case 0x1b: - if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) - ret = gd54xx->blt.modeext; - break; + case 0x1b: + if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5436) + ret = gd54xx->blt.modeext; + break; - case 0x1c: - ret = gd54xx->blt.trans_col & 0xff; - break; - case 0x1d: - ret = (gd54xx->blt.trans_col >> 8) & 0xff; - break; + case 0x1c: + ret = gd54xx->blt.trans_col & 0xff; + break; + case 0x1d: + ret = (gd54xx->blt.trans_col >> 8) & 0xff; + break; - case 0x20: - ret = gd54xx->blt.trans_mask & 0xff; - break; - case 0x21: - ret = (gd54xx->blt.trans_mask >> 8) & 0xff; - break; + case 0x20: + ret = gd54xx->blt.trans_mask & 0xff; + break; + case 0x21: + ret = (gd54xx->blt.trans_mask >> 8) & 0xff; + break; - case 0x40: - ret = gd54xx->blt.status; - break; - } + case 0x40: + ret = gd54xx->blt.status; + break; + } } else if (gd54xx->mmio_vram_overlap) - ret = gd54xx_read(addr, gd54xx); - else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd54xx_mem_sys_dest_read(gd54xx); + ret = gd54xx_read(addr, gd54xx); + else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd54xx_mem_sys_dest_read(gd54xx); } return ret; } - static uint16_t gd543x_mmio_readw(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint16_t ret = 0xffff; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint16_t ret = 0xffff; if (gd543x_do_mmio(svga, addr)) - ret = gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8); + ret = gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr + 1, gd54xx) << 8); else if (gd54xx->mmio_vram_overlap) - ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8); - else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd543x_mmio_read(addr, p); - ret |= gd543x_mmio_read(addr + 1, p) << 8; - return ret; + ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr + 1, gd54xx) << 8); + else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd543x_mmio_read(addr, p); + ret |= gd543x_mmio_read(addr + 1, p) << 8; + return ret; } return ret; } - static uint32_t gd543x_mmio_readl(uint32_t addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint32_t ret = 0xffffffff; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint32_t ret = 0xffffffff; if (gd543x_do_mmio(svga, addr)) - ret = gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr+1, gd54xx) << 8) | (gd543x_mmio_read(addr+2, gd54xx) << 16) | (gd543x_mmio_read(addr+3, gd54xx) << 24); + ret = gd543x_mmio_read(addr, gd54xx) | (gd543x_mmio_read(addr + 1, gd54xx) << 8) | (gd543x_mmio_read(addr + 2, gd54xx) << 16) | (gd543x_mmio_read(addr + 3, gd54xx) << 24); else if (gd54xx->mmio_vram_overlap) - ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr+1, gd54xx) << 8) | (gd54xx_read(addr+2, gd54xx) << 16) | (gd54xx_read(addr+3, gd54xx) << 24); - else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && - !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { - ret = gd543x_mmio_read(addr, p); - ret |= gd543x_mmio_read(addr + 1, p) << 8; - ret |= gd543x_mmio_read(addr + 2, p) << 16; - ret |= gd543x_mmio_read(addr + 3, p) << 24; - return ret; + ret = gd54xx_read(addr, gd54xx) | (gd54xx_read(addr + 1, gd54xx) << 8) | (gd54xx_read(addr + 2, gd54xx) << 16) | (gd54xx_read(addr + 3, gd54xx) << 24); + else if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { + ret = gd543x_mmio_read(addr, p); + ret |= gd543x_mmio_read(addr + 1, p) << 8; + ret |= gd543x_mmio_read(addr + 2, p) << 16; + ret |= gd543x_mmio_read(addr + 3, p) << 24; + return ret; } return ret; } - static void gd5480_vgablt_write(uint32_t addr, uint8_t val, void *p) { addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - gd543x_mmio_writeb((addr & 0x000000ff) | 0x000b8000, val, p); + gd543x_mmio_writeb((addr & 0x000000ff) | 0x000b8000, val, p); else if (addr < 0x00000100) - gd54xx_out(0x03c0 + addr, val, p); + gd54xx_out(0x03c0 + addr, val, p); } - static void gd5480_vgablt_writew(uint32_t addr, uint16_t val, void *p) { addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - gd543x_mmio_writew((addr & 0x000000ff) | 0x000b8000, val, p); + gd543x_mmio_writew((addr & 0x000000ff) | 0x000b8000, val, p); else if (addr < 0x00000100) { - gd5480_vgablt_write(addr, val & 0xff, p); - gd5480_vgablt_write(addr + 1, val >> 8, p); - } + gd5480_vgablt_write(addr, val & 0xff, p); + gd5480_vgablt_write(addr + 1, val >> 8, p); + } } - static void gd5480_vgablt_writel(uint32_t addr, uint32_t val, void *p) { addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - gd543x_mmio_writel((addr & 0x000000ff) | 0x000b8000, val, p); + gd543x_mmio_writel((addr & 0x000000ff) | 0x000b8000, val, p); else if (addr < 0x00000100) { - gd5480_vgablt_writew(addr, val & 0xffff, p); - gd5480_vgablt_writew(addr + 2, val >> 16, p); - } + gd5480_vgablt_writew(addr, val & 0xffff, p); + gd5480_vgablt_writew(addr + 2, val >> 16, p); + } } - static uint8_t gd5480_vgablt_read(uint32_t addr, void *p) { @@ -3111,14 +3059,13 @@ gd5480_vgablt_read(uint32_t addr, void *p) addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - ret = gd543x_mmio_read((addr & 0x000000ff) | 0x000b8000, p); + ret = gd543x_mmio_read((addr & 0x000000ff) | 0x000b8000, p); else if (addr < 0x00000100) - ret = gd54xx_in(0x03c0 + addr, p); + ret = gd54xx_in(0x03c0 + addr, p); return ret; } - static uint16_t gd5480_vgablt_readw(uint32_t addr, void *p) { @@ -3127,16 +3074,15 @@ gd5480_vgablt_readw(uint32_t addr, void *p) addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - ret = gd543x_mmio_readw((addr & 0x000000ff) | 0x000b8000, p); + ret = gd543x_mmio_readw((addr & 0x000000ff) | 0x000b8000, p); else if (addr < 0x00000100) { - ret = gd5480_vgablt_read(addr, p); - ret |= (gd5480_vgablt_read(addr + 1, p) << 8); + ret = gd5480_vgablt_read(addr, p); + ret |= (gd5480_vgablt_read(addr + 1, p) << 8); } return ret; } - static uint32_t gd5480_vgablt_readl(uint32_t addr, void *p) { @@ -3145,54 +3091,51 @@ gd5480_vgablt_readl(uint32_t addr, void *p) addr &= 0x00000fff; if ((addr >= 0x00000100) && (addr < 0x00000200)) - ret = gd543x_mmio_readl((addr & 0x000000ff) | 0x000b8000, p); + ret = gd543x_mmio_readl((addr & 0x000000ff) | 0x000b8000, p); else if (addr < 0x00000100) { - ret = gd5480_vgablt_readw(addr, p); - ret |= (gd5480_vgablt_readw(addr + 2, p) << 16); + ret = gd5480_vgablt_readw(addr, p); + ret |= (gd5480_vgablt_readw(addr + 2, p) << 16); } return ret; } - static uint8_t gd54xx_color_expand(gd54xx_t *gd54xx, int mask, int shift) { uint8_t ret; if (gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) - ret = gd54xx->blt.fg_col >> (shift << 3); + ret = gd54xx->blt.fg_col >> (shift << 3); else - ret = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); + ret = mask ? (gd54xx->blt.fg_col >> (shift << 3)) : (gd54xx->blt.bg_col >> (shift << 3)); return ret; } - static int gd54xx_get_pixel_width(gd54xx_t *gd54xx) { int ret = 1; switch (gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) { - case CIRRUS_BLTMODE_PIXELWIDTH8: - ret = 1; - break; - case CIRRUS_BLTMODE_PIXELWIDTH16: - ret = 2; - break; - case CIRRUS_BLTMODE_PIXELWIDTH24: - ret = 3; - break; - case CIRRUS_BLTMODE_PIXELWIDTH32: - ret = 4; - break; + case CIRRUS_BLTMODE_PIXELWIDTH8: + ret = 1; + break; + case CIRRUS_BLTMODE_PIXELWIDTH16: + ret = 2; + break; + case CIRRUS_BLTMODE_PIXELWIDTH24: + ret = 3; + break; + case CIRRUS_BLTMODE_PIXELWIDTH32: + ret = 4; + break; } return ret; } - static void gd54xx_blit(gd54xx_t *gd54xx, uint8_t mask, uint8_t *dst, uint8_t target, int skip) { @@ -3200,70 +3143,67 @@ gd54xx_blit(gd54xx_t *gd54xx, uint8_t mask, uint8_t *dst, uint8_t target, int sk /* skip indicates whether or not it is a pixel to be skipped (used for left skip); mask indicates transparency or not (only when transparent comparison is enabled): - color expand: direct pattern bit; 1 = write, 0 = do not write - (the other way around in inverse mode); - normal 8-bpp or 16-bpp: does not match transparent color = write, - matches transparent color = do not write */ + color expand: direct pattern bit; 1 = write, 0 = do not write + (the other way around in inverse mode); + normal 8-bpp or 16-bpp: does not match transparent color = write, + matches transparent color = do not write */ /* Make sure to always ignore transparency and skip in case of mem sys dest. */ is_transp = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? 0 : (gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP); is_bgonly = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? 0 : (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_BACKGROUNDONLY); - skip = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? 0 : skip; + skip = (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) ? 0 : skip; if (is_transp) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && - (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) - mask = !mask; + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) + mask = !mask; - /* If mask is 1 and it is not a pixel to be skipped, write it. */ - if (mask && !skip) - *dst = target; + /* If mask is 1 and it is not a pixel to be skipped, write it. */ + if (mask && !skip) + *dst = target; } else if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && is_bgonly) { - /* If mask is 1 or it is not a pixel to be skipped, write it. - (Skip only background pixels.) */ - if (mask || !skip) - *dst = target; + /* If mask is 1 or it is not a pixel to be skipped, write it. + (Skip only background pixels.) */ + if (mask || !skip) + *dst = target; } else { - /* If if it is not a pixel to be skipped, write it. */ - if (!skip) - *dst = target; + /* If if it is not a pixel to be skipped, write it. */ + if (!skip) + *dst = target; } } - static int gd54xx_transparent_comp(gd54xx_t *gd54xx, uint32_t xx, uint8_t src) { svga_t *svga = &gd54xx->svga; - int ret = 1; + int ret = 1; if ((gd54xx->blt.pixel_width <= 2) && gd54xx_has_transp(svga, 0)) { - ret = src ^ ((uint8_t *) &(gd54xx->blt.trans_col))[xx]; - if (gd54xx_has_transp(svga, 1)) - ret &= ~(((uint8_t *) &(gd54xx->blt.trans_mask))[xx]); - ret = !ret; + ret = src ^ ((uint8_t *) &(gd54xx->blt.trans_col))[xx]; + if (gd54xx_has_transp(svga, 1)) + ret &= ~(((uint8_t *) &(gd54xx->blt.trans_mask))[xx]); + ret = !ret; } return ret; } - static void gd54xx_pattern_copy(gd54xx_t *gd54xx) { - uint8_t target, src, *dst; - int x, y, pattern_y, pattern_pitch; + uint8_t target, src, *dst; + int x, y, pattern_y, pattern_pitch; uint32_t bitmask = 0, xx, pixel; uint32_t srca, srca2, dsta; - svga_t *svga = &gd54xx->svga; + svga_t *svga = &gd54xx->svga; pattern_pitch = gd54xx->blt.pixel_width << 3; if (gd54xx->blt.pixel_width == 3) - pattern_pitch = 32; + pattern_pitch = 32; if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - pattern_pitch = 1; + pattern_pitch = 1; dsta = gd54xx->blt.dst_addr & svga->vram_mask; /* The vertical offset is in the three low-order bits of the Source Address register. */ @@ -3282,144 +3222,141 @@ gd54xx_pattern_copy(gd54xx_t *gd54xx) srca = (gd54xx->blt.src_addr & ~0x07) & svga->vram_mask; for (y = 0; y <= gd54xx->blt.height; y++) { - /* Go to the correct pattern line. */ - srca2 = srca + (pattern_y * pattern_pitch); - pixel = 0; - for (x = 0; x <= gd54xx->blt.width; x += gd54xx->blt.pixel_width) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) - bitmask = 1; - else - bitmask = svga->vram[srca2 & svga->vram_mask] & (0x80 >> pixel); - } - for (xx = 0; xx < gd54xx->blt.pixel_width; xx++) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - src = gd54xx_color_expand(gd54xx, bitmask, xx); - else { - src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & svga->vram_mask]; - bitmask = gd54xx_transparent_comp(gd54xx, xx, src); - } - dst = &(svga->vram[(dsta + x + xx) & svga->vram_mask]); - target = *dst; - gd54xx_rop(gd54xx, &target, &target, &src); - if (gd54xx->blt.pixel_width == 3) - gd54xx_blit(gd54xx, bitmask, dst, target, ((x + xx) < gd54xx->blt.pattern_x)); - else - gd54xx_blit(gd54xx, bitmask, dst, target, (x < gd54xx->blt.pattern_x)); - } - pixel = (pixel + 1) & 7; - svga->changedvram[((dsta + x) & svga->vram_mask) >> 12] = changeframecount; - } - pattern_y = (pattern_y + 1) & 7; - dsta += gd54xx->blt.dst_pitch; + /* Go to the correct pattern line. */ + srca2 = srca + (pattern_y * pattern_pitch); + pixel = 0; + for (x = 0; x <= gd54xx->blt.width; x += gd54xx->blt.pixel_width) { + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { + if (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_SOLIDFILL) + bitmask = 1; + else + bitmask = svga->vram[srca2 & svga->vram_mask] & (0x80 >> pixel); + } + for (xx = 0; xx < gd54xx->blt.pixel_width; xx++) { + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) + src = gd54xx_color_expand(gd54xx, bitmask, xx); + else { + src = svga->vram[(srca2 + (x % (gd54xx->blt.pixel_width << 3)) + xx) & svga->vram_mask]; + bitmask = gd54xx_transparent_comp(gd54xx, xx, src); + } + dst = &(svga->vram[(dsta + x + xx) & svga->vram_mask]); + target = *dst; + gd54xx_rop(gd54xx, &target, &target, &src); + if (gd54xx->blt.pixel_width == 3) + gd54xx_blit(gd54xx, bitmask, dst, target, ((x + xx) < gd54xx->blt.pattern_x)); + else + gd54xx_blit(gd54xx, bitmask, dst, target, (x < gd54xx->blt.pattern_x)); + } + pixel = (pixel + 1) & 7; + svga->changedvram[((dsta + x) & svga->vram_mask) >> 12] = changeframecount; + } + pattern_y = (pattern_y + 1) & 7; + dsta += gd54xx->blt.dst_pitch; } } - static void gd54xx_reset_blit(gd54xx_t *gd54xx) { gd54xx->countminusone = 0; - gd54xx->blt.status &= ~(CIRRUS_BLT_START|CIRRUS_BLT_BUSY|CIRRUS_BLT_FIFOUSED); + gd54xx->blt.status &= ~(CIRRUS_BLT_START | CIRRUS_BLT_BUSY | CIRRUS_BLT_FIFOUSED); } - /* Each blit is either 1 byte -> 1 byte (non-color expand blit) or 1 byte -> 8/16/24/32 bytes (color expand blit). */ static void gd54xx_mem_sys_src(gd54xx_t *gd54xx, uint32_t cpu_dat, uint32_t count) { uint8_t *dst, exp, target; - int mask_shift; + int mask_shift; uint32_t byte_pos, bitmask = 0; - svga_t *svga = &gd54xx->svga; + svga_t *svga = &gd54xx->svga; gd54xx->blt.ms_is_dest = 0; if (gd54xx->blt.mode & (CIRRUS_BLTMODE_MEMSYSDEST | CIRRUS_BLTMODE_PATTERNCOPY)) - gd54xx_reset_blit(gd54xx); + gd54xx_reset_blit(gd54xx); else if (count == 0xffffffff) { - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.x_count = gd54xx->blt.xx_count = 0; - gd54xx->blt.y_count = 0; - gd54xx->countminusone = 1; - gd54xx->blt.sys_src32 = 0x00000000; - gd54xx->blt.sys_cnt = 0; - return; + gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; + gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; + gd54xx->blt.x_count = gd54xx->blt.xx_count = 0; + gd54xx->blt.y_count = 0; + gd54xx->countminusone = 1; + gd54xx->blt.sys_src32 = 0x00000000; + gd54xx->blt.sys_cnt = 0; + return; } else if (gd54xx->countminusone) { - if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) || (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { - if (!gd54xx->blt.xx_count && !gd54xx->blt.x_count) - byte_pos = (((gd54xx->blt.mask >> 5) & 3) << 3); - else - byte_pos = 0; - mask_shift = 31 - byte_pos; - if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) - cpu_dat >>= byte_pos; - } else - mask_shift = 7; + if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) || (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_DWORDGRANULARITY)) { + if (!gd54xx->blt.xx_count && !gd54xx->blt.x_count) + byte_pos = (((gd54xx->blt.mask >> 5) & 3) << 3); + else + byte_pos = 0; + mask_shift = 31 - byte_pos; + if (!(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) + cpu_dat >>= byte_pos; + } else + mask_shift = 7; - while (mask_shift > -1) { - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - bitmask = (cpu_dat >> mask_shift) & 0x01; - exp = gd54xx_color_expand(gd54xx, bitmask, gd54xx->blt.xx_count); - } else { - exp = cpu_dat & 0xff; - bitmask = gd54xx_transparent_comp(gd54xx, gd54xx->blt.xx_count, exp); - } + while (mask_shift > -1) { + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { + bitmask = (cpu_dat >> mask_shift) & 0x01; + exp = gd54xx_color_expand(gd54xx, bitmask, gd54xx->blt.xx_count); + } else { + exp = cpu_dat & 0xff; + bitmask = gd54xx_transparent_comp(gd54xx, gd54xx->blt.xx_count, exp); + } - dst = &(svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); - target = *dst; - gd54xx_rop(gd54xx, &target, &target, &exp); - if ((gd54xx->blt.pixel_width == 3) && (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) - gd54xx_blit(gd54xx, bitmask, dst, target, ((gd54xx->blt.x_count + gd54xx->blt.xx_count) < gd54xx->blt.pattern_x)); - else - gd54xx_blit(gd54xx, bitmask, dst, target, (gd54xx->blt.x_count < gd54xx->blt.pattern_x)); + dst = &(svga->vram[gd54xx->blt.dst_addr_backup & svga->vram_mask]); + target = *dst; + gd54xx_rop(gd54xx, &target, &target, &exp); + if ((gd54xx->blt.pixel_width == 3) && (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND)) + gd54xx_blit(gd54xx, bitmask, dst, target, ((gd54xx->blt.x_count + gd54xx->blt.xx_count) < gd54xx->blt.pattern_x)); + else + gd54xx_blit(gd54xx, bitmask, dst, target, (gd54xx->blt.x_count < gd54xx->blt.pattern_x)); - gd54xx->blt.dst_addr_backup += gd54xx->blt.dir; + gd54xx->blt.dst_addr_backup += gd54xx->blt.dir; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - gd54xx->blt.xx_count = (gd54xx->blt.xx_count + 1) % gd54xx->blt.pixel_width; + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) + gd54xx->blt.xx_count = (gd54xx->blt.xx_count + 1) % gd54xx->blt.pixel_width; - svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; + svga->changedvram[(gd54xx->blt.dst_addr_backup & svga->vram_mask) >> 12] = changeframecount; - if (!gd54xx->blt.xx_count) { - /* 1 mask bit = 1 blitted pixel */ - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - mask_shift--; - else { - cpu_dat >>= 8; - mask_shift -= 8; - } + if (!gd54xx->blt.xx_count) { + /* 1 mask bit = 1 blitted pixel */ + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) + mask_shift--; + else { + cpu_dat >>= 8; + mask_shift -= 8; + } - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - gd54xx->blt.x_count = (gd54xx->blt.x_count + gd54xx->blt.pixel_width) % (gd54xx->blt.width + 1); - else - gd54xx->blt.x_count = (gd54xx->blt.x_count + 1) % (gd54xx->blt.width + 1); + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) + gd54xx->blt.x_count = (gd54xx->blt.x_count + gd54xx->blt.pixel_width) % (gd54xx->blt.width + 1); + else + gd54xx->blt.x_count = (gd54xx->blt.x_count + 1) % (gd54xx->blt.width + 1); - if (!gd54xx->blt.x_count) { - gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) % (gd54xx->blt.height + 1); - if (gd54xx->blt.y_count) - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + (gd54xx->blt.dst_pitch * gd54xx->blt.y_count * gd54xx->blt.dir); - else { - /* If we're here, the blit is over, reset. */ - gd54xx_reset_blit(gd54xx); - } - /* Stop blitting and request new data if end of line reached. */ - return; - } - } - } + if (!gd54xx->blt.x_count) { + gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) % (gd54xx->blt.height + 1); + if (gd54xx->blt.y_count) + gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr + (gd54xx->blt.dst_pitch * gd54xx->blt.y_count * gd54xx->blt.dir); + else { + /* If we're here, the blit is over, reset. */ + gd54xx_reset_blit(gd54xx); + } + /* Stop blitting and request new data if end of line reached. */ + return; + } + } + } } } - static void gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) { - uint8_t src = 0, dst; + uint8_t src = 0, dst; uint16_t width = gd54xx->blt.width; - int x_max = 0, shift = 0, mask = 0; + int x_max = 0, shift = 0, mask = 0; uint32_t src_addr = gd54xx->blt.src_addr; uint32_t dst_addr = gd54xx->blt.dst_addr; @@ -3428,353 +3365,349 @@ gd54xx_normal_blit(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; gd54xx->blt.height_internal = gd54xx->blt.height; - gd54xx->blt.x_count = 0; - gd54xx->blt.y_count = 0; + gd54xx->blt.x_count = 0; + gd54xx->blt.y_count = 0; while (count) { - src = 0; - mask = 0; + src = 0; + mask = 0; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - mask = svga->vram[src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width)); - shift = (gd54xx->blt.x_count % gd54xx->blt.pixel_width); - src = gd54xx_color_expand(gd54xx, mask, shift); - } else { - src = svga->vram[src_addr & svga->vram_mask]; - src_addr += gd54xx->blt.dir; - mask = 1; - } - count--; + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { + mask = svga->vram[src_addr & svga->vram_mask] & (0x80 >> (gd54xx->blt.x_count / gd54xx->blt.pixel_width)); + shift = (gd54xx->blt.x_count % gd54xx->blt.pixel_width); + src = gd54xx_color_expand(gd54xx, mask, shift); + } else { + src = svga->vram[src_addr & svga->vram_mask]; + src_addr += gd54xx->blt.dir; + mask = 1; + } + count--; - dst = svga->vram[dst_addr & svga->vram_mask]; - svga->changedvram[(dst_addr & svga->vram_mask) >> 12] = changeframecount; + dst = svga->vram[dst_addr & svga->vram_mask]; + svga->changedvram[(dst_addr & svga->vram_mask) >> 12] = changeframecount; - gd54xx_rop(gd54xx, (uint8_t *) &dst, (uint8_t *) &dst, (const uint8_t *) &src); + gd54xx_rop(gd54xx, (uint8_t *) &dst, (uint8_t *) &dst, (const uint8_t *) &src); - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) - mask = !mask; + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && (gd54xx->blt.modeext & CIRRUS_BLTMODEEXT_COLOREXPINV)) + mask = !mask; - /* This handles 8bpp and 16bpp non-color-expanding transparent comparisons. */ - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && - ((gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) <= CIRRUS_BLTMODE_PIXELWIDTH16) && - (src != ((gd54xx->blt.trans_mask >> (shift << 3)) & 0xff))) - mask = 0; + /* This handles 8bpp and 16bpp non-color-expanding transparent comparisons. */ + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !(gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) && ((gd54xx->blt.mode & CIRRUS_BLTMODE_PIXELWIDTHMASK) <= CIRRUS_BLTMODE_PIXELWIDTH16) && (src != ((gd54xx->blt.trans_mask >> (shift << 3)) & 0xff))) + mask = 0; - if (((gd54xx->blt.width - width) >= gd54xx->blt.pattern_x) && - !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) { - svga->vram[dst_addr & svga->vram_mask] = dst; - } + if (((gd54xx->blt.width - width) >= gd54xx->blt.pattern_x) && !((gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP) && !mask)) { + svga->vram[dst_addr & svga->vram_mask] = dst; + } - dst_addr += gd54xx->blt.dir; - gd54xx->blt.x_count++; + dst_addr += gd54xx->blt.dir; + gd54xx->blt.x_count++; - if (gd54xx->blt.x_count == x_max) { - gd54xx->blt.x_count = 0; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) - src_addr++; - } + if (gd54xx->blt.x_count == x_max) { + gd54xx->blt.x_count = 0; + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) + src_addr++; + } - width--; - if (width == 0xffff) { - width = gd54xx->blt.width; - dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + (gd54xx->blt.dst_pitch * gd54xx->blt.dir); - gd54xx->blt.y_count = (gd54xx->blt.y_count + gd54xx->blt.dir) & 7; + width--; + if (width == 0xffff) { + width = gd54xx->blt.width; + dst_addr = gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr_backup + (gd54xx->blt.dst_pitch * gd54xx->blt.dir); + gd54xx->blt.y_count = (gd54xx->blt.y_count + gd54xx->blt.dir) & 7; - if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - if (gd54xx->blt.x_count != 0) - src_addr++; - } else - src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + (gd54xx->blt.src_pitch * gd54xx->blt.dir); + if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { + if (gd54xx->blt.x_count != 0) + src_addr++; + } else + src_addr = gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr_backup + (gd54xx->blt.src_pitch * gd54xx->blt.dir); - dst_addr &= svga->vram_mask; - gd54xx->blt.dst_addr_backup &= svga->vram_mask; - src_addr &= svga->vram_mask; - gd54xx->blt.src_addr_backup &= svga->vram_mask; + dst_addr &= svga->vram_mask; + gd54xx->blt.dst_addr_backup &= svga->vram_mask; + src_addr &= svga->vram_mask; + gd54xx->blt.src_addr_backup &= svga->vram_mask; - gd54xx->blt.x_count = 0; + gd54xx->blt.x_count = 0; - gd54xx->blt.height_internal--; - if (gd54xx->blt.height_internal == 0xffff) { - gd54xx_reset_blit(gd54xx); - return; - } - } + gd54xx->blt.height_internal--; + if (gd54xx->blt.height_internal == 0xffff) { + gd54xx_reset_blit(gd54xx); + return; + } + } } /* Count exhausted, stuff still left to blit. */ gd54xx_reset_blit(gd54xx); } - static void gd54xx_mem_sys_dest(uint32_t count, gd54xx_t *gd54xx, svga_t *svga) { gd54xx->blt.ms_is_dest = 1; if (gd54xx->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) { - fatal("mem sys dest pattern copy not allowed (see 1994 manual)\n"); - gd54xx_reset_blit(gd54xx); + fatal("mem sys dest pattern copy not allowed (see 1994 manual)\n"); + gd54xx_reset_blit(gd54xx); } else if (gd54xx->blt.mode & CIRRUS_BLTMODE_COLOREXPAND) { - fatal("mem sys dest color expand not allowed (see 1994 manual)\n"); - gd54xx_reset_blit(gd54xx); + fatal("mem sys dest color expand not allowed (see 1994 manual)\n"); + gd54xx_reset_blit(gd54xx); } else { - if (count == 0xffffffff) { - gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; - gd54xx->blt.msd_buf_cnt = 0; - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; - gd54xx->blt.x_count = gd54xx->blt.xx_count = 0; - gd54xx->blt.y_count = 0; - gd54xx->countminusone = 1; - count = 32; - } + if (count == 0xffffffff) { + gd54xx->blt.dst_addr_backup = gd54xx->blt.dst_addr; + gd54xx->blt.msd_buf_cnt = 0; + gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr; + gd54xx->blt.x_count = gd54xx->blt.xx_count = 0; + gd54xx->blt.y_count = 0; + gd54xx->countminusone = 1; + count = 32; + } - gd54xx->blt.msd_buf_pos = 0; + gd54xx->blt.msd_buf_pos = 0; - while (gd54xx->blt.msd_buf_pos < 32) { - gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & svga->vram_mask]; - gd54xx->blt.src_addr_backup += gd54xx->blt.dir; - gd54xx->blt.msd_buf_pos++; + while (gd54xx->blt.msd_buf_pos < 32) { + gd54xx->blt.msd_buf[gd54xx->blt.msd_buf_pos & 0x1f] = svga->vram[gd54xx->blt.src_addr_backup & svga->vram_mask]; + gd54xx->blt.src_addr_backup += gd54xx->blt.dir; + gd54xx->blt.msd_buf_pos++; - gd54xx->blt.x_count = (gd54xx->blt.x_count + 1) % (gd54xx->blt.width + 1); + gd54xx->blt.x_count = (gd54xx->blt.x_count + 1) % (gd54xx->blt.width + 1); - if (!gd54xx->blt.x_count) { - gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) % (gd54xx->blt.height + 1); + if (!gd54xx->blt.x_count) { + gd54xx->blt.y_count = (gd54xx->blt.y_count + 1) % (gd54xx->blt.height + 1); - if (gd54xx->blt.y_count) - gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr + (gd54xx->blt.src_pitch * gd54xx->blt.y_count * gd54xx->blt.dir); - else - gd54xx->countminusone = 2; /* Signal end of blit. */ - /* End of line reached, stop and notify regardless of how much we already transferred. */ - goto request_more_data; - } - } + if (gd54xx->blt.y_count) + gd54xx->blt.src_addr_backup = gd54xx->blt.src_addr + (gd54xx->blt.src_pitch * gd54xx->blt.y_count * gd54xx->blt.dir); + else + gd54xx->countminusone = 2; /* Signal end of blit. */ + /* End of line reached, stop and notify regardless of how much we already transferred. */ + goto request_more_data; + } + } - /* End of while. */ + /* End of while. */ request_more_data: - /* If the byte count we have blitted are not divisible by 4, round them up. */ - if (gd54xx->blt.msd_buf_pos & 3) - gd54xx->blt.msd_buf_cnt = (gd54xx->blt.msd_buf_pos & ~3) + 4; - else - gd54xx->blt.msd_buf_cnt = gd54xx->blt.msd_buf_pos; - gd54xx->blt.msd_buf_pos = 0; - return; + /* If the byte count we have blitted are not divisible by 4, round them up. */ + if (gd54xx->blt.msd_buf_pos & 3) + gd54xx->blt.msd_buf_cnt = (gd54xx->blt.msd_buf_pos & ~3) + 4; + else + gd54xx->blt.msd_buf_cnt = gd54xx->blt.msd_buf_pos; + gd54xx->blt.msd_buf_pos = 0; + return; } } - static void gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *svga) { - if ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) && - !(gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) && - !(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP)) - gd54xx->blt.dir = -1; + if ((gd54xx->blt.mode & CIRRUS_BLTMODE_BACKWARDS) && !(gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) && !(gd54xx->blt.mode & CIRRUS_BLTMODE_TRANSPARENTCOMP)) + gd54xx->blt.dir = -1; else - gd54xx->blt.dir = 1; + gd54xx->blt.dir = 1; gd54xx->blt.pixel_width = gd54xx_get_pixel_width(gd54xx); - if (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY|CIRRUS_BLTMODE_COLOREXPAND)) { - if (gd54xx->blt.pixel_width == 3) - gd54xx->blt.pattern_x = gd54xx->blt.mask & 0x1f; /* (Mask & 0x1f) bytes. */ - else - gd54xx->blt.pattern_x = (gd54xx->blt.mask & 0x07) * gd54xx->blt.pixel_width; /* (Mask & 0x07) pixels. */ + if (gd54xx->blt.mode & (CIRRUS_BLTMODE_PATTERNCOPY | CIRRUS_BLTMODE_COLOREXPAND)) { + if (gd54xx->blt.pixel_width == 3) + gd54xx->blt.pattern_x = gd54xx->blt.mask & 0x1f; /* (Mask & 0x1f) bytes. */ + else + gd54xx->blt.pattern_x = (gd54xx->blt.mask & 0x07) * gd54xx->blt.pixel_width; /* (Mask & 0x07) pixels. */ } else - gd54xx->blt.pattern_x = 0; /* No skip in normal blit mode. */ + gd54xx->blt.pattern_x = 0; /* No skip in normal blit mode. */ if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSSRC) - gd54xx_mem_sys_src(gd54xx, cpu_dat, count); + gd54xx_mem_sys_src(gd54xx, cpu_dat, count); else if (gd54xx->blt.mode & CIRRUS_BLTMODE_MEMSYSDEST) - gd54xx_mem_sys_dest(count, gd54xx, svga); + gd54xx_mem_sys_dest(count, gd54xx, svga); else if (gd54xx->blt.mode & CIRRUS_BLTMODE_PATTERNCOPY) { - gd54xx_pattern_copy(gd54xx); - gd54xx_reset_blit(gd54xx); + gd54xx_pattern_copy(gd54xx); + gd54xx_reset_blit(gd54xx); } else - gd54xx_normal_blit(count, gd54xx, svga); + gd54xx_normal_blit(count, gd54xx, svga); } - static uint8_t cl_pci_read(int func, int addr, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint8_t ret = 0x00; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint8_t ret = 0x00; if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - ret = 0x00; - else switch (addr) { - case 0x00: - ret = 0x13; /*Cirrus Logic*/ - break; - case 0x01: - ret = 0x10; - break; + ret = 0x00; + else + switch (addr) { + case 0x00: + ret = 0x13; /*Cirrus Logic*/ + break; + case 0x01: + ret = 0x10; + break; - case 0x02: - ret = svga->crtc[0x27]; - break; - case 0x03: - ret = 0x00; - break; + case 0x02: + ret = svga->crtc[0x27]; + break; + case 0x03: + ret = 0x00; + break; - case PCI_REG_COMMAND: - ret = gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - break; + case PCI_REG_COMMAND: + ret = gd54xx->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + break; - case 0x07: - ret = 0x02; /*Fast DEVSEL timing*/ - break; + case 0x07: + ret = 0x02; /*Fast DEVSEL timing*/ + break; - case 0x08: - ret = gd54xx->rev; /*Revision ID*/ - break; - case 0x09: - ret = 0x00; /*Programming interface*/ - break; + case 0x08: + ret = gd54xx->rev; /*Revision ID*/ + break; + case 0x09: + ret = 0x00; /*Programming interface*/ + break; - case 0x0a: - ret = 0x00; /*Supports VGA interface*/ - break; - case 0x0b: - ret = 0x03; - break; + case 0x0a: + ret = 0x00; /*Supports VGA interface*/ + break; + case 0x0b: + ret = 0x03; + break; - case 0x10: - ret = 0x08; /*Linear frame buffer address*/ - break; - case 0x11: - ret = 0x00; - break; - case 0x12: - ret = 0x00; - break; - case 0x13: - ret = gd54xx->lfb_base >> 24; - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - ret = 0xfe; - break; + case 0x10: + ret = 0x08; /*Linear frame buffer address*/ + break; + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = 0x00; + break; + case 0x13: + ret = gd54xx->lfb_base >> 24; + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) + ret = 0xfe; + break; - case 0x14: - ret = 0x00; /*PCI VGA/BitBLT Register Base Address*/ - break; - case 0x15: - ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 8) & 0xf0) : 0x00; - break; - case 0x16: - ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 16) & 0xff) : 0x00; - break; - case 0x17: - ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 24) & 0xff) : 0x00; - break; + case 0x14: + ret = 0x00; /*PCI VGA/BitBLT Register Base Address*/ + break; + case 0x15: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 8) & 0xf0) : 0x00; + break; + case 0x16: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 16) & 0xff) : 0x00; + break; + case 0x17: + ret = (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) ? ((gd54xx->vgablt_base >> 24) & 0xff) : 0x00; + break; - case 0x30: - ret = (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ - break; - case 0x31: - ret = 0x00; - break; - case 0x32: - ret = gd54xx->pci_regs[0x32]; - break; - case 0x33: - ret = gd54xx->pci_regs[0x33]; - break; + case 0x30: + ret = (gd54xx->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ + break; + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = gd54xx->pci_regs[0x32]; + break; + case 0x33: + ret = gd54xx->pci_regs[0x33]; + break; - case 0x3c: - ret = gd54xx->int_line; - break; - case 0x3d: - ret = PCI_INTA; - break; - } + case 0x3c: + ret = gd54xx->int_line; + break; + case 0x3d: + ret = PCI_INTA; + break; + } return ret; } - static void cl_pci_write(int func, int addr, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; - svga_t *svga = &gd54xx->svga; - uint32_t byte; + gd54xx_t *gd54xx = (gd54xx_t *) p; + svga_t *svga = &gd54xx->svga; + uint32_t byte; if ((addr >= 0x30) && (addr <= 0x33) && (!gd54xx->has_bios)) - return; + return; switch (addr) { - case PCI_REG_COMMAND: - gd54xx->pci_regs[PCI_REG_COMMAND] = val & 0x23; - mem_mapping_disable(&gd54xx->vgablt_mapping); - io_removehandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - if (val & PCI_COMMAND_IO) - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); - if ((val & PCI_COMMAND_MEM) && (gd54xx->vgablt_base != 0x00000000) && (gd54xx->vgablt_base < 0xfff00000)) - mem_mapping_set_addr(&gd54xx->vgablt_mapping, gd54xx->vgablt_base, 0x1000); - if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && (gd54xx->pci_regs[0x30] & 0x01)) { - uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); - mem_mapping_set_addr(&gd54xx->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&gd54xx->bios_rom.mapping); - gd543x_recalc_mapping(gd54xx); - break; + case PCI_REG_COMMAND: + gd54xx->pci_regs[PCI_REG_COMMAND] = val & 0x23; + mem_mapping_disable(&gd54xx->vgablt_mapping); + io_removehandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + if (val & PCI_COMMAND_IO) + io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + if ((val & PCI_COMMAND_MEM) && (gd54xx->vgablt_base != 0x00000000) && (gd54xx->vgablt_base < 0xfff00000)) + mem_mapping_set_addr(&gd54xx->vgablt_mapping, gd54xx->vgablt_base, 0x1000); + if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && (gd54xx->pci_regs[0x30] & 0x01)) { + uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); + mem_mapping_set_addr(&gd54xx->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&gd54xx->bios_rom.mapping); + gd543x_recalc_mapping(gd54xx); + break; - case 0x13: - /* 5480, like 5446 rev. B, has a 32 MB aperture, with the second set used for - BitBLT transfers. */ - if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) - val &= 0xfe; - gd54xx->lfb_base = val << 24; - gd543x_recalc_mapping(gd54xx); - break; + case 0x13: + /* 5480, like 5446 rev. B, has a 32 MB aperture, with the second set used for + BitBLT transfers. */ + if (svga->crtc[0x27] == CIRRUS_ID_CLGD5480) + val &= 0xfe; + gd54xx->lfb_base = val << 24; + gd543x_recalc_mapping(gd54xx); + break; - case 0x15: case 0x16: case 0x17: - if (svga->crtc[0x27] != CIRRUS_ID_CLGD5480) - return; - byte = (addr & 3) << 3; - gd54xx->vgablt_base &= ~(0xff << byte); - if (addr == 0x15) - val &= 0xf0; - gd54xx->vgablt_base |= (val << byte); - mem_mapping_disable(&gd54xx->vgablt_mapping); - if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && (gd54xx->vgablt_base != 0x00000000) && (gd54xx->vgablt_base < 0xfff00000)) - mem_mapping_set_addr(&gd54xx->vgablt_mapping, gd54xx->vgablt_base, 0x1000); - break; + case 0x15: + case 0x16: + case 0x17: + if (svga->crtc[0x27] != CIRRUS_ID_CLGD5480) + return; + byte = (addr & 3) << 3; + gd54xx->vgablt_base &= ~(0xff << byte); + if (addr == 0x15) + val &= 0xf0; + gd54xx->vgablt_base |= (val << byte); + mem_mapping_disable(&gd54xx->vgablt_mapping); + if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && (gd54xx->vgablt_base != 0x00000000) && (gd54xx->vgablt_base < 0xfff00000)) + mem_mapping_set_addr(&gd54xx->vgablt_mapping, gd54xx->vgablt_base, 0x1000); + break; - case 0x30: case 0x32: case 0x33: - gd54xx->pci_regs[addr] = val; - if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && (gd54xx->pci_regs[0x30] & 0x01)) { - uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); - mem_mapping_set_addr(&gd54xx->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&gd54xx->bios_rom.mapping); - return; + case 0x30: + case 0x32: + case 0x33: + gd54xx->pci_regs[addr] = val; + if ((gd54xx->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM) && (gd54xx->pci_regs[0x30] & 0x01)) { + uint32_t addr = (gd54xx->pci_regs[0x32] << 16) | (gd54xx->pci_regs[0x33] << 24); + mem_mapping_set_addr(&gd54xx->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&gd54xx->bios_rom.mapping); + return; - case 0x3c: - gd54xx->int_line = val; - return; + case 0x3c: + gd54xx->int_line = val; + return; } } static uint8_t gd5428_mca_read(int port, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; - return gd54xx->pos_regs[port & 7]; + return gd54xx->pos_regs[port & 7]; } static void gd5428_mca_write(int port, uint8_t val, void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; - if (port < 0x102) - return; + if (port < 0x102) + return; - gd54xx->pos_regs[port & 7] = val; - gd543x_recalc_mapping(gd54xx); + gd54xx->pos_regs[port & 7] = val; + gd543x_recalc_mapping(gd54xx); } static uint8_t @@ -3787,23 +3720,23 @@ static void gd54xx_reset(void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; - svga_t *svga = &gd54xx->svga; + svga_t *svga = &gd54xx->svga; memset(svga->crtc, 0x00, sizeof(svga->crtc)); memset(svga->seqregs, 0x00, sizeof(svga->seqregs)); memset(svga->gdcreg, 0x00, sizeof(svga->gdcreg)); - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = 1000ull << 32; + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; svga->dispofftime = 1000ull << 32; - svga->bpp = 8; + svga->bpp = 8; io_removehandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); mem_mapping_disable(&gd54xx->vgablt_mapping); if (gd54xx->has_bios && gd54xx->pci) - mem_mapping_disable(&gd54xx->bios_rom.mapping); + mem_mapping_disable(&gd54xx->bios_rom.mapping); memset(gd54xx->pci_regs, 0x00, 256); @@ -3819,23 +3752,23 @@ gd54xx_reset(void *priv) svga->hwcursor.yoff = svga->hwcursor.xoff = 0; if (gd54xx->id >= CIRRUS_ID_CLGD5420) { - gd54xx->vclk_n[0] = 0x4a; - gd54xx->vclk_d[0] = 0x2b; - gd54xx->vclk_n[1] = 0x5b; - gd54xx->vclk_d[1] = 0x2f; - gd54xx->vclk_n[2] = 0x45; - gd54xx->vclk_d[2] = 0x30; - gd54xx->vclk_n[3] = 0x7e; - gd54xx->vclk_d[3] = 0x33; + gd54xx->vclk_n[0] = 0x4a; + gd54xx->vclk_d[0] = 0x2b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x30; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; } else { - gd54xx->vclk_n[0] = 0x66; - gd54xx->vclk_d[0] = 0x3b; - gd54xx->vclk_n[1] = 0x5b; - gd54xx->vclk_d[1] = 0x2f; - gd54xx->vclk_n[2] = 0x45; - gd54xx->vclk_d[2] = 0x2c; - gd54xx->vclk_n[3] = 0x7e; - gd54xx->vclk_d[3] = 0x33; + gd54xx->vclk_n[0] = 0x66; + gd54xx->vclk_d[0] = 0x3b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x2c; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; } svga->extra_banks[1] = 0x8000; @@ -3850,244 +3783,244 @@ gd54xx_reset(void *priv) svga->seqregs[6] = 0x0f; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) - gd54xx->unlocked = 1; + gd54xx->unlocked = 1; else - gd54xx->unlocked = 0; + gd54xx->unlocked = 0; } - static void -*gd54xx_init(const device_t *info) + * + gd54xx_init(const device_t *info) { gd54xx_t *gd54xx = malloc(sizeof(gd54xx_t)); - svga_t *svga = &gd54xx->svga; - int id = info->local & 0xff; - int vram; - char *romfn = NULL; - char *romfn1 = NULL, *romfn2 = NULL; + svga_t *svga = &gd54xx->svga; + int id = info->local & 0xff; + int vram; + char *romfn = NULL; + char *romfn1 = NULL, *romfn2 = NULL; memset(gd54xx, 0, sizeof(gd54xx_t)); - gd54xx->pci = !!(info->flags & DEVICE_PCI); - gd54xx->vlb = !!(info->flags & DEVICE_VLB); - gd54xx->mca = !!(info->flags & DEVICE_MCA); + gd54xx->pci = !!(info->flags & DEVICE_PCI); + gd54xx->vlb = !!(info->flags & DEVICE_VLB); + gd54xx->mca = !!(info->flags & DEVICE_MCA); gd54xx->bit32 = gd54xx->pci || gd54xx->vlb; - gd54xx->rev = 0; + gd54xx->rev = 0; gd54xx->has_bios = 1; gd54xx->id = id; switch (id) { - case CIRRUS_ID_CLGD5401: - romfn = BIOS_GD5401_PATH; - break; + case CIRRUS_ID_CLGD5401: + romfn = BIOS_GD5401_PATH; + break; - case CIRRUS_ID_CLGD5402: - if (info->local & 0x200) - romfn = BIOS_GD5402_ONBOARD_PATH; - else - romfn = BIOS_GD5402_PATH; - break; + case CIRRUS_ID_CLGD5402: + if (info->local & 0x200) + romfn = BIOS_GD5402_ONBOARD_PATH; + else + romfn = BIOS_GD5402_PATH; + break; - case CIRRUS_ID_CLGD5420: - romfn = BIOS_GD5420_PATH; - break; + case CIRRUS_ID_CLGD5420: + romfn = BIOS_GD5420_PATH; + break; - case CIRRUS_ID_CLGD5422: - case CIRRUS_ID_CLGD5424: - romfn = BIOS_GD5422_PATH; - break; + case CIRRUS_ID_CLGD5422: + case CIRRUS_ID_CLGD5424: + romfn = BIOS_GD5422_PATH; + break; - case CIRRUS_ID_CLGD5426: - if (info->local & 0x200) - romfn = NULL; - else { - if (info->local & 0x100) - romfn = BIOS_GD5426_DIAMOND_A1_ISA_PATH; - else { - if (gd54xx->vlb) - romfn = BIOS_GD5428_PATH; - else if (gd54xx->mca) - romfn = BIOS_GD5426_MCA_PATH; - else - romfn = BIOS_GD5428_ISA_PATH; - } - } - break; + case CIRRUS_ID_CLGD5426: + if (info->local & 0x200) + romfn = NULL; + else { + if (info->local & 0x100) + romfn = BIOS_GD5426_DIAMOND_A1_ISA_PATH; + else { + if (gd54xx->vlb) + romfn = BIOS_GD5428_PATH; + else if (gd54xx->mca) + romfn = BIOS_GD5426_MCA_PATH; + else + romfn = BIOS_GD5428_ISA_PATH; + } + } + break; - case CIRRUS_ID_CLGD5428: - if (info->local & 0x100) - if (gd54xx->vlb) - romfn = BIOS_GD5428_DIAMOND_B1_VLB_PATH; - else { - romfn1 = BIOS_GD5428_BOCA_ISA_PATH_1; - romfn2 = BIOS_GD5428_BOCA_ISA_PATH_2; - } - else { - if (gd54xx->vlb) - romfn = BIOS_GD5428_PATH; - else if (gd54xx->mca) - romfn = BIOS_GD5428_MCA_PATH; - else - romfn = BIOS_GD5428_ISA_PATH; - } - break; + case CIRRUS_ID_CLGD5428: + if (info->local & 0x100) + if (gd54xx->vlb) + romfn = BIOS_GD5428_DIAMOND_B1_VLB_PATH; + else { + romfn1 = BIOS_GD5428_BOCA_ISA_PATH_1; + romfn2 = BIOS_GD5428_BOCA_ISA_PATH_2; + } + else { + if (gd54xx->vlb) + romfn = BIOS_GD5428_PATH; + else if (gd54xx->mca) + romfn = BIOS_GD5428_MCA_PATH; + else + romfn = BIOS_GD5428_ISA_PATH; + } + break; - case CIRRUS_ID_CLGD5429: - romfn = BIOS_GD5429_PATH; - break; + case CIRRUS_ID_CLGD5429: + romfn = BIOS_GD5429_PATH; + break; - case CIRRUS_ID_CLGD5432: - case CIRRUS_ID_CLGD5434_4: - if (info->local & 0x200) { - romfn = NULL; - gd54xx->has_bios = 0; - } - break; + case CIRRUS_ID_CLGD5432: + case CIRRUS_ID_CLGD5434_4: + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } + break; - case CIRRUS_ID_CLGD5434: - if (info->local & 0x200) { - romfn = NULL; - gd54xx->has_bios = 0; - } else if (gd54xx->vlb) { - romfn = BIOS_GD5430_ORCHID_VLB_PATH; - } else { - if (info->local & 0x100) - romfn = BIOS_GD5434_DIAMOND_A3_ISA_PATH; - else - romfn = BIOS_GD5434_PATH; - } - break; + case CIRRUS_ID_CLGD5434: + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else if (gd54xx->vlb) { + romfn = BIOS_GD5430_ORCHID_VLB_PATH; + } else { + if (info->local & 0x100) + romfn = BIOS_GD5434_DIAMOND_A3_ISA_PATH; + else + romfn = BIOS_GD5434_PATH; + } + break; - case CIRRUS_ID_CLGD5436: - romfn = BIOS_GD5436_PATH; - break; + case CIRRUS_ID_CLGD5436: + romfn = BIOS_GD5436_PATH; + break; - case CIRRUS_ID_CLGD5430: - if (info->local & 0x400) { - /* CL-GD 5440 */ - gd54xx->rev = 0x47; - if (info->local & 0x200) { - romfn = NULL; - gd54xx->has_bios = 0; - } else - romfn = BIOS_GD5440_PATH; - } else { - /* CL-GD 5430 */ - if (info->local & 0x200) { - romfn = NULL; - gd54xx->has_bios = 0; - } else if (gd54xx->pci) { - romfn = BIOS_GD5430_PATH; - } else if ((gd54xx->vlb) && (info->local & 0x100)) - romfn = BIOS_GD5430_ORCHID_VLB_PATH; - else - romfn = BIOS_GD5430_DIAMOND_A8_VLB_PATH; - } - break; + case CIRRUS_ID_CLGD5430: + if (info->local & 0x400) { + /* CL-GD 5440 */ + gd54xx->rev = 0x47; + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else + romfn = BIOS_GD5440_PATH; + } else { + /* CL-GD 5430 */ + if (info->local & 0x200) { + romfn = NULL; + gd54xx->has_bios = 0; + } else if (gd54xx->pci) { + romfn = BIOS_GD5430_PATH; + } else if ((gd54xx->vlb) && (info->local & 0x100)) + romfn = BIOS_GD5430_ORCHID_VLB_PATH; + else + romfn = BIOS_GD5430_DIAMOND_A8_VLB_PATH; + } + break; - case CIRRUS_ID_CLGD5446: - if (info->local & 0x100) - romfn = BIOS_GD5446_STB_PATH; - else - romfn = BIOS_GD5446_PATH; - break; + case CIRRUS_ID_CLGD5446: + if (info->local & 0x100) + romfn = BIOS_GD5446_STB_PATH; + else + romfn = BIOS_GD5446_PATH; + break; - case CIRRUS_ID_CLGD5480: - romfn = BIOS_GD5480_PATH; - break; + case CIRRUS_ID_CLGD5480: + romfn = BIOS_GD5480_PATH; + break; } if (info->flags & DEVICE_MCA) { - vram = 1024; - gd54xx->vram_size = vram << 10; + vram = 1024; + gd54xx->vram_size = vram << 10; } else { - if (id <= CIRRUS_ID_CLGD5428) { - if ((id == CIRRUS_ID_CLGD5426) && (info->local & 0x200)) - vram = 1024; - else if (id == CIRRUS_ID_CLGD5401) - vram = 256; - else if (id == CIRRUS_ID_CLGD5402) - vram = 512; - else - vram = device_get_config_int("memory"); - gd54xx->vram_size = vram << 10; - } else { - vram = device_get_config_int("memory"); - gd54xx->vram_size = vram << 20; - } + if (id <= CIRRUS_ID_CLGD5428) { + if ((id == CIRRUS_ID_CLGD5426) && (info->local & 0x200)) + vram = 1024; + else if (id == CIRRUS_ID_CLGD5401) + vram = 256; + else if (id == CIRRUS_ID_CLGD5402) + vram = 512; + else + vram = device_get_config_int("memory"); + gd54xx->vram_size = vram << 10; + } else { + vram = device_get_config_int("memory"); + gd54xx->vram_size = vram << 20; + } } gd54xx->vram_mask = gd54xx->vram_size - 1; if (romfn) rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); else if (romfn1 && romfn2) - rom_init_interleaved(&gd54xx->bios_rom, BIOS_GD5428_BOCA_ISA_PATH_1, BIOS_GD5428_BOCA_ISA_PATH_2, 0xc0000, - 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init_interleaved(&gd54xx->bios_rom, BIOS_GD5428_BOCA_ISA_PATH_1, BIOS_GD5428_BOCA_ISA_PATH_2, 0xc0000, + 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (info->flags & DEVICE_ISA) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_isa); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_isa); else if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_pci); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_pci); else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_gd54xx_vlb); if (id >= CIRRUS_ID_CLGD5426) { - svga_init(info, &gd54xx->svga, gd54xx, gd54xx->vram_size, - gd54xx_recalctimings, gd54xx_in, gd54xx_out, - gd54xx_hwcursor_draw, gd54xx_overlay_draw); + svga_init(info, &gd54xx->svga, gd54xx, gd54xx->vram_size, + gd54xx_recalctimings, gd54xx_in, gd54xx_out, + gd54xx_hwcursor_draw, gd54xx_overlay_draw); } else { - svga_init(info, &gd54xx->svga, gd54xx, gd54xx->vram_size, - gd54xx_recalctimings, gd54xx_in, gd54xx_out, - gd54xx_hwcursor_draw, NULL); + svga_init(info, &gd54xx->svga, gd54xx, gd54xx->vram_size, + gd54xx_recalctimings, gd54xx_in, gd54xx_out, + gd54xx_hwcursor_draw, NULL); } svga->vblank_start = gd54xx_vblank_start; - svga->ven_write = gd54xx_write_modes45; - if ((vram == 1) || (vram >= 256 && vram <= 1024)) - svga->decode_mask = gd54xx->vram_mask; + svga->ven_write = gd54xx_write_modes45; + if ((vram == 1) || (vram >= 256 && vram <= 1024)) + svga->decode_mask = gd54xx->vram_mask; if (gd54xx->bit32) { - 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, - gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, - gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); - mem_mapping_add(&gd54xx->linear_mapping, 0, 0, - gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, - gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); - mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0, - gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl, - gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); - mem_mapping_add(&gd54xx->vgablt_mapping, 0, 0, - gd5480_vgablt_read, gd5480_vgablt_readw, gd5480_vgablt_readl, - gd5480_vgablt_write, gd5480_vgablt_writew, gd5480_vgablt_writel, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + 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, + gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, + gd543x_mmio_writeb, gd543x_mmio_writew, gd543x_mmio_writel, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); + mem_mapping_add(&gd54xx->linear_mapping, 0, 0, + gd54xx_readb_linear, gd54xx_readw_linear, gd54xx_readl_linear, + gd54xx_writeb_linear, gd54xx_writew_linear, gd54xx_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); + mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0, + gd5436_aperture2_readb, gd5436_aperture2_readw, gd5436_aperture2_readl, + gd5436_aperture2_writeb, gd5436_aperture2_writew, gd5436_aperture2_writel, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); + mem_mapping_add(&gd54xx->vgablt_mapping, 0, 0, + gd5480_vgablt_read, gd5480_vgablt_readw, gd5480_vgablt_readl, + gd5480_vgablt_write, gd5480_vgablt_writew, gd5480_vgablt_writel, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); } else { - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, NULL, gd54xx_write, gd54xx_writew, NULL); - mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, - gd543x_mmio_read, gd543x_mmio_readw, NULL, - gd543x_mmio_writeb, gd543x_mmio_writew, NULL, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); - mem_mapping_add(&gd54xx->linear_mapping, 0, 0, - gd54xx_readb_linear, gd54xx_readw_linear, NULL, - gd54xx_writeb_linear, gd54xx_writew_linear, NULL, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); - mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0, - gd5436_aperture2_readb, gd5436_aperture2_readw, NULL, - gd5436_aperture2_writeb, gd5436_aperture2_writew, NULL, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); - mem_mapping_add(&gd54xx->vgablt_mapping, 0, 0, - gd5480_vgablt_read, gd5480_vgablt_readw, NULL, - gd5480_vgablt_write, gd5480_vgablt_writew, NULL, - NULL, MEM_MAPPING_EXTERNAL, gd54xx); + mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, NULL, gd54xx_write, gd54xx_writew, NULL); + mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, + gd543x_mmio_read, gd543x_mmio_readw, NULL, + gd543x_mmio_writeb, gd543x_mmio_writew, NULL, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); + mem_mapping_add(&gd54xx->linear_mapping, 0, 0, + gd54xx_readb_linear, gd54xx_readw_linear, NULL, + gd54xx_writeb_linear, gd54xx_writew_linear, NULL, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); + mem_mapping_add(&gd54xx->aperture2_mapping, 0, 0, + gd5436_aperture2_readb, gd5436_aperture2_readw, NULL, + gd5436_aperture2_writeb, gd5436_aperture2_writew, NULL, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); + mem_mapping_add(&gd54xx->vgablt_mapping, 0, 0, + gd5480_vgablt_read, gd5480_vgablt_readw, NULL, + gd5480_vgablt_write, gd5480_vgablt_writew, NULL, + NULL, MEM_MAPPING_EXTERNAL, gd54xx); } io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); if (gd54xx->pci && id >= CIRRUS_ID_CLGD5430) { - pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); - mem_mapping_disable(&gd54xx->bios_rom.mapping); + pci_add_card(PCI_ADD_VIDEO, cl_pci_read, cl_pci_write, gd54xx); + mem_mapping_disable(&gd54xx->bios_rom.mapping); } mem_mapping_set_p(&svga->mapping, gd54xx); @@ -4099,23 +4032,23 @@ static void svga->hwcursor.yoff = svga->hwcursor.xoff = 0; if (id >= CIRRUS_ID_CLGD5420) { - gd54xx->vclk_n[0] = 0x4a; - gd54xx->vclk_d[0] = 0x2b; - gd54xx->vclk_n[1] = 0x5b; - gd54xx->vclk_d[1] = 0x2f; - gd54xx->vclk_n[2] = 0x45; - gd54xx->vclk_d[2] = 0x30; - gd54xx->vclk_n[3] = 0x7e; - gd54xx->vclk_d[3] = 0x33; + gd54xx->vclk_n[0] = 0x4a; + gd54xx->vclk_d[0] = 0x2b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x30; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; } else { - gd54xx->vclk_n[0] = 0x66; - gd54xx->vclk_d[0] = 0x3b; - gd54xx->vclk_n[1] = 0x5b; - gd54xx->vclk_d[1] = 0x2f; - gd54xx->vclk_n[2] = 0x45; - gd54xx->vclk_d[2] = 0x2c; - gd54xx->vclk_n[3] = 0x7e; - gd54xx->vclk_d[3] = 0x33; + gd54xx->vclk_n[0] = 0x66; + gd54xx->vclk_d[0] = 0x3b; + gd54xx->vclk_n[1] = 0x5b; + gd54xx->vclk_d[1] = 0x2f; + gd54xx->vclk_n[2] = 0x45; + gd54xx->vclk_d[2] = 0x2c; + gd54xx->vclk_n[3] = 0x7e; + gd54xx->vclk_d[3] = 0x33; } svga->extra_banks[1] = 0x8000; @@ -4131,24 +4064,24 @@ static void svga->seqregs[6] = 0x0f; if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429) - gd54xx->unlocked = 1; + gd54xx->unlocked = 1; if (gd54xx->mca) { - gd54xx->pos_regs[0] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x82 : 0x7b; - gd54xx->pos_regs[1] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x81 : 0x91; - mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx); - io_sethandler(0x46e8, 0x0001, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + gd54xx->pos_regs[0] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x82 : 0x7b; + gd54xx->pos_regs[1] = svga->crtc[0x27] == CIRRUS_ID_CLGD5426 ? 0x81 : 0x91; + mca_add(gd5428_mca_read, gd5428_mca_write, gd5428_mca_feedb, NULL, gd54xx); + io_sethandler(0x46e8, 0x0001, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); } if (gd54xx_is_5434(svga)) { - gd54xx->i2c = i2c_gpio_init("ddc_cl54xx"); - gd54xx->ddc = ddc_init(i2c_gpio_get_bus(gd54xx->i2c)); + gd54xx->i2c = i2c_gpio_init("ddc_cl54xx"); + gd54xx->ddc = ddc_init(i2c_gpio_get_bus(gd54xx->i2c)); } if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5446) - gd54xx->crtcreg_mask = 0x7f; + gd54xx->crtcreg_mask = 0x7f; else - gd54xx->crtcreg_mask = 0x3f; + gd54xx->crtcreg_mask = 0x3f; gd54xx->overlay.colorkeycompare = 0xff; @@ -4296,32 +4229,30 @@ gd5480_available(void) void gd54xx_close(void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; svga_close(&gd54xx->svga); if (gd54xx->i2c) { - ddc_close(gd54xx->ddc); - i2c_gpio_close(gd54xx->i2c); + ddc_close(gd54xx->ddc); + i2c_gpio_close(gd54xx->i2c); } free(gd54xx); } - void gd54xx_speed_changed(void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; svga_recalctimings(&gd54xx->svga); } - void gd54xx_force_redraw(void *p) { - gd54xx_t *gd54xx = (gd54xx_t *)p; + gd54xx_t *gd54xx = (gd54xx_t *) p; gd54xx->svga.fullchange = changeframecount; } @@ -4545,467 +4476,467 @@ static const device_config_t gd5480_config[] = { // clang-format on const device_t gd5401_isa_device = { - .name = "Cirrus Logic GD5401 (ISA) (ACUMOS AVGA1)", + .name = "Cirrus Logic GD5401 (ISA) (ACUMOS AVGA1)", .internal_name = "cl_gd5401_isa", - .flags = DEVICE_ISA, - .local = CIRRUS_ID_CLGD5401, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_ISA, + .local = CIRRUS_ID_CLGD5401, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5401_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = NULL, + .force_redraw = gd54xx_force_redraw, + .config = NULL, }; const device_t gd5402_isa_device = { - .name = "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2)", + .name = "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2)", .internal_name = "cl_gd5402_isa", - .flags = DEVICE_ISA, - .local = CIRRUS_ID_CLGD5402, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_ISA, + .local = CIRRUS_ID_CLGD5402, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5402_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = NULL, + .force_redraw = gd54xx_force_redraw, + .config = NULL, }; const device_t gd5402_onboard_device = { - .name = "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2) (On-Board)", + .name = "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2) (On-Board)", .internal_name = "cl_gd5402_onboard", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5402 | 0x200, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5402 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = NULL }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = NULL, + .force_redraw = gd54xx_force_redraw, + .config = NULL, }; const device_t gd5420_isa_device = { - .name = "Cirrus Logic GD5420 (ISA)", + .name = "Cirrus Logic GD5420 (ISA)", .internal_name = "cl_gd5420_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5420, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5420, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5420_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd542x_config, + .force_redraw = gd54xx_force_redraw, + .config = gd542x_config, }; const device_t gd5422_isa_device = { - .name = "Cirrus Logic GD5422 (ISA)", + .name = "Cirrus Logic GD5422 (ISA)", .internal_name = "cl_gd5422_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5422, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5422, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5422_available }, /* Common BIOS between 5422 and 5424 */ .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd542x_config, + .force_redraw = gd54xx_force_redraw, + .config = gd542x_config, }; const device_t gd5424_vlb_device = { - .name = "Cirrus Logic GD5424 (VLB)", + .name = "Cirrus Logic GD5424 (VLB)", .internal_name = "cl_gd5424_vlb", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5424, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5424, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5422_available }, /* Common BIOS between 5422 and 5424 */ .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd542x_config, + .force_redraw = gd54xx_force_redraw, + .config = gd542x_config, }; const device_t gd5426_isa_device = { - .name = "Cirrus Logic GD5426 (ISA)", + .name = "Cirrus Logic GD5426 (ISA)", .internal_name = "cl_gd5426_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5426, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5426, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_isa_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; /*According to a Diamond bios file listing and vgamuseum*/ const device_t gd5426_diamond_speedstar_pro_a1_isa_device = { - .name = "Cirrus Logic GD5426 (ISA) (Diamond SpeedStar Pro Rev. A1)", + .name = "Cirrus Logic GD5426 (ISA) (Diamond SpeedStar Pro Rev. A1)", .internal_name = "cl_gd5426_diamond_a1_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5426 | 0x100, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5426 | 0x100, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5426_diamond_a1_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; const device_t gd5426_vlb_device = { - .name = "Cirrus Logic GD5426 (VLB)", + .name = "Cirrus Logic GD5426 (VLB)", .internal_name = "cl_gd5426_vlb", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5426, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5426, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; const device_t gd5426_onboard_device = { - .name = "Cirrus Logic GD5426 (VLB) (On-Board)", + .name = "Cirrus Logic GD5426 (VLB) (On-Board)", .internal_name = "cl_gd5426_onboard", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5426 | 0x200, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5426 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = NULL }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = NULL + .force_redraw = gd54xx_force_redraw, + .config = NULL }; const device_t gd5428_isa_device = { - .name = "Cirrus Logic GD5428 (ISA)", + .name = "Cirrus Logic GD5428 (ISA)", .internal_name = "cl_gd5428_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5428, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5428, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_isa_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; const device_t gd5428_vlb_device = { - .name = "Cirrus Logic GD5428 (VLB)", + .name = "Cirrus Logic GD5428 (VLB)", .internal_name = "cl_gd5428_vlb", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5428, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5428, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; /*According to a Diamond bios file listing and vgamuseum*/ const device_t gd5428_diamond_speedstar_pro_b1_vlb_device = { - .name = "Cirrus Logic GD5428 (VLB) (Diamond SpeedStar Pro Rev. B1)", + .name = "Cirrus Logic GD5428 (VLB) (Diamond SpeedStar Pro Rev. B1)", .internal_name = "cl_gd5428_diamond_b1_vlb", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5428 | 0x100, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5428 | 0x100, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_diamond_b1_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; const device_t gd5428_boca_isa_device = { - .name = "Cirrus Logic GD5428 (ISA) (BOCA Research 4610)", + .name = "Cirrus Logic GD5428 (ISA) (BOCA Research 4610)", .internal_name = "cl_gd5428_boca_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5428 | 0x100, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5428 | 0x100, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_boca_isa_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; const device_t gd5428_mca_device = { - .name = "Cirrus Logic GD5428 (MCA) (IBM SVGA Adapter/A)", + .name = "Cirrus Logic GD5428 (MCA) (IBM SVGA Adapter/A)", .internal_name = "ibm1mbsvga", - .flags = DEVICE_MCA, - .local = CIRRUS_ID_CLGD5428, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_MCA, + .local = CIRRUS_ID_CLGD5428, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_mca_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = NULL + .force_redraw = gd54xx_force_redraw, + .config = NULL }; const device_t gd5426_mca_device = { - .name = "Cirrus Logic GD5426 (MCA) (Reply Video Adapter)", + .name = "Cirrus Logic GD5426 (MCA) (Reply Video Adapter)", .internal_name = "replymcasvga", - .flags = DEVICE_MCA, - .local = CIRRUS_ID_CLGD5426, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_MCA, + .local = CIRRUS_ID_CLGD5426, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5426_mca_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5426_config + .force_redraw = gd54xx_force_redraw, + .config = gd5426_config }; const device_t gd5428_onboard_device = { - .name = "Cirrus Logic GD5428 (ISA) (On-Board)", + .name = "Cirrus Logic GD5428 (ISA) (On-Board)", .internal_name = "cl_gd5428_onboard", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5428, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5428, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5428_isa_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5428_onboard_config + .force_redraw = gd54xx_force_redraw, + .config = gd5428_onboard_config }; const device_t gd5429_isa_device = { - .name = "Cirrus Logic GD5429 (ISA)", + .name = "Cirrus Logic GD5429 (ISA)", .internal_name = "cl_gd5429_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5429, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5429, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5429_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5429_config + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config }; const device_t gd5429_vlb_device = { - .name = "Cirrus Logic GD5429 (VLB)", + .name = "Cirrus Logic GD5429 (VLB)", .internal_name = "cl_gd5429_vlb", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5429, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5429, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5429_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5429_config + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config }; /*According to a Diamond bios file listing and vgamuseum*/ const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device = { - .name = "Cirrus Logic GD5430 (VLB) (Diamond SpeedStar Pro SE Rev. A8)", + .name = "Cirrus Logic GD5430 (VLB) (Diamond SpeedStar Pro SE Rev. A8)", .internal_name = "cl_gd5430_vlb_diamond", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5430, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5430, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5430_diamond_a8_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5429_config + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config }; const device_t gd5430_vlb_device = { - .name = "Cirrus Logic GD5430", + .name = "Cirrus Logic GD5430", .internal_name = "cl_gd5430_vlb", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5430 | 0x100, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5430 | 0x100, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5430_orchid_vlb_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5429_config + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config }; const device_t gd5430_pci_device = { - .name = "Cirrus Logic GD5430 (PCI)", + .name = "Cirrus Logic GD5430 (PCI)", .internal_name = "cl_gd5430_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5430, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5430, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5430_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5429_config + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config }; const device_t gd5434_isa_device = { - .name = "Cirrus Logic GD5434 (ISA)", + .name = "Cirrus Logic GD5434 (ISA)", .internal_name = "cl_gd5434_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5434, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5434, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5434_isa_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5434_config + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config }; /*According to a Diamond bios file listing and vgamuseum*/ const device_t gd5434_diamond_speedstar_64_a3_isa_device = { - .name = "Cirrus Logic GD5434 (ISA) (Diamond SpeedStar 64 Rev. A3)", + .name = "Cirrus Logic GD5434 (ISA) (Diamond SpeedStar 64 Rev. A3)", .internal_name = "cl_gd5434_diamond_a3_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = CIRRUS_ID_CLGD5434 | 0x100, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = CIRRUS_ID_CLGD5434 | 0x100, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5434_diamond_a3_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5429_config + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config }; const device_t gd5434_onboard_pci_device = { - .name = "Cirrus Logic GD5434-4 (PCI) (On-Board)", + .name = "Cirrus Logic GD5434-4 (PCI) (On-Board)", .internal_name = "cl_gd5434_onboard_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5434 | 0x200, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5434 | 0x200, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = NULL }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5434_onboard_config + .force_redraw = gd54xx_force_redraw, + .config = gd5434_onboard_config }; const device_t gd5434_vlb_device = { - .name = "Cirrus Logic GD5434 (VLB)", + .name = "Cirrus Logic GD5434 (VLB)", .internal_name = "cl_gd5434_vlb", - .flags = DEVICE_VLB, - .local = CIRRUS_ID_CLGD5434, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_VLB, + .local = CIRRUS_ID_CLGD5434, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5430_orchid_vlb_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5434_config + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config }; const device_t gd5434_pci_device = { - .name = "Cirrus Logic GD5434 (PCI)", + .name = "Cirrus Logic GD5434 (PCI)", .internal_name = "cl_gd5434_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5434, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5434, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5434_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5434_config + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config }; const device_t gd5436_pci_device = { - .name = "Cirrus Logic GD5436 (PCI)", + .name = "Cirrus Logic GD5436 (PCI)", .internal_name = "cl_gd5436_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5436, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5436, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5436_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5434_config + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config }; const device_t gd5440_onboard_pci_device = { - .name = "Cirrus Logic GD5440 (PCI) (On-Board)", + .name = "Cirrus Logic GD5440 (PCI) (On-Board)", .internal_name = "cl_gd5440_onboard_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5440 | 0x600, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5440 | 0x600, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = NULL }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5440_onboard_config + .force_redraw = gd54xx_force_redraw, + .config = gd5440_onboard_config }; const device_t gd5440_pci_device = { - .name = "Cirrus Logic GD5440 (PCI)", + .name = "Cirrus Logic GD5440 (PCI)", .internal_name = "cl_gd5440_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5440 | 0x400, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5440 | 0x400, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5440_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5429_config + .force_redraw = gd54xx_force_redraw, + .config = gd5429_config }; const device_t gd5446_pci_device = { - .name = "Cirrus Logic GD5446 (PCI)", + .name = "Cirrus Logic GD5446 (PCI)", .internal_name = "cl_gd5446_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5446, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5446, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5446_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5434_config + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config }; const device_t gd5446_stb_pci_device = { - .name = "Cirrus Logic GD5446 (PCI) (STB Nitro 64V)", + .name = "Cirrus Logic GD5446 (PCI) (STB Nitro 64V)", .internal_name = "cl_gd5446_stb_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5446 | 0x100, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5446 | 0x100, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5446_stb_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5434_config + .force_redraw = gd54xx_force_redraw, + .config = gd5434_config }; const device_t gd5480_pci_device = { - .name = "Cirrus Logic GD5480 (PCI)", + .name = "Cirrus Logic GD5480 (PCI)", .internal_name = "cl_gd5480_pci", - .flags = DEVICE_PCI, - .local = CIRRUS_ID_CLGD5480, - .init = gd54xx_init, - .close = gd54xx_close, - .reset = gd54xx_reset, + .flags = DEVICE_PCI, + .local = CIRRUS_ID_CLGD5480, + .init = gd54xx_init, + .close = gd54xx_close, + .reset = gd54xx_reset, { .available = gd5480_available }, .speed_changed = gd54xx_speed_changed, - .force_redraw = gd54xx_force_redraw, - .config = gd5480_config + .force_redraw = gd54xx_force_redraw, + .config = gd5480_config }; diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 2dc2d2308..03f20543d 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -35,400 +35,350 @@ #include <86box/vid_colorplus.h> #include <86box/vid_cga_comp.h> - /* Bits in the colorplus control register: */ -#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ -#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */ -#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */ -#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */ +#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ +#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */ +#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */ +#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */ /* Bits in the CGA graphics mode register */ -#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */ +#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */ -#define CGA_RGB 0 -#define CGA_COMPOSITE 1 +#define CGA_RGB 0 +#define CGA_COMPOSITE 1 -#define COMPOSITE_OLD 0 -#define COMPOSITE_NEW 1 - - -video_timings_t timing_colorplus = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +#define COMPOSITE_OLD 0 +#define COMPOSITE_NEW 1 +video_timings_t timing_colorplus = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; void cga_recalctimings(cga_t *cga); -void colorplus_out(uint16_t addr, uint8_t val, void *p) +void +colorplus_out(uint16_t addr, uint8_t val, void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *) p; - if (addr == 0x3DD) - { - colorplus->control = val & 0x70; - } - else - { - cga_out(addr, val, &colorplus->cga); - } + if (addr == 0x3DD) { + colorplus->control = val & 0x70; + } else { + cga_out(addr, val, &colorplus->cga); + } } -uint8_t colorplus_in(uint16_t addr, void *p) +uint8_t +colorplus_in(uint16_t addr, void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *) p; - return cga_in(addr, &colorplus->cga); + return cga_in(addr, &colorplus->cga); } -void colorplus_write(uint32_t addr, uint8_t val, void *p) +void +colorplus_write(uint32_t addr, uint8_t val, void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *) p; - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && - (colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) - { - addr ^= 0x4000; - } - else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) - { - addr &= 0x3FFF; - } - colorplus->cga.vram[addr & 0x7fff] = val; - if (colorplus->cga.snow_enabled) + if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { + addr ^= 0x4000; + } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { + addr &= 0x3FFF; + } + colorplus->cga.vram[addr & 0x7fff] = val; + if (colorplus->cga.snow_enabled) { + int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc; + colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff]; + colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff]; + } + cycles -= 4; +} + +uint8_t +colorplus_read(uint32_t addr, void *p) +{ + colorplus_t *colorplus = (colorplus_t *) p; + + if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) { + addr ^= 0x4000; + } else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) { + addr &= 0x3FFF; + } + cycles -= 4; + if (colorplus->cga.snow_enabled) { + int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc; + colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff]; + colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff]; + } + return colorplus->cga.vram[addr & 0x7fff]; +} + +void +colorplus_recalctimings(colorplus_t *colorplus) +{ + cga_recalctimings(&colorplus->cga); +} + +void +colorplus_poll(void *p) +{ + colorplus_t *colorplus = (colorplus_t *) p; + int x, c; + int oldvc; + uint16_t dat0, dat1; + int cols[4]; + int col; + int oldsc; + static const int cols16[16] = { 0x10, 0x12, 0x14, 0x16, + 0x18, 0x1A, 0x1C, 0x1E, + 0x11, 0x13, 0x15, 0x17, + 0x19, 0x1B, 0x1D, 0x1F }; + uint8_t *plane0 = colorplus->cga.vram; + uint8_t *plane1 = colorplus->cga.vram + 0x4000; + + /* If one of the extra modes is not selected, drop down to the CGA + * drawing code. */ + if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) { + cga_poll(&colorplus->cga); + return; + } + + if (!colorplus->cga.linepos) { + timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime); + colorplus->cga.cgastat |= 1; + colorplus->cga.linepos = 1; + oldsc = colorplus->cga.sc; + if ((colorplus->cga.crtc[8] & 3) == 3) + colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7; + if (colorplus->cga.cgadispon) { + if (colorplus->cga.displine < colorplus->cga.firstline) { + colorplus->cga.firstline = colorplus->cga.displine; + video_wait_for_buffer(); + } + colorplus->cga.lastline = colorplus->cga.displine; + /* Left / right border */ + for (c = 0; c < 8; c++) { + buffer32->line[colorplus->cga.displine][c] = buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16; + } + if (colorplus->control & COLORPLUS_320x200_MODE) { + for (x = 0; x < colorplus->cga.crtc[1]; x++) { + dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; + dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; + colorplus->cga.ma++; + for (c = 0; c < 8; c++) { + buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]; + dat0 <<= 2; + dat1 <<= 2; + } + } + } else if (colorplus->control & COLORPLUS_640x200_MODE) { + cols[0] = (colorplus->cga.cgacol & 15) | 16; + col = (colorplus->cga.cgacol & 16) ? 24 : 16; + if (colorplus->cga.cgamode & 4) { + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; + } else if (colorplus->cga.cgacol & 32) { + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; + } else { + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; + } + for (x = 0; x < colorplus->cga.crtc[1]; x++) { + dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; + dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; + colorplus->cga.ma++; + for (c = 0; c < 16; c++) { + buffer32->line[colorplus->cga.displine][(x << 4) + c + 8] = cols[(dat0 >> 15) | ((dat1 >> 15) << 1)]; + dat0 <<= 1; + dat1 <<= 1; + } + } + } + } else /* Top / bottom border */ { - int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc; - colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff]; - colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff]; + cols[0] = (colorplus->cga.cgacol & 15) + 16; + hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); } - cycles -= 4; -} -uint8_t colorplus_read(uint32_t addr, void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; + x = (colorplus->cga.crtc[1] << 4) + 16; - if ((colorplus->control & COLORPLUS_PLANE_SWAP) && - (colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) - { - addr ^= 0x4000; - } - else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) - { - addr &= 0x3FFF; - } - cycles -= 4; - if (colorplus->cga.snow_enabled) - { - int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc; - colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff]; - colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff]; + if (colorplus->cga.composite) + Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]); + + colorplus->cga.sc = oldsc; + if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc) + colorplus->cga.cgastat |= 8; + colorplus->cga.displine++; + if (colorplus->cga.displine >= 360) + colorplus->cga.displine = 0; + } else { + timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime); + colorplus->cga.linepos = 0; + if (colorplus->cga.vsynctime) { + colorplus->cga.vsynctime--; + if (!colorplus->cga.vsynctime) + colorplus->cga.cgastat &= ~8; } - return colorplus->cga.vram[addr & 0x7fff]; -} - -void colorplus_recalctimings(colorplus_t *colorplus) -{ - cga_recalctimings(&colorplus->cga); -} - -void colorplus_poll(void *p) -{ - colorplus_t *colorplus = (colorplus_t *)p; - int x, c; - int oldvc; - uint16_t dat0, dat1; - int cols[4]; - int col; - int oldsc; - static const int cols16[16] = { 0x10,0x12,0x14,0x16, - 0x18,0x1A,0x1C,0x1E, - 0x11,0x13,0x15,0x17, - 0x19,0x1B,0x1D,0x1F }; - uint8_t *plane0 = colorplus->cga.vram; - uint8_t *plane1 = colorplus->cga.vram + 0x4000; - - /* If one of the extra modes is not selected, drop down to the CGA - * drawing code. */ - if (!((colorplus->control & COLORPLUS_EITHER_MODE) && - (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) - { - cga_poll(&colorplus->cga); - return; - } - - if (!colorplus->cga.linepos) - { - timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime); - colorplus->cga.cgastat |= 1; - colorplus->cga.linepos = 1; - oldsc = colorplus->cga.sc; - if ((colorplus->cga.crtc[8] & 3) == 3) - colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7; - if (colorplus->cga.cgadispon) - { - if (colorplus->cga.displine < colorplus->cga.firstline) - { - colorplus->cga.firstline = colorplus->cga.displine; - video_wait_for_buffer(); - } - colorplus->cga.lastline = colorplus->cga.displine; - /* Left / right border */ - for (c = 0; c < 8; c++) - { - buffer32->line[colorplus->cga.displine][c] = - buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] = - (colorplus->cga.cgacol & 15) + 16; - } - if (colorplus->control & COLORPLUS_320x200_MODE) - { - for (x = 0; x < colorplus->cga.crtc[1]; x++) - { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; - for (c = 0; c < 8; c++) - { - buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] = - buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] = - cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)]; - dat0 <<= 2; - dat1 <<= 2; - } - } - } - else if (colorplus->control & COLORPLUS_640x200_MODE) - { - cols[0] = (colorplus->cga.cgacol & 15) | 16; - col = (colorplus->cga.cgacol & 16) ? 24 : 16; - if (colorplus->cga.cgamode & 4) - { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; - } - else if (colorplus->cga.cgacol & 32) - { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; - } - else - { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; - } - for (x = 0; x < colorplus->cga.crtc[1]; x++) - { - dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | - plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1]; - colorplus->cga.ma++; - for (c = 0; c < 16; c++) - { - buffer32->line[colorplus->cga.displine][(x << 4) + c + 8] = - cols[(dat0 >> 15) | ((dat1 >> 15) << 1)]; - dat0 <<= 1; - dat1 <<= 1; - } - } - } - } - else /* Top / bottom border */ - { - cols[0] = (colorplus->cga.cgacol & 15) + 16; - hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]); - } - - x = (colorplus->cga.crtc[1] << 4) + 16; - - if (colorplus->cga.composite) - Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]); - - colorplus->cga.sc = oldsc; - if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc) - colorplus->cga.cgastat |= 8; - colorplus->cga.displine++; - if (colorplus->cga.displine >= 360) - colorplus->cga.displine = 0; + if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) { + colorplus->cga.con = 0; + colorplus->cga.coff = 1; } - else - { - timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime); - colorplus->cga.linepos = 0; - if (colorplus->cga.vsynctime) - { - colorplus->cga.vsynctime--; - if (!colorplus->cga.vsynctime) - colorplus->cga.cgastat &= ~8; - } - if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) - { - colorplus->cga.con = 0; - colorplus->cga.coff = 1; - } - if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1)) - colorplus->cga.maback = colorplus->cga.ma; - if (colorplus->cga.vadj) - { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; - colorplus->cga.vadj--; - if (!colorplus->cga.vadj) - { - colorplus->cga.cgadispon = 1; - colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - colorplus->cga.sc = 0; - } - } - else if (colorplus->cga.sc == colorplus->cga.crtc[9]) - { - colorplus->cga.maback = colorplus->cga.ma; - colorplus->cga.sc = 0; - oldvc = colorplus->cga.vc; - colorplus->cga.vc++; - colorplus->cga.vc &= 127; + if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1)) + colorplus->cga.maback = colorplus->cga.ma; + if (colorplus->cga.vadj) { + colorplus->cga.sc++; + colorplus->cga.sc &= 31; + colorplus->cga.ma = colorplus->cga.maback; + colorplus->cga.vadj--; + if (!colorplus->cga.vadj) { + colorplus->cga.cgadispon = 1; + colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; + colorplus->cga.sc = 0; + } + } else if (colorplus->cga.sc == colorplus->cga.crtc[9]) { + colorplus->cga.maback = colorplus->cga.ma; + colorplus->cga.sc = 0; + oldvc = colorplus->cga.vc; + colorplus->cga.vc++; + colorplus->cga.vc &= 127; - if (colorplus->cga.vc == colorplus->cga.crtc[6]) - colorplus->cga.cgadispon = 0; + if (colorplus->cga.vc == colorplus->cga.crtc[6]) + colorplus->cga.cgadispon = 0; - if (oldvc == colorplus->cga.crtc[4]) - { - colorplus->cga.vc = 0; - colorplus->cga.vadj = colorplus->cga.crtc[5]; - if (!colorplus->cga.vadj) colorplus->cga.cgadispon = 1; - if (!colorplus->cga.vadj) colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; - if ((colorplus->cga.crtc[10] & 0x60) == 0x20) colorplus->cga.cursoron = 0; - else colorplus->cga.cursoron = colorplus->cga.cgablink & 8; - } - - if (colorplus->cga.vc == colorplus->cga.crtc[7]) - { - colorplus->cga.cgadispon = 0; - colorplus->cga.displine = 0; - colorplus->cga.vsynctime = 16; - if (colorplus->cga.crtc[7]) - { - if (colorplus->cga.cgamode & 1) x = (colorplus->cga.crtc[1] << 3) + 16; - else x = (colorplus->cga.crtc[1] << 4) + 16; - colorplus->cga.lastline++; - if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) - { - xsize = x; - ysize = colorplus->cga.lastline - colorplus->cga.firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, (ysize << 1) + 16); - } - - if (colorplus->cga.composite) - video_blit_memtoscreen(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); - else - video_blit_memtoscreen_8(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); - frames++; - - video_res_x = xsize - 16; - video_res_y = ysize; - if (colorplus->cga.cgamode & 1) - { - video_res_x /= 8; - video_res_y /= colorplus->cga.crtc[9] + 1; - video_bpp = 0; - } - else if (!(colorplus->cga.cgamode & 2)) - { - video_res_x /= 16; - video_res_y /= colorplus->cga.crtc[9] + 1; - video_bpp = 0; - } - else if (!(colorplus->cga.cgamode & 16)) - { - video_res_x /= 2; - video_bpp = 2; - } - else - { - video_bpp = 1; - } - } - colorplus->cga.firstline = 1000; - colorplus->cga.lastline = 0; - colorplus->cga.cgablink++; - colorplus->cga.oddeven ^= 1; - } - } + if (oldvc == colorplus->cga.crtc[4]) { + colorplus->cga.vc = 0; + colorplus->cga.vadj = colorplus->cga.crtc[5]; + if (!colorplus->cga.vadj) + colorplus->cga.cgadispon = 1; + if (!colorplus->cga.vadj) + colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff; + if ((colorplus->cga.crtc[10] & 0x60) == 0x20) + colorplus->cga.cursoron = 0; else - { - colorplus->cga.sc++; - colorplus->cga.sc &= 31; - colorplus->cga.ma = colorplus->cga.maback; - } - if (colorplus->cga.cgadispon) - colorplus->cga.cgastat &= ~1; - if ((colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1)))) - colorplus->cga.con = 1; - if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) - { - for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++) - colorplus->cga.charbuffer[x] = colorplus->cga.vram[(((colorplus->cga.ma << 1) + x) & 0x3fff)]; + colorplus->cga.cursoron = colorplus->cga.cgablink & 8; + } + + if (colorplus->cga.vc == colorplus->cga.crtc[7]) { + colorplus->cga.cgadispon = 0; + colorplus->cga.displine = 0; + colorplus->cga.vsynctime = 16; + if (colorplus->cga.crtc[7]) { + if (colorplus->cga.cgamode & 1) + x = (colorplus->cga.crtc[1] << 3) + 16; + else + x = (colorplus->cga.crtc[1] << 4) + 16; + colorplus->cga.lastline++; + if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) { + xsize = x; + ysize = colorplus->cga.lastline - colorplus->cga.firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + set_screen_size(xsize, (ysize << 1) + 16); + } + + if (colorplus->cga.composite) + video_blit_memtoscreen(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); + else + video_blit_memtoscreen_8(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8); + frames++; + + video_res_x = xsize - 16; + video_res_y = ysize; + if (colorplus->cga.cgamode & 1) { + video_res_x /= 8; + video_res_y /= colorplus->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(colorplus->cga.cgamode & 2)) { + video_res_x /= 16; + video_res_y /= colorplus->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(colorplus->cga.cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else { + video_bpp = 1; + } } + colorplus->cga.firstline = 1000; + colorplus->cga.lastline = 0; + colorplus->cga.cgablink++; + colorplus->cga.oddeven ^= 1; + } + } else { + colorplus->cga.sc++; + colorplus->cga.sc &= 31; + colorplus->cga.ma = colorplus->cga.maback; } + if (colorplus->cga.cgadispon) + colorplus->cga.cgastat &= ~1; + if ((colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1)))) + colorplus->cga.con = 1; + if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) { + for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++) + colorplus->cga.charbuffer[x] = colorplus->cga.vram[(((colorplus->cga.ma << 1) + x) & 0x3fff)]; + } + } } -void colorplus_init(colorplus_t *colorplus) +void +colorplus_init(colorplus_t *colorplus) { - cga_init(&colorplus->cga); + cga_init(&colorplus->cga); } -void *colorplus_standalone_init(const device_t *info) +void * +colorplus_standalone_init(const device_t *info) { - int display_type; + int display_type; - colorplus_t *colorplus = malloc(sizeof(colorplus_t)); - memset(colorplus, 0, sizeof(colorplus_t)); + colorplus_t *colorplus = malloc(sizeof(colorplus_t)); + memset(colorplus, 0, sizeof(colorplus_t)); - video_inform(VIDEO_FLAG_TYPE_CGA, &timing_colorplus); + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_colorplus); - /* Copied from the CGA init. Ideally this would be done by - * calling a helper function rather than duplicating code */ - display_type = device_get_config_int("display_type"); - colorplus->cga.composite = (display_type != CGA_RGB); - colorplus->cga.revision = device_get_config_int("composite_type"); - colorplus->cga.snow_enabled = device_get_config_int("snow_enabled"); + /* Copied from the CGA init. Ideally this would be done by + * calling a helper function rather than duplicating code */ + display_type = device_get_config_int("display_type"); + colorplus->cga.composite = (display_type != CGA_RGB); + colorplus->cga.revision = device_get_config_int("composite_type"); + colorplus->cga.snow_enabled = device_get_config_int("snow_enabled"); - colorplus->cga.vram = malloc(0x8000); + colorplus->cga.vram = malloc(0x8000); - cga_comp_init(colorplus->cga.revision); - timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1); - mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus); - io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); + cga_comp_init(colorplus->cga.revision); + timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1); + mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus); + io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); - lpt3_init(0x3BC); + lpt3_init(0x3BC); - return colorplus; + return colorplus; } -void colorplus_close(void *p) +void +colorplus_close(void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *) p; - free(colorplus->cga.vram); - free(colorplus); + free(colorplus->cga.vram); + free(colorplus); } -void colorplus_speed_changed(void *p) +void +colorplus_speed_changed(void *p) { - colorplus_t *colorplus = (colorplus_t *)p; + colorplus_t *colorplus = (colorplus_t *) p; - cga_recalctimings(&colorplus->cga); + cga_recalctimings(&colorplus->cga); } static const device_config_t colorplus_config[] = { -// clang-format off + // clang-format off { .name = "display_type", .description = "Display type", @@ -479,17 +429,16 @@ static const device_config_t colorplus_config[] = { // clang-format on }; -const device_t colorplus_device = -{ - .name = "Colorplus", +const device_t colorplus_device = { + .name = "Colorplus", .internal_name = "plantronics", - .flags = DEVICE_ISA, - .local = 0, - .init = colorplus_standalone_init, - .close = colorplus_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = colorplus_standalone_init, + .close = colorplus_close, + .reset = NULL, { .available = NULL }, .speed_changed = colorplus_speed_changed, - .force_redraw = NULL, - .config = colorplus_config + .force_redraw = NULL, + .config = colorplus_config }; diff --git a/src/video/vid_compaq_cga.c b/src/video/vid_compaq_cga.c index 052fcfb7d..9b61b70f5 100644 --- a/src/video/vid_compaq_cga.c +++ b/src/video/vid_compaq_cga.c @@ -36,378 +36,375 @@ #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> - -#define CGA_RGB 0 +#define CGA_RGB 0 #define CGA_COMPOSITE 1 +static uint32_t vflags; +static uint8_t mdaattr[256][2][2]; -static uint32_t vflags; -static uint8_t mdaattr[256][2][2]; - - -typedef struct compaq_cga_t -{ +typedef struct compaq_cga_t { cga_t cga; } compaq_cga_t; - #ifdef ENABLE_COMPAQ_CGA_LOG int compaq_cga_do_log = ENABLE_COMPAQ_CGA_LOG; - static void compaq_cga_log(const char *fmt, ...) { va_list ap; if (compaq_cga_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define compaq_cga_log(fmt, ...) +# define compaq_cga_log(fmt, ...) #endif - void compaq_cga_recalctimings(compaq_cga_t *self) { double _dispontime, _dispofftime, disptime; disptime = self->cga.crtc[0] + 1; - _dispontime = self->cga.crtc[1]; + _dispontime = self->cga.crtc[1]; _dispofftime = disptime - _dispontime; _dispontime *= MDACONST; _dispofftime *= MDACONST; - self->cga.dispontime = (uint64_t)(_dispontime); - self->cga.dispofftime = (uint64_t)(_dispofftime); + self->cga.dispontime = (uint64_t) (_dispontime); + self->cga.dispofftime = (uint64_t) (_dispofftime); } - void compaq_cga_poll(void *p) { - compaq_cga_t *self = (compaq_cga_t *)p; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c, xs_temp, ys_temp; - int oldvc; - uint8_t chr, attr; - uint8_t border; - uint8_t cols[4]; - int oldsc; - int underline = 0; - int blink = 0; + compaq_cga_t *self = (compaq_cga_t *) p; + uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c, xs_temp, ys_temp; + int oldvc; + uint8_t chr, attr; + uint8_t border; + uint8_t cols[4]; + int oldsc; + int underline = 0; + int blink = 0; /* If in graphics mode or character height is not 13, behave as CGA */ if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) { - overscan_x = overscan_y = 16; - cga_poll(&self->cga); - return; + overscan_x = overscan_y = 16; + cga_poll(&self->cga); + return; } else - overscan_x = overscan_y = 0; + overscan_x = overscan_y = 0; /* We are in Compaq 350-line CGA territory */ if (!self->cga.linepos) { - timer_advance_u64(&self->cga.timer, self->cga.dispofftime); - self->cga.cgastat |= 1; - self->cga.linepos = 1; - oldsc = self->cga.sc; - if ((self->cga.crtc[8] & 3) == 3) - self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7; - if (self->cga.cgadispon) { - if (self->cga.displine < self->cga.firstline) { - self->cga.firstline = self->cga.displine; - video_wait_for_buffer(); - compaq_cga_log("Firstline %i\n", firstline); - } - self->cga.lastline = self->cga.displine; + timer_advance_u64(&self->cga.timer, self->cga.dispofftime); + self->cga.cgastat |= 1; + self->cga.linepos = 1; + oldsc = self->cga.sc; + if ((self->cga.crtc[8] & 3) == 3) + self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7; + if (self->cga.cgadispon) { + if (self->cga.displine < self->cga.firstline) { + self->cga.firstline = self->cga.displine; + video_wait_for_buffer(); + compaq_cga_log("Firstline %i\n", firstline); + } + self->cga.lastline = self->cga.displine; - cols[0] = (self->cga.cgacol & 15) + 16; + cols[0] = (self->cga.cgacol & 15) + 16; - for (c = 0; c < 8; c++) { - buffer32->line[self->cga.displine][c] = cols[0]; - if (self->cga.cgamode & 1) - buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 3) + 8] = cols[0]; - else - buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 4) + 8] = cols[0]; - } + for (c = 0; c < 8; c++) { + buffer32->line[self->cga.displine][c] = cols[0]; + if (self->cga.cgamode & 1) + buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 3) + 8] = cols[0]; + else + buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 4) + 8] = cols[0]; + } - if (self->cga.cgamode & 1) { - for (x = 0; x < self->cga.crtc[1]; x++) { - chr = self->cga.charbuffer[x << 1]; - attr = self->cga.charbuffer[(x << 1) + 1]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); + if (self->cga.cgamode & 1) { + for (x = 0; x < self->cga.crtc[1]; x++) { + chr = self->cga.charbuffer[x << 1]; + attr = self->cga.charbuffer[(x << 1) + 1]; + drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - if (vflags) { - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - } + if (vflags) { + underline = 0; + blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + } - if (vflags && (self->cga.cgamode & 0x80)) { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; + if (vflags && (self->cga.cgamode & 0x80)) { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; - if ((self->cga.sc == 12) && ((attr & 7) == 1)) - underline = 1; - } else if (self->cga.cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; + if ((self->cga.sc == 12) && ((attr & 7) == 1)) + underline = 1; + } else if (self->cga.cgamode & 0x20) { + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; - if (vflags) { - if (blink) - cols[1] = cols[0]; - } else { - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) - cols[1] = cols[0]; - } - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } + if (vflags) { + if (blink) + cols[1] = cols[0]; + } else { + if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) + cols[1] = cols[0]; + } + } else { + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; + } - if (vflags && underline) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - self->cga.ma++; - } - } else { - for (x = 0; x < self->cga.crtc[1]; x++) { - chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)]; - attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)]; - drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); + if (vflags && underline) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + self->cga.ma++; + } + } else { + for (x = 0; x < self->cga.crtc[1]; x++) { + chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)]; + attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)]; + drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron); - if (vflags) { - underline = 0; - blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - } + if (vflags) { + underline = 0; + blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); + } - if (vflags && (self->cga.cgamode & 0x80)) { - cols[0] = mdaattr[attr][blink][0]; - cols[1] = mdaattr[attr][blink][1]; - if (self->cga.sc == 12 && (attr & 7) == 1) underline = 1; - } else if (self->cga.cgamode & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; + if (vflags && (self->cga.cgamode & 0x80)) { + cols[0] = mdaattr[attr][blink][0]; + cols[1] = mdaattr[attr][blink][1]; + if (self->cga.sc == 12 && (attr & 7) == 1) + underline = 1; + } else if (self->cga.cgamode & 0x20) { + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; - if (vflags) { - if (blink) - cols[1] = cols[0]; - } else { - if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) - cols[1] = cols[0]; - } - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - self->cga.ma++; + if (vflags) { + if (blink) + cols[1] = cols[0]; + } else { + if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) + cols[1] = cols[0]; + } + } else { + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; + } + self->cga.ma++; - if (vflags && underline) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4)+(c << 1) + 8] = - buffer32->line[self->cga.displine][(x << 4)+(c << 1) + 9] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4)+(c << 1) + 8] = - buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = - buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = - cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - } - } else { - cols[0] = (self->cga.cgacol & 15) + 16; + if (vflags && underline) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + } + } else { + cols[0] = (self->cga.cgacol & 15) + 16; - if (self->cga.cgamode & 1) hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]); - else hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]); - } + if (self->cga.cgamode & 1) + hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]); + else + hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]); + } - if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16; - else x = (self->cga.crtc[1] << 4) + 16; + if (self->cga.cgamode & 1) + x = (self->cga.crtc[1] << 3) + 16; + else + x = (self->cga.crtc[1] << 4) + 16; - if (self->cga.composite) { - if (self->cga.cgamode & 0x10) - border = 0x00; - else - border = self->cga.cgacol & 0x0f; + if (self->cga.composite) { + if (self->cga.cgamode & 0x10) + border = 0x00; + else + border = self->cga.cgacol & 0x0f; - if (vflags) - Composite_Process(self->cga.cgamode & 0x7f, border, x >> 2, buffer32->line[self->cga.displine]); - else - Composite_Process(self->cga.cgamode, border, x >> 2, buffer32->line[self->cga.displine]); - } + if (vflags) + Composite_Process(self->cga.cgamode & 0x7f, border, x >> 2, buffer32->line[self->cga.displine]); + else + Composite_Process(self->cga.cgamode, border, x >> 2, buffer32->line[self->cga.displine]); + } - self->cga.sc = oldsc; - if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc) - self->cga.cgastat |= 8; - self->cga.displine++; - if (self->cga.displine >= 500) - self->cga.displine = 0; + self->cga.sc = oldsc; + if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc) + self->cga.cgastat |= 8; + self->cga.displine++; + if (self->cga.displine >= 500) + self->cga.displine = 0; } else { - timer_advance_u64(&self->cga.timer, self->cga.dispontime); - self->cga.linepos = 0; - if (self->cga.vsynctime) { - self->cga.vsynctime--; - if (!self->cga.vsynctime) - self->cga.cgastat &= ~8; - } + timer_advance_u64(&self->cga.timer, self->cga.dispontime); + self->cga.linepos = 0; + if (self->cga.vsynctime) { + self->cga.vsynctime--; + if (!self->cga.vsynctime) + self->cga.cgastat &= ~8; + } - if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) { - self->cga.con = 0; - self->cga.coff = 1; - } - if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1)) - self->cga.maback = self->cga.ma; - if (self->cga.vadj) { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - self->cga.vadj--; - if (!self->cga.vadj) { - self->cga.cgadispon = 1; - self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - self->cga.sc = 0; - } - } else if (self->cga.sc == self->cga.crtc[9]) { - self->cga.maback = self->cga.ma; - self->cga.sc = 0; - oldvc = self->cga.vc; - self->cga.vc++; - self->cga.vc &= 127; + if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) { + self->cga.con = 0; + self->cga.coff = 1; + } + if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1)) + self->cga.maback = self->cga.ma; + if (self->cga.vadj) { + self->cga.sc++; + self->cga.sc &= 31; + self->cga.ma = self->cga.maback; + self->cga.vadj--; + if (!self->cga.vadj) { + self->cga.cgadispon = 1; + self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; + self->cga.sc = 0; + } + } else if (self->cga.sc == self->cga.crtc[9]) { + self->cga.maback = self->cga.ma; + self->cga.sc = 0; + oldvc = self->cga.vc; + self->cga.vc++; + self->cga.vc &= 127; - if (self->cga.vc == self->cga.crtc[6]) - self->cga.cgadispon = 0; + if (self->cga.vc == self->cga.crtc[6]) + self->cga.cgadispon = 0; - if (oldvc == self->cga.crtc[4]) { - self->cga.vc = 0; - self->cga.vadj = self->cga.crtc[5]; + if (oldvc == self->cga.crtc[4]) { + self->cga.vc = 0; + self->cga.vadj = self->cga.crtc[5]; - if (!self->cga.vadj) self->cga.cgadispon = 1; + if (!self->cga.vadj) + self->cga.cgadispon = 1; - if (!self->cga.vadj) self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; + if (!self->cga.vadj) + self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff; - if ((self->cga.crtc[10] & 0x60) == 0x20) - self->cga.cursoron = 0; - else - self->cga.cursoron = self->cga.cgablink & 8; - } + if ((self->cga.crtc[10] & 0x60) == 0x20) + self->cga.cursoron = 0; + else + self->cga.cursoron = self->cga.cgablink & 8; + } - if (self->cga.vc == self->cga.crtc[7]) { - self->cga.cgadispon = 0; - self->cga.displine = 0; - self->cga.vsynctime = 16; + if (self->cga.vc == self->cga.crtc[7]) { + self->cga.cgadispon = 0; + self->cga.displine = 0; + self->cga.vsynctime = 16; - if (self->cga.crtc[7]) { - compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline, - self->cga.firstline ,self->cga.lastline - self->cga.firstline); + if (self->cga.crtc[7]) { + compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline, + self->cga.firstline, self->cga.lastline - self->cga.firstline); - if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16; - else x = (self->cga.crtc[1] << 4) + 16; + if (self->cga.cgamode & 1) + x = (self->cga.crtc[1] << 3) + 16; + else + x = (self->cga.crtc[1] << 4) + 16; - self->cga.lastline++; + self->cga.lastline++; - xs_temp = x; - ys_temp = (self->cga.lastline - self->cga.firstline); + xs_temp = x; + ys_temp = (self->cga.lastline - self->cga.firstline); - if ((xs_temp > 0) && (ys_temp > 0)) { - if (xs_temp < 64) xs_temp = 656; - if (ys_temp < 32) ys_temp = 400; - if (!enable_overscan) - xs_temp -= 16; + if ((xs_temp > 0) && (ys_temp > 0)) { + if (xs_temp < 64) + xs_temp = 656; + if (ys_temp < 32) + ys_temp = 400; + if (!enable_overscan) + xs_temp -= 16; - if ((self->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - xsize = xs_temp; - ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + if ((self->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + xsize = xs_temp; + ysize = ys_temp; + set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); - if (video_force_resize_get()) - video_force_resize_set(0); - } + if (video_force_resize_get()) + video_force_resize_set(0); + } - if (enable_overscan) { - if (self->cga.composite) - video_blit_memtoscreen(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16); - else - video_blit_memtoscreen_8(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16); - } else { - if (self->cga.composite) - video_blit_memtoscreen(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline); - else - video_blit_memtoscreen_8(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline); - } - } + if (enable_overscan) { + if (self->cga.composite) + video_blit_memtoscreen(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16); + else + video_blit_memtoscreen_8(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16); + } else { + if (self->cga.composite) + video_blit_memtoscreen(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline); + else + video_blit_memtoscreen_8(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline); + } + } - frames++; + frames++; - video_res_x = xsize; - if (enable_overscan) - xsize -= 16; - video_res_y = ysize; - if (self->cga.cgamode & 1) { - video_res_x /= 8; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(self->cga.cgamode & 2)) { - video_res_x /= 16; - video_res_y /= self->cga.crtc[9] + 1; - video_bpp = 0; - } else if (!(self->cga.cgamode & 16)) { - video_res_x /= 2; - video_bpp = 2; - } else - video_bpp = 1; - } + video_res_x = xsize; + if (enable_overscan) + xsize -= 16; + video_res_y = ysize; + if (self->cga.cgamode & 1) { + video_res_x /= 8; + video_res_y /= self->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(self->cga.cgamode & 2)) { + video_res_x /= 16; + video_res_y /= self->cga.crtc[9] + 1; + video_bpp = 0; + } else if (!(self->cga.cgamode & 16)) { + video_res_x /= 2; + video_bpp = 2; + } else + video_bpp = 1; + } - self->cga.firstline = 1000; - self->cga.lastline = 0; - self->cga.cgablink++; - self->cga.oddeven ^= 1; - } - } else { - self->cga.sc++; - self->cga.sc &= 31; - self->cga.ma = self->cga.maback; - } + self->cga.firstline = 1000; + self->cga.lastline = 0; + self->cga.cgablink++; + self->cga.oddeven ^= 1; + } + } else { + self->cga.sc++; + self->cga.sc &= 31; + self->cga.ma = self->cga.maback; + } - if (self->cga.cgadispon) - self->cga.cgastat &= ~1; + if (self->cga.cgadispon) + self->cga.cgastat &= ~1; - if ((self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))) - self->cga.con = 1; + if ((self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1)))) + self->cga.con = 1; - if (self->cga.cgadispon && (self->cga.cgamode & 1)) { - for (x = 0; x < (self->cga.crtc[1] << 1); x++) - self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)]; - } + if (self->cga.cgadispon && (self->cga.cgamode & 1)) { + for (x = 0; x < (self->cga.crtc[1] << 1); x++) + self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)]; + } } } - void * compaq_cga_init(const device_t *info) { - int display_type; - int c; + int display_type; + int c; compaq_cga_t *self = malloc(sizeof(compaq_cga_t)); memset(self, 0, sizeof(compaq_cga_t)); - display_type = device_get_config_int("display_type"); - self->cga.composite = (display_type != CGA_RGB); - self->cga.revision = device_get_config_int("composite_type"); + display_type = device_get_config_int("display_type"); + self->cga.composite = (display_type != CGA_RGB); + self->cga.revision = device_get_config_int("composite_type"); self->cga.snow_enabled = device_get_config_int("snow_enabled"); self->cga.vram = malloc(0x4000); @@ -418,24 +415,26 @@ compaq_cga_init(const device_t *info) io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self); if (info->local) { - for (c = 0; c < 256; c++) { - mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; - if (c & 8) mdaattr[c][0][1] = 15 + 16; - else mdaattr[c][0][1] = 7 + 16; - } + for (c = 0; c < 256; c++) { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; + if (c & 8) + mdaattr[c][0][1] = 15 + 16; + else + mdaattr[c][0][1] = 7 + 16; + } - mdaattr[0x70][0][1] = 16; - mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; - mdaattr[0xF0][0][1] = 16; - mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; - mdaattr[0x78][0][1] = 16 + 7; - mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; - mdaattr[0xF8][0][1] = 16 + 7; - mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; - mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; - mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; - mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; - mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; + mdaattr[0x70][0][1] = 16; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; + mdaattr[0xF0][0][1] = 16; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; + mdaattr[0x78][0][1] = 16 + 7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; + mdaattr[0xF8][0][1] = 16 + 7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; } vflags = info->local; @@ -443,7 +442,7 @@ compaq_cga_init(const device_t *info) overscan_x = overscan_y = 16; self->cga.rgb_type = device_get_config_int("rgb_type"); - cga_palette = (self->cga.rgb_type << 1); + cga_palette = (self->cga.rgb_type << 1); cgapal_rebuild(); self->cga.crtc[9] = 13; @@ -451,55 +450,52 @@ compaq_cga_init(const device_t *info) return self; } - void compaq_cga_close(void *p) { - compaq_cga_t *self = (compaq_cga_t *)p; + compaq_cga_t *self = (compaq_cga_t *) p; free(self->cga.vram); free(self); } - void compaq_cga_speed_changed(void *p) { - compaq_cga_t *self = (compaq_cga_t *)p; + compaq_cga_t *self = (compaq_cga_t *) p; - if (self->cga.crtc[9] == 13) /* Character height */ - compaq_cga_recalctimings(self); + if (self->cga.crtc[9] == 13) /* Character height */ + compaq_cga_recalctimings(self); else - cga_recalctimings(&self->cga); + cga_recalctimings(&self->cga); } - extern const device_config_t cga_config[]; const device_t compaq_cga_device = { - .name = "Compaq CGA", + .name = "Compaq CGA", .internal_name = "compaq_cga", - .flags = DEVICE_ISA, - .local = 0, - .init = compaq_cga_init, - .close = compaq_cga_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = compaq_cga_init, + .close = compaq_cga_close, + .reset = NULL, { .available = NULL }, .speed_changed = compaq_cga_speed_changed, - .force_redraw = NULL, - .config = cga_config + .force_redraw = NULL, + .config = cga_config }; const device_t compaq_cga_2_device = { - .name = "Compaq CGA 2", + .name = "Compaq CGA 2", .internal_name = "compaq_cga_2", - .flags = DEVICE_ISA, - .local = 1, - .init = compaq_cga_init, - .close = compaq_cga_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 1, + .init = compaq_cga_init, + .close = compaq_cga_close, + .reset = NULL, { .available = NULL }, .speed_changed = compaq_cga_speed_changed, - .force_redraw = NULL, - .config = cga_config + .force_redraw = NULL, + .config = cga_config }; diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 6fc8276e4..b263448fc 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -24,30 +24,30 @@ #include <86box/86box.h> #include <86box/i2c.h> - -#define PIXEL_MM(px) ((uint16_t) (((px) * 25.4) / 96)) -#define STANDARD_TIMING(slot, width, aspect_ratio, refresh) do { \ - edid->slot.horiz_pixels = ((width) >> 3) - 31; \ - edid->slot.aspect_ratio_refresh_rate = ((aspect_ratio) << 6) | ((refresh) - 60); \ - } while (0) -#define DETAILED_TIMING(slot, clk, width, height, hblank, vblank, hfp, hsp, vfp, vsp) do { \ - edid->slot.pixel_clock_lsb = ((clk) / 10) & 0xff; \ - edid->slot.pixel_clock_msb = ((clk) / 10) >> 8; \ - edid->slot.h_active_lsb = (width) & 0xff; \ - edid->slot.h_blank_lsb = (hblank) & 0xff; \ - edid->slot.h_active_blank_msb = (((width) >> 4) & 0xf0) | (((hblank) >> 8) & 0x0f); \ - edid->slot.v_active_lsb = (height) & 0xff; \ - edid->slot.v_blank_lsb = (vblank) & 0xff; \ - edid->slot.v_active_blank_msb = (((height) >> 4) & 0xf0) | (((vblank) >> 8) & 0x0f); \ - edid->slot.h_front_porch_lsb = (hfp) & 0xff; \ - edid->slot.h_sync_pulse_lsb = (hsp) & 0xff; \ - edid->slot.v_front_porch_sync_pulse_lsb = (((vfp) & 0x0f) << 4) | ((vsp) & 0x0f); \ - edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0xc0) | (((hsp) >> 4) & 0x30) | (((vfp) >> 2) & 0x0c) | (((vsp) >> 4) & 0x03); \ - edid->slot.h_size_lsb = horiz_mm & 0xff; \ - edid->slot.v_size_lsb = vert_mm & 0xff; \ - edid->slot.hv_size_msb = ((horiz_mm >> 4) & 0xf0) | ((vert_mm >> 8) & 0x0f); \ - } while (0) - +#define PIXEL_MM(px) ((uint16_t) (((px) *25.4) / 96)) +#define STANDARD_TIMING(slot, width, aspect_ratio, refresh) \ + do { \ + edid->slot.horiz_pixels = ((width) >> 3) - 31; \ + edid->slot.aspect_ratio_refresh_rate = ((aspect_ratio) << 6) | ((refresh) -60); \ + } while (0) +#define DETAILED_TIMING(slot, clk, width, height, hblank, vblank, hfp, hsp, vfp, vsp) \ + do { \ + edid->slot.pixel_clock_lsb = ((clk) / 10) & 0xff; \ + edid->slot.pixel_clock_msb = ((clk) / 10) >> 8; \ + edid->slot.h_active_lsb = (width) &0xff; \ + edid->slot.h_blank_lsb = (hblank) &0xff; \ + edid->slot.h_active_blank_msb = (((width) >> 4) & 0xf0) | (((hblank) >> 8) & 0x0f); \ + edid->slot.v_active_lsb = (height) &0xff; \ + edid->slot.v_blank_lsb = (vblank) &0xff; \ + edid->slot.v_active_blank_msb = (((height) >> 4) & 0xf0) | (((vblank) >> 8) & 0x0f); \ + edid->slot.h_front_porch_lsb = (hfp) &0xff; \ + edid->slot.h_sync_pulse_lsb = (hsp) &0xff; \ + edid->slot.v_front_porch_sync_pulse_lsb = (((vfp) &0x0f) << 4) | ((vsp) &0x0f); \ + edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0xc0) | (((hsp) >> 4) & 0x30) | (((vfp) >> 2) & 0x0c) | (((vsp) >> 4) & 0x03); \ + edid->slot.h_size_lsb = horiz_mm & 0xff; \ + edid->slot.v_size_lsb = vert_mm & 0xff; \ + edid->slot.hv_size_msb = ((horiz_mm >> 4) & 0xf0) | ((vert_mm >> 8) & 0x0f); \ + } while (0) enum { STD_ASPECT_16_10 = 0x0, @@ -57,76 +57,75 @@ enum { }; typedef struct { - uint8_t horiz_pixels, aspect_ratio_refresh_rate; + uint8_t horiz_pixels, aspect_ratio_refresh_rate; } edid_standard_timing_t; typedef struct { - uint8_t pixel_clock_lsb, pixel_clock_msb, h_active_lsb, h_blank_lsb, - h_active_blank_msb, v_active_lsb, v_blank_lsb, v_active_blank_msb, - h_front_porch_lsb, h_sync_pulse_lsb, v_front_porch_sync_pulse_lsb, - hv_front_porch_sync_pulse_msb, h_size_lsb, v_size_lsb, hv_size_msb, - h_border, v_border, features; + uint8_t pixel_clock_lsb, pixel_clock_msb, h_active_lsb, h_blank_lsb, + h_active_blank_msb, v_active_lsb, v_blank_lsb, v_active_blank_msb, + h_front_porch_lsb, h_sync_pulse_lsb, v_front_porch_sync_pulse_lsb, + hv_front_porch_sync_pulse_msb, h_size_lsb, v_size_lsb, hv_size_msb, + h_border, v_border, features; } edid_detailed_timing_t; typedef struct { - uint8_t magic[2], reserved, tag, range_limit_offsets; + uint8_t magic[2], reserved, tag, range_limit_offsets; union { - char ascii[13]; - struct { - uint8_t min_v_field, max_v_field, min_h_line, max_h_line, max_pixel_clock, - timing_type; - union { - uint8_t padding[7]; - struct { - uint8_t reserved, gtf_start_freq, gtf_c, gtf_m_lsb, gtf_m_msb, - gtf_k, gtf_j; - }; - struct { - uint8_t cvt_version, add_clock_precision, max_active_pixels, - aspect_ratios, aspect_ratio_pref, scaling_support, - refresh_pref; - }; - }; - } range_limits; - struct { - edid_standard_timing_t timings[6]; - uint8_t padding; - } ext_standard_timings; - struct { - uint8_t version; - struct { - uint8_t lines_lsb, lines_msb_aspect_ratio, refresh_rate; - } timings[4]; - } cvt_timings; - struct { - uint8_t version, timings[6], reserved[6]; - } established_timings3; + char ascii[13]; + struct { + uint8_t min_v_field, max_v_field, min_h_line, max_h_line, max_pixel_clock, + timing_type; + union { + uint8_t padding[7]; + struct { + uint8_t reserved, gtf_start_freq, gtf_c, gtf_m_lsb, gtf_m_msb, + gtf_k, gtf_j; + }; + struct { + uint8_t cvt_version, add_clock_precision, max_active_pixels, + aspect_ratios, aspect_ratio_pref, scaling_support, + refresh_pref; + }; + }; + } range_limits; + struct { + edid_standard_timing_t timings[6]; + uint8_t padding; + } ext_standard_timings; + struct { + uint8_t version; + struct { + uint8_t lines_lsb, lines_msb_aspect_ratio, refresh_rate; + } timings[4]; + } cvt_timings; + struct { + uint8_t version, timings[6], reserved[6]; + } established_timings3; }; } edid_descriptor_t; typedef struct { - uint8_t magic[8], mfg[2], mfg_product[2], serial[4], mfg_week, mfg_year, - edid_version, edid_rev; - uint8_t input_params, horiz_size, vert_size, gamma, features; - uint8_t red_green_lsb, blue_white_lsb, red_x_msb, red_y_msb, green_x_msb, - green_y_msb, blue_x_msb, blue_y_msb, white_x_msb, white_y_msb; - uint8_t established_timings[3]; + uint8_t magic[8], mfg[2], mfg_product[2], serial[4], mfg_week, mfg_year, + edid_version, edid_rev; + uint8_t input_params, horiz_size, vert_size, gamma, features; + uint8_t red_green_lsb, blue_white_lsb, red_x_msb, red_y_msb, green_x_msb, + green_y_msb, blue_x_msb, blue_y_msb, white_x_msb, white_y_msb; + uint8_t established_timings[3]; edid_standard_timing_t standard_timings[8]; union { - edid_detailed_timing_t detailed_timings[4]; - edid_descriptor_t descriptors[4]; + edid_detailed_timing_t detailed_timings[4]; + edid_descriptor_t descriptors[4]; }; - uint8_t extensions, checksum; + uint8_t extensions, checksum; - uint8_t ext_tag, ext_rev, ext_dtd_offset, ext_native_dtds; + uint8_t ext_tag, ext_rev, ext_dtd_offset, ext_native_dtds; union { - edid_detailed_timing_t ext_detailed_timings[6]; - edid_descriptor_t ext_descriptors[6]; + edid_detailed_timing_t ext_detailed_timings[6]; + edid_descriptor_t ext_descriptors[6]; }; - uint8_t padding[15], checksum2; + uint8_t padding[15], checksum2; } edid_t; - void * ddc_init(void *i2c) { @@ -138,60 +137,60 @@ ddc_init(void *i2c) memset(&edid->magic[1], 0xff, sizeof(edid->magic) - 2); - edid->mfg[0] = 0x09; /* manufacturer "BOX" (apparently unassigned by UEFI) */ - edid->mfg[1] = 0xf8; - edid->mfg_week = 48; - edid->mfg_year = 2020 - 1990; + edid->mfg[0] = 0x09; /* manufacturer "BOX" (apparently unassigned by UEFI) */ + edid->mfg[1] = 0xf8; + edid->mfg_week = 48; + edid->mfg_year = 2020 - 1990; edid->edid_version = 0x01; - edid->edid_rev = 0x03; /* EDID 1.3 */ + edid->edid_rev = 0x03; /* EDID 1.3 */ edid->input_params = 0x0e; /* analog input; separate sync; composite sync; sync on green */ - edid->horiz_size = horiz_mm / 10; - edid->vert_size = vert_mm / 10; - edid->features = 0xeb; /* DPMS standby/suspend/active-off; RGB color; first timing is preferred; GTF/CVT */ + edid->horiz_size = horiz_mm / 10; + edid->vert_size = vert_mm / 10; + edid->features = 0xeb; /* DPMS standby/suspend/active-off; RGB color; first timing is preferred; GTF/CVT */ - edid->red_green_lsb = 0x81; + edid->red_green_lsb = 0x81; edid->blue_white_lsb = 0xf1; - edid->red_x_msb = 0xa3; - edid->red_y_msb = 0x57; - edid->green_x_msb = 0x53; - edid->green_y_msb = 0x9f; - edid->blue_x_msb = 0x27; - edid->blue_y_msb = 0x0a; - edid->white_x_msb = 0x50; - edid->white_y_msb = 0x00; + edid->red_x_msb = 0xa3; + edid->red_y_msb = 0x57; + edid->green_x_msb = 0x53; + edid->green_y_msb = 0x9f; + edid->blue_x_msb = 0x27; + edid->blue_y_msb = 0x0a; + edid->white_x_msb = 0x50; + edid->white_y_msb = 0x00; memset(&edid->established_timings, 0xff, sizeof(edid->established_timings)); /* all enabled */ /* 60 Hz timings */ - STANDARD_TIMING(standard_timings[0], 1280, STD_ASPECT_16_9, 60); /* 1280x720 */ + STANDARD_TIMING(standard_timings[0], 1280, STD_ASPECT_16_9, 60); /* 1280x720 */ STANDARD_TIMING(standard_timings[1], 1280, STD_ASPECT_16_10, 60); /* 1280x800 */ - STANDARD_TIMING(standard_timings[2], 1366, STD_ASPECT_16_9, 60); /* 1360x768 (closest to 1366x768) */ + STANDARD_TIMING(standard_timings[2], 1366, STD_ASPECT_16_9, 60); /* 1360x768 (closest to 1366x768) */ STANDARD_TIMING(standard_timings[3], 1440, STD_ASPECT_16_10, 60); /* 1440x900 */ - STANDARD_TIMING(standard_timings[4], 1600, STD_ASPECT_16_9, 60); /* 1600x900 */ + STANDARD_TIMING(standard_timings[4], 1600, STD_ASPECT_16_9, 60); /* 1600x900 */ STANDARD_TIMING(standard_timings[5], 1680, STD_ASPECT_16_10, 60); /* 1680x1050 */ - STANDARD_TIMING(standard_timings[6], 1920, STD_ASPECT_16_9, 60); /* 1920x1080 */ - STANDARD_TIMING(standard_timings[7], 2048, STD_ASPECT_4_3, 60); /* 2048x1536 */ + STANDARD_TIMING(standard_timings[6], 1920, STD_ASPECT_16_9, 60); /* 1920x1080 */ + STANDARD_TIMING(standard_timings[7], 2048, STD_ASPECT_4_3, 60); /* 2048x1536 */ /* Detailed timing for the preferred mode of 800x600 @ 60 Hz */ DETAILED_TIMING(detailed_timings[0], 40000, 800, 600, 256, 28, 40, 128, 1, 4); - edid->descriptors[1].tag = 0xf7; /* established timings 3 */ + edid->descriptors[1].tag = 0xf7; /* established timings 3 */ edid->descriptors[1].established_timings3.version = 0x0a; memset(&edid->descriptors[1].established_timings3.timings, 0xff, sizeof(edid->descriptors[1].established_timings3.timings)); /* all enabled */ - edid->descriptors[1].established_timings3.timings[5] &= 0xf0; /* reserved bits */ + edid->descriptors[1].established_timings3.timings[5] &= 0xf0; /* reserved bits */ - edid->descriptors[2].tag = 0xfd; /* range limits */ - edid->descriptors[2].range_limits.min_v_field = 45; - edid->descriptors[2].range_limits.max_v_field = 125; - edid->descriptors[2].range_limits.min_h_line = 30; /* 640x480 = ~31.5 KHz */ - edid->descriptors[2].range_limits.max_h_line = 115; /* 1920x1440 = 112.5 KHz */ - edid->descriptors[2].range_limits.max_pixel_clock = 30; /* 1920x1440 = 297 MHz */ - edid->descriptors[2].range_limits.timing_type = 0x00; /* default GTF */ - edid->descriptors[2].range_limits.padding[0] = 0x0a; + edid->descriptors[2].tag = 0xfd; /* range limits */ + edid->descriptors[2].range_limits.min_v_field = 45; + edid->descriptors[2].range_limits.max_v_field = 125; + edid->descriptors[2].range_limits.min_h_line = 30; /* 640x480 = ~31.5 KHz */ + edid->descriptors[2].range_limits.max_h_line = 115; /* 1920x1440 = 112.5 KHz */ + edid->descriptors[2].range_limits.max_pixel_clock = 30; /* 1920x1440 = 297 MHz */ + edid->descriptors[2].range_limits.timing_type = 0x00; /* default GTF */ + edid->descriptors[2].range_limits.padding[0] = 0x0a; memset(&edid->descriptors[2].range_limits.padding[1], 0x20, sizeof(edid->descriptors[2].range_limits.padding) - 1); - edid->descriptors[3].tag = 0xfc; /* display name */ + edid->descriptors[3].tag = 0xfc; /* display name */ memcpy(&edid->descriptors[3].ascii, "86Box Monitor", 13); /* exactly 13 characters (would otherwise require LF termination and space padding) */ edid->extensions = 1; @@ -199,10 +198,10 @@ ddc_init(void *i2c) edid->checksum += edid_bytes[c]; edid->checksum = 256 - edid->checksum; - edid->ext_tag = 0x02; - edid->ext_rev = 0x03; + edid->ext_tag = 0x02; + edid->ext_rev = 0x03; edid->ext_native_dtds = 0x80; /* underscans IT; no native extended modes */ - edid->ext_dtd_offset = 0x04; + edid->ext_dtd_offset = 0x04; /* Detailed timing for 1366x768 */ DETAILED_TIMING(ext_detailed_timings[0], 85500, 1366, 768, 426, 30, 70, 143, 3, 3); @@ -210,12 +209,12 @@ ddc_init(void *i2c) /* High refresh rate timings (VGA is limited to 85 Hz) */ edid->ext_descriptors[1].tag = 0xfa; /* standard timing identifiers */ #define ext_standard_timings0 ext_descriptors[1].ext_standard_timings.timings - STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 90); /* 640x480 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[1], 640, STD_ASPECT_4_3, 120); /* 640x480 @ 120 Hz */ - STANDARD_TIMING(ext_standard_timings0[2], 800, STD_ASPECT_4_3, 90); /* 800x600 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[3], 800, STD_ASPECT_4_3, 120); /* 800x600 @ 120 Hz */ - STANDARD_TIMING(ext_standard_timings0[4], 1024, STD_ASPECT_4_3, 90); /* 1024x768 @ 90 Hz */ - STANDARD_TIMING(ext_standard_timings0[5], 1280, STD_ASPECT_5_4, 90); /* 1280x1024 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 90); /* 640x480 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[1], 640, STD_ASPECT_4_3, 120); /* 640x480 @ 120 Hz */ + STANDARD_TIMING(ext_standard_timings0[2], 800, STD_ASPECT_4_3, 90); /* 800x600 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[3], 800, STD_ASPECT_4_3, 120); /* 800x600 @ 120 Hz */ + STANDARD_TIMING(ext_standard_timings0[4], 1024, STD_ASPECT_4_3, 90); /* 1024x768 @ 90 Hz */ + STANDARD_TIMING(ext_standard_timings0[5], 1280, STD_ASPECT_5_4, 90); /* 1280x1024 @ 90 Hz */ edid->ext_descriptors[1].ext_standard_timings.padding = 0x0a; for (uint8_t c = 128; c < 255; c++) @@ -225,7 +224,6 @@ ddc_init(void *i2c) return i2c_eeprom_init(i2c, 0x50, edid_bytes, sizeof(edid_t), 0); } - void ddc_close(void *eeprom) { diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index a8f23b7b8..ba18a0ba8 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -34,17 +34,14 @@ #include <86box/vid_ati_eeprom.h> #include <86box/vid_ega.h> - void ega_doblit(int wx, int wy, ega_t *ega); - -#define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" -#define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin" -#define BIOS_SEGA_PATH "roms/video/ega/lega.vbi" -#define BIOS_ATIEGA_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" -#define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin" -#define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN" - +#define BIOS_IBM_PATH "roms/video/ega/ibm_6277356_ega_card_u44_27128.bin" +#define BIOS_CPQ_PATH "roms/video/ega/108281-001.bin" +#define BIOS_SEGA_PATH "roms/video/ega/lega.vbi" +#define BIOS_ATIEGA_PATH "roms/video/ega/ATI EGA Wonder 800+ N1.00.BIN" +#define BIOS_ISKRA_PATH "roms/video/ega/143-02.bin", "roms/video/ega/143-03.bin" +#define BIOS_TSENG_PATH "roms/video/ega/EGA ET2000.BIN" enum { EGA_IBM = 0, @@ -55,44 +52,42 @@ enum { EGA_TSENG }; +static video_timings_t timing_ega = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; +static uint8_t ega_rotate[8][256]; +static uint32_t pallook16[256], pallook64[256]; +static int ega_type = 0, old_overscan_color = 0; -static video_timings_t timing_ega = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; -static uint8_t ega_rotate[8][256]; -static uint32_t pallook16[256], pallook64[256]; -static int ega_type = 0, old_overscan_color = 0; - -extern uint8_t edatlookup[4][4]; +extern uint8_t edatlookup[4][4]; /* 3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour): 7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines). */ -int egaswitchread, egaswitches=9; -int update_overscan = 0; - - -uint8_t ega_in(uint16_t addr, void *p); +int egaswitchread, egaswitches = 9; +int update_overscan = 0; +uint8_t ega_in(uint16_t addr, void *p); void ega_out(uint16_t addr, uint8_t val, void *p) { - ega_t *ega = (ega_t *)p; - int c; + ega_t *ega = (ega_t *) p; + int c; uint8_t o, old; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x1ce: - ega->index = val; - break; - case 0x1cf: - ega->regs[ega->index] = val; - switch (ega->index) { - case 0xb0: - ega_recalctimings(ega); - break; - case 0xb2: case 0xbe: + case 0x1ce: + ega->index = val; + break; + case 0x1cf: + ega->regs[ega->index] = val; + switch (ega->index) { + case 0xb0: + ega_recalctimings(ega); + break; + case 0xb2: + case 0xbe: #if 0 if (ega->regs[0xbe] & 8) { /*Read/write bank mode*/ svga->read_bank = ((ega->regs[0xb2] >> 5) & 7) * 0x10000; @@ -100,232 +95,236 @@ ega_out(uint16_t addr, uint8_t val, void *p) } else /*Single bank mode*/ svga->read_bank = svga->write_bank = ((ega->regs[0xb2] >> 1) & 7) * 0x10000; #endif - break; - case 0xb3: - ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); - break; - } - break; + break; + case 0xb3: + ati_eeprom_write((ati_eeprom_t *) ega->eeprom, val & 8, val & 2, val & 1); + break; + } + break; - case 0x3c0: case 0x3c1: - if (!ega->attrff) { - ega->attraddr = val & 31; - if ((val & 0x20) != ega->attr_palette_enable) { - ega->fullchange = 3; - ega->attr_palette_enable = val & 0x20; - ega_recalctimings(ega); - } - } else { - o = ega->attrregs[ega->attraddr & 31]; - ega->attrregs[ega->attraddr & 31] = val; - if (ega->attraddr < 16) - ega->fullchange = changeframecount; - if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); - else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); - } - ega->fullchange = changeframecount; - } - /* Recalculate timings on change of attribute register 0x11 - (overscan border color) too. */ - if (ega->attraddr == 0x10) { - if (o != val) - ega_recalctimings(ega); - } else if (ega->attraddr == 0x11) { - ega->overscan_color = ega->vres ? pallook16[val & 0x0f] : pallook64[val & 0x3f]; - if (o != val) - ega_recalctimings(ega); - } else if (ega->attraddr == 0x12) - ega->plane_mask = val & 0xf; - } - ega->attrff ^= 1; - break; - case 0x3c2: - o = ega->miscout; - egaswitchread = (val & 0xc) >> 2; - ega->vres = !(val & 0x80); - ega->pallook = ega->vres ? pallook16 : pallook64; - ega->vidclock = val & 4; - ega->miscout = val; - ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f]; - io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if (!(val & 1)) - io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - if ((o ^ val) & 0x80) - ega_recalctimings(ega); - break; - case 0x3c4: - ega->seqaddr = val; - break; - case 0x3c5: - o = ega->seqregs[ega->seqaddr & 0xf]; - ega->seqregs[ega->seqaddr & 0xf] = val; - if (o != val && (ega->seqaddr & 0xf) == 1) - ega_recalctimings(ega); - switch (ega->seqaddr & 0xf) { - case 1: - if (ega->scrblank && !(val & 0x20)) - ega->fullchange = 3; - ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); - break; - case 2: - ega->writemask = val & 0xf; - break; - case 3: - ega->charsetb = (((val >> 2) & 3) * 0x10000) + 2; - ega->charseta = ((val & 3) * 0x10000) + 2; - break; - case 4: - ega->chain2_write = !(val & 4); - break; - } - break; - case 0x3ce: - ega->gdcaddr = val; - break; - case 0x3cf: - ega->gdcreg[ega->gdcaddr & 15] = val; - switch (ega->gdcaddr & 15) { - case 2: - ega->colourcompare = val; - break; - case 4: - ega->readplane = val & 3; - break; - case 5: - ega->writemode = val & 3; - ega->readmode = val & 8; - ega->chain2_read = val & 0x10; - break; - case 6: - switch (val & 0xc) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x20000); - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x10000); - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&ega->mapping, 0xb0000, 0x08000); - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&ega->mapping, 0xb8000, 0x08000); - break; - } - break; - case 7: - ega->colournocare = val; - break; - } - break; - case 0x3d0: case 0x3d4: - ega->crtcreg = val & 31; - return; - case 0x3d1: case 0x3d5: - if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) - return; - if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) - val = (ega->crtc[7] & ~0x10) | (val & 0x10); - old = ega->crtc[ega->crtcreg]; - ega->crtc[ega->crtcreg] = val; - if (old != val) { - if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) { - if ((ega->crtcreg == 0xc) || (ega->crtcreg == 0xd)) { - ega->fullchange = 3; - ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + ((ega->crtc[8] & 0x60) >> 5); - } else { + case 0x3c0: + case 0x3c1: + if (!ega->attrff) { + ega->attraddr = val & 31; + if ((val & 0x20) != ega->attr_palette_enable) { + ega->fullchange = 3; + ega->attr_palette_enable = val & 0x20; + ega_recalctimings(ega); + } + } else { + o = ega->attrregs[ega->attraddr & 31]; + ega->attrregs[ega->attraddr & 31] = val; + if (ega->attraddr < 16) ega->fullchange = changeframecount; - ega_recalctimings(ega); - } - } - } - break; + if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) { + for (c = 0; c < 16; c++) { + if (ega->attrregs[0x10] & 0x80) + ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); + else + ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); + } + ega->fullchange = changeframecount; + } + /* Recalculate timings on change of attribute register 0x11 + (overscan border color) too. */ + if (ega->attraddr == 0x10) { + if (o != val) + ega_recalctimings(ega); + } else if (ega->attraddr == 0x11) { + ega->overscan_color = ega->vres ? pallook16[val & 0x0f] : pallook64[val & 0x3f]; + if (o != val) + ega_recalctimings(ega); + } else if (ega->attraddr == 0x12) + ega->plane_mask = val & 0xf; + } + ega->attrff ^= 1; + break; + case 0x3c2: + o = ega->miscout; + egaswitchread = (val & 0xc) >> 2; + ega->vres = !(val & 0x80); + ega->pallook = ega->vres ? pallook16 : pallook64; + ega->vidclock = val & 4; + ega->miscout = val; + ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f]; + io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + if (!(val & 1)) + io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + if ((o ^ val) & 0x80) + ega_recalctimings(ega); + break; + case 0x3c4: + ega->seqaddr = val; + break; + case 0x3c5: + o = ega->seqregs[ega->seqaddr & 0xf]; + ega->seqregs[ega->seqaddr & 0xf] = val; + if (o != val && (ega->seqaddr & 0xf) == 1) + ega_recalctimings(ega); + switch (ega->seqaddr & 0xf) { + case 1: + if (ega->scrblank && !(val & 0x20)) + ega->fullchange = 3; + ega->scrblank = (ega->scrblank & ~0x20) | (val & 0x20); + break; + case 2: + ega->writemask = val & 0xf; + break; + case 3: + ega->charsetb = (((val >> 2) & 3) * 0x10000) + 2; + ega->charseta = ((val & 3) * 0x10000) + 2; + break; + case 4: + ega->chain2_write = !(val & 4); + break; + } + break; + case 0x3ce: + ega->gdcaddr = val; + break; + case 0x3cf: + ega->gdcreg[ega->gdcaddr & 15] = val; + switch (ega->gdcaddr & 15) { + case 2: + ega->colourcompare = val; + break; + case 4: + ega->readplane = val & 3; + break; + case 5: + ega->writemode = val & 3; + ega->readmode = val & 8; + ega->chain2_read = val & 0x10; + break; + case 6: + switch (val & 0xc) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x20000); + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&ega->mapping, 0xa0000, 0x10000); + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&ega->mapping, 0xb0000, 0x08000); + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&ega->mapping, 0xb8000, 0x08000); + break; + } + break; + case 7: + ega->colournocare = val; + break; + } + break; + case 0x3d0: + case 0x3d4: + ega->crtcreg = val & 31; + return; + case 0x3d1: + case 0x3d5: + if ((ega->crtcreg < 7) && (ega->crtc[0x11] & 0x80)) + return; + if ((ega->crtcreg == 7) && (ega->crtc[0x11] & 0x80)) + val = (ega->crtc[7] & ~0x10) | (val & 0x10); + old = ega->crtc[ega->crtcreg]; + ega->crtc[ega->crtcreg] = val; + if (old != val) { + if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) { + if ((ega->crtcreg == 0xc) || (ega->crtcreg == 0xd)) { + ega->fullchange = 3; + ega->ma_latch = ((ega->crtc[0xc] << 8) | ega->crtc[0xd]) + ((ega->crtc[8] & 0x60) >> 5); + } else { + ega->fullchange = changeframecount; + ega_recalctimings(ega); + } + } + } + break; } } - uint8_t ega_in(uint16_t addr, void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *) p; uint8_t ret = 0xff; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x1ce: - ret = ega->index; - break; - case 0x1cf: - switch (ega->index) { - case 0xb7: - ret = ega->regs[ega->index] & ~8; - if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) - ret |= 8; - break; - default: - ret = ega->regs[ega->index]; - break; - } - break; + case 0x1ce: + ret = ega->index; + break; + case 0x1cf: + switch (ega->index) { + case 0xb7: + ret = ega->regs[ega->index] & ~8; + if (ati_eeprom_read((ati_eeprom_t *) ega->eeprom)) + ret |= 8; + break; + default: + ret = ega->regs[ega->index]; + break; + } + break; - case 0x3c0: - if (ega_type) - ret = ega->attraddr | ega->attr_palette_enable; - break; - case 0x3c1: - if (ega_type) - ret = ega->attrregs[ega->attraddr]; - break; - case 0x3c2: - ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; - break; - case 0x3c4: - if (ega_type) - ret = ega->seqaddr; - break; - case 0x3c5: - if (ega_type) - ret = ega->seqregs[ega->seqaddr & 0xf]; - break; - case 0x3c8: - if (ega_type) - ret = 2; - break; - case 0x3cc: - if (ega_type) - ret = ega->miscout; - break; - case 0x3ce: - if (ega_type) - ret = ega->gdcaddr; - break; - case 0x3cf: - if (ega_type) - ret = ega->gdcreg[ega->gdcaddr & 0xf]; - break; - case 0x3d0: case 0x3d4: - if (ega_type) - ret = ega->crtcreg; - break; - case 0x3d1: - case 0x3d5: - if (ega_type) - ret = ega->crtc[ega->crtcreg]; - break; - case 0x3da: - ega->attrff = 0; - ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ - ret = ega->stat; - break; + case 0x3c0: + if (ega_type) + ret = ega->attraddr | ega->attr_palette_enable; + break; + case 0x3c1: + if (ega_type) + ret = ega->attrregs[ega->attraddr]; + break; + case 0x3c2: + ret = (egaswitches & (8 >> egaswitchread)) ? 0x10 : 0x00; + break; + case 0x3c4: + if (ega_type) + ret = ega->seqaddr; + break; + case 0x3c5: + if (ega_type) + ret = ega->seqregs[ega->seqaddr & 0xf]; + break; + case 0x3c8: + if (ega_type) + ret = 2; + break; + case 0x3cc: + if (ega_type) + ret = ega->miscout; + break; + case 0x3ce: + if (ega_type) + ret = ega->gdcaddr; + break; + case 0x3cf: + if (ega_type) + ret = ega->gdcreg[ega->gdcaddr & 0xf]; + break; + case 0x3d0: + case 0x3d4: + if (ega_type) + ret = ega->crtcreg; + break; + case 0x3d1: + case 0x3d5: + if (ega_type) + ret = ega->crtc[ega->crtcreg]; + break; + case 0x3da: + ega->attrff = 0; + ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ + ret = ega->stat; + break; } return ret; } - void ega_recalctimings(ega_t *ega) { @@ -334,25 +333,33 @@ ega_recalctimings(ega_t *ega) double _dispontime, _dispofftime, disptime; double crtcconst; - ega->vtotal = ega->crtc[6]; - ega->dispend = ega->crtc[0x12]; + ega->vtotal = ega->crtc[6]; + ega->dispend = ega->crtc[0x12]; ega->vsyncstart = ega->crtc[0x10]; - ega->split = ega->crtc[0x18]; + ega->split = ega->crtc[0x18]; - if (ega->crtc[7] & 1) ega->vtotal |= 0x100; - if (ega->crtc[7] & 32) ega->vtotal |= 0x200; + if (ega->crtc[7] & 1) + ega->vtotal |= 0x100; + if (ega->crtc[7] & 32) + ega->vtotal |= 0x200; ega->vtotal += 2; - if (ega->crtc[7] & 2) ega->dispend |= 0x100; - if (ega->crtc[7] & 64) ega->dispend |= 0x200; + if (ega->crtc[7] & 2) + ega->dispend |= 0x100; + if (ega->crtc[7] & 64) + ega->dispend |= 0x200; ega->dispend++; - if (ega->crtc[7] & 4) ega->vsyncstart |= 0x100; - if (ega->crtc[7] & 128) ega->vsyncstart |= 0x200; + if (ega->crtc[7] & 4) + ega->vsyncstart |= 0x100; + if (ega->crtc[7] & 128) + ega->vsyncstart |= 0x200; ega->vsyncstart++; - if (ega->crtc[7] & 0x10) ega->split |= 0x100; - if (ega->crtc[9] & 0x40) ega->split |= 0x200; + if (ega->crtc[7] & 0x10) + ega->split |= 0x100; + if (ega->crtc[9] & 0x40) + ega->split |= 0x200; ega->split++; ega->hdisp = ega->crtc[1]; @@ -360,37 +367,39 @@ ega_recalctimings(ega_t *ega) ega->rowoffset = ega->crtc[0x13]; - ega->linedbl = ega->crtc[9] & 0x80; + ega->linedbl = ega->crtc[9] & 0x80; ega->rowcount = ega->crtc[9] & 0x1f; if (ega->eeprom) { - clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); + clksel = ((ega->miscout & 0xc) >> 2) | ((ega->regs[0xbe] & 0x10) ? 4 : 0); - switch (clksel) { - case 0: - crtcconst = (cpuclock / 25175000.0 * (double)(1ull << 32)); - break; - case 1: - crtcconst = (cpuclock / 28322000.0 * (double)(1ull << 32)); - break; - case 4: - crtcconst = (cpuclock / 14318181.0 * (double)(1ull << 32)); - break; - case 5: - crtcconst = (cpuclock / 16257000.0 * (double)(1ull << 32)); - break; - case 7: - default: - crtcconst = (cpuclock / 36000000.0 * (double)(1ull << 32)); - break; - } - if (!(ega->seqregs[1] & 1)) - crtcconst *= 9.0; - else - crtcconst *= 8.0; + switch (clksel) { + case 0: + crtcconst = (cpuclock / 25175000.0 * (double) (1ull << 32)); + break; + case 1: + crtcconst = (cpuclock / 28322000.0 * (double) (1ull << 32)); + break; + case 4: + crtcconst = (cpuclock / 14318181.0 * (double) (1ull << 32)); + break; + case 5: + crtcconst = (cpuclock / 16257000.0 * (double) (1ull << 32)); + break; + case 7: + default: + crtcconst = (cpuclock / 36000000.0 * (double) (1ull << 32)); + break; + } + if (!(ega->seqregs[1] & 1)) + crtcconst *= 9.0; + else + crtcconst *= 8.0; } else { - if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); - else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); + if (ega->vidclock) + crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); + else + crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); } ega->interlace = 0; @@ -399,610 +408,668 @@ ega_recalctimings(ega_t *ega) ega->render = ega_render_blank; if (!ega->scrblank && ega->attr_palette_enable) { - if (!(ega->gdcreg[6] & 1)) { - if (ega->seqregs[1] & 8) { - ega->render = ega_render_text_40; - ega->hdisp *= (ega->seqregs[1] & 1) ? 16 : 18; - } else { - ega->render = ega_render_text_80; - ega->hdisp *= (ega->seqregs[1] & 1) ? 8 : 9; - } - ega->hdisp_old = ega->hdisp; - } else { - ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8; - ega->hdisp_old = ega->hdisp; + if (!(ega->gdcreg[6] & 1)) { + if (ega->seqregs[1] & 8) { + ega->render = ega_render_text_40; + ega->hdisp *= (ega->seqregs[1] & 1) ? 16 : 18; + } else { + ega->render = ega_render_text_80; + ega->hdisp *= (ega->seqregs[1] & 1) ? 8 : 9; + } + ega->hdisp_old = ega->hdisp; + } else { + ega->hdisp *= (ega->seqregs[1] & 8) ? 16 : 8; + ega->hdisp_old = ega->hdisp; - switch (ega->gdcreg[5] & 0x20) { - case 0x00: - if (ega->seqregs[1] & 8) - ega->render = ega_render_4bpp_lowres; - else - ega->render = ega_render_4bpp_highres; - break; - case 0x20: - if (ega->seqregs[1] & 8) - ega->render = ega_render_2bpp_lowres; - else - ega->render = ega_render_2bpp_highres; - break; - } - } + switch (ega->gdcreg[5] & 0x20) { + case 0x00: + if (ega->seqregs[1] & 8) + ega->render = ega_render_4bpp_lowres; + else + ega->render = ega_render_4bpp_highres; + break; + case 0x20: + if (ega->seqregs[1] & 8) + ega->render = ega_render_2bpp_lowres; + else + ega->render = ega_render_2bpp_highres; + break; + } + } } if (enable_overscan) { - overscan_y = (ega->rowcount + 1) << 1; + overscan_y = (ega->rowcount + 1) << 1; - if (overscan_y < 16) - overscan_y = 16; + if (overscan_y < 16) + overscan_y = 16; } overscan_x = (ega->seqregs[1] & 1) ? 16 : 18; if (ega->seqregs[1] & 8) - overscan_x <<= 1; + overscan_x <<= 1; ega->y_add = (overscan_y >> 1) - (ega->crtc[8] & 0x1f); ega->x_add = (overscan_x >> 1); if (ega->seqregs[1] & 8) { - disptime = (double) ((ega->crtc[0] + 2) << 1); - _dispontime = (double) ((ega->crtc[1] + 1) << 1); + disptime = (double) ((ega->crtc[0] + 2) << 1); + _dispontime = (double) ((ega->crtc[1] + 1) << 1); } else { - disptime = (double) (ega->crtc[0] + 2); - _dispontime = (double) (ega->crtc[1] + 1); + disptime = (double) (ega->crtc[0] + 2); + _dispontime = (double) (ega->crtc[1] + 1); } _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; _dispofftime *= crtcconst; - ega->dispontime = (uint64_t)(_dispontime); - ega->dispofftime = (uint64_t)(_dispofftime); + ega->dispontime = (uint64_t) (_dispontime); + ega->dispofftime = (uint64_t) (_dispofftime); if (ega->dispontime < TIMER_USEC) - ega->dispontime = TIMER_USEC; + ega->dispontime = TIMER_USEC; if (ega->dispofftime < TIMER_USEC) - ega->dispofftime = TIMER_USEC; + ega->dispofftime = TIMER_USEC; ega_recalc_remap_func(ega); } - void ega_poll(void *p) { - ega_t *ega = (ega_t *)p; - int x, old_ma; - int wx = 640, wy = 350; + ega_t *ega = (ega_t *) p; + int x, old_ma; + int wx = 640, wy = 350; uint32_t blink_delay; if (!ega->linepos) { - timer_advance_u64(&ega->timer, ega->dispofftime); - ega->stat |= 1; - ega->linepos = 1; + timer_advance_u64(&ega->timer, ega->dispofftime); + ega->stat |= 1; + ega->linepos = 1; - if (ega->dispon) { - ega->hdisp_on = 1; + if (ega->dispon) { + ega->hdisp_on = 1; - ega->ma &= ega->vrammask; - if (ega->firstline == 2000) { - ega->firstline = ega->displine; - video_wait_for_buffer(); - } + ega->ma &= ega->vrammask; + if (ega->firstline == 2000) { + ega->firstline = ega->displine; + video_wait_for_buffer(); + } - if (ega->vres) { - old_ma = ega->ma; + if (ega->vres) { + old_ma = ega->ma; - ega->displine <<= 1; - ega->y_add <<= 1; + ega->displine <<= 1; + ega->y_add <<= 1; - ega->render(ega); + ega->render(ega); - ega->x_add = (overscan_x >> 1); - ega_render_overscan_left(ega); - ega_render_overscan_right(ega); - ega->x_add = (overscan_x >> 1) - ega->scrollcache; + ega->x_add = (overscan_x >> 1); + ega_render_overscan_left(ega); + ega_render_overscan_right(ega); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; - ega->displine++; + ega->displine++; - ega->ma = old_ma; + ega->ma = old_ma; - ega->render(ega); + ega->render(ega); - ega->x_add = (overscan_x >> 1); - ega_render_overscan_left(ega); - ega_render_overscan_right(ega); - ega->x_add = (overscan_x >> 1) - ega->scrollcache; + ega->x_add = (overscan_x >> 1); + ega_render_overscan_left(ega); + ega_render_overscan_right(ega); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; - ega->y_add >>= 1; - ega->displine >>= 1; - } else { - ega_render_overscan_left(ega); - ega->render(ega); - ega_render_overscan_right(ega); - } + ega->y_add >>= 1; + ega->displine >>= 1; + } else { + ega_render_overscan_left(ega); + ega->render(ega); + ega_render_overscan_right(ega); + } - if (ega->lastline < ega->displine) - ega->lastline = ega->displine; - } + if (ega->lastline < ega->displine) + ega->lastline = ega->displine; + } - ega->displine++; - if (ega->interlace) - ega->displine++; - if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) - ega->stat &= ~8; - ega->vslines++; - if (ega->displine > 500) - ega->displine = 0; + ega->displine++; + if (ega->interlace) + ega->displine++; + if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines) + ega->stat &= ~8; + ega->vslines++; + if (ega->displine > 500) + ega->displine = 0; } else { - timer_advance_u64(&ega->timer, ega->dispontime); + timer_advance_u64(&ega->timer, ega->dispontime); - if (ega->dispon) - ega->stat &= ~1; - ega->hdisp_on = 0; + if (ega->dispon) + ega->stat &= ~1; + ega->hdisp_on = 0; - ega->linepos = 0; - if ((ega->sc == (ega->crtc[11] & 31)) || (ega->sc == ega->rowcount)) - ega->con = 0; - if (ega->dispon) { - if (ega->linedbl && !ega->linecountff) { - ega->linecountff = 1; - ega->ma = ega->maback; - } if (ega->sc == (ega->crtc[9] & 31)) { - ega->linecountff = 0; - ega->sc = 0; + ega->linepos = 0; + if ((ega->sc == (ega->crtc[11] & 31)) || (ega->sc == ega->rowcount)) + ega->con = 0; + if (ega->dispon) { + if (ega->linedbl && !ega->linecountff) { + ega->linecountff = 1; + ega->ma = ega->maback; + } + if (ega->sc == (ega->crtc[9] & 31)) { + ega->linecountff = 0; + ega->sc = 0; - ega->maback += (ega->rowoffset << 3); - if (ega->interlace) - ega->maback += (ega->rowoffset << 3); - ega->maback &= ega->vrammask; - ega->ma = ega->maback; - } else { - ega->linecountff = 0; - ega->sc++; - ega->sc &= 31; - ega->ma = ega->maback; - } - } - ega->vc++; - ega->vc &= 511; - if (ega->vc == ega->split) { - if (ega->interlace && ega->oddeven) - ega->ma = ega->maback = ega->ma_latch + (ega->rowoffset << 1); - else - ega->ma = ega->maback = ega->ma_latch; - ega->ma <<= 2; - ega->maback <<= 2; - ega->sc = 0; - if (ega->attrregs[0x10] & 0x20) { - ega->scrollcache = 0; - ega->x_add = (overscan_x >> 1); - } - } - if (ega->vc == ega->dispend) { - ega->dispon = 0; - blink_delay = (ega->crtc[11] & 0x60) >> 5; - if (ega->crtc[10] & 0x20) - ega->cursoron = 0; - else if (blink_delay == 2) - ega->cursoron = ((ega->blink % 96) >= 48); - else - ega->cursoron = ega->blink & (16 + (16 * blink_delay)); + ega->maback += (ega->rowoffset << 3); + if (ega->interlace) + ega->maback += (ega->rowoffset << 3); + ega->maback &= ega->vrammask; + ega->ma = ega->maback; + } else { + ega->linecountff = 0; + ega->sc++; + ega->sc &= 31; + ega->ma = ega->maback; + } + } + ega->vc++; + ega->vc &= 511; + if (ega->vc == ega->split) { + if (ega->interlace && ega->oddeven) + ega->ma = ega->maback = ega->ma_latch + (ega->rowoffset << 1); + else + ega->ma = ega->maback = ega->ma_latch; + ega->ma <<= 2; + ega->maback <<= 2; + ega->sc = 0; + if (ega->attrregs[0x10] & 0x20) { + ega->scrollcache = 0; + ega->x_add = (overscan_x >> 1); + } + } + if (ega->vc == ega->dispend) { + ega->dispon = 0; + blink_delay = (ega->crtc[11] & 0x60) >> 5; + if (ega->crtc[10] & 0x20) + ega->cursoron = 0; + else if (blink_delay == 2) + ega->cursoron = ((ega->blink % 96) >= 48); + else + ega->cursoron = ega->blink & (16 + (16 * blink_delay)); - if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) - ega->fullchange = 2; - ega->blink = (ega->blink + 1) & 0x7f; + if (!(ega->gdcreg[6] & 1) && !(ega->blink & 15)) + ega->fullchange = 2; + ega->blink = (ega->blink + 1) & 0x7f; - if (ega->fullchange) - ega->fullchange--; - } - if (ega->vc == ega->vsyncstart) { - ega->dispon = 0; - ega->stat |= 8; - x = ega->hdisp; + if (ega->fullchange) + ega->fullchange--; + } + if (ega->vc == ega->vsyncstart) { + ega->dispon = 0; + ega->stat |= 8; + x = ega->hdisp; - if (ega->interlace && !ega->oddeven) - ega->lastline++; - if (ega->interlace && ega->oddeven) - ega->firstline--; + if (ega->interlace && !ega->oddeven) + ega->lastline++; + if (ega->interlace && ega->oddeven) + ega->firstline--; - wx = x; + wx = x; - if (ega->vres) { - wy = (ega->lastline - ega->firstline) << 1; - ega_doblit(wx, wy, ega); - } else { - wy = ega->lastline - ega->firstline; - ega_doblit(wx, wy, ega); - } + if (ega->vres) { + wy = (ega->lastline - ega->firstline) << 1; + ega_doblit(wx, wy, ega); + } else { + wy = ega->lastline - ega->firstline; + ega_doblit(wx, wy, ega); + } - frames++; + frames++; - ega->firstline = 2000; - ega->lastline = 0; + ega->firstline = 2000; + ega->lastline = 0; - ega->firstline_draw = 2000; - ega->lastline_draw = 0; + ega->firstline_draw = 2000; + ega->lastline_draw = 0; - ega->oddeven ^= 1; + ega->oddeven ^= 1; - changeframecount = ega->interlace ? 3 : 2; - ega->vslines = 0; + changeframecount = ega->interlace ? 3 : 2; + ega->vslines = 0; - if (ega->interlace && ega->oddeven) - ega->ma = ega->maback = ega->ma_latch + (ega->rowoffset << 1); - else - ega->ma = ega->maback = ega->ma_latch; - ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; + if (ega->interlace && ega->oddeven) + ega->ma = ega->maback = ega->ma_latch + (ega->rowoffset << 1); + else + ega->ma = ega->maback = ega->ma_latch; + ega->ca = (ega->crtc[0xe] << 8) | ega->crtc[0xf]; - ega->ma <<= 2; - ega->maback <<= 2; - ega->ca <<= 2; - } - if (ega->vc == ega->vtotal) { - ega->vc = 0; - ega->sc = 0; - ega->dispon = 1; - ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0; + ega->ma <<= 2; + ega->maback <<= 2; + ega->ca <<= 2; + } + if (ega->vc == ega->vtotal) { + ega->vc = 0; + ega->sc = 0; + ega->dispon = 1; + ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0; - ega->scrollcache = (ega->attrregs[0x13] & 0x0f); - if (!(ega->gdcreg[6] & 1) && !(ega->attrregs[0x10] & 1)) { /*Text mode*/ - if (ega->seqregs[1] & 1) - ega->scrollcache &= 0x07; - else { - ega->scrollcache++; - if (ega->scrollcache > 8) - ega->scrollcache = 0; - } - } else - ega->scrollcache &= 0x07; + ega->scrollcache = (ega->attrregs[0x13] & 0x0f); + if (!(ega->gdcreg[6] & 1) && !(ega->attrregs[0x10] & 1)) { /*Text mode*/ + if (ega->seqregs[1] & 1) + ega->scrollcache &= 0x07; + else { + ega->scrollcache++; + if (ega->scrollcache > 8) + ega->scrollcache = 0; + } + } else + ega->scrollcache &= 0x07; - if (ega->seqregs[1] & 8) - ega->scrollcache <<= 1; + if (ega->seqregs[1] & 8) + ega->scrollcache <<= 1; - ega->x_add = (overscan_x >> 1) - ega->scrollcache; + ega->x_add = (overscan_x >> 1) - ega->scrollcache; - ega->linecountff = 0; - } - if (ega->sc == (ega->crtc[10] & 31)) - ega->con = 1; + ega->linecountff = 0; + } + if (ega->sc == (ega->crtc[10] & 31)) + ega->con = 1; } } - void ega_doblit(int wx, int wy, ega_t *ega) { - int y_add = (enable_overscan) ? overscan_y : 0; - int x_add = (enable_overscan) ? overscan_x : 0; - int y_start = (enable_overscan) ? 0 : (overscan_y >> 1); - int x_start = (enable_overscan) ? 0 : (overscan_x >> 1); - int bottom = (overscan_y >> 1) + (ega->crtc[8] & 0x1f); + int y_add = (enable_overscan) ? overscan_y : 0; + int x_add = (enable_overscan) ? overscan_x : 0; + int y_start = (enable_overscan) ? 0 : (overscan_y >> 1); + int x_start = (enable_overscan) ? 0 : (overscan_x >> 1); + int bottom = (overscan_y >> 1) + (ega->crtc[8] & 0x1f); uint32_t *p; - int i, j; - int xs_temp, ys_temp; + int i, j; + int xs_temp, ys_temp; if (ega->vres) { - y_add <<= 1; - y_start <<= 1; - bottom <<= 1; + y_add <<= 1; + y_start <<= 1; + bottom <<= 1; } if ((wx <= 0) || (wy <= 0)) - return; + return; if (ega->vres) - ega->y_add <<= 1; + ega->y_add <<= 1; xs_temp = wx; ys_temp = wy + 1; if (ega->vres) - ys_temp++; + ys_temp++; if (xs_temp < 64) - xs_temp = 640; + xs_temp = 640; if (ys_temp < 32) - ys_temp = 200; + ys_temp = 200; if ((ega->crtc[0x17] & 0x80) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - /* Screen res has changed.. fix up, and let them know. */ - xsize = xs_temp; - ysize = ys_temp; + /* Screen res has changed.. fix up, and let them know. */ + xsize = xs_temp; + ysize = ys_temp; - if ((xsize > 1984) || (ysize > 2016)) { - /* 2048x2048 is the biggest safe render texture, to account for overscan, - we suppress overscan starting from x 1984 and y 2016. */ - x_add = 0; - y_add = 0; - suppress_overscan = 1; - } else - suppress_overscan = 0; + if ((xsize > 1984) || (ysize > 2016)) { + /* 2048x2048 is the biggest safe render texture, to account for overscan, + we suppress overscan starting from x 1984 and y 2016. */ + x_add = 0; + y_add = 0; + suppress_overscan = 1; + } else + suppress_overscan = 0; - set_screen_size(xsize + x_add, ysize + y_add); + set_screen_size(xsize + x_add, ysize + y_add); - if (video_force_resize_get()) - video_force_resize_set(0); + if (video_force_resize_get()) + video_force_resize_set(0); } if ((wx >= 160) && ((wy + 1) >= 120)) { - /* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */ - for (i = 0; i < ega->y_add; i++) { - p = &buffer32->line[i & 0x7ff][0]; + /* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */ + for (i = 0; i < ega->y_add; i++) { + p = &buffer32->line[i & 0x7ff][0]; - for (j = 0; j < (xsize + x_add); j++) - p[j] = ega->overscan_color; - } + for (j = 0; j < (xsize + x_add); j++) + p[j] = ega->overscan_color; + } - for (i = 0; i < bottom; i++) { - p = &buffer32->line[(ysize + ega->y_add + i) & 0x7ff][0]; + for (i = 0; i < bottom; i++) { + p = &buffer32->line[(ysize + ega->y_add + i) & 0x7ff][0]; - for (j = 0; j < (xsize + x_add); j++) - p[j] = ega->overscan_color; - } + for (j = 0; j < (xsize + x_add); j++) + p[j] = ega->overscan_color; + } } video_blit_memtoscreen(x_start, y_start, xsize + x_add, ysize + y_add); if (ega->vres) - ega->y_add >>= 1; + ega->y_add >>= 1; } - void ega_write(uint32_t addr, uint8_t val, void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *) p; uint8_t vala, valb, valc, vald; - int writemask2 = ega->writemask; + int writemask2 = ega->writemask; cycles -= video_timing_write_b; - if (addr >= 0xB0000) addr &= 0x7fff; - else addr &= 0xffff; + if (addr >= 0xB0000) + addr &= 0x7fff; + else + addr &= 0xffff; if (ega->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; } addr <<= 2; if (addr >= ega->vram_limit) - return; + return; if (!(ega->gdcreg[6] & 1)) - ega->fullchange = 2; + ega->fullchange = 2; switch (ega->writemode) { - case 1: - if (writemask2 & 1) ega->vram[addr] = ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = ega->ld; - break; - case 0: - if (ega->gdcreg[3] & 7) - val = ega_rotate[ega->gdcreg[3] & 7][val]; + case 1: + if (writemask2 & 1) + ega->vram[addr] = ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = ega->ld; + break; + case 0: + if (ega->gdcreg[3] & 7) + val = ega_rotate[ega->gdcreg[3] & 7][val]; - if ((ega->gdcreg[8] == 0xff) && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { - if (writemask2 & 1) ega->vram[addr] = val; - if (writemask2 & 2) ega->vram[addr | 0x1] = val; - if (writemask2 & 4) ega->vram[addr | 0x2] = val; - if (writemask2 & 8) ega->vram[addr | 0x3] = val; - } else { - if (ega->gdcreg[1] & 1) vala = (ega->gdcreg[0] & 1) ? 0xff : 0; - else vala = val; - if (ega->gdcreg[1] & 2) valb = (ega->gdcreg[0] & 2) ? 0xff : 0; - else valb = val; - if (ega->gdcreg[1] & 4) valc = (ega->gdcreg[0] & 4) ? 0xff : 0; - else valc = val; - if (ega->gdcreg[1] & 8) vald = (ega->gdcreg[0] & 8) ? 0xff : 0; - else vald = val; - switch (ega->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; - break; - } - } - break; - case 2: - if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { - if (writemask2 & 1) ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - } else { - vala = ((val & 1) ? 0xff : 0); - valb = ((val & 2) ? 0xff : 0); - valc = ((val & 4) ? 0xff : 0); - vald = ((val & 8) ? 0xff : 0); - switch (ega->gdcreg[3] & 0x18) { - case 0: /*Set*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); - break; - case 8: /*AND*/ - if (writemask2 & 1) ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; - break; - case 0x10: /*OR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; - break; - case 0x18: /*XOR*/ - if (writemask2 & 1) ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; - if (writemask2 & 2) ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; - if (writemask2 & 4) ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; - if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; - break; - } - } - break; + if ((ega->gdcreg[8] == 0xff) && !(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { + if (writemask2 & 1) + ega->vram[addr] = val; + if (writemask2 & 2) + ega->vram[addr | 0x1] = val; + if (writemask2 & 4) + ega->vram[addr | 0x2] = val; + if (writemask2 & 8) + ega->vram[addr | 0x3] = val; + } else { + if (ega->gdcreg[1] & 1) + vala = (ega->gdcreg[0] & 1) ? 0xff : 0; + else + vala = val; + if (ega->gdcreg[1] & 2) + valb = (ega->gdcreg[0] & 2) ? 0xff : 0; + else + valb = val; + if (ega->gdcreg[1] & 4) + valc = (ega->gdcreg[0] & 4) ? 0xff : 0; + else + valc = val; + if (ega->gdcreg[1] & 8) + vald = (ega->gdcreg[0] & 8) ? 0xff : 0; + else + vald = val; + switch (ega->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; + break; + } + } + break; + case 2: + if (!(ega->gdcreg[3] & 0x18) && !ega->gdcreg[1]) { + if (writemask2 & 1) + ega->vram[addr] = (((val & 1) ? 0xff : 0) & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (writemask2 & 2) + ega->vram[addr | 0x1] = (((val & 2) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (writemask2 & 4) + ega->vram[addr | 0x2] = (((val & 4) ? 0xff : 0) & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (writemask2 & 8) + ega->vram[addr | 0x3] = (((val & 8) ? 0xff : 0) & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + } else { + vala = ((val & 1) ? 0xff : 0); + valb = ((val & 2) ? 0xff : 0); + valc = ((val & 4) ? 0xff : 0); + vald = ((val & 8) ? 0xff : 0); + switch (ega->gdcreg[3] & 0x18) { + case 0: /*Set*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | (ega->la & ~ega->gdcreg[8]); + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | (ega->lb & ~ega->gdcreg[8]); + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | (ega->lc & ~ega->gdcreg[8]); + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | (ega->ld & ~ega->gdcreg[8]); + break; + case 8: /*AND*/ + if (writemask2 & 1) + ega->vram[addr] = (vala | ~ega->gdcreg[8]) & ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb | ~ega->gdcreg[8]) & ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc | ~ega->gdcreg[8]) & ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald | ~ega->gdcreg[8]) & ega->ld; + break; + case 0x10: /*OR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) | ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) | ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) | ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) | ega->ld; + break; + case 0x18: /*XOR*/ + if (writemask2 & 1) + ega->vram[addr] = (vala & ega->gdcreg[8]) ^ ega->la; + if (writemask2 & 2) + ega->vram[addr | 0x1] = (valb & ega->gdcreg[8]) ^ ega->lb; + if (writemask2 & 4) + ega->vram[addr | 0x2] = (valc & ega->gdcreg[8]) ^ ega->lc; + if (writemask2 & 8) + ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; + break; + } + } + break; } } - uint8_t ega_read(uint32_t addr, void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *) p; uint8_t temp, temp2, temp3, temp4; - int readplane = ega->readplane; + int readplane = ega->readplane; cycles -= video_timing_read_b; - if (addr >= 0xb0000) addr &= 0x7fff; - else addr &= 0xffff; + if (addr >= 0xb0000) + addr &= 0x7fff; + else + addr &= 0xffff; if (ega->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - if (addr & 0x4000) - addr |= 1; - addr &= ~0x4000; + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + if (addr & 0x4000) + addr |= 1; + addr &= ~0x4000; } addr <<= 2; if (addr >= ega->vram_limit) - return 0xff; + return 0xff; ega->la = ega->vram[addr]; ega->lb = ega->vram[addr | 0x1]; ega->lc = ega->vram[addr | 0x2]; ega->ld = ega->vram[addr | 0x3]; if (ega->readmode) { - temp = ega->la; - temp ^= (ega->colourcompare & 1) ? 0xff : 0; - temp &= (ega->colournocare & 1) ? 0xff : 0; - temp2 = ega->lb; - temp2 ^= (ega->colourcompare & 2) ? 0xff : 0; - temp2 &= (ega->colournocare & 2) ? 0xff : 0; - temp3 = ega->lc; - temp3 ^= (ega->colourcompare & 4) ? 0xff : 0; - temp3 &= (ega->colournocare & 4) ? 0xff : 0; - temp4 = ega->ld; - temp4 ^= (ega->colourcompare & 8) ? 0xff : 0; - temp4 &= (ega->colournocare & 8) ? 0xff : 0; - return ~(temp | temp2 | temp3 | temp4); + temp = ega->la; + temp ^= (ega->colourcompare & 1) ? 0xff : 0; + temp &= (ega->colournocare & 1) ? 0xff : 0; + temp2 = ega->lb; + temp2 ^= (ega->colourcompare & 2) ? 0xff : 0; + temp2 &= (ega->colournocare & 2) ? 0xff : 0; + temp3 = ega->lc; + temp3 ^= (ega->colourcompare & 4) ? 0xff : 0; + temp3 &= (ega->colournocare & 4) ? 0xff : 0; + temp4 = ega->ld; + temp4 ^= (ega->colourcompare & 8) ? 0xff : 0; + temp4 &= (ega->colournocare & 8) ? 0xff : 0; + return ~(temp | temp2 | temp3 | temp4); } return ega->vram[addr | readplane]; } - void ega_init(ega_t *ega, int monitor_type, int is_mono) { int c, d, e; - ega->vram = malloc(0x40000); + ega->vram = malloc(0x40000); ega->vrammask = 0x3ffff; for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { - ega_rotate[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } + e = c; + for (d = 0; d < 8; d++) { + ega_rotate[d][c] = e; + e = (e >> 1) | ((e & 1) ? 0x80 : 0); + } } for (c = 0; c < 4; c++) { - for (d = 0; d < 4; d++) { - edatlookup[c][d] = 0; - if (c & 1) edatlookup[c][d] |= 1; - if (d & 1) edatlookup[c][d] |= 2; - if (c & 2) edatlookup[c][d] |= 0x10; - if (d & 2) edatlookup[c][d] |= 0x20; - } + for (d = 0; d < 4; d++) { + edatlookup[c][d] = 0; + if (c & 1) + edatlookup[c][d] |= 1; + if (d & 1) + edatlookup[c][d] |= 2; + if (c & 2) + edatlookup[c][d] |= 0x10; + if (d & 2) + edatlookup[c][d] |= 0x20; + } } if (is_mono) { - for (c = 0; c < 256; c++) { - if (((c >> 3) & 3) == 0) - pallook64[c] = pallook16[c] = makecol32(0, 0, 0); - else switch (monitor_type >> 4) { - case DISPLAY_GREEN: - switch ((c >> 3) & 3) { - case 1: - pallook64[c] = pallook16[c] = makecol32(0x08, 0xc7, 0x2c); - break; - case 2: - pallook64[c] = pallook16[c] = makecol32(0x04, 0x8a, 0x20); - break; - case 3: - pallook64[c] = pallook16[c] = makecol32(0x34, 0xff, 0x5d); - break; - } - break; - case DISPLAY_AMBER: - switch ((c >> 3) & 3) { - case 1: - pallook64[c] = pallook16[c] = makecol32(0xef, 0x79, 0x00); - break; - case 2: - pallook64[c] = pallook16[c] = makecol32(0xb2, 0x4d, 0x00); - break; - case 3: - pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); - break; - } - break; - case DISPLAY_WHITE: default: - switch ((c >> 3) & 3) { - case 1: - pallook64[c] = pallook16[c] = makecol32(0xaf, 0xb3, 0xb0); - break; - case 2: - pallook64[c] = pallook16[c] = makecol32(0x7a, 0x81, 0x83); - break; - case 3: - pallook64[c] = pallook16[c] = makecol32(0xff, 0xfd, 0xed); - break; - } - break; - } - } + for (c = 0; c < 256; c++) { + if (((c >> 3) & 3) == 0) + pallook64[c] = pallook16[c] = makecol32(0, 0, 0); + else + switch (monitor_type >> 4) { + case DISPLAY_GREEN: + switch ((c >> 3) & 3) { + case 1: + pallook64[c] = pallook16[c] = makecol32(0x08, 0xc7, 0x2c); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0x04, 0x8a, 0x20); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0x34, 0xff, 0x5d); + break; + } + break; + case DISPLAY_AMBER: + switch ((c >> 3) & 3) { + case 1: + pallook64[c] = pallook16[c] = makecol32(0xef, 0x79, 0x00); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0xb2, 0x4d, 0x00); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0xff, 0xe3, 0x34); + break; + } + break; + case DISPLAY_WHITE: + default: + switch ((c >> 3) & 3) { + case 1: + pallook64[c] = pallook16[c] = makecol32(0xaf, 0xb3, 0xb0); + break; + case 2: + pallook64[c] = pallook16[c] = makecol32(0x7a, 0x81, 0x83); + break; + case 3: + pallook64[c] = pallook16[c] = makecol32(0xff, 0xfd, 0xed); + break; + } + break; + } + } - io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); } else { - for (c = 0; c < 256; c++) { - pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); - pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); - pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); - if ((c & 0x17) == 6) - pallook16[c] = makecol32(0xaa, 0x55, 0); - } + for (c = 0; c < 256; c++) { + pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55); + pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa); + pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55); + if ((c & 0x17) == 6) + pallook16[c] = makecol32(0xaa, 0x55, 0); + } - ega->miscout |= 1; + ega->miscout |= 1; } ega->pallook = pallook16; @@ -1010,7 +1077,7 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) egaswitches = monitor_type & 0xf; ega->vram_limit = 256 * 1024; - ega->vrammask = ega->vram_limit - 1; + ega->vrammask = ega->vram_limit - 1; old_overscan_color = 0; @@ -1028,12 +1095,11 @@ ega_init(ega_t *ega, int monitor_type, int is_mono) timer_add(&ega->timer, ega_poll, ega, 1); } - static void * ega_standalone_init(const device_t *info) { ega_t *ega = malloc(sizeof(ega_t)); - int monitor_type, c; + int monitor_type, c; memset(ega, 0, sizeof(ega_t)); @@ -1044,131 +1110,121 @@ ega_standalone_init(const device_t *info) ega->x_add = 8; ega->y_add = 14; - if ((info->local == EGA_IBM) || (info->local == EGA_ISKRA) || - (info->local == EGA_TSENG)) - ega_type = 0; + if ((info->local == EGA_IBM) || (info->local == EGA_ISKRA) || (info->local == EGA_TSENG)) + ega_type = 0; else - ega_type = 1; + ega_type = 1; - switch(info->local) { - case EGA_IBM: - default: - rom_init(&ega->bios_rom, BIOS_IBM_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case EGA_COMPAQ: - rom_init(&ega->bios_rom, BIOS_CPQ_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case EGA_SUPEREGA: - rom_init(&ega->bios_rom, BIOS_SEGA_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case EGA_ATI: - rom_init(&ega->bios_rom, BIOS_ATIEGA_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case EGA_ISKRA: - rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case EGA_TSENG: - rom_init(&ega->bios_rom, BIOS_TSENG_PATH, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; + switch (info->local) { + case EGA_IBM: + default: + rom_init(&ega->bios_rom, BIOS_IBM_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case EGA_COMPAQ: + rom_init(&ega->bios_rom, BIOS_CPQ_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case EGA_SUPEREGA: + rom_init(&ega->bios_rom, BIOS_SEGA_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case EGA_ATI: + rom_init(&ega->bios_rom, BIOS_ATIEGA_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case EGA_ISKRA: + rom_init_interleaved(&ega->bios_rom, BIOS_ISKRA_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case EGA_TSENG: + rom_init(&ega->bios_rom, BIOS_TSENG_PATH, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; } if ((ega->bios_rom.rom[0x3ffe] == 0xaa) && (ega->bios_rom.rom[0x3fff] == 0x55)) { - for (c = 0; c < 0x2000; c++) { - uint8_t temp = ega->bios_rom.rom[c]; - ega->bios_rom.rom[c] = ega->bios_rom.rom[0x3fff - c]; - ega->bios_rom.rom[0x3fff - c] = temp; - } + for (c = 0; c < 0x2000; c++) { + uint8_t temp = ega->bios_rom.rom[c]; + ega->bios_rom.rom[c] = ega->bios_rom.rom[0x3fff - c]; + ega->bios_rom.rom[0x3fff - c] = temp; + } } monitor_type = device_get_config_int("monitor_type"); ega_init(ega, monitor_type, (monitor_type & 0x0F) == 0x0B); ega->vram_limit = device_get_config_int("memory") * 1024; - ega->vrammask = ega->vram_limit - 1; + ega->vrammask = ega->vram_limit - 1; mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); if (info->local == EGA_ATI) { - io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - ega->eeprom = malloc(sizeof(ati_eeprom_t)); - memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); - ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0); + io_sethandler(0x01ce, 0x0002, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); + ega->eeprom = malloc(sizeof(ati_eeprom_t)); + memset(ega->eeprom, 0, sizeof(ati_eeprom_t)); + ati_eeprom_load((ati_eeprom_t *) ega->eeprom, "egawonder800.nvr", 0); } return ega; } - static int ega_standalone_available(void) { return rom_present(BIOS_IBM_PATH); } - static int cpqega_standalone_available(void) { return rom_present(BIOS_CPQ_PATH); } - static int sega_standalone_available(void) { return rom_present(BIOS_SEGA_PATH); } - static int atiega_standalone_available(void) { return rom_present(BIOS_ATIEGA_PATH); } - static int iskra_ega_standalone_available(void) { return rom_present("roms/video/ega/143-02.bin") && rom_present("roms/video/ega/143-03.bin"); } - static int et2000_standalone_available(void) { return rom_present(BIOS_TSENG_PATH); } - static void ega_close(void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *) p; if (ega->eeprom) - free(ega->eeprom); + free(ega->eeprom); free(ega->vram); free(ega); } - static void ega_speed_changed(void *p) { - ega_t *ega = (ega_t *)p; + ega_t *ega = (ega_t *) p; ega_recalctimings(ega); } - /* SW1 SW2 SW3 SW4 OFF OFF ON OFF Monochrome (5151) 1011 0x0B ON OFF OFF ON Color 40x25 (5153) 0110 0x06 @@ -1179,7 +1235,7 @@ ega_speed_changed(void *p) 0 = Switch closed (ON); 1 = Switch open (OFF). */ static const device_config_t ega_config[] = { -// clang-format off + // clang-format off { .name = "memory", .description = "Memory size", @@ -1253,85 +1309,85 @@ static const device_config_t ega_config[] = { }; const device_t ega_device = { - .name = "EGA", + .name = "EGA", .internal_name = "ega", - .flags = DEVICE_ISA, - .local = EGA_IBM, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = EGA_IBM, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, { .available = ega_standalone_available }, .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config + .force_redraw = NULL, + .config = ega_config }; const device_t cpqega_device = { - .name = "Compaq EGA", + .name = "Compaq EGA", .internal_name = "compaq_ega", - .flags = DEVICE_ISA, - .local = EGA_COMPAQ, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = EGA_COMPAQ, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, { .available = cpqega_standalone_available }, .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config + .force_redraw = NULL, + .config = ega_config }; const device_t sega_device = { - .name = "SuperEGA", + .name = "SuperEGA", .internal_name = "superega", - .flags = DEVICE_ISA, - .local = EGA_SUPEREGA, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = EGA_SUPEREGA, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, { .available = sega_standalone_available }, .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config + .force_redraw = NULL, + .config = ega_config }; const device_t atiega_device = { - .name = "ATI EGA Wonder 800+", + .name = "ATI EGA Wonder 800+", .internal_name = "egawonder800", - .flags = DEVICE_ISA, - .local = EGA_ATI, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = EGA_ATI, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, { .available = atiega_standalone_available }, .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config + .force_redraw = NULL, + .config = ega_config }; const device_t iskra_ega_device = { - .name = "Iskra EGA (Cyrillic ROM)", + .name = "Iskra EGA (Cyrillic ROM)", .internal_name = "iskra_ega", - .flags = DEVICE_ISA, - .local = EGA_ISKRA, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = EGA_ISKRA, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, { .available = iskra_ega_standalone_available }, .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config + .force_redraw = NULL, + .config = ega_config }; const device_t et2000_device = { - .name = "Tseng Labs ET2000", + .name = "Tseng Labs ET2000", .internal_name = "et2000", - .flags = DEVICE_ISA, - .local = EGA_TSENG, - .init = ega_standalone_init, - .close = ega_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = EGA_TSENG, + .init = ega_standalone_init, + .close = ega_close, + .reset = NULL, { .available = et2000_standalone_available }, .speed_changed = ega_speed_changed, - .force_redraw = NULL, - .config = ega_config + .force_redraw = NULL, + .config = ega_config }; diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index b925ab944..a9699dbf9 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -29,174 +29,172 @@ #include <86box/vid_ega.h> #include <86box/vid_ega_render_remap.h> - int ega_display_line(ega_t *ega) { - int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; - unsigned int dl = ega->displine; + int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; + unsigned int dl = ega->displine; if (ega->crtc[9] & 0x1f) - dl -= (ega->crtc[8] & 0x1f); + dl -= (ega->crtc[8] & 0x1f); dl += y_add; dl &= 0x7ff; return dl; } - void ega_render_blank(ega_t *ega) { int x, xx; if ((ega->displine + ega->y_add) < 0) - return; + return; for (x = 0; x < (ega->hdisp + ega->scrollcache); x++) { - switch (ega->seqregs[1] & 9) { - case 0: - for (xx = 0; xx < 9; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0; - break; - case 1: - for (xx = 0; xx < 8; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 8) + xx] = 0; - break; - case 8: - for (xx = 0; xx < 18; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 18) + xx] = 0; - break; - case 9: - for (xx = 0; xx < 16; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 16) + xx] = 0; - break; - } + switch (ega->seqregs[1] & 9) { + case 0: + for (xx = 0; xx < 9; xx++) + buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0; + break; + case 1: + for (xx = 0; xx < 8; xx++) + buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 8) + xx] = 0; + break; + case 8: + for (xx = 0; xx < 18; xx++) + buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 18) + xx] = 0; + break; + case 9: + for (xx = 0; xx < 16; xx++) + buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 16) + xx] = 0; + break; + } } } - void ega_render_overscan_left(ega_t *ega) { int i; if ((ega->displine + ega->y_add) < 0) - return; + return; if (ega->scrblank || (ega->hdisp == 0)) - return; + return; for (i = 0; i < ega->x_add; i++) - buffer32->line[ega->displine + ega->y_add][i] = ega->overscan_color; + buffer32->line[ega->displine + ega->y_add][i] = ega->overscan_color; } - void ega_render_overscan_right(ega_t *ega) { int i, right; if ((ega->displine + ega->y_add) < 0) - return; + return; if (ega->scrblank || (ega->hdisp == 0)) - return; + return; right = (overscan_x >> 1) + ega->scrollcache; for (i = 0; i < right; i++) - buffer32->line[ega->displine + ega->y_add][ega->x_add + ega->hdisp + i] = ega->overscan_color; + buffer32->line[ega->displine + ega->y_add][ega->x_add + ega->hdisp + i] = ega->overscan_color; } - void ega_render_text_40(ega_t *ega) { uint32_t *p; - int x, xx; - int drawcursor, xinc; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - uint32_t addr; + int x, xx; + int drawcursor, xinc; + uint8_t chr, attr, dat; + uint32_t charaddr; + int fg, bg; + uint32_t addr; if ((ega->displine + ega->y_add) < 0) - return; + return; if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; + ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; if (ega->fullchange) { - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; - xinc = (ega->seqregs[1] & 1) ? 16 : 18; + p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + xinc = (ega->seqregs[1] & 1) ? 16 : 18; - for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { - addr = ega->remap_func(ega, ega->ma) & ega->vrammask; + for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { + addr = ega->remap_func(ega, ega->ma) & ega->vrammask; - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - if (ega->crtc[0x17] & 0x80) { - chr = ega->vram[addr]; - attr = ega->vram[addr + 1]; - } else - chr = attr = 0; + if (ega->crtc[0x17] & 0x80) { + chr = ega->vram[addr]; + attr = ega->vram[addr + 1]; + } else + chr = attr = 0; - if (attr & 8) - charaddr = ega->charsetb + ((chr * 0x80)); - else - charaddr = ega->charseta + ((chr * 0x80)); + if (attr & 8) + charaddr = ega->charsetb + ((chr * 0x80)); + else + charaddr = ega->charseta + ((chr * 0x80)); - if (drawcursor) { - bg = ega->pallook[ega->egapal[attr & 0x0f]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } else { - fg = ega->pallook[ega->egapal[attr & 0x0f]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; + if (drawcursor) { + bg = ega->pallook[ega->egapal[attr & 0x0f]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } else { + fg = ega->pallook[ega->egapal[attr & 0x0f]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; - if ((attr & 0x80) && ega->attrregs[0x10] & 8) { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 0x10) - fg = bg; - } - } + if ((attr & 0x80) && ega->attrregs[0x10] & 8) { + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 0x10) + fg = bg; + } + } - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 1) { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - } else { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - p[16] = p[17] = bg; - else - p[16] = p[17] = (dat & 1) ? fg : bg; - } - ega->ma += 4; - p += xinc; - } - ega->ma &= ega->vrammask; + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 1) { + for (xx = 0; xx < 16; xx += 2) + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + } else { + for (xx = 0; xx < 16; xx += 2) + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + p[16] = p[17] = bg; + else + p[16] = p[17] = (dat & 1) ? fg : bg; + } + ega->ma += 4; + p += xinc; + } + ega->ma &= ega->vrammask; } } - void ega_render_text_80(ega_t *ega) { uint32_t *p; - int x, xx; - int drawcursor, xinc; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - uint32_t addr; + int x, xx; + int drawcursor, xinc; + uint8_t chr, attr, dat; + uint32_t charaddr; + int fg, bg; + uint32_t addr; if ((ega->displine + ega->y_add) < 0) - return; + return; if (ega->firstline_draw == 2000) - ega->firstline_draw = ega->displine; + ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; if (ega->fullchange) { - p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; + p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; xinc = (ega->seqregs[1] & 1) ? 8 : 9; for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { @@ -205,8 +203,8 @@ ega_render_text_80(ega_t *ega) drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); if (ega->crtc[0x17] & 0x80) { - chr = ega->vram[addr]; - attr = ega->vram[addr + 1]; + chr = ega->vram[addr]; + attr = ega->vram[addr + 1]; } else chr = attr = 0; @@ -229,7 +227,7 @@ ega_render_text_80(ega_t *ega) } dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 1) { + if (ega->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) p[xx] = (dat & (0x80 >> xx)) ? fg : bg; } else { @@ -247,16 +245,15 @@ ega_render_text_80(ega_t *ega) } } - void ega_render_2bpp_lowres(ega_t *ega) { - int x; - uint8_t dat[2]; + int x; + uint8_t dat[2]; uint32_t addr, *p; if ((ega->displine + ega->y_add) < 0) - return; + return; p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; @@ -277,11 +274,11 @@ ega_render_2bpp_lowres(ega_t *ega) ega->ma &= ega->vrammask; if (ega->crtc[0x17] & 0x80) { - p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]]; - p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; + p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]]; + p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]]; p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]]; p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]]; p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]]; @@ -292,16 +289,15 @@ ega_render_2bpp_lowres(ega_t *ega) } } - void ega_render_2bpp_highres(ega_t *ega) { - int x; - uint8_t dat[2]; + int x; + uint8_t dat[2]; uint32_t addr, *p; if ((ega->displine + ega->y_add) < 0) - return; + return; p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; @@ -337,16 +333,15 @@ ega_render_2bpp_highres(ega_t *ega) } } - void ega_render_4bpp_lowres(ega_t *ega) { - int x, oddeven; - uint8_t dat, edat[4]; + int x, oddeven; + uint8_t dat, edat[4]; uint32_t addr, *p; if ((ega->displine + ega->y_add) < 0) - return; + return; p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; @@ -355,32 +350,32 @@ ega_render_4bpp_lowres(ega_t *ega) ega->lastline_draw = ega->displine; for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { - addr = ega->remap_func(ega, ega->ma); + addr = ega->remap_func(ega, ega->ma); oddeven = 0; if (ega->seqregs[1] & 4) { oddeven = (addr & 4) ? 1 : 0; edat[0] = ega->vram[addr | oddeven]; edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; + edat[1] = edat[3] = 0; ega->ma += 2; } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]); + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); ega->ma += 4; } ega->ma &= ega->vrammask; if (ega->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; - p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; + p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; } else @@ -390,16 +385,15 @@ ega_render_4bpp_lowres(ega_t *ega) } } - void ega_render_4bpp_highres(ega_t *ega) { - int x, oddeven; - uint8_t dat, edat[4]; + int x, oddeven; + uint8_t dat, edat[4]; uint32_t addr, *p; if ((ega->displine + ega->y_add) < 0) - return; + return; p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; @@ -408,32 +402,32 @@ ega_render_4bpp_highres(ega_t *ega) ega->lastline_draw = ega->displine; for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { - addr = ega->remap_func(ega, ega->ma); + addr = ega->remap_func(ega, ega->ma); oddeven = 0; if (ega->seqregs[1] & 4) { oddeven = (addr & 4) ? 1 : 0; edat[0] = ega->vram[addr | oddeven]; edat[2] = ega->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; + edat[1] = edat[3] = 0; ega->ma += 2; } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]); + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]); ega->ma += 4; } ega->ma &= ega->vrammask; if (ega->crtc[0x17] & 0x80) { - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]]; p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]]; } else diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 76e609ee0..bafaeb887 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -53,40 +53,44 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#define ET4000_TYPE_ISA 1 /* ISA ET4000AX */ +#define ET4000_TYPE_MCA 2 /* MCA ET4000AX */ +#define ET4000_TYPE_KOREAN 3 /* Korean ET4000 */ +#define ET4000_TYPE_TRIGEM 4 /* Trigem 286M ET4000 */ +#define ET4000_TYPE_KASAN 5 /* Kasan ET4000 */ -#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" -#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" -#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" -#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" -#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom" +#define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN" +#define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin" +#define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom" +#define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin" +#define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom" typedef struct { - const char *name; - int type; + const char *name; + int type; - svga_t svga; + svga_t svga; - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; - rom_t bios_rom; + rom_t bios_rom; - uint8_t banking; - uint32_t vram_size, - vram_mask; + uint8_t banking; + uint32_t vram_size, + vram_mask; - uint8_t port_22cb_val; - uint8_t port_32cb_val; - int get_korean_font_enabled; - int get_korean_font_index; - uint16_t get_korean_font_base; + uint8_t port_22cb_val; + uint8_t port_32cb_val; + int get_korean_font_enabled; + int get_korean_font_index; + uint16_t get_korean_font_base; - uint8_t kasan_cfg_index; - uint8_t kasan_cfg_regs[16]; - uint16_t kasan_access_addr; - uint8_t kasan_font_data[4]; + uint8_t kasan_cfg_index; + uint8_t kasan_cfg_regs[16]; + uint16_t kasan_access_addr; + uint8_t kasan_font_data[4]; } et4000_t; - static const uint8_t crtc_mask[0x40] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -98,645 +102,638 @@ static const uint8_t crtc_mask[0x40] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static video_timings_t timing_et4000_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; -static video_timings_t timing_et4000_mca = {VIDEO_MCA, 4, 5, 10, 5, 5, 10}; +static video_timings_t timing_et4000_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_et4000_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; -static void et4000_kasan_out(uint16_t addr, uint8_t val, void *p); +static void et4000_kasan_out(uint16_t addr, uint8_t val, void *p); static uint8_t et4000_kasan_in(uint16_t addr, void *p); static uint8_t et4000_in(uint16_t addr, void *priv) { - et4000_t *dev = (et4000_t *)priv; - svga_t *svga = &dev->svga; + et4000_t *dev = (et4000_t *) priv; + svga_t *svga = &dev->svga; - if (((addr & 0xfff0) == 0x3d0 || - (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3c2: - if (dev->type == 1) { - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) - return 0; - else - return 0x10; - } - break; + case 0x3c2: + if (dev->type == ET4000_TYPE_MCA) { + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) + return 0; + else + return 0x10; + } + break; - case 0x3c5: - if ((svga->seqaddr & 0xf) == 7) - return svga->seqregs[svga->seqaddr & 0xf] | 4; - break; + case 0x3c5: + if ((svga->seqaddr & 0xf) == 7) + return svga->seqregs[svga->seqaddr & 0xf] | 4; + break; - case 0x3c6: - case 0x3c7: - case 0x3c8: - case 0x3c9: - return sc1502x_ramdac_in(addr, svga->ramdac, svga); + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + return sc1502x_ramdac_in(addr, svga->ramdac, svga); - case 0x3cd: /*Banking*/ - return dev->banking; + case 0x3cd: /*Banking*/ + return dev->banking; - case 0x3d4: - return svga->crtcreg; + case 0x3d4: + return svga->crtcreg; - case 0x3d5: - return svga->crtc[svga->crtcreg]; + case 0x3d5: + return svga->crtc[svga->crtcreg]; } return svga_in(addr, svga); } - static uint8_t et4000k_in(uint16_t addr, void *priv) { - et4000_t *dev = (et4000_t *)priv; - uint8_t val = 0xff; + et4000_t *dev = (et4000_t *) priv; + uint8_t val = 0xff; switch (addr) { - case 0x22cb: - return dev->port_22cb_val; + case 0x22cb: + return dev->port_22cb_val; - case 0x22cf: - val = 0; - switch(dev->get_korean_font_enabled) { - case 3: - if ((dev->port_32cb_val & 0x30) == 0x30) { - val = fontdatksc5601[dev->get_korean_font_base].chr[dev->get_korean_font_index++]; - dev->get_korean_font_index &= 0x1f; - } else - if ((dev->port_32cb_val & 0x30) == 0x20 && - (dev->get_korean_font_base & 0x7f) > 0x20 && - (dev->get_korean_font_base & 0x7f) < 0x7f) { - switch(dev->get_korean_font_base & 0x3f80) { - case 0x2480: - if (dev->get_korean_font_index < 16) - val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index]; - else - if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) - val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8]; - break; + case 0x22cf: + val = 0; + switch (dev->get_korean_font_enabled) { + case 3: + if ((dev->port_32cb_val & 0x30) == 0x30) { + val = fontdatksc5601[dev->get_korean_font_base].chr[dev->get_korean_font_index++]; + dev->get_korean_font_index &= 0x1f; + } else if ((dev->port_32cb_val & 0x30) == 0x20 && (dev->get_korean_font_base & 0x7f) > 0x20 && (dev->get_korean_font_base & 0x7f) < 0x7f) { + switch (dev->get_korean_font_base & 0x3f80) { + case 0x2480: + if (dev->get_korean_font_index < 16) + val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index]; + else if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) + val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8]; + break; - case 0x3f00: - if (dev->get_korean_font_index < 16) - val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index]; - else - if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) - val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8]; - break; + case 0x3f00: + if (dev->get_korean_font_index < 16) + val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index]; + else if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) + val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8]; + break; - default: - break; - } - dev->get_korean_font_index++; - dev->get_korean_font_index %= 72; - } - break; + default: + break; + } + dev->get_korean_font_index++; + dev->get_korean_font_index %= 72; + } + break; - case 4: - val = 0x0f; - break; + case 4: + val = 0x0f; + break; - default: - break; - } - return val; + default: + break; + } + return val; - case 0x32cb: - return dev->port_32cb_val; + case 0x32cb: + return dev->port_32cb_val; - default: - return et4000_in(addr, priv); + default: + return et4000_in(addr, priv); } } - static void et4000_out(uint16_t addr, uint8_t val, void *priv) { - et4000_t *dev = (et4000_t *)priv; - svga_t *svga = &dev->svga; - uint8_t old; + et4000_t *dev = (et4000_t *) priv; + svga_t *svga = &dev->svga; + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || - (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3c6: - case 0x3c7: - case 0x3c8: - case 0x3c9: - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - return; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + return; - case 0x3cd: /*Banking*/ - if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { - svga->write_bank = (val & 0xf) * 0x10000; - svga->read_bank = ((val >> 4) & 0xf) * 0x10000; - } - dev->banking = val; - return; + case 0x3cd: /*Banking*/ + if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { + svga->write_bank = (val & 0xf) * 0x10000; + svga->read_bank = ((val >> 4) & 0xf) * 0x10000; + } + dev->banking = val; + return; - case 0x3cf: - if ((svga->gdcaddr & 15) == 6) { - if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { - svga->write_bank = (dev->banking & 0x0f) * 0x10000; - svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; - } else - svga->write_bank = svga->read_bank = 0; + case 0x3cf: + if ((svga->gdcaddr & 15) == 6) { + if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { + svga->write_bank = (dev->banking & 0x0f) * 0x10000; + svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; + } else + svga->write_bank = svga->read_bank = 0; - old = svga->gdcreg[6]; - svga_out(addr, val, svga); - if ((old & 0xc) != 0 && (val & 0xc) == 0) - { - /*override mask - ET4000 supports linear 128k at A0000*/ - svga->banked_mask = 0x1ffff; - } - return; - } - break; + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) { + /*override mask - ET4000 supports linear 128k at A0000*/ + svga->banked_mask = 0x1ffff; + } + return; + } + break; - case 0x3d4: - svga->crtcreg = val & 0x3f; - return; + case 0x3d4: + svga->crtcreg = val & 0x3f; + return; - case 0x3d5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 0x35) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + case 0x3d5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 0x35) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + val &= crtc_mask[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (svga->crtcreg == 0x36) { - if (!(val & 0x10) && !(svga->gdcreg[6] & 0x08)) { - svga->write_bank = (dev->banking & 0x0f) * 0x10000; - svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; - } else - svga->write_bank = svga->read_bank = 0; - } + if (svga->crtcreg == 0x36) { + if (!(val & 0x10) && !(svga->gdcreg[6] & 0x08)) { + svga->write_bank = (dev->banking & 0x0f) * 0x10000; + svga->read_bank = ((dev->banking >> 4) & 0x0f) * 0x10000; + } else + svga->write_bank = svga->read_bank = 0; + } - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - break; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; } svga_out(addr, val, svga); } - static void et4000k_out(uint16_t addr, uint8_t val, void *priv) { - et4000_t *dev = (et4000_t *)priv; + et4000_t *dev = (et4000_t *) priv; switch (addr) { - case 0x22cb: - dev->port_22cb_val = (dev->port_22cb_val & 0xf0) | (val & 0x0f); - dev->get_korean_font_enabled = val & 7; - if (dev->get_korean_font_enabled == 3) - dev->get_korean_font_index = 0; - break; + case 0x22cb: + dev->port_22cb_val = (dev->port_22cb_val & 0xf0) | (val & 0x0f); + dev->get_korean_font_enabled = val & 7; + if (dev->get_korean_font_enabled == 3) + dev->get_korean_font_index = 0; + break; - case 0x22cf: - switch(dev->get_korean_font_enabled) { - case 1: - dev->get_korean_font_base = ((val & 0x7f) << 7) | (dev->get_korean_font_base & 0x7f); - break; + case 0x22cf: + switch (dev->get_korean_font_enabled) { + case 1: + dev->get_korean_font_base = ((val & 0x7f) << 7) | (dev->get_korean_font_base & 0x7f); + break; - case 2: - dev->get_korean_font_base = (dev->get_korean_font_base & 0x3f80) | (val & 0x7f) | (((val ^ 0x80) & 0x80) << 8); - break; + case 2: + dev->get_korean_font_base = (dev->get_korean_font_base & 0x3f80) | (val & 0x7f) | (((val ^ 0x80) & 0x80) << 8); + break; - case 3: - if ((dev->port_32cb_val & 0x30) == 0x20 && - (dev->get_korean_font_base & 0x7f) > 0x20 && - (dev->get_korean_font_base & 0x7f) < 0x7f) { - switch (dev->get_korean_font_base & 0x3f80) { - case 0x2480: - if (dev->get_korean_font_index < 16) - fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val; - else - if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) - fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val; - break; + case 3: + if ((dev->port_32cb_val & 0x30) == 0x20 && (dev->get_korean_font_base & 0x7f) > 0x20 && (dev->get_korean_font_base & 0x7f) < 0x7f) { + switch (dev->get_korean_font_base & 0x3f80) { + case 0x2480: + if (dev->get_korean_font_index < 16) + fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val; + else if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) + fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val; + break; - case 0x3f00: - if (dev->get_korean_font_index < 16) - fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val; - else - if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) - fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val; - break; + case 0x3f00: + if (dev->get_korean_font_index < 16) + fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val; + else if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) + fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val; + break; - default: - break; - } - dev->get_korean_font_index++; - } - break; + default: + break; + } + dev->get_korean_font_index++; + } + break; - default: - break; - } - break; + default: + break; + } + break; - case 0x32cb: - dev->port_32cb_val = val; - svga_recalctimings(&dev->svga); - break; + case 0x32cb: + dev->port_32cb_val = val; + svga_recalctimings(&dev->svga); + break; - default: - et4000_out(addr, val, priv); - break; + default: + et4000_out(addr, val, priv); + break; } } static uint8_t et4000_kasan_in(uint16_t addr, void *priv) { - et4000_t *et4000 = (et4000_t *)priv; - uint8_t val = 0xFF; + et4000_t *et4000 = (et4000_t *) priv; + uint8_t val = 0xFF; - if (addr == 0x258) { - val = et4000->kasan_cfg_index; - } else if (addr == 0x259) { - if (et4000->kasan_cfg_index >= 0xF0) { - val = et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0]; - if (et4000->kasan_cfg_index == 0xF4 && et4000->kasan_cfg_regs[0] & 0x20) - val |= 0x80; - } - } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { - switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { - case 2: - val = 0; - break; - case 5: - if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) - val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index]; - else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) - val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index]; - else - val = fontdatksc5601[et4000->get_korean_font_base].chr[et4000->get_korean_font_index]; - break; - default: - break; - } - } else - val = et4000_in(addr, priv); + if (addr == 0x258) { + val = et4000->kasan_cfg_index; + } else if (addr == 0x259) { + if (et4000->kasan_cfg_index >= 0xF0) { + val = et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0]; + if (et4000->kasan_cfg_index == 0xF4 && et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + } + } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { + case 2: + val = 0; + break; + case 5: + if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) + val = fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index]; + else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) + val = fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index]; + else + val = fontdatksc5601[et4000->get_korean_font_base].chr[et4000->get_korean_font_index]; + break; + default: + break; + } + } else + val = et4000_in(addr, priv); - return val; + return val; } static void et4000_kasan_out(uint16_t addr, uint8_t val, void *priv) { - et4000_t *et4000 = (et4000_t *)priv; + et4000_t *et4000 = (et4000_t *) priv; - if (addr == 0x258) { - et4000->kasan_cfg_index = val; - } else if (addr == 0x259) { - if (et4000->kasan_cfg_index >= 0xF0) { - switch (et4000->kasan_cfg_index - 0xF0) { - case 0: - if (et4000->kasan_cfg_regs[4] & 8) - val = (val & 0xFC) | (et4000->kasan_cfg_regs[0] & 3); - et4000->kasan_cfg_regs[0] = val; - svga_recalctimings(&et4000->svga); - break; - case 1: - case 2: - et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; - io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); - et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; - io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); - break; - case 4: - if (et4000->kasan_cfg_regs[0] & 0x20) - val |= 0x80; - et4000->svga.ksc5601_swap_mode = (val & 4) >> 2; - et4000->kasan_cfg_regs[4] = val; - svga_recalctimings(&et4000->svga); - break; - case 5: - et4000->kasan_cfg_regs[5] = val; - et4000->svga.ksc5601_english_font_type = 0x100 | val; - case 6: - case 7: - et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; - default: - et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; - svga_recalctimings(&et4000->svga); - break; - } - } - } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { - switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { - case 0: - if (et4000->kasan_cfg_regs[0] & 2) { - et4000->get_korean_font_index = ((val & 1) << 4) | ((val & 0x1E) >> 1); - et4000->get_korean_font_base = (et4000->get_korean_font_base & ~7) | (val >> 5); - } - break; - case 1: - if (et4000->kasan_cfg_regs[0] & 2) - et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F8) | (val << 3); - break; - case 2: - if (et4000->kasan_cfg_regs[0] & 2) - et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F800) | ((val & 7) << 11); - break; - case 3: - case 4: - case 5: - if (et4000->kasan_cfg_regs[0] & 1) - et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; - break; - case 6: - if ((et4000->kasan_cfg_regs[0] & 1) && (et4000->kasan_font_data[3] & !(val & 0x80)) && (et4000->get_korean_font_base & 0x7F) >= 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) { - if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) - fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = et4000->kasan_font_data[2]; - else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) - fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = et4000->kasan_font_data[2]; - } - et4000->kasan_font_data[3] = val; - break; - default: - break; - } - } else - et4000_out(addr, val, priv); + if (addr == 0x258) { + et4000->kasan_cfg_index = val; + } else if (addr == 0x259) { + if (et4000->kasan_cfg_index >= 0xF0) { + switch (et4000->kasan_cfg_index - 0xF0) { + case 0: + if (et4000->kasan_cfg_regs[4] & 8) + val = (val & 0xFC) | (et4000->kasan_cfg_regs[0] & 3); + et4000->kasan_cfg_regs[0] = val; + svga_recalctimings(&et4000->svga); + break; + case 1: + case 2: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + io_removehandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + et4000->kasan_access_addr = (et4000->kasan_cfg_regs[2] << 8) | et4000->kasan_cfg_regs[1]; + io_sethandler(et4000->kasan_access_addr, 0x0008, et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, et4000); + break; + case 4: + if (et4000->kasan_cfg_regs[0] & 0x20) + val |= 0x80; + et4000->svga.ksc5601_swap_mode = (val & 4) >> 2; + et4000->kasan_cfg_regs[4] = val; + svga_recalctimings(&et4000->svga); + break; + case 5: + et4000->kasan_cfg_regs[5] = val; + et4000->svga.ksc5601_english_font_type = 0x100 | val; + case 6: + case 7: + et4000->svga.ksc5601_udc_area_msb[et4000->kasan_cfg_index - 0xF6] = val; + default: + et4000->kasan_cfg_regs[et4000->kasan_cfg_index - 0xF0] = val; + svga_recalctimings(&et4000->svga); + break; + } + } + } else if (addr >= et4000->kasan_access_addr && addr < et4000->kasan_access_addr + 8) { + switch (addr - ((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1]))) { + case 0: + if (et4000->kasan_cfg_regs[0] & 2) { + et4000->get_korean_font_index = ((val & 1) << 4) | ((val & 0x1E) >> 1); + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~7) | (val >> 5); + } + break; + case 1: + if (et4000->kasan_cfg_regs[0] & 2) + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F8) | (val << 3); + break; + case 2: + if (et4000->kasan_cfg_regs[0] & 2) + et4000->get_korean_font_base = (et4000->get_korean_font_base & ~0x7F800) | ((val & 7) << 11); + break; + case 3: + case 4: + case 5: + if (et4000->kasan_cfg_regs[0] & 1) { + et4000->kasan_font_data[addr - (((et4000->kasan_cfg_regs[2] << 8) | (et4000->kasan_cfg_regs[1])) + 3)] = val; + } + break; + case 6: + if ((et4000->kasan_cfg_regs[0] & 1) && (et4000->kasan_font_data[3] & !(val & 0x80)) && (et4000->get_korean_font_base & 0x7F) >= 0x20 && (et4000->get_korean_font_base & 0x7F) < 0x7F) { + if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[0] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[0] & 0x80)) + fontdatksc5601_user[(et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + else if (((et4000->get_korean_font_base >> 7) & 0x7F) == (et4000->svga.ksc5601_udc_area_msb[1] & 0x7F) && (et4000->svga.ksc5601_udc_area_msb[1] & 0x80)) + fontdatksc5601_user[96 + (et4000->get_korean_font_base & 0x7F) - 0x20].chr[et4000->get_korean_font_index] = et4000->kasan_font_data[2]; + } + et4000->kasan_font_data[3] = val; + break; + default: + break; + } + } else + et4000_out(addr, val, priv); } uint32_t get_et4000_addr(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - uint32_t nbank; + svga_t *svga = (svga_t *) p; + uint32_t nbank; - switch (svga->crtc[0x37] & 0x0B) { - case 0x00: - case 0x01: - nbank = 0; - addr &= 0xFFFF; - break; - case 0x02: - nbank = (addr & 1) << 1; - addr = (addr >> 1) & 0xFFFF; - break; - case 0x03: - nbank = addr & 3; - addr = (addr >> 2) & 0xFFFF; - break; - case 0x08: - case 0x09: - nbank = 0; - addr &= 0x3FFFF; - break; - case 0x0A: - nbank = (addr & 1) << 1; - addr = (addr >> 1) & 0x3FFFF; - break; - case 0x0B: - nbank = addr & 3; - addr = (addr >> 2) & 0x3FFFF; - break; - default: - nbank = 0; - break; - } + switch (svga->crtc[0x37] & 0x0B) { + case 0x00: + case 0x01: + nbank = 0; + addr &= 0xFFFF; + break; + case 0x02: + nbank = (addr & 1) << 1; + addr = (addr >> 1) & 0xFFFF; + break; + case 0x03: + nbank = addr & 3; + addr = (addr >> 2) & 0xFFFF; + break; + case 0x08: + case 0x09: + nbank = 0; + addr &= 0x3FFFF; + break; + case 0x0A: + nbank = (addr & 1) << 1; + addr = (addr >> 1) & 0x3FFFF; + break; + case 0x0B: + nbank = addr & 3; + addr = (addr >> 2) & 0x3FFFF; + break; + default: + nbank = 0; + break; + } - if (svga->vram_max >= 1024 * 1024) { - addr = (addr << 2) | (nbank & 3); - if ((svga->crtc[0x37] & 3) == 2) - addr >>= 1; - else if ((svga->crtc[0x37] & 3) < 2) - addr >>= 2; - } else if (svga->vram_max >= 512 * 1024) { - addr = (addr << 1) | ((nbank & 2) >> 1) | ((nbank & 1) << 19); - if ((svga->crtc[0x37] & 3) < 2) - addr >>= 1; - } else if(svga->vram_max >= 256 * 1024) - addr = addr | (nbank << 18); - else if (svga->vram_max > 128 * 1024) { - addr = (addr << 1) | ((nbank & 2) >> 1) | ((nbank & 1) << 17); - if ((svga->crtc[0x37] & 3) < 2) - addr >>= 1; - } else - addr = addr | (nbank << 16); + if (svga->vram_max >= 1024 * 1024) { + addr = (addr << 2) | (nbank & 3); + if ((svga->crtc[0x37] & 3) == 2) + addr >>= 1; + else if ((svga->crtc[0x37] & 3) < 2) + addr >>= 2; + } else if (svga->vram_max >= 512 * 1024) { + addr = (addr << 1) | ((nbank & 2) >> 1) | ((nbank & 1) << 19); + if ((svga->crtc[0x37] & 3) < 2) + addr >>= 1; + } else if (svga->vram_max >= 256 * 1024) + addr = addr | (nbank << 18); + else if (svga->vram_max > 128 * 1024) { + addr = (addr << 1) | ((nbank & 2) >> 1) | ((nbank & 1) << 17); + if ((svga->crtc[0x37] & 3) < 2) + addr >>= 1; + } else + addr = addr | (nbank << 16); - return addr; + return addr; } static void et4000_recalctimings(svga_t *svga) { - et4000_t *dev = (et4000_t *)svga->p; + et4000_t *dev = (et4000_t *) svga->p; - svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; - if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; - if (svga->crtc[0x35] & 2) svga->vtotal += 0x400; - if (svga->crtc[0x35] & 4) svga->dispend += 0x400; - if (svga->crtc[0x35] & 8) svga->vsyncstart += 0x400; - if (svga->crtc[0x35] & 0x10) svga->split += 0x400; - if (!svga->rowoffset) svga->rowoffset = 0x100; - if (svga->crtc[0x3f] & 1) svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; + svga->ma_latch |= (svga->crtc[0x33] & 3) << 16; + if (svga->crtc[0x35] & 1) + svga->vblankstart += 0x400; + if (svga->crtc[0x35] & 2) + svga->vtotal += 0x400; + if (svga->crtc[0x35] & 4) + svga->dispend += 0x400; + if (svga->crtc[0x35] & 8) + svga->vsyncstart += 0x400; + if (svga->crtc[0x35] & 0x10) + svga->split += 0x400; + if (!svga->rowoffset) + svga->rowoffset = 0x100; + if (svga->crtc[0x3f] & 1) + svga->htotal += 256; + if (svga->attrregs[0x16] & 0x20) + svga->hdisp <<= 1; - switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { - case 0: - case 1: - break; - case 3: - svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; - break; - case 5: - svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - default: - svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - } + switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { + case 0: + case 1: + break; + case 3: + svga->clock = (cpuclock * (double) (1ull << 32)) / 40000000.0; + break; + case 5: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0; + break; + default: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + } - switch (svga->bpp) { - case 15: - case 16: - svga->hdisp /= 2; - break; + switch (svga->bpp) { + case 15: + case 16: + svga->hdisp /= 2; + break; - case 24: - svga->hdisp /= 3; - break; - } + case 24: + svga->hdisp /= 3; + break; + } - if (dev->type == 2 || dev->type == 3 || dev->type == 4) { - if ((svga->render == svga_render_text_80) && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { - if (dev->port_32cb_val & 0x80) { - svga->ma_latch -= 2; - svga->ca_adj = -2; - } - if ((dev->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { - svga->render = svga_render_text_80_ksc5601; - } - } - } + if (dev->type == ET4000_TYPE_KOREAN || dev->type == ET4000_TYPE_TRIGEM || dev->type == ET4000_TYPE_KASAN) { + if ((svga->render == svga_render_text_80) && ((svga->crtc[0x37] & 0x0A) == 0x0A)) { + if (dev->port_32cb_val & 0x80) { + svga->ma_latch -= 2; + svga->ca_adj = -2; + } + if ((dev->port_32cb_val & 0xB4) == ((svga->crtc[0x37] & 3) == 2 ? 0xB4 : 0xB0)) { + svga->render = svga_render_text_80_ksc5601; + } + } + } } static void et4000_kasan_recalctimings(svga_t *svga) { - et4000_t *et4000 = (et4000_t *)svga->p; + et4000_t *et4000 = (et4000_t *) svga->p; - et4000_recalctimings(svga); + et4000_recalctimings(svga); - if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { - svga->ma_latch -= 3; - svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; - svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; - if((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) - svga->render = svga_render_text_80_ksc5601; - } + if (svga->render == svga_render_text_80 && (et4000->kasan_cfg_regs[0] & 8)) { + svga->ma_latch -= 3; + svga->ca_adj = (et4000->kasan_cfg_regs[0] >> 6) - 3; + svga->ksc5601_sbyte_mask = (et4000->kasan_cfg_regs[0] & 4) << 5; + if ((et4000->kasan_cfg_regs[0] & 0x23) == 0x20 && (et4000->kasan_cfg_regs[4] & 0x80) && ((svga->crtc[0x37] & 0x0B) == 0x0A)) + svga->render = svga_render_text_80_ksc5601; + } } static uint8_t et4000_mca_read(int port, void *priv) { - et4000_t *et4000 = (et4000_t *)priv; + et4000_t *et4000 = (et4000_t *) priv; - return(et4000->pos_regs[port & 7]); + return (et4000->pos_regs[port & 7]); } - static void et4000_mca_write(int port, uint8_t val, void *priv) { - et4000_t *et4000 = (et4000_t *)priv; + et4000_t *et4000 = (et4000_t *) priv; /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; + if (port < 0x0102) + return; /* Save the MCA register value. */ et4000->pos_regs[port & 7] = val; } - static uint8_t et4000_mca_feedb(void *priv) { return 1; } - static void * et4000_init(const device_t *info) { const char *fn; - et4000_t *dev; - int i; + et4000_t *dev; + int i; - dev = (et4000_t *)malloc(sizeof(et4000_t)); + dev = (et4000_t *) malloc(sizeof(et4000_t)); memset(dev, 0x00, sizeof(et4000_t)); dev->name = info->name; dev->type = info->local; - fn = BIOS_ROM_PATH; + fn = BIOS_ROM_PATH; - switch(dev->type) { - case 0: /* ISA ET4000AX */ - dev->vram_size = device_get_config_int("memory") << 10; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); - svga_init(info, &dev->svga, dev, dev->vram_size, - et4000_recalctimings, et4000_in, et4000_out, - NULL, NULL); - io_sethandler(0x03c0, 32, - et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev); - break; + switch (dev->type) { + case ET4000_TYPE_ISA: /* ISA ET4000AX */ + dev->vram_size = device_get_config_int("memory") << 10; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); + svga_init(info, &dev->svga, dev, dev->vram_size, + et4000_recalctimings, et4000_in, et4000_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); + break; - case 1: /* MCA ET4000AX */ - dev->vram_size = 1024 << 10; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_mca); - svga_init(info, &dev->svga, dev, dev->vram_size, - et4000_recalctimings, et4000_in, et4000_out, - NULL, NULL); - io_sethandler(0x03c0, 32, - et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev); - dev->pos_regs[0] = 0xf2; /* ET4000 MCA board ID */ - dev->pos_regs[1] = 0x80; - mca_add(et4000_mca_read, et4000_mca_write, et4000_mca_feedb, NULL, dev); - break; + case ET4000_TYPE_MCA: /* MCA ET4000AX */ + dev->vram_size = 1024 << 10; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_mca); + svga_init(info, &dev->svga, dev, dev->vram_size, + et4000_recalctimings, et4000_in, et4000_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); + dev->pos_regs[0] = 0xf2; /* ET4000 MCA board ID */ + dev->pos_regs[1] = 0x80; + mca_add(et4000_mca_read, et4000_mca_write, et4000_mca_feedb, NULL, dev); + break; - case 2: /* Korean ET4000 */ - case 3: /* Trigem 286M ET4000 */ - dev->vram_size = device_get_config_int("memory") << 10; - dev->port_22cb_val = 0x60; - dev->port_32cb_val = 0; - dev->svga.ksc5601_sbyte_mask = 0x80; - dev->svga.ksc5601_udc_area_msb[0] = 0xC9; - dev->svga.ksc5601_udc_area_msb[1] = 0xFE; - dev->svga.ksc5601_swap_mode = 0; - dev->svga.ksc5601_english_font_type = 0; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); - svga_init(info, &dev->svga, dev, dev->vram_size, - et4000_recalctimings, et4000k_in, et4000k_out, - NULL, NULL); - io_sethandler(0x03c0, 32, - et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); - io_sethandler(0x22cb, 1, - et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); - io_sethandler(0x22cf, 1, - et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); - io_sethandler(0x32cb, 1, - et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); - loadfont(KOREAN_FONT_ROM_PATH, 6); - fn = KOREAN_BIOS_ROM_PATH; - break; - case 4: /* Kasan ET4000 */ - dev->vram_size = device_get_config_int("memory") << 10; - dev->svga.ksc5601_sbyte_mask = 0; - dev->svga.ksc5601_udc_area_msb[0] = 0xC9; - dev->svga.ksc5601_udc_area_msb[1] = 0xFE; - dev->svga.ksc5601_swap_mode = 0; - dev->svga.ksc5601_english_font_type = 0x1FF; - dev->kasan_cfg_index = 0; - for (i=0; i<16; i++) - dev->kasan_cfg_regs[i] = 0; - for(i=0; i<4; i++) - dev->kasan_font_data[i] = 0; - dev->kasan_cfg_regs[1] = 0x50; - dev->kasan_cfg_regs[2] = 2; - dev->kasan_cfg_regs[3] = 6; - dev->kasan_cfg_regs[4] = 0x78; - dev->kasan_cfg_regs[5] = 0xFF; - dev->kasan_cfg_regs[6] = 0xC9; - dev->kasan_cfg_regs[7] = 0xFE; - dev->kasan_access_addr = 0x250; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); - svga_init(info, &dev->svga, dev, dev->vram_size, - et4000_kasan_recalctimings, et4000_in, et4000_out, - NULL, NULL); - io_sethandler(0x03c0, 32, - et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); - io_sethandler(0x0250, 8, - et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); - io_sethandler(0x0258, 2, - et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); - loadfont(KASAN_FONT_ROM_PATH, 6); - fn = KASAN_BIOS_ROM_PATH; - break; + case ET4000_TYPE_KOREAN: /* Korean ET4000 */ + case ET4000_TYPE_TRIGEM: /* Trigem 286M ET4000 */ + dev->vram_size = device_get_config_int("memory") << 10; + dev->port_22cb_val = 0x60; + dev->port_32cb_val = 0; + dev->svga.ksc5601_sbyte_mask = 0x80; + dev->svga.ksc5601_udc_area_msb[0] = 0xC9; + dev->svga.ksc5601_udc_area_msb[1] = 0xFE; + dev->svga.ksc5601_swap_mode = 0; + dev->svga.ksc5601_english_font_type = 0; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); + svga_init(info, &dev->svga, dev, dev->vram_size, + et4000_recalctimings, et4000k_in, et4000k_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, dev); + io_sethandler(0x22cb, 1, + et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, dev); + io_sethandler(0x22cf, 1, + et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, dev); + io_sethandler(0x32cb, 1, + et4000k_in, NULL, NULL, et4000k_out, NULL, NULL, dev); + loadfont(KOREAN_FONT_ROM_PATH, 6); + fn = KOREAN_BIOS_ROM_PATH; + break; + case ET4000_TYPE_KASAN: /* Kasan ET4000 */ + dev->vram_size = device_get_config_int("memory") << 10; + dev->svga.ksc5601_sbyte_mask = 0; + dev->svga.ksc5601_udc_area_msb[0] = 0xC9; + dev->svga.ksc5601_udc_area_msb[1] = 0xFE; + dev->svga.ksc5601_swap_mode = 0; + dev->svga.ksc5601_english_font_type = 0x1FF; + dev->kasan_cfg_index = 0; + for (i = 0; i < 16; i++) + dev->kasan_cfg_regs[i] = 0; + for (i = 0; i < 4; i++) + dev->kasan_font_data[i] = 0; + dev->kasan_cfg_regs[1] = 0x50; + dev->kasan_cfg_regs[2] = 2; + dev->kasan_cfg_regs[3] = 6; + dev->kasan_cfg_regs[4] = 0x78; + dev->kasan_cfg_regs[5] = 0xFF; + dev->kasan_cfg_regs[6] = 0xC9; + dev->kasan_cfg_regs[7] = 0xFE; + dev->kasan_access_addr = 0x250; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000_isa); + svga_init(info, &dev->svga, dev, dev->vram_size, + et4000_kasan_recalctimings, et4000_in, et4000_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + et4000_in, NULL, NULL, et4000_out, NULL, NULL, dev); + io_sethandler(0x0250, 8, + et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); + io_sethandler(0x0258, 2, + et4000_kasan_in, NULL, NULL, et4000_kasan_out, NULL, NULL, dev); + loadfont(KASAN_FONT_ROM_PATH, 6); + fn = KASAN_BIOS_ROM_PATH; + break; } dev->svga.ramdac = device_add(&sc1502x_ramdac_device); @@ -744,68 +741,61 @@ et4000_init(const device_t *info) dev->vram_mask = dev->vram_size - 1; rom_init(&dev->bios_rom, (char *) fn, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); dev->svga.translate_address = get_et4000_addr; - dev->svga.packed_chain4 = 1; + dev->svga.packed_chain4 = 1; - return(dev); + return (dev); } - static void et4000_close(void *priv) { - et4000_t *dev = (et4000_t *)priv; + et4000_t *dev = (et4000_t *) priv; svga_close(&dev->svga); free(dev); } - static void et4000_speed_changed(void *priv) { - et4000_t *dev = (et4000_t *)priv; + et4000_t *dev = (et4000_t *) priv; svga_recalctimings(&dev->svga); } - static void et4000_force_redraw(void *priv) { - et4000_t *dev = (et4000_t *)priv; + et4000_t *dev = (et4000_t *) priv; dev->svga.fullchange = changeframecount; } - static int et4000_available(void) { return rom_present(BIOS_ROM_PATH); } - static int et4000k_available(void) { - return rom_present(KOREAN_BIOS_ROM_PATH) && - rom_present(KOREAN_FONT_ROM_PATH); + return rom_present(KOREAN_BIOS_ROM_PATH) && rom_present(KOREAN_FONT_ROM_PATH); } static int et4000_kasan_available(void) { - return rom_present(KASAN_BIOS_ROM_PATH) && - rom_present(KASAN_FONT_ROM_PATH); + return rom_present(KASAN_BIOS_ROM_PATH) && rom_present(KASAN_FONT_ROM_PATH); } static const device_config_t et4000_config[] = { -// clang-format off + // clang-format off { .name = "memory", .description = "Memory size", @@ -836,71 +826,71 @@ static const device_config_t et4000_config[] = { }; const device_t et4000_isa_device = { - .name = "Tseng Labs ET4000AX (ISA)", + .name = "Tseng Labs ET4000AX (ISA)", .internal_name = "et4000ax", - .flags = DEVICE_ISA, - .local = 0, - .init = et4000_init, - .close = et4000_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = ET4000_TYPE_ISA, + .init = et4000_init, + .close = et4000_close, + .reset = NULL, { .available = et4000_available }, .speed_changed = et4000_speed_changed, - .force_redraw = et4000_force_redraw, - .config = et4000_config + .force_redraw = et4000_force_redraw, + .config = et4000_config }; const device_t et4000_mca_device = { - .name = "Tseng Labs ET4000AX (MCA)", + .name = "Tseng Labs ET4000AX (MCA)", .internal_name = "et4000mca", - .flags = DEVICE_MCA, - .local = 1, - .init = et4000_init, - .close = et4000_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = ET4000_TYPE_MCA, + .init = et4000_init, + .close = et4000_close, + .reset = NULL, { .available = et4000_available }, .speed_changed = et4000_speed_changed, - .force_redraw = et4000_force_redraw, - .config = et4000_config + .force_redraw = et4000_force_redraw, + .config = et4000_config }; const device_t et4000k_isa_device = { - .name = "Trigem Korean VGA (Tseng Labs ET4000AX Korean)", + .name = "Trigem Korean VGA (Tseng Labs ET4000AX Korean)", .internal_name = "tgkorvga", - .flags = DEVICE_ISA, - .local = 2, - .init = et4000_init, - .close = et4000_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = ET4000_TYPE_KOREAN, + .init = et4000_init, + .close = et4000_close, + .reset = NULL, { .available = et4000k_available }, .speed_changed = et4000_speed_changed, - .force_redraw = et4000_force_redraw, - .config = et4000_config + .force_redraw = et4000_force_redraw, + .config = et4000_config }; const device_t et4000k_tg286_isa_device = { - .name = "Trigem Korean VGA (Trigem 286M)", + .name = "Trigem Korean VGA (Trigem 286M)", .internal_name = "et4000k_tg286_isa", - .flags = DEVICE_ISA, - .local = 3, - .init = et4000_init, - .close = et4000_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = ET4000_TYPE_TRIGEM, + .init = et4000_init, + .close = et4000_close, + .reset = NULL, { .available = et4000k_available }, .speed_changed = et4000_speed_changed, - .force_redraw = et4000_force_redraw, - .config = et4000_config + .force_redraw = et4000_force_redraw, + .config = et4000_config }; const device_t et4000_kasan_isa_device = { - .name = "Kasan Hangulmadang-16 VGA (Tseng Labs ET4000AX Korean)", + .name = "Kasan Hangulmadang-16 VGA (Tseng Labs ET4000AX Korean)", .internal_name = "kasan16vga", - .flags = DEVICE_ISA, - .local = 4, - .init = et4000_init, - .close = et4000_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = ET4000_TYPE_KASAN, + .init = et4000_init, + .close = et4000_close, + .reset = NULL, { .available = et4000_kasan_available }, .speed_changed = et4000_speed_changed, - .force_redraw = et4000_force_redraw, - .config = et4000_config + .force_redraw = et4000_force_redraw, + .config = et4000_config }; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 5a897fcc1..7e97fe543 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -37,752 +37,788 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#define BIOS_ROM_PATH_DIAMOND "roms/video/et4000w32/et4000w32.bin" +#define BIOS_ROM_PATH_CARDEX "roms/video/et4000w32/cardex.vbi" +#define BIOS_ROM_PATH_W32 "roms/video/et4000w32/ET4000W32VLB_bios_MX27C512.BIN" +#define BIOS_ROM_PATH_W32I_ISA "roms/video/et4000w32/ET4KW32I.VBI" +#define BIOS_ROM_PATH_W32I_VLB "roms/video/et4000w32/tseng.u41.bin" +#define BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.BIN" +#define BIOS_ROM_PATH_W32P "roms/video/et4000w32/ET4K_W32.BIN" +#define BIOS_ROM_PATH_W32P_REVC "roms/video/et4000w32/et4000w32pcardex.BIN" -#define BIOS_ROM_PATH_DIAMOND "roms/video/et4000w32/et4000w32.bin" -#define BIOS_ROM_PATH_CARDEX "roms/video/et4000w32/cardex.vbi" -#define BIOS_ROM_PATH_W32 "roms/video/et4000w32/ET4000W32VLB_bios_MX27C512.BIN" -#define BIOS_ROM_PATH_W32I_ISA "roms/video/et4000w32/ET4KW32I.VBI" -#define BIOS_ROM_PATH_W32I_VLB "roms/video/et4000w32/tseng.u41.bin" -#define BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB "roms/video/et4000w32/VideoMagic-BioS-HXIRTW32PWSRL.BIN" -#define BIOS_ROM_PATH_W32P "roms/video/et4000w32/ET4K_W32.BIN" -#define BIOS_ROM_PATH_W32P_REVC "roms/video/et4000w32/et4000w32pcardex.BIN" +#define ACL_WRST 1 +#define ACL_RDST 2 +#define ACL_XYST 4 +#define ACL_SSO 8 - -#define ACL_WRST 1 -#define ACL_RDST 2 -#define ACL_XYST 4 -#define ACL_SSO 8 - - -enum -{ +enum { ET4000W32, ET4000W32I, ET4000W32P_REVC, - ET4000W32P_VIDEOMAGIC_REVB, + ET4000W32P_VIDEOMAGIC_REVB, ET4000W32P, ET4000W32P_CARDEX, ET4000W32P_DIAMOND }; +typedef struct et4000w32p_t { + mem_mapping_t linear_mapping; + mem_mapping_t mmu_mapping; -typedef struct et4000w32p_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmu_mapping; + rom_t bios_rom; - rom_t bios_rom; + svga_t svga; - svga_t svga; + uint8_t banking, banking2, adjust_cursor, rev; - uint8_t banking, banking2, adjust_cursor, rev; + uint8_t regs[256], pci_regs[256]; - uint8_t regs[256], pci_regs[256]; + int index, vlb, pci, interleaved, + bank, type; - int index, vlb, pci, interleaved, - bank, type; - - uint32_t linearbase; - uint32_t vram_mask; + uint32_t linearbase; + uint32_t vram_mask; /* Accelerator */ struct { - struct { - uint8_t vbus, pixel_depth, xy_dir, pattern_wrap, - source_wrap, ctrl_routing, ctrl_reload, rop_fg, - rop_bg; + struct { + uint8_t vbus, pixel_depth, xy_dir, pattern_wrap, + source_wrap, ctrl_routing, ctrl_reload, rop_fg, + rop_bg; - uint16_t pattern_off, source_off, dest_off, mix_off, - count_x,count_y, pos_x, pos_y, - error, dmin, dmaj; + uint16_t pattern_off, source_off, dest_off, mix_off, + count_x, count_y, pos_x, pos_y, + error, dmin, dmaj; - uint32_t pattern_addr, source_addr, dest_addr, mix_addr; - } queued, internal; + uint32_t pattern_addr, source_addr, dest_addr, mix_addr; + } queued, internal; - uint8_t suspend_terminate, osr; - uint8_t status; - uint16_t x_count, y_count; + uint8_t suspend_terminate, osr; + uint8_t status; + uint16_t x_count, y_count; - int pattern_x, source_x, pattern_x_back, source_x_back, - pattern_y, source_y, cpu_dat_pos, pix_pos, - cpu_input_num, fifo_queue; - int pattern_x_diff, pattern_y_diff, pattern_x_diff2, pattern_y_diff2; - int patcnt, mmu_start; + int pattern_x, source_x, pattern_x_back, source_x_back, + pattern_y, source_y, cpu_dat_pos, pix_pos, + cpu_input_num, fifo_queue; + int pattern_x_diff, pattern_y_diff, pattern_x_diff2, pattern_y_diff2; + int patcnt, mmu_start; - uint32_t pattern_addr, source_addr, dest_addr, mix_addr, - pattern_back, source_back, dest_back, mix_back, - cpu_input; + uint32_t pattern_addr, source_addr, dest_addr, mix_addr, + pattern_back, source_back, dest_back, mix_back, + cpu_input; - uint64_t cpu_dat; + uint64_t cpu_dat; } acl; struct { - uint32_t base[3]; - uint8_t ctrl; + uint32_t base[3]; + uint8_t ctrl; } mmu; - volatile int busy; + volatile int busy; } et4000w32p_t; +static int et4000w32_vbus[4] = { 1, 2, 4, 4 }; -static int et4000w32_vbus[4] = {1, 2, 4, 4}; +static int et4000w32_max_x[8] = { 0, 0, 4, 8, 0x10, 0x20, 0x40, 0x70000000 }; +static int et4000w32_wrap_x[8] = { 0, 0, 3, 7, 0x0F, 0x1F, 0x3F, ~0 }; +static int et4000w32_wrap_y[8] = { 1, 2, 4, 8, ~0, ~0, ~0, ~0 }; -static int et4000w32_max_x[8] = {0,0,4,8,0x10,0x20,0x40,0x70000000}; -static int et4000w32_wrap_x[8] = {0,0,3,7,0x0F,0x1F,0x3F,~0}; -static int et4000w32_wrap_y[8] = {1,2,4,8,~0,~0,~0,~0}; +static video_timings_t timing_et4000w32_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; +static video_timings_t timing_et4000w32_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; +static video_timings_t timing_et4000w32_isa = { .type = VIDEO_ISA, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; -static video_timings_t timing_et4000w32_vlb = {VIDEO_BUS, 4, 4, 4, 10, 10, 10}; -static video_timings_t timing_et4000w32_pci = {VIDEO_PCI, 4, 4, 4, 10, 10, 10}; -static video_timings_t timing_et4000w32_isa = {VIDEO_ISA, 4, 4, 4, 10, 10, 10}; +void et4000w32p_recalcmapping(et4000w32p_t *et4000); +static uint8_t et4000w32p_mmu_read(uint32_t addr, void *p); +static void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p); -void et4000w32p_recalcmapping(et4000w32p_t *et4000); - -static uint8_t et4000w32p_mmu_read(uint32_t addr, void *p); -static void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p); - -static void et4000w32_blit_start(et4000w32p_t *et4000); -static void et4000w32p_blit_start(et4000w32p_t *et4000); -static void et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4000w32p_t *et4000); -static void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); -uint8_t et4000w32p_in(uint16_t addr, void *p); - +static void et4000w32_blit_start(et4000w32p_t *et4000); +static void et4000w32p_blit_start(et4000w32p_t *et4000); +static void et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4000w32p_t *et4000); +static void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000); +uint8_t et4000w32p_in(uint16_t addr, void *p); #ifdef ENABLE_ET4000W32_LOG int et4000w32_do_log = ENABLE_ET4000W32_LOG; - static void et4000w32_log(const char *fmt, ...) { va_list ap; if (et4000w32_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define et4000w32_log(fmt, ...) +# define et4000w32_log(fmt, ...) #endif - void et4000w32p_out(uint16_t addr, uint8_t val, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - uint8_t old; - uint32_t add2addr = 0; + et4000w32p_t *et4000 = (et4000w32p_t *) p; + svga_t *svga = &et4000->svga; + uint8_t old; + uint32_t add2addr = 0; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x3c2: - if (et4000->type == ET4000W32P_DIAMOND) - icd2061_write(svga->clock_gen, (val >> 2) & 3); - break; + case 0x3c2: + if (et4000->type == ET4000W32P_DIAMOND) + icd2061_write(svga->clock_gen, (val >> 2) & 3); + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (et4000->type <= ET4000W32P_REVC) - sdac_ramdac_out(addr, 0, val, svga->ramdac, svga); - else - stg_ramdac_out(addr, val, svga->ramdac, svga); - return; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (et4000->type <= ET4000W32P_REVC) + sdac_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + stg_ramdac_out(addr, val, svga->ramdac, svga); + return; - case 0x3cb: /* Banking extension */ - if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { - svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20); - svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16); - } - et4000->banking2 = val; - return; - case 0x3cd: /* Banking */ - if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { - svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536); - svga->read_bank = (svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536); - } - et4000->banking = val; - return; - case 0x3cf: - switch (svga->gdcaddr & 15) { - case 6: - if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { - svga->write_bank = ((et4000->banking2 & 1) << 20) | ((et4000->banking & 0xf) * 65536); - svga->read_bank = ((et4000->banking2 & 0x10) << 16) | (((et4000->banking >> 4) & 0xf) * 65536); - } else - svga->write_bank = svga->read_bank = 0; + case 0x3cb: /* Banking extension */ + if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { + svga->write_bank = (svga->write_bank & 0xfffff) | ((val & 1) << 20); + svga->read_bank = (svga->read_bank & 0xfffff) | ((val & 0x10) << 16); + } + et4000->banking2 = val; + return; + case 0x3cd: /* Banking */ + if (!(svga->crtc[0x36] & 0x10) && !(svga->gdcreg[6] & 0x08)) { + svga->write_bank = (svga->write_bank & 0x100000) | ((val & 0xf) * 65536); + svga->read_bank = (svga->read_bank & 0x100000) | (((val >> 4) & 0xf) * 65536); + } + et4000->banking = val; + return; + case 0x3cf: + switch (svga->gdcaddr & 15) { + case 6: + if (!(svga->crtc[0x36] & 0x10) && !(val & 0x08)) { + svga->write_bank = ((et4000->banking2 & 1) << 20) | ((et4000->banking & 0xf) * 65536); + svga->read_bank = ((et4000->banking2 & 0x10) << 16) | (((et4000->banking >> 4) & 0xf) * 65536); + } else + svga->write_bank = svga->read_bank = 0; - svga->gdcreg[svga->gdcaddr & 15] = val; - et4000w32p_recalcmapping(et4000); - return; - } - break; - case 0x3d4: - svga->crtcreg = val & 0x3f; - return; - case 0x3d5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 0x35) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (svga->crtcreg == 0x36) { - if (!(val & 0x10) && !(svga->gdcreg[6] & 0x08)) { - svga->write_bank = ((et4000->banking2 & 1) << 20) | ((et4000->banking & 0xf) * 65536); - svga->read_bank = ((et4000->banking2 & 0x10) << 16) | (((et4000->banking >> 4) & 0xf) * 65536); - } else - svga->write_bank = svga->read_bank = 0; - } - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - if (svga->crtcreg == 0x30) { - if (et4000->pci && (et4000->rev != 5)) - et4000->linearbase = (et4000->linearbase & 0xc0000000) | ((val & 0xfc) << 22); - else - et4000->linearbase = val << 22; - et4000w32p_recalcmapping(et4000); - } - if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) - et4000w32p_recalcmapping(et4000); - break; + svga->gdcreg[svga->gdcaddr & 15] = val; + et4000w32p_recalcmapping(et4000); + return; + } + break; + case 0x3d4: + svga->crtcreg = val & 0x3f; + return; + case 0x3d5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 0x35) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (svga->crtcreg == 0x36) { + if (!(val & 0x10) && !(svga->gdcreg[6] & 0x08)) { + svga->write_bank = ((et4000->banking2 & 1) << 20) | ((et4000->banking & 0xf) * 65536); + svga->read_bank = ((et4000->banking2 & 0x10) << 16) | (((et4000->banking >> 4) & 0xf) * 65536); + } else + svga->write_bank = svga->read_bank = 0; + } + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + if (svga->crtcreg == 0x30) { + if (et4000->pci && (et4000->rev != 5)) + et4000->linearbase = (et4000->linearbase & 0xc0000000) | ((val & 0xfc) << 22); + else + et4000->linearbase = val << 22; + et4000w32p_recalcmapping(et4000); + } + if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) + et4000w32p_recalcmapping(et4000); + break; - case 0x210a: case 0x211a: case 0x212a: case 0x213a: - case 0x214a: case 0x215a: case 0x216a: case 0x217a: - et4000->index = val; - return; - case 0x210b: case 0x211b: case 0x212b: case 0x213b: - case 0x214b: case 0x215b: case 0x216b: case 0x217b: - et4000->regs[et4000->index] = val; - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || (et4000->type == ET4000W32)) ? 128 : 64; - svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); - svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); - svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); - svga->hwcursor.xoff = et4000->regs[0xE2]; - svga->hwcursor.yoff = et4000->regs[0xE6]; + case 0x210a: + case 0x211a: + case 0x212a: + case 0x213a: + case 0x214a: + case 0x215a: + case 0x216a: + case 0x217a: + et4000->index = val; + return; + case 0x210b: + case 0x211b: + case 0x212b: + case 0x213b: + case 0x214b: + case 0x215b: + case 0x216b: + case 0x217b: + et4000->regs[et4000->index] = val; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || (et4000->type == ET4000W32)) ? 128 : 64; + svga->hwcursor.x = et4000->regs[0xE0] | ((et4000->regs[0xE1] & 7) << 8); + svga->hwcursor.y = et4000->regs[0xE4] | ((et4000->regs[0xE5] & 7) << 8); + svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); + svga->hwcursor.xoff = et4000->regs[0xE2]; + svga->hwcursor.yoff = et4000->regs[0xE6]; - if (et4000->type == ET4000W32) { - switch (svga->bpp) { - case 8: - svga->hwcursor.xoff += 32; - break; - } - } + if (et4000->type == ET4000W32) { + switch (svga->bpp) { + case 8: + svga->hwcursor.xoff += 32; + break; + } + } - if (svga->hwcursor.cur_xsize == 128) { - svga->hwcursor.xoff &= 0x7f; - svga->hwcursor.yoff &= 0x7f; - if (et4000->type > ET4000W32P_REVC) { - if (svga->bpp == 24) { - et4000->adjust_cursor = 2; - } - } - } else { - if (et4000->type > ET4000W32P_REVC) { - if (svga->bpp == 24 && et4000->adjust_cursor) { - et4000->adjust_cursor = 0; - } - } - svga->hwcursor.xoff &= 0x3f; - svga->hwcursor.yoff &= 0x3f; - } - svga->hwcursor.addr = (et4000->regs[0xe8] | (et4000->regs[0xe9] << 8) | ((et4000->regs[0xea] & 7) << 16)) << 2; + if (svga->hwcursor.cur_xsize == 128) { + svga->hwcursor.xoff &= 0x7f; + svga->hwcursor.yoff &= 0x7f; + if (et4000->type > ET4000W32P_REVC) { + if (svga->bpp == 24) { + et4000->adjust_cursor = 2; + } + } + } else { + if (et4000->type > ET4000W32P_REVC) { + if (svga->bpp == 24 && et4000->adjust_cursor) { + et4000->adjust_cursor = 0; + } + } + svga->hwcursor.xoff &= 0x3f; + svga->hwcursor.yoff &= 0x3f; + } + svga->hwcursor.addr = (et4000->regs[0xe8] | (et4000->regs[0xe9] << 8) | ((et4000->regs[0xea] & 7) << 16)) << 2; - add2addr = svga->hwcursor.yoff * ((svga->hwcursor.cur_xsize == 128) ? 32 : 16); - svga->hwcursor.addr += add2addr; - return; + add2addr = svga->hwcursor.yoff * ((svga->hwcursor.cur_xsize == 128) ? 32 : 16); + svga->hwcursor.addr += add2addr; + return; } svga_out(addr, val, svga); } - uint8_t et4000w32p_in(uint16_t addr, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; + et4000w32p_t *et4000 = (et4000w32p_t *) p; + svga_t *svga = &et4000->svga; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x3c5: - if ((svga->seqaddr & 0xf) == 7) - return svga->seqregs[svga->seqaddr & 0xf] | 4; - break; + case 0x3c5: + if ((svga->seqaddr & 0xf) == 7) + return svga->seqregs[svga->seqaddr & 0xf] | 4; + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (et4000->type <= ET4000W32P_REVC) - return sdac_ramdac_in(addr, 0, svga->ramdac, svga); - else - return stg_ramdac_in(addr, svga->ramdac, svga); - break; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (et4000->type <= ET4000W32P_REVC) + return sdac_ramdac_in(addr, 0, svga->ramdac, svga); + else + return stg_ramdac_in(addr, svga->ramdac, svga); + break; - case 0x3cb: - return et4000->banking2; - case 0x3cd: - return et4000->banking; - case 0x3d4: - return svga->crtcreg; - case 0x3d5: - if (et4000->type == ET4000W32) { - if (svga->crtcreg == 0x37) - return 0x09; - } - return svga->crtc[svga->crtcreg]; + case 0x3cb: + return et4000->banking2; + case 0x3cd: + return et4000->banking; + case 0x3d4: + return svga->crtcreg; + case 0x3d5: + if (et4000->type == ET4000W32) { + if (svga->crtcreg == 0x37) + return 0x09; + } + return svga->crtc[svga->crtcreg]; - case 0x3da: - svga->attrff = 0; + case 0x3da: + svga->attrff = 0; - /*Bit 1 of the Input Status Register is required by the OS/2 and NT ET4000W32/I drivers to be set otherwise - the guest will loop infinitely upon reaching the GUI*/ - if (svga->cgastat & 0x01) - svga->cgastat &= ~0x32; - else - svga->cgastat ^= 0x32; - return svga->cgastat; + /*Bit 1 of the Input Status Register is required by the OS/2 and NT ET4000W32/I drivers to be set otherwise + the guest will loop infinitely upon reaching the GUI*/ + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x32; + else + svga->cgastat ^= 0x32; + return svga->cgastat; - case 0x210a: case 0x211a: case 0x212a: case 0x213a: - case 0x214a: case 0x215a: case 0x216a: case 0x217a: - return et4000->index; - case 0x210B: case 0x211B: case 0x212B: case 0x213B: - case 0x214B: case 0x215B: case 0x216B: case 0x217B: - if (et4000->index == 0xec) { - return (et4000->regs[0xec] & 0xf) | (et4000->rev << 4); - } - if (et4000->index == 0xee) { - if (svga->bpp == 8) { - if ((svga->gdcreg[5] & 0x60) >= 0x40) - return 3; - else if ((svga->gdcreg[5] & 0x60) == 0x20) - return 1; - else - return 2; - } else if (svga->bpp == 15 || svga->bpp == 16) - return 4; - else - break; - } - if (et4000->index == 0xef) { - if (et4000->pci) - return (et4000->regs[0xef] & 0x0f) | (et4000->rev << 4) | et4000->pci; - else - return (et4000->regs[0xef] & 0x8f) | (et4000->rev << 4) | et4000->vlb; - } - return et4000->regs[et4000->index]; + case 0x210a: + case 0x211a: + case 0x212a: + case 0x213a: + case 0x214a: + case 0x215a: + case 0x216a: + case 0x217a: + return et4000->index; + case 0x210B: + case 0x211B: + case 0x212B: + case 0x213B: + case 0x214B: + case 0x215B: + case 0x216B: + case 0x217B: + if (et4000->index == 0xec) { + return (et4000->regs[0xec] & 0xf) | (et4000->rev << 4); + } + if (et4000->index == 0xee) { + if (svga->bpp == 8) { + if ((svga->gdcreg[5] & 0x60) >= 0x40) + return 3; + else if ((svga->gdcreg[5] & 0x60) == 0x20) + return 1; + else + return 2; + } else if (svga->bpp == 15 || svga->bpp == 16) + return 4; + else + break; + } + if (et4000->index == 0xef) { + if (et4000->pci) + return (et4000->regs[0xef] & 0x0f) | (et4000->rev << 4) | et4000->pci; + else + return (et4000->regs[0xef] & 0x8f) | (et4000->rev << 4) | et4000->vlb; + } + return et4000->regs[et4000->index]; } return svga_in(addr, svga); } - void et4000w32p_recalctimings(svga_t *svga) { - et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; + et4000w32p_t *et4000 = (et4000w32p_t *) svga->p; svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; - if (svga->crtc[0x35] & 0x01) svga->vblankstart += 0x400; - if (svga->crtc[0x35] & 0x02) svga->vtotal += 0x400; - if (svga->crtc[0x35] & 0x04) svga->dispend += 0x400; - if (svga->crtc[0x35] & 0x08) svga->vsyncstart += 0x400; - if (svga->crtc[0x35] & 0x10) svga->split += 0x400; - if (svga->crtc[0x3F] & 0x80) svga->rowoffset += 0x100; - if (svga->crtc[0x3F] & 0x01) svga->htotal += 256; - if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; + if (svga->crtc[0x35] & 0x01) + svga->vblankstart += 0x400; + if (svga->crtc[0x35] & 0x02) + svga->vtotal += 0x400; + if (svga->crtc[0x35] & 0x04) + svga->dispend += 0x400; + if (svga->crtc[0x35] & 0x08) + svga->vsyncstart += 0x400; + if (svga->crtc[0x35] & 0x10) + svga->split += 0x400; + if (svga->crtc[0x3F] & 0x80) + svga->rowoffset += 0x100; + if (svga->crtc[0x3F] & 0x01) + svga->htotal += 256; + if (svga->attrregs[0x16] & 0x20) + svga->hdisp <<= 1; - svga->clock = (cpuclock * (double)(1ull << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); + svga->clock = (cpuclock * (double) (1ull << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen); - if (et4000->type != ET4000W32P_DIAMOND) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->gdcreg[5] & 0x40) { - switch (svga->bpp) { - case 8: - svga->clock /= 2; - break; - case 15: case 16: - svga->clock /= 3; - break; - case 24: - svga->clock /= 4; - break; - } - } - } - } - - if (svga->adv_flags & FLAG_NOSKEW) { - /* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */ - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ - svga->ma_latch--; - - if ((svga->seqregs[1] & 8)) /*40 column*/ - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - } else { - /* Also adjust the graphics mode clocks in some cases. */ - if ((svga->gdcreg[5] & 0x40) && (svga->bpp != 32)) { - if ((svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24)) - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - else - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - } else if ((svga->gdcreg[5] & 0x40) == 0) { - svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; - if (svga->hdisp == 648 || svga->hdisp == 808 || svga->hdisp == 1032) - svga->hdisp -= 8; - } - } + if (et4000->type != ET4000W32P_DIAMOND) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (svga->gdcreg[5] & 0x40) { + switch (svga->bpp) { + case 8: + svga->clock /= 2; + break; + case 15: + case 16: + svga->clock /= 3; + break; + case 24: + svga->clock /= 4; + break; + } + } + } } - if (et4000->type == ET4000W32) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->gdcreg[5] & 0x40) { - switch (svga->bpp) { - case 8: - if (svga->hdisp == 640 || svga->hdisp == 800 || svga->hdisp == 1024) - break; - svga->hdisp -= 24; - break; - } - } - } - } + if (svga->adv_flags & FLAG_NOSKEW) { + /* On the Cardex ET4000/W32p-based cards, adjust text mode clocks by 1. */ + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ + svga->ma_latch--; + + if ((svga->seqregs[1] & 8)) /*40 column*/ + svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; + else + svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; + } else { + /* Also adjust the graphics mode clocks in some cases. */ + if ((svga->gdcreg[5] & 0x40) && (svga->bpp != 32)) { + if ((svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24)) + svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; + else + svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; + } else if ((svga->gdcreg[5] & 0x40) == 0) { + svga->hdisp += (svga->seqregs[1] & 1) ? 8 : 9; + if (svga->hdisp == 648 || svga->hdisp == 808 || svga->hdisp == 1032) + svga->hdisp -= 8; + } + } + } + + if (et4000->type == ET4000W32) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (svga->gdcreg[5] & 0x40) { + switch (svga->bpp) { + case 8: + if (svga->hdisp == 640 || svga->hdisp == 800 || svga->hdisp == 1024) + break; + svga->hdisp -= 24; + break; + } + } + } + } et4000->adjust_cursor = 0; - switch (svga->bpp) { - case 15: case 16: - svga->hdisp >>= 1; - if (et4000->type <= ET4000W32P_REVC) { - if (et4000->type == ET4000W32P_REVC) { - if (svga->hdisp != 1024) - et4000->adjust_cursor = 1; - } else - et4000->adjust_cursor = 1; - } - break; - case 24: - svga->hdisp /= 3; - if (et4000->type <= ET4000W32P_REVC) - et4000->adjust_cursor = 2; - if (et4000->type == ET4000W32P_DIAMOND && (svga->hdisp == 640/2 || svga->hdisp == 1232)) { - svga->hdisp = 640; - } - break; - } + switch (svga->bpp) { + case 15: + case 16: + svga->hdisp >>= 1; + if (et4000->type <= ET4000W32P_REVC) { + if (et4000->type == ET4000W32P_REVC) { + if (svga->hdisp != 1024) + et4000->adjust_cursor = 1; + } else + et4000->adjust_cursor = 1; + } + break; + case 24: + svga->hdisp /= 3; + if (et4000->type <= ET4000W32P_REVC) + et4000->adjust_cursor = 2; + if (et4000->type == ET4000W32P_DIAMOND && (svga->hdisp == 640 / 2 || svga->hdisp == 1232)) { + svga->hdisp = 640; + } + break; + } svga->render = svga_render_blank; 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 */ - svga->render = svga_render_text_40; - else - svga->render = svga_render_text_80; - } else { - if (svga->adv_flags & FLAG_NOSKEW) { - svga->ma_latch--; - } + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */ + if (svga->seqregs[1] & 8) /* 40 column */ + svga->render = svga_render_text_40; + else + svga->render = svga_render_text_80; + } else { + if (svga->adv_flags & FLAG_NOSKEW) { + svga->ma_latch--; + } - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (et4000->rev == 5) - svga->ma_latch++; + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (et4000->rev == 5) + svga->ma_latch++; - if (svga->seqregs[1] & 8) /* Low res (320) */ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /* 4 colours */ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: case 0x60: /* 256+ colours */ - if (et4000->type <= ET4000W32P_REVC) - svga->clock /= 2; + if (svga->seqregs[1] & 8) /* Low res (320) */ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /* 4 colours */ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /* 256+ colours */ + if (et4000->type <= ET4000W32P_REVC) + svga->clock /= 2; - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 17: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_15bpp_mix_lowres; - else - svga->render = svga_render_15bpp_mix_highres; - break; - case 24: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres || (svga->seqregs[1] & 8)) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - } - break; - } - } + switch (svga->bpp) { + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; + case 15: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_15bpp_lowres; + else + svga->render = svga_render_15bpp_highres; + break; + case 16: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; + case 17: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_15bpp_mix_lowres; + else + svga->render = svga_render_15bpp_mix_highres; + break; + case 24: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; + case 32: + if (svga->lowres || (svga->seqregs[1] & 8)) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + break; + } + break; + } + } } } - void et4000w32p_recalcmapping(et4000w32p_t *et4000) { svga_t *svga = &et4000->svga; - int map; + int map; if (et4000->pci && !(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&et4000->linear_mapping); - mem_mapping_disable(&et4000->mmu_mapping); - return; + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&et4000->linear_mapping); + mem_mapping_disable(&et4000->mmu_mapping); + return; } - if (svga->crtc[0x36] & 0x10) { /* Linear frame buffer */ - mem_mapping_set_addr(&et4000->linear_mapping, et4000->linearbase, 0x200000); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&et4000->mmu_mapping); + if (svga->crtc[0x36] & 0x10) { /* Linear frame buffer */ + mem_mapping_set_addr(&et4000->linear_mapping, et4000->linearbase, 0x200000); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&et4000->mmu_mapping); } else { - map = (svga->gdcreg[6] & 0xc) >> 2; - if (svga->crtc[0x36] & 0x20) map |= 4; - if (svga->crtc[0x36] & 0x08) map |= 8; - mem_mapping_disable(&et4000->linear_mapping); - switch (map) { - case 0x0: case 0x4: case 0x8: case 0xc: /* 128k at A0000 */ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x1ffff; - break; - case 0x1: /* 64k at A0000 */ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0xffff; - break; - case 0x2: /* 32k at B0000 */ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x7fff; - break; - case 0x3: /* 32k at B8000 */ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_disable(&et4000->mmu_mapping); - svga->banked_mask = 0x7fff; - break; - case 0x5: case 0x9: case 0xd: /* 64k at A0000, MMU at B8000 */ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000); - svga->banked_mask = 0xffff; - break; - case 0x6: case 0xa: case 0xe: /* 32k at B0000, MMU at A8000 */ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0x7: case 0xb: case 0xf: /* 32k at B8000, MMU at A8000 */ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + map = (svga->gdcreg[6] & 0xc) >> 2; + if (svga->crtc[0x36] & 0x20) + map |= 4; + if (svga->crtc[0x36] & 0x08) + map |= 8; + mem_mapping_disable(&et4000->linear_mapping); + switch (map) { + case 0x0: + case 0x4: + case 0x8: + case 0xc: /* 128k at A0000 */ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0x1ffff; + break; + case 0x1: /* 64k at A0000 */ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0xffff; + break; + case 0x2: /* 32k at B0000 */ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0x7fff; + break; + case 0x3: /* 32k at B8000 */ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_disable(&et4000->mmu_mapping); + svga->banked_mask = 0x7fff; + break; + case 0x5: + case 0x9: + case 0xd: /* 64k at A0000, MMU at B8000 */ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_set_addr(&et4000->mmu_mapping, 0xb8000, 0x08000); + svga->banked_mask = 0xffff; + break; + case 0x6: + case 0xa: + case 0xe: /* 32k at B0000, MMU at A8000 */ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0x7: + case 0xb: + case 0xf: /* 32k at B8000, MMU at A8000 */ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_set_addr(&et4000->mmu_mapping, 0xa8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } } if (!et4000->interleaved && (svga->crtc[0x32] & 0x80)) - mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&svga->mapping); } - static void et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val) { - et4000->acl.fifo_queue++; + et4000->acl.fifo_queue++; switch (addr & 0xff) { - case 0x80: - et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3fff00) | val; - break; - case 0x81: - et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3f00ff) | (val << 8); - break; - case 0x82: - et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00ffff) | ((val & 0x3f) << 16); - break; - case 0x84: - et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3fff00) | val; - break; - case 0x85: - et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3f00ff) | (val << 8); - break; - case 0x86: - et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00ffff) | ((val & 0x3f) << 16); - break; - case 0x88: - et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x0f00) | val; - break; - case 0x89: - et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00ff) | ((val & 0x0f) << 8); - break; - case 0x8a: - et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x0f00) | val; - break; - case 0x8b: - et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00ff) | ((val & 0x0f) << 8); - break; - case 0x8c: - et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x0f00) | val; - break; - case 0x8d: - et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | ((val & 0x0f) << 8); - break; - case 0x8e: - if (et4000->type >= ET4000W32P_REVC) - et4000->acl.queued.pixel_depth = val & 0x30; - else - et4000->acl.queued.vbus = val & 0x03; - break; - case 0x8f: - if (et4000->type >= ET4000W32P_REVC) - et4000->acl.queued.xy_dir = val & 0xb7; - else - et4000->acl.queued.xy_dir = val & 0x03; - break; - case 0x90: - et4000->acl.queued.pattern_wrap = val & 0x77; - break; - case 0x92: - et4000->acl.queued.source_wrap = val & 0x77; - break; - case 0x98: - et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x0f00) | val; - break; - case 0x99: - et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00ff) | ((val & 0x0f) << 8); - break; - case 0x9a: - et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x0f00) | val; - break; - case 0x9b: - et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | ((val & 0x0f) << 8); - break; - case 0x9c: - if (et4000->type >= ET4000W32P_REVC) - et4000->acl.queued.ctrl_routing = val & 0xdb; - else - et4000->acl.queued.ctrl_routing = val & 0xb7; - break; - case 0x9d: - et4000->acl.queued.ctrl_reload = val & 0x03; - break; - case 0x9e: - et4000->acl.queued.rop_bg = val; - break; - case 0x9f: - et4000->acl.queued.rop_fg = val; - break; - case 0xa0: - et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3fff00) | val; - break; - case 0xa1: - et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3f00ff) | (val << 8); - break; - case 0xa2: - et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffff) | ((val & 0x3f) << 16); - break; - case 0xa3: - et4000->acl.internal = et4000->acl.queued; - if (et4000->type >= ET4000W32P_REVC) { - et4000w32p_blit_start(et4000); - et4000w32_log("Destination Address write and start XY Block, xcnt = %i, ycnt = %i\n", et4000->acl.x_count + 1, et4000->acl.y_count + 1); - if (!(et4000->acl.queued.ctrl_routing & 0x43)) { - et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); - } - if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) { - et4000w32p_blit(4, ~0, 0, 0, et4000); - } - } else { - et4000w32_blit_start(et4000); - et4000->acl.cpu_input_num = 0; - if (!(et4000->acl.queued.ctrl_routing & 0x37)) { - et4000->acl.mmu_start = 0; - et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); - } - } - break; - case 0xa4: - et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; - break; - case 0xa5: - et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); - break; - case 0xa6: - et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); - break; - case 0xa7: - et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); - break; - case 0xa8: - et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; - break; - case 0xa9: - et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); - break; - case 0xaa: - et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; - break; - case 0xab: - et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); - break; - case 0xac: - et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; - break; - case 0xad: - et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); - break; - case 0xae: - et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; - break; - case 0xaf: - et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); - break; + case 0x80: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3fff00) | val; + break; + case 0x81: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3f00ff) | (val << 8); + break; + case 0x82: + et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x84: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3fff00) | val; + break; + case 0x85: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x3f00ff) | (val << 8); + break; + case 0x86: + et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x88: + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x0f00) | val; + break; + case 0x89: + et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x8a: + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x0f00) | val; + break; + case 0x8b: + et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x8c: + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x0f00) | val; + break; + case 0x8d: + et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x8e: + if (et4000->type >= ET4000W32P_REVC) + et4000->acl.queued.pixel_depth = val & 0x30; + else + et4000->acl.queued.vbus = val & 0x03; + break; + case 0x8f: + if (et4000->type >= ET4000W32P_REVC) + et4000->acl.queued.xy_dir = val & 0xb7; + else + et4000->acl.queued.xy_dir = val & 0x03; + break; + case 0x90: + et4000->acl.queued.pattern_wrap = val & 0x77; + break; + case 0x92: + et4000->acl.queued.source_wrap = val & 0x77; + break; + case 0x98: + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x0f00) | val; + break; + case 0x99: + et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x9a: + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x0f00) | val; + break; + case 0x9b: + et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00ff) | ((val & 0x0f) << 8); + break; + case 0x9c: + if (et4000->type >= ET4000W32P_REVC) + et4000->acl.queued.ctrl_routing = val & 0xdb; + else + et4000->acl.queued.ctrl_routing = val & 0xb7; + break; + case 0x9d: + et4000->acl.queued.ctrl_reload = val & 0x03; + break; + case 0x9e: + et4000->acl.queued.rop_bg = val; + break; + case 0x9f: + et4000->acl.queued.rop_fg = val; + break; + case 0xa0: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3fff00) | val; + break; + case 0xa1: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x3f00ff) | (val << 8); + break; + case 0xa2: + et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0xa3: + et4000->acl.internal = et4000->acl.queued; + if (et4000->type >= ET4000W32P_REVC) { + et4000w32p_blit_start(et4000); + et4000w32_log("Destination Address write and start XY Block, xcnt = %i, ycnt = %i\n", et4000->acl.x_count + 1, et4000->acl.y_count + 1); + if (!(et4000->acl.queued.ctrl_routing & 0x43)) { + et4000w32p_blit(0xffffff, ~0, 0, 0, et4000); + } + if ((et4000->acl.queued.ctrl_routing & 0x40) && !(et4000->acl.internal.ctrl_routing & 3)) { + et4000w32p_blit(4, ~0, 0, 0, et4000); + } + } else { + et4000w32_blit_start(et4000); + et4000->acl.cpu_input_num = 0; + if (!(et4000->acl.queued.ctrl_routing & 0x37)) { + et4000->acl.mmu_start = 0; + et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); + } + } + break; + case 0xa4: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; + break; + case 0xa5: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); + break; + case 0xa6: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); + break; + case 0xa7: + et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); + break; + case 0xa8: + et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; + break; + case 0xa9: + et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); + break; + case 0xaa: + et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; + break; + case 0xab: + et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); + break; + case 0xac: + et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; + break; + case 0xad: + et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); + break; + case 0xae: + et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; + break; + case 0xaf: + et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); + break; } } @@ -790,339 +826,351 @@ static void et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val, uint8_t bank) { if (et4000->type >= ET4000W32P_REVC) { - if (!(et4000->acl.status & ACL_XYST)) { - et4000w32_log("XY MMU block not started\n"); - return; - } - if (et4000->acl.internal.ctrl_routing & 3) { - et4000->acl.fifo_queue++; - if ((et4000->acl.internal.ctrl_routing & 3) == 2) /*CPU data is Mix data*/ - et4000w32p_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); - else if ((et4000->acl.internal.ctrl_routing & 3) == 1) /*CPU data is Source data*/ - et4000w32p_blit(1, ~0, val, 2, et4000); - } + if (!(et4000->acl.status & ACL_XYST)) { + et4000w32_log("XY MMU block not started\n"); + return; + } + if (et4000->acl.internal.ctrl_routing & 3) { + et4000->acl.fifo_queue++; + if ((et4000->acl.internal.ctrl_routing & 3) == 2) /*CPU data is Mix data*/ + et4000w32p_blit(8 - (et4000->acl.mix_addr & 7), val >> (et4000->acl.mix_addr & 7), 0, 1, et4000); + else if ((et4000->acl.internal.ctrl_routing & 3) == 1) /*CPU data is Source data*/ + et4000w32p_blit(1, ~0, val, 2, et4000); + } } else { - if (!(et4000->acl.status & ACL_XYST)) { - et4000->acl.fifo_queue++; - et4000->acl.queued.dest_addr = ((addr & 0x1fff) + et4000->mmu.base[bank]); - et4000->acl.internal = et4000->acl.queued; - et4000w32_blit_start(et4000); - et4000w32_log("ET4000W32 Accelerated MMU aperture start XY Block (Implicit): bank = %i, patx = %i, paty = %i, wrap y = %i\n", et4000->bank, et4000->acl.pattern_x, et4000->acl.pattern_y, et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]); - et4000->acl.cpu_input_num = 0; - if (!(et4000->acl.queued.ctrl_routing & 0x37)) { - et4000->acl.mmu_start = 1; - et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); - } - } + if (!(et4000->acl.status & ACL_XYST)) { + et4000->acl.fifo_queue++; + et4000->acl.queued.dest_addr = ((addr & 0x1fff) + et4000->mmu.base[bank]); + et4000->acl.internal = et4000->acl.queued; + et4000w32_blit_start(et4000); + et4000w32_log("ET4000W32 Accelerated MMU aperture start XY Block (Implicit): bank = %i, patx = %i, paty = %i, wrap y = %i\n", et4000->bank, et4000->acl.pattern_x, et4000->acl.pattern_y, et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]); + et4000->acl.cpu_input_num = 0; + if (!(et4000->acl.queued.ctrl_routing & 0x37)) { + et4000->acl.mmu_start = 1; + et4000w32_blit(-1, 0, 0, 0xffffffff, et4000); + } + } - if (et4000->acl.internal.ctrl_routing & 7) { - et4000->acl.fifo_queue++; - et4000->acl.cpu_input = (et4000->acl.cpu_input & ~(0xff << (et4000->acl.cpu_input_num << 3))) | - (val << (et4000->acl.cpu_input_num << 3)); - et4000->acl.cpu_input_num++; + if (et4000->acl.internal.ctrl_routing & 7) { + et4000->acl.fifo_queue++; + et4000->acl.cpu_input = (et4000->acl.cpu_input & ~(0xff << (et4000->acl.cpu_input_num << 3))) | (val << (et4000->acl.cpu_input_num << 3)); + et4000->acl.cpu_input_num++; - if (et4000->acl.cpu_input_num == et4000w32_vbus[et4000->acl.internal.vbus]) { - if ((et4000->acl.internal.ctrl_routing & 7) == 2) /*CPU data is Mix data*/ - et4000w32_blit(et4000->acl.cpu_input_num << 3, 2, 0, et4000->acl.cpu_input, et4000); - else if ((et4000->acl.internal.ctrl_routing & 7) == 1) /*CPU data is Source data*/ - et4000w32_blit(et4000->acl.cpu_input_num, 1, et4000->acl.cpu_input, 0xffffffff, et4000); + if (et4000->acl.cpu_input_num == et4000w32_vbus[et4000->acl.internal.vbus]) { + if ((et4000->acl.internal.ctrl_routing & 7) == 2) /*CPU data is Mix data*/ + et4000w32_blit(et4000->acl.cpu_input_num << 3, 2, 0, et4000->acl.cpu_input, et4000); + else if ((et4000->acl.internal.ctrl_routing & 7) == 1) /*CPU data is Source data*/ + et4000w32_blit(et4000->acl.cpu_input_num, 1, et4000->acl.cpu_input, 0xffffffff, et4000); - et4000->acl.cpu_input_num = 0; - } + et4000->acl.cpu_input_num = 0; + } - if ((et4000->acl.internal.ctrl_routing & 7) == 4) /*CPU data is X Count*/ - et4000w32_blit(val | (et4000->acl.queued.count_x << 8), 0, 0, 0xffffffff, et4000); - if ((et4000->acl.internal.ctrl_routing & 7) == 5) /*CPU data is Y Count*/ - et4000w32_blit(val | (et4000->acl.queued.count_y << 8), 0, 0, 0xffffffff, et4000); - } + if ((et4000->acl.internal.ctrl_routing & 7) == 4) /*CPU data is X Count*/ + et4000w32_blit(val | (et4000->acl.queued.count_x << 8), 0, 0, 0xffffffff, et4000); + if ((et4000->acl.internal.ctrl_routing & 7) == 5) /*CPU data is Y Count*/ + et4000w32_blit(val | (et4000->acl.queued.count_y << 8), 0, 0, 0xffffffff, et4000); + } } } static void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; + et4000w32p_t *et4000 = (et4000w32p_t *) p; + svga_t *svga = &et4000->svga; switch (addr & 0x6000) { - case 0x0000: /* MMU 0 */ - case 0x2000: /* MMU 1 */ - case 0x4000: /* MMU 2 */ - et4000->bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << et4000->bank)) { - et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val, et4000->bank); - } else { - if (((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) < svga->vram_max) { - svga->vram[((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) & et4000->vram_mask] = val; - svga->changedvram[(((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) & et4000->vram_mask) >> 12] = changeframecount; - } - } - break; - case 0x6000: - if ((addr & 0xff) >= 0x80) { - et4000w32p_accel_write_fifo(et4000, addr & 0x7fff, val); - } else { - switch (addr & 0xff) { - case 0x00: - et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3fff00) | val; - break; - case 0x01: - et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3f00ff) | (val << 8); - break; - case 0x02: - et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00ffff) | ((val & 0x3f) << 16); - break; - case 0x04: - et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3fff00) | val; - break; - case 0x05: - et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3f00ff) | (val << 8); - break; - case 0x06: - et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00ffff) | ((val & 0x3f) << 16); - break; - case 0x08: - et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3fff00) | val; - break; - case 0x09: - et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3f00ff) | (val << 8); - break; - case 0x0a: - et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00ffff) | ((val & 0x3f) << 16); - break; - case 0x13: - et4000->mmu.ctrl = val; - break; - case 0x30: - et4000->acl.suspend_terminate = val; - break; - case 0x31: - et4000->acl.osr = val; - break; - } - } - break; + case 0x0000: /* MMU 0 */ + case 0x2000: /* MMU 1 */ + case 0x4000: /* MMU 2 */ + et4000->bank = (addr >> 13) & 3; + if (et4000->mmu.ctrl & (1 << et4000->bank)) { + et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val, et4000->bank); + } else { + if (((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) < svga->vram_max) { + svga->vram[((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) & et4000->vram_mask] = val; + svga->changedvram[(((addr & 0x1fff) + et4000->mmu.base[et4000->bank]) & et4000->vram_mask) >> 12] = changeframecount; + } + } + break; + case 0x6000: + if ((addr & 0xff) >= 0x80) { + et4000w32p_accel_write_fifo(et4000, addr & 0x7fff, val); + } else { + switch (addr & 0xff) { + case 0x00: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3fff00) | val; + break; + case 0x01: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x3f00ff) | (val << 8); + break; + case 0x02: + et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x04: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3fff00) | val; + break; + case 0x05: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x3f00ff) | (val << 8); + break; + case 0x06: + et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x08: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3fff00) | val; + break; + case 0x09: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x3f00ff) | (val << 8); + break; + case 0x0a: + et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00ffff) | ((val & 0x3f) << 16); + break; + case 0x13: + et4000->mmu.ctrl = val; + break; + case 0x30: + et4000->acl.suspend_terminate = val; + break; + case 0x31: + et4000->acl.osr = val; + break; + } + } + break; } } static uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; - uint8_t temp; + et4000w32p_t *et4000 = (et4000w32p_t *) p; + svga_t *svga = &et4000->svga; + uint8_t temp; switch (addr & 0x6000) { - case 0x0000: /* MMU 0 */ - case 0x2000: /* MMU 1 */ - case 0x4000: /* MMU 2 */ - et4000->bank = (addr >> 13) & 3; - if (et4000->mmu.ctrl & (1 << et4000->bank)) { - temp = 0xff; - if (et4000->acl.cpu_dat_pos) { - et4000->acl.cpu_dat_pos--; - temp = et4000->acl.cpu_dat & 0xff; - et4000->acl.cpu_dat >>= 8; - } - if ((et4000->acl.queued.ctrl_routing & 0x40) && !et4000->acl.cpu_dat_pos && !(et4000->acl.internal.ctrl_routing & 3)) - et4000w32p_blit(4, ~0, 0, 0, et4000); + case 0x0000: /* MMU 0 */ + case 0x2000: /* MMU 1 */ + case 0x4000: /* MMU 2 */ + et4000->bank = (addr >> 13) & 3; + if (et4000->mmu.ctrl & (1 << et4000->bank)) { + temp = 0xff; + if (et4000->acl.cpu_dat_pos) { + et4000->acl.cpu_dat_pos--; + temp = et4000->acl.cpu_dat & 0xff; + et4000->acl.cpu_dat >>= 8; + } + if ((et4000->acl.queued.ctrl_routing & 0x40) && !et4000->acl.cpu_dat_pos && !(et4000->acl.internal.ctrl_routing & 3)) + et4000w32p_blit(4, ~0, 0, 0, et4000); - /* ???? */ - return temp; - } + /* ???? */ + return temp; + } - if ((addr & 0x1fff) + et4000->mmu.base[et4000->bank] >= svga->vram_max) - return 0xff; + if ((addr & 0x1fff) + et4000->mmu.base[et4000->bank] >= svga->vram_max) + return 0xff; - return svga->vram[(addr & 0x1fff) + et4000->mmu.base[et4000->bank]]; + return svga->vram[(addr & 0x1fff) + et4000->mmu.base[et4000->bank]]; - case 0x6000: - switch (addr & 0xff) { - case 0x00: - return et4000->mmu.base[0] & 0xff; - case 0x01: - return et4000->mmu.base[0] >> 8; - case 0x02: - return et4000->mmu.base[0] >> 16; - case 0x03: - return et4000->mmu.base[0] >> 24; - case 0x04: - return et4000->mmu.base[1] & 0xff; - case 0x05: - return et4000->mmu.base[1] >> 8; - case 0x06: - return et4000->mmu.base[1] >> 16; - case 0x07: - return et4000->mmu.base[1] >> 24; - case 0x08: - return et4000->mmu.base[2] & 0xff; - case 0x09: - return et4000->mmu.base[2] >> 8; - case 0x0a: - return et4000->mmu.base[2] >> 16; - case 0x0b: - return et4000->mmu.base[2] >> 24; - case 0x13: - return et4000->mmu.ctrl; + case 0x6000: + switch (addr & 0xff) { + case 0x00: + return et4000->mmu.base[0] & 0xff; + case 0x01: + return et4000->mmu.base[0] >> 8; + case 0x02: + return et4000->mmu.base[0] >> 16; + case 0x03: + return et4000->mmu.base[0] >> 24; + case 0x04: + return et4000->mmu.base[1] & 0xff; + case 0x05: + return et4000->mmu.base[1] >> 8; + case 0x06: + return et4000->mmu.base[1] >> 16; + case 0x07: + return et4000->mmu.base[1] >> 24; + case 0x08: + return et4000->mmu.base[2] & 0xff; + case 0x09: + return et4000->mmu.base[2] >> 8; + case 0x0a: + return et4000->mmu.base[2] >> 16; + case 0x0b: + return et4000->mmu.base[2] >> 24; + case 0x13: + return et4000->mmu.ctrl; - case 0x36: - if (et4000->acl.fifo_queue) { - et4000->acl.status |= ACL_RDST; - et4000->acl.fifo_queue = 0; - } else - et4000->acl.status &= ~ACL_RDST; - return et4000->acl.status; + case 0x36: + if (et4000->acl.fifo_queue) { + et4000->acl.status |= ACL_RDST; + et4000->acl.fifo_queue = 0; + } else + et4000->acl.status &= ~ACL_RDST; + return et4000->acl.status; - case 0x80: - return et4000->acl.internal.pattern_addr & 0xff; - case 0x81: - return et4000->acl.internal.pattern_addr >> 8; - case 0x82: - return et4000->acl.internal.pattern_addr >> 16; - case 0x83: - return et4000->acl.internal.pattern_addr >> 24; - case 0x84: - return et4000->acl.internal.source_addr & 0xff; - case 0x85: - return et4000->acl.internal.source_addr >> 8; - case 0x86: - return et4000->acl.internal.source_addr >> 16; - case 0x87: - return et4000->acl.internal.source_addr >> 24; - case 0x88: - return et4000->acl.internal.pattern_off & 0xff; - case 0x89: - return et4000->acl.internal.pattern_off >> 8; - case 0x8a: - return et4000->acl.internal.source_off & 0xff; - case 0x8b: - return et4000->acl.internal.source_off >> 8; - case 0x8c: - return et4000->acl.internal.dest_off & 0xff; - case 0x8d: - return et4000->acl.internal.dest_off >> 8; - case 0x8e: - if (et4000->type >= ET4000W32P_REVC) - return et4000->acl.internal.pixel_depth; - else - return et4000->acl.internal.vbus; - break; - case 0x8f: return et4000->acl.internal.xy_dir; - case 0x90: return et4000->acl.internal.pattern_wrap; - case 0x92: return et4000->acl.internal.source_wrap; - case 0x98: return et4000->acl.internal.count_x & 0xff; - case 0x99: return et4000->acl.internal.count_x >> 8; - case 0x9a: return et4000->acl.internal.count_y & 0xff; - case 0x9b: return et4000->acl.internal.count_y >> 8; - case 0x9c: return et4000->acl.internal.ctrl_routing; - case 0x9d: return et4000->acl.internal.ctrl_reload; - case 0x9e: return et4000->acl.internal.rop_bg; - case 0x9f: return et4000->acl.internal.rop_fg; - case 0xa0: return et4000->acl.internal.dest_addr & 0xff; - case 0xa1: return et4000->acl.internal.dest_addr >> 8; - case 0xa2: return et4000->acl.internal.dest_addr >> 16; - case 0xa3: return et4000->acl.internal.dest_addr >> 24; - } + case 0x80: + return et4000->acl.internal.pattern_addr & 0xff; + case 0x81: + return et4000->acl.internal.pattern_addr >> 8; + case 0x82: + return et4000->acl.internal.pattern_addr >> 16; + case 0x83: + return et4000->acl.internal.pattern_addr >> 24; + case 0x84: + return et4000->acl.internal.source_addr & 0xff; + case 0x85: + return et4000->acl.internal.source_addr >> 8; + case 0x86: + return et4000->acl.internal.source_addr >> 16; + case 0x87: + return et4000->acl.internal.source_addr >> 24; + case 0x88: + return et4000->acl.internal.pattern_off & 0xff; + case 0x89: + return et4000->acl.internal.pattern_off >> 8; + case 0x8a: + return et4000->acl.internal.source_off & 0xff; + case 0x8b: + return et4000->acl.internal.source_off >> 8; + case 0x8c: + return et4000->acl.internal.dest_off & 0xff; + case 0x8d: + return et4000->acl.internal.dest_off >> 8; + case 0x8e: + if (et4000->type >= ET4000W32P_REVC) + return et4000->acl.internal.pixel_depth; + else + return et4000->acl.internal.vbus; + break; + case 0x8f: + return et4000->acl.internal.xy_dir; + case 0x90: + return et4000->acl.internal.pattern_wrap; + case 0x92: + return et4000->acl.internal.source_wrap; + case 0x98: + return et4000->acl.internal.count_x & 0xff; + case 0x99: + return et4000->acl.internal.count_x >> 8; + case 0x9a: + return et4000->acl.internal.count_y & 0xff; + case 0x9b: + return et4000->acl.internal.count_y >> 8; + case 0x9c: + return et4000->acl.internal.ctrl_routing; + case 0x9d: + return et4000->acl.internal.ctrl_reload; + case 0x9e: + return et4000->acl.internal.rop_bg; + case 0x9f: + return et4000->acl.internal.rop_fg; + case 0xa0: + return et4000->acl.internal.dest_addr & 0xff; + case 0xa1: + return et4000->acl.internal.dest_addr >> 8; + case 0xa2: + return et4000->acl.internal.dest_addr >> 16; + case 0xa3: + return et4000->acl.internal.dest_addr >> 24; + } - return 0xff; + return 0xff; } return 0xff; } - void et4000w32_blit_start(et4000w32p_t *et4000) { - et4000->acl.x_count = et4000->acl.internal.count_x; - et4000->acl.y_count = et4000->acl.internal.count_y; + et4000->acl.x_count = et4000->acl.internal.count_x; + et4000->acl.y_count = et4000->acl.internal.count_y; - et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; - et4000->acl.source_addr = et4000->acl.internal.source_addr; - et4000->acl.dest_addr = et4000->acl.internal.dest_addr; - et4000->acl.dest_back = et4000->acl.dest_addr; + et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; + et4000->acl.source_addr = et4000->acl.internal.source_addr; + et4000->acl.dest_addr = et4000->acl.internal.dest_addr; + et4000->acl.dest_back = et4000->acl.dest_addr; et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; et4000->acl.status |= ACL_XYST; - et4000->acl.status &= ~ACL_SSO; + et4000->acl.status &= ~ACL_SSO; if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) - et4000->acl.status |= ACL_SSO; + et4000->acl.status |= ACL_SSO; if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) { - et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; - et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; + et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; + et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; } et4000->acl.pattern_back = et4000->acl.pattern_addr; if (!(et4000->acl.internal.pattern_wrap & 0x40)) { - if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ - et4000->acl.pattern_y = (et4000->acl.pattern_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); - } else - et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); - et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); + if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ + et4000->acl.pattern_y = (et4000->acl.pattern_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); + } else + et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); + et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); } et4000->acl.pattern_x_back = et4000->acl.pattern_x; if (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]) { - et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; - et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; } et4000->acl.source_back = et4000->acl.source_addr; if (!(et4000->acl.internal.source_wrap & 0x40)) { - if ((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ - et4000->acl.source_y = (et4000->acl.source_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); - } else - et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); - et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); + if ((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) == 0x00) { /*This is to avoid a division by zero crash*/ + et4000->acl.source_y = (et4000->acl.source_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); + } else + et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); + et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } et4000->acl.source_x_back = et4000->acl.source_x; } - static void et4000w32p_blit_start(et4000w32p_t *et4000) { - et4000->acl.x_count = et4000->acl.internal.count_x; - et4000->acl.y_count = et4000->acl.internal.count_y; + et4000->acl.x_count = et4000->acl.internal.count_x; + et4000->acl.y_count = et4000->acl.internal.count_y; if (!(et4000->acl.queued.xy_dir & 0x20)) - et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; - et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; - et4000->acl.source_addr = et4000->acl.internal.source_addr; - et4000->acl.mix_addr = et4000->acl.internal.mix_addr; - et4000->acl.mix_back = et4000->acl.mix_addr; - et4000->acl.dest_addr = et4000->acl.internal.dest_addr; - et4000->acl.dest_back = et4000->acl.dest_addr; - et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; - et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; + et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; + et4000->acl.pattern_addr = et4000->acl.internal.pattern_addr; + et4000->acl.source_addr = et4000->acl.internal.source_addr; + et4000->acl.mix_addr = et4000->acl.internal.mix_addr; + et4000->acl.mix_back = et4000->acl.mix_addr; + et4000->acl.dest_addr = et4000->acl.internal.dest_addr; + et4000->acl.dest_back = et4000->acl.dest_addr; + et4000->acl.internal.pos_x = et4000->acl.internal.pos_y = 0; + et4000->acl.pattern_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0; et4000->acl.status |= ACL_XYST; - et4000w32_log("ACL status XYST set\n"); + et4000w32_log("ACL status XYST set\n"); if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40)) - et4000->acl.status |= ACL_SSO; + et4000->acl.status |= ACL_SSO; if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) { - et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; - et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; + et4000->acl.pattern_x = et4000->acl.pattern_addr & et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; + et4000->acl.pattern_addr &= ~et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]; } et4000->acl.pattern_back = et4000->acl.pattern_addr; if (!(et4000->acl.internal.pattern_wrap & 0x40)) { - et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); - et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); + et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); + et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); } et4000->acl.pattern_x_back = et4000->acl.pattern_x; if (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]) { - et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; - et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.source_x = et4000->acl.source_addr & et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.source_addr &= ~et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7]; } et4000->acl.source_back = et4000->acl.source_addr; if (!(et4000->acl.internal.source_wrap & 0x40)) { - et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); - et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); + et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); + et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } et4000->acl.source_x_back = et4000->acl.source_x; @@ -1130,341 +1178,848 @@ et4000w32p_blit_start(et4000w32p_t *et4000) et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3; et4000->acl.cpu_dat_pos = 0; - et4000->acl.cpu_dat = 0; + et4000->acl.cpu_dat = 0; et4000->acl.pix_pos = 0; } - void et4000w32_incx(int c, et4000w32p_t *et4000) { - et4000->acl.dest_addr += c; - et4000->acl.pattern_x += c; - et4000->acl.source_x += c; - et4000->acl.mix_addr += c; + et4000->acl.dest_addr += c; + et4000->acl.pattern_x += c; + et4000->acl.source_x += c; + et4000->acl.mix_addr += c; if (et4000->acl.pattern_x >= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]) - et4000->acl.pattern_x -= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; - if (et4000->acl.source_x >= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]) - et4000->acl.source_x -= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.pattern_x -= et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; + if (et4000->acl.source_x >= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]) + et4000->acl.source_x -= et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; } - void et4000w32_decx(int c, et4000w32p_t *et4000) { - et4000->acl.dest_addr -= c; - et4000->acl.pattern_x -= c; - et4000->acl.source_x -= c; - et4000->acl.mix_addr -= c; + et4000->acl.dest_addr -= c; + et4000->acl.pattern_x -= c; + et4000->acl.source_x -= c; + et4000->acl.mix_addr -= c; if (et4000->acl.pattern_x < 0) - et4000->acl.pattern_x += et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; - if (et4000->acl.source_x < 0) - et4000->acl.source_x += et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; + et4000->acl.pattern_x += et4000w32_max_x[et4000->acl.internal.pattern_wrap & 7]; + if (et4000->acl.source_x < 0) + et4000->acl.source_x += et4000w32_max_x[et4000->acl.internal.source_wrap & 7]; } - void et4000w32_incy(et4000w32p_t *et4000) { - et4000->acl.pattern_addr += et4000->acl.internal.pattern_off + 1; - et4000->acl.source_addr += et4000->acl.internal.source_off + 1; - et4000->acl.mix_addr += et4000->acl.internal.mix_off + 1; - et4000->acl.dest_addr += et4000->acl.internal.dest_off + 1; + et4000->acl.pattern_addr += et4000->acl.internal.pattern_off + 1; + et4000->acl.source_addr += et4000->acl.internal.source_off + 1; + et4000->acl.mix_addr += et4000->acl.internal.mix_off + 1; + et4000->acl.dest_addr += et4000->acl.internal.dest_off + 1; et4000->acl.pattern_y++; if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { - et4000->acl.pattern_y = 0; - et4000->acl.pattern_addr = et4000->acl.pattern_back; + et4000->acl.pattern_y = 0; + et4000->acl.pattern_addr = et4000->acl.pattern_back; } et4000->acl.source_y++; if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { - et4000->acl.source_y = 0; - et4000->acl.source_addr = et4000->acl.source_back; + et4000->acl.source_y = 0; + et4000->acl.source_addr = et4000->acl.source_back; } } - void et4000w32_decy(et4000w32p_t *et4000) { - et4000->acl.pattern_addr -= et4000->acl.internal.pattern_off + 1; - et4000->acl.source_addr -= et4000->acl.internal.source_off + 1; - et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; - et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; + et4000->acl.pattern_addr -= et4000->acl.internal.pattern_off + 1; + et4000->acl.source_addr -= et4000->acl.internal.source_off + 1; + et4000->acl.mix_addr -= et4000->acl.internal.mix_off + 1; + et4000->acl.dest_addr -= et4000->acl.internal.dest_off + 1; et4000->acl.pattern_y--; if (et4000->acl.pattern_y < 0 && !(et4000->acl.internal.pattern_wrap & 0x40)) { - et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; - et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); + et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; + et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); } et4000->acl.source_y--; if (et4000->acl.source_y < 0 && !(et4000->acl.internal.source_wrap & 0x40)) { - et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; - et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] *(et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); + et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; + et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); } } - -#define ROPMIX(R, D, P, S, out) \ - { \ - switch (R) { \ - case 0x00: out = 0; break; \ - case 0x01: out = ~(D | (P | S)); break; \ - case 0x02: out = D & ~(P | S); break; \ - case 0x03: out = ~(P | S); break; \ - case 0x04: out = S & ~(D | P); break; \ - case 0x05: out = ~(D | P); break; \ - case 0x06: out = ~(P | ~(D ^ S)); break; \ - case 0x07: out = ~(P | (D & S)); break; \ - case 0x08: out = S & (D & ~P); break; \ - case 0x09: out = ~(P | (D ^ S)); break; \ - case 0x0a: out = D & ~P; break; \ - case 0x0b: out = ~(P | (S & ~D)); break; \ - case 0x0c: out = S & ~P; break; \ - case 0x0d: out = ~(P | (D & ~S)); break; \ - case 0x0e: out = ~(P | ~(D | S)); break; \ - case 0x0f: out = ~P; break; \ - case 0x10: out = P & ~(D | S); break; \ - case 0x11: out = ~(D | S); break; \ - case 0x12: out = ~(S | ~(D ^ P)); break; \ - case 0x13: out = ~(S | (D & P)); break; \ - case 0x14: out = ~(D | ~(P ^ S)); break; \ - case 0x15: out = ~(D | (P & S)); break; \ - case 0x16: out = P ^ (S ^ (D & ~(P & S))); break; \ - case 0x17: out = ~(S ^ ((S ^ P) & (D ^ S))); break; \ - case 0x18: out = (S ^ P) & (P ^ D); break; \ - case 0x19: out = ~(S ^ (D & ~(P & S))); break; \ - case 0x1a: out = P ^ (D | (S & P)); break; \ - case 0x1b: out = ~(S ^ (D & (P ^ S))); break; \ - case 0x1c: out = P ^ (S | (D & P)); break; \ - case 0x1d: out = ~(D ^ (S & (P ^ D))); break; \ - case 0x1e: out = P ^ (D | S); break; \ - case 0x1f: out = ~(P & (D | S)); break; \ - case 0x20: out = D & (P & ~S); break; \ - case 0x21: out = ~(S | (D ^ P)); break; \ - case 0x22: out = D & ~S; break; \ - case 0x23: out = ~(S | (P & ~D)); break; \ - case 0x24: out = (S ^ P) & (D ^ S); break; \ - case 0x25: out = ~(P ^ (D & ~(S & P))); break; \ - case 0x26: out = S ^ (D | (P & S)); break; \ - case 0x27: out = S ^ (D | ~(P ^ S)); break; \ - case 0x28: out = D & (P ^ S); break; \ - case 0x29: out = ~(P ^ (S ^ (D | (P & S)))); break; \ - case 0x2a: out = D & ~(P & S); break; \ - case 0x2b: out = ~(S ^ ((S ^ P) & (P ^ D))); break; \ - case 0x2c: out = S ^ (P & (D | S)); break; \ - case 0x2d: out = P ^ (S | ~D); break; \ - case 0x2e: out = P ^ (S | (D ^ P)); break; \ - case 0x2f: out = ~(P & (S | ~D)); break; \ - case 0x30: out = P & ~S; break; \ - case 0x31: out = ~(S | (D & ~P)); break; \ - case 0x32: out = S ^ (D | (P | S)); break; \ - case 0x33: out = ~S; break; \ - case 0x34: out = S ^ (P | (D & S)); break; \ - case 0x35: out = S ^ (P | ~(D ^ S)); break; \ - case 0x36: out = S ^ (D | P); break; \ - case 0x37: out = ~(S & (D | P)); break; \ - case 0x38: out = P ^ (S & (D | P)); break; \ - case 0x39: out = S ^ (P | ~D); break; \ - case 0x3a: out = S ^ (P | (D ^ S)); break; \ - case 0x3b: out = ~(S & (P | ~D)); break; \ - case 0x3c: out = P ^ S; break; \ - case 0x3d: out = S ^ (P | ~(D | S)); break; \ - case 0x3e: out = S ^ (P | (D & ~S)); break; \ - case 0x3f: out = ~(P & S); break; \ - case 0x40: out = P & (S & ~D); break; \ - case 0x41: out = ~(D | (P ^ S)); break; \ - case 0x42: out = (S ^ D) & (P ^ D); break; \ - case 0x43: out = ~(S ^ (P & ~(D & S))); break; \ - case 0x44: out = S & ~D; break; \ - case 0x45: out = ~(D | (P & ~S)); break; \ - case 0x46: out = D ^ (S | (P & D)); break; \ - case 0x47: out = ~(P ^ (S & (D ^ P))); break; \ - case 0x48: out = S & (D ^ P); break; \ - case 0x49: out = ~(P ^ (D ^ (S | (P & D)))); break; \ - case 0x4a: out = D ^ (P & (S | D)); break; \ - case 0x4b: out = P ^ (D | ~S); break; \ - case 0x4c: out = S & ~(D & P); break; \ - case 0x4d: out = ~(S ^ ((S ^ P) | (D ^ S))); break; \ - case 0x4e: out = P ^ (D | (S ^ P)); break; \ - case 0x4f: out = ~(P & (D | ~S)); break; \ - case 0x50: out = P & ~D; break; \ - case 0x51: out = ~(D | (S & ~P)); break; \ - case 0x52: out = D ^ (P | (S & D)); break; \ - case 0x53: out = ~(S ^ (P & (D ^ S))); break; \ - case 0x54: out = ~(D | ~(P | S)); break; \ - case 0x55: out = ~D; break; \ - case 0x56: out = D ^ (P | S); break; \ - case 0x57: out = ~(D & (P | S)); break; \ - case 0x58: out = P ^ (D & (S | P)); break; \ - case 0x59: out = D ^ (P | ~S); break; \ - case 0x5a: out = D ^ P; break; \ - case 0x5b: out = D ^ (P | ~(S | D)); break; \ - case 0x5c: out = D ^ (P | (S ^ D)); break; \ - case 0x5d: out = ~(D & (P | ~S)); break; \ - case 0x5e: out = D ^ (P | (S & ~D)); break; \ - case 0x5f: out = ~(D & P); break; \ - case 0x60: out = P & (D ^ S); break; \ - case 0x61: out = ~(D ^ (S ^ (P | (D & S)))); break; \ - case 0x62: out = D ^ (S & (P | D)); break; \ - case 0x63: out = S ^ (D | ~P); break; \ - case 0x64: out = S ^ (D & (P | S)); break; \ - case 0x65: out = D ^ (S | ~P); break; \ - case 0x66: out = D ^ S; break; \ - case 0x67: out = S ^ (D | ~(P | S)); break; \ - case 0x68: out = ~(D ^ (S ^ (P | ~(D | S)))); break; \ - case 0x69: out = ~(P ^ (D ^ S)); break; \ - case 0x6a: out = D ^ (P & S); break; \ - case 0x6b: out = ~(P ^ (S ^ (D & (P | S)))); break; \ - case 0x6c: out = S ^ (D & P); break; \ - case 0x6d: out = ~(P ^ (D ^ (S & (P | D)))); break; \ - case 0x6e: out = S ^ (D & (P | ~S)); break; \ - case 0x6f: out = ~(P & ~(D ^ S)); break; \ - case 0x70: out = P & ~(D & S); break; \ - case 0x71: out = ~(S ^ ((S ^ D) & (P ^ D))); break; \ - case 0x72: out = S ^ (D | (P ^ S)); break; \ - case 0x73: out = ~(S & (D | ~P)); break; \ - case 0x74: out = D ^ (S | (P ^ D)); break; \ - case 0x75: out = ~(D & (S | ~P)); break; \ - case 0x76: out = S ^ (D | (P & ~S)); break; \ - case 0x77: out = ~(D & S); break; \ - case 0x78: out = P ^ (D & S); break; \ - case 0x79: out = ~(D ^ (S ^ (P & (D | S)))); break; \ - case 0x7a: out = D ^ (P & (S | ~D)); break; \ - case 0x7b: out = ~(S & ~(D ^ P)); break; \ - case 0x7c: out = S ^ (P & (D | ~S)); break; \ - case 0x7d: out = ~(D & ~(P ^ S)); break; \ - case 0x7e: out = (S ^ P) | (D ^ S); break; \ - case 0x7f: out = ~(D & (P & S)); break; \ - case 0x80: out = D & (P & S); break; \ - case 0x81: out = ~((S ^ P) | (D ^ S)); break; \ - case 0x82: out = D & ~(P ^ S); break; \ - case 0x83: out = ~(S ^ (P & (D | ~S))); break; \ - case 0x84: out = S & ~(D ^ P); break; \ - case 0x85: out = ~(P ^ (D & (S | ~P))); break; \ - case 0x86: out = D ^ (S ^ (P & (D | S))); break; \ - case 0x87: out = ~(P ^ (D & S)); break; \ - case 0x88: out = D & S; break; \ - case 0x89: out = ~(S ^ (D | (P & ~S))); break; \ - case 0x8a: out = D & (S | ~P); break; \ - case 0x8b: out = ~(D ^ (S | (P ^ D))); break; \ - case 0x8c: out = S & (D | ~P); break; \ - case 0x8d: out = ~(S ^ (D | (P ^ S))); break; \ - case 0x8e: out = S ^ ((S ^ D) & (P ^ D)); break; \ - case 0x8f: out = ~(P & ~(D & S)); break; \ - case 0x90: out = P & ~(D ^ S); break; \ - case 0x91: out = ~(S ^ (D & (P | ~S))); break; \ - case 0x92: out = D ^ (P ^ (S & (D | P))); break; \ - case 0x93: out = ~(S ^ (P & D)); break; \ - case 0x94: out = P ^ (S ^ (D & (P | S))); break; \ - case 0x95: out = ~(D ^ (P & S)); break; \ - case 0x96: out = D ^ (P ^ S); break; \ - case 0x97: out = P ^ (S ^ (D | ~(P | S))); break; \ - case 0x98: out = ~(S ^ (D | ~(P | S))); break; \ - case 0x99: out = ~(D ^ S); break; \ - case 0x9a: out = D ^ (P & ~S); break; \ - case 0x9b: out = ~(S ^ (D & (P | S))); break; \ - case 0x9c: out = S ^ (P & ~D); break; \ - case 0x9d: out = ~(D ^ (S & (P | D))); break; \ - case 0x9e: out = D ^ (S ^ (P | (D & S))); break; \ - case 0x9f: out = ~(P & (D ^ S)); break; \ - case 0xa0: out = D & P; break; \ - case 0xa1: out = ~(P ^ (D | (S & ~P))); break; \ - case 0xa2: out = D & (P | ~S); break; \ - case 0xa3: out = ~(D ^ (P | (S ^ D))); break; \ - case 0xa4: out = ~(P ^ (D | ~(S | P))); break; \ - case 0xa5: out = ~(P ^ D); break; \ - case 0xa6: out = D ^ (S & ~P); break; \ - case 0xa7: out = ~(P ^ (D & (S | P))); break; \ - case 0xa8: out = D & (P | S); break; \ - case 0xa9: out = ~(D ^ (P | S)); break; \ - case 0xaa: out = D; break; \ - case 0xab: out = D | ~(P | S); break; \ - case 0xac: out = S ^ (P & (D ^ S)); break; \ - case 0xad: out = ~(D ^ (P | (S & D))); break; \ - case 0xae: out = D | (S & ~P); break; \ - case 0xaf: out = D | ~P; break; \ - case 0xb0: out = P & (D | ~S); break; \ - case 0xb1: out = ~(P ^ (D | (S ^ P))); break; \ - case 0xb2: out = S ^ ((S ^ P) | (D ^ S)); break; \ - case 0xb3: out = ~(S & ~(D & P)); break; \ - case 0xb4: out = P ^ (S & ~D); break; \ - case 0xb5: out = ~(D ^ (P & (S | D))); break; \ - case 0xb6: out = D ^ (P ^ (S | (D & P))); break; \ - case 0xb7: out = ~(S & (D ^ P)); break; \ - case 0xb8: out = P ^ (S & (D ^ P)); break; \ - case 0xb9: out = ~(D ^ (S | (P & D))); break; \ - case 0xba: out = D | (P & ~S); break; \ - case 0xbb: out = D | ~S; break; \ - case 0xbc: out = S ^ (P & ~(D & S)); break; \ - case 0xbd: out = ~((S ^ D) & (P ^ D)); break; \ - case 0xbe: out = D | (P ^ S); break; \ - case 0xbf: out = D | ~(P & S); break; \ - case 0xc0: out = P & S; break; \ - case 0xc1: out = ~(S ^ (P | (D & ~S))); break; \ - case 0xc2: out = ~(S ^ (P | ~(D | S))); break; \ - case 0xc3: out = ~(P ^ S); break; \ - case 0xc4: out = S & (P | ~D); break; \ - case 0xc5: out = ~(S ^ (P | (D ^ S))); break; \ - case 0xc6: out = S ^ (D & ~P); break; \ - case 0xc7: out = ~(P ^ (S & (D | P))); break; \ - case 0xc8: out = S & (D | P); break; \ - case 0xc9: out = ~(S ^ (P | D)); break; \ - case 0xca: out = D ^ (P & (S ^ D)); break; \ - case 0xcb: out = ~(S ^ (P | (D & S))); break; \ - case 0xcc: out = S; break; \ - case 0xcd: out = S | ~(D | P); break; \ - case 0xce: out = S | (D & ~P); break; \ - case 0xcf: out = S | ~P; break; \ - case 0xd0: out = P & (S | ~D); break; \ - case 0xd1: out = ~(P ^ (S | (D ^ P))); break; \ - case 0xd2: out = P ^ (D & ~S); break; \ - case 0xd3: out = ~(S ^ (P & (D | S))); break; \ - case 0xd4: out = S ^ ((S ^ P) & (P ^ D)); break; \ - case 0xd5: out = ~(D & ~(P & S)); break; \ - case 0xd6: out = P ^ (S ^ (D | (P & S))); break; \ - case 0xd7: out = ~(D & (P ^ S)); break; \ - case 0xd8: out = P ^ (D & (S ^ P)); break; \ - case 0xd9: out = ~(S ^ (D | (P & S))); break; \ - case 0xda: out = D ^ (P & ~(S & D)); break; \ - case 0xdb: out = ~((S ^ P) & (D ^ S)); break; \ - case 0xdc: out = S | (P & ~D); break; \ - case 0xdd: out = S | ~D; break; \ - case 0xde: out = S | (D ^ P); break; \ - case 0xdf: out = S | ~(D & P); break; \ - case 0xe0: out = P & (D | S); break; \ - case 0xe1: out = ~(P ^ (D | S)); break; \ - case 0xe2: out = D ^ (S & (P ^ D)); break; \ - case 0xe3: out = ~(P ^ (S | (D & P))); break; \ - case 0xe4: out = S ^ (D & (P ^ S)); break; \ - case 0xe5: out = ~(P ^ (D | (S & P))); break; \ - case 0xe6: out = S ^ (D & ~(P & S)); break; \ - case 0xe7: out = ~((S ^ P) & (P ^ D)); break; \ - case 0xe8: out = S ^ ((S ^ P) & (D ^ S)); break; \ - case 0xe9: out = ~(D ^ (S ^ (P & ~(D & S)))); break; \ - case 0xea: out = D | (P & S); break; \ - case 0xeb: out = D | ~(P ^ S); break; \ - case 0xec: out = S | (D & P); break; \ - case 0xed: out = S | ~(D ^ P); break; \ - case 0xee: out = D | S; break; \ - case 0xef: out = S | (D | ~P); break; \ - case 0xf0: out = P; break; \ - case 0xf1: out = P | ~(D | S); break; \ - case 0xf2: out = P | (D & ~S); break; \ - case 0xf3: out = P | ~S; break; \ - case 0xf4: out = P | (S & ~D); break; \ - case 0xf5: out = P | ~D; break; \ - case 0xf6: out = P | (D ^ S); break; \ - case 0xf7: out = P | ~(D & S); break; \ - case 0xf8: out = P | (D & S); break; \ - case 0xf9: out = P | ~(D ^ S); break; \ - case 0xfa: out = D | P; break; \ - case 0xfb: out = D | (P | ~S); break; \ - case 0xfc: out = P | S; break; \ - case 0xfd: out = P | (S | ~D); break; \ - case 0xfe: out = D | (P | S); break; \ - case 0xff: out = ~0; break; \ - } \ - } +#define ROPMIX(R, D, P, S, out) \ + { \ + switch (R) { \ + case 0x00: \ + out = 0; \ + break; \ + case 0x01: \ + out = ~(D | (P | S)); \ + break; \ + case 0x02: \ + out = D & ~(P | S); \ + break; \ + case 0x03: \ + out = ~(P | S); \ + break; \ + case 0x04: \ + out = S & ~(D | P); \ + break; \ + case 0x05: \ + out = ~(D | P); \ + break; \ + case 0x06: \ + out = ~(P | ~(D ^ S)); \ + break; \ + case 0x07: \ + out = ~(P | (D & S)); \ + break; \ + case 0x08: \ + out = S & (D & ~P); \ + break; \ + case 0x09: \ + out = ~(P | (D ^ S)); \ + break; \ + case 0x0a: \ + out = D & ~P; \ + break; \ + case 0x0b: \ + out = ~(P | (S & ~D)); \ + break; \ + case 0x0c: \ + out = S & ~P; \ + break; \ + case 0x0d: \ + out = ~(P | (D & ~S)); \ + break; \ + case 0x0e: \ + out = ~(P | ~(D | S)); \ + break; \ + case 0x0f: \ + out = ~P; \ + break; \ + case 0x10: \ + out = P & ~(D | S); \ + break; \ + case 0x11: \ + out = ~(D | S); \ + break; \ + case 0x12: \ + out = ~(S | ~(D ^ P)); \ + break; \ + case 0x13: \ + out = ~(S | (D & P)); \ + break; \ + case 0x14: \ + out = ~(D | ~(P ^ S)); \ + break; \ + case 0x15: \ + out = ~(D | (P & S)); \ + break; \ + case 0x16: \ + out = P ^ (S ^ (D & ~(P & S))); \ + break; \ + case 0x17: \ + out = ~(S ^ ((S ^ P) & (D ^ S))); \ + break; \ + case 0x18: \ + out = (S ^ P) & (P ^ D); \ + break; \ + case 0x19: \ + out = ~(S ^ (D & ~(P & S))); \ + break; \ + case 0x1a: \ + out = P ^ (D | (S & P)); \ + break; \ + case 0x1b: \ + out = ~(S ^ (D & (P ^ S))); \ + break; \ + case 0x1c: \ + out = P ^ (S | (D & P)); \ + break; \ + case 0x1d: \ + out = ~(D ^ (S & (P ^ D))); \ + break; \ + case 0x1e: \ + out = P ^ (D | S); \ + break; \ + case 0x1f: \ + out = ~(P & (D | S)); \ + break; \ + case 0x20: \ + out = D & (P & ~S); \ + break; \ + case 0x21: \ + out = ~(S | (D ^ P)); \ + break; \ + case 0x22: \ + out = D & ~S; \ + break; \ + case 0x23: \ + out = ~(S | (P & ~D)); \ + break; \ + case 0x24: \ + out = (S ^ P) & (D ^ S); \ + break; \ + case 0x25: \ + out = ~(P ^ (D & ~(S & P))); \ + break; \ + case 0x26: \ + out = S ^ (D | (P & S)); \ + break; \ + case 0x27: \ + out = S ^ (D | ~(P ^ S)); \ + break; \ + case 0x28: \ + out = D & (P ^ S); \ + break; \ + case 0x29: \ + out = ~(P ^ (S ^ (D | (P & S)))); \ + break; \ + case 0x2a: \ + out = D & ~(P & S); \ + break; \ + case 0x2b: \ + out = ~(S ^ ((S ^ P) & (P ^ D))); \ + break; \ + case 0x2c: \ + out = S ^ (P & (D | S)); \ + break; \ + case 0x2d: \ + out = P ^ (S | ~D); \ + break; \ + case 0x2e: \ + out = P ^ (S | (D ^ P)); \ + break; \ + case 0x2f: \ + out = ~(P & (S | ~D)); \ + break; \ + case 0x30: \ + out = P & ~S; \ + break; \ + case 0x31: \ + out = ~(S | (D & ~P)); \ + break; \ + case 0x32: \ + out = S ^ (D | (P | S)); \ + break; \ + case 0x33: \ + out = ~S; \ + break; \ + case 0x34: \ + out = S ^ (P | (D & S)); \ + break; \ + case 0x35: \ + out = S ^ (P | ~(D ^ S)); \ + break; \ + case 0x36: \ + out = S ^ (D | P); \ + break; \ + case 0x37: \ + out = ~(S & (D | P)); \ + break; \ + case 0x38: \ + out = P ^ (S & (D | P)); \ + break; \ + case 0x39: \ + out = S ^ (P | ~D); \ + break; \ + case 0x3a: \ + out = S ^ (P | (D ^ S)); \ + break; \ + case 0x3b: \ + out = ~(S & (P | ~D)); \ + break; \ + case 0x3c: \ + out = P ^ S; \ + break; \ + case 0x3d: \ + out = S ^ (P | ~(D | S)); \ + break; \ + case 0x3e: \ + out = S ^ (P | (D & ~S)); \ + break; \ + case 0x3f: \ + out = ~(P & S); \ + break; \ + case 0x40: \ + out = P & (S & ~D); \ + break; \ + case 0x41: \ + out = ~(D | (P ^ S)); \ + break; \ + case 0x42: \ + out = (S ^ D) & (P ^ D); \ + break; \ + case 0x43: \ + out = ~(S ^ (P & ~(D & S))); \ + break; \ + case 0x44: \ + out = S & ~D; \ + break; \ + case 0x45: \ + out = ~(D | (P & ~S)); \ + break; \ + case 0x46: \ + out = D ^ (S | (P & D)); \ + break; \ + case 0x47: \ + out = ~(P ^ (S & (D ^ P))); \ + break; \ + case 0x48: \ + out = S & (D ^ P); \ + break; \ + case 0x49: \ + out = ~(P ^ (D ^ (S | (P & D)))); \ + break; \ + case 0x4a: \ + out = D ^ (P & (S | D)); \ + break; \ + case 0x4b: \ + out = P ^ (D | ~S); \ + break; \ + case 0x4c: \ + out = S & ~(D & P); \ + break; \ + case 0x4d: \ + out = ~(S ^ ((S ^ P) | (D ^ S))); \ + break; \ + case 0x4e: \ + out = P ^ (D | (S ^ P)); \ + break; \ + case 0x4f: \ + out = ~(P & (D | ~S)); \ + break; \ + case 0x50: \ + out = P & ~D; \ + break; \ + case 0x51: \ + out = ~(D | (S & ~P)); \ + break; \ + case 0x52: \ + out = D ^ (P | (S & D)); \ + break; \ + case 0x53: \ + out = ~(S ^ (P & (D ^ S))); \ + break; \ + case 0x54: \ + out = ~(D | ~(P | S)); \ + break; \ + case 0x55: \ + out = ~D; \ + break; \ + case 0x56: \ + out = D ^ (P | S); \ + break; \ + case 0x57: \ + out = ~(D & (P | S)); \ + break; \ + case 0x58: \ + out = P ^ (D & (S | P)); \ + break; \ + case 0x59: \ + out = D ^ (P | ~S); \ + break; \ + case 0x5a: \ + out = D ^ P; \ + break; \ + case 0x5b: \ + out = D ^ (P | ~(S | D)); \ + break; \ + case 0x5c: \ + out = D ^ (P | (S ^ D)); \ + break; \ + case 0x5d: \ + out = ~(D & (P | ~S)); \ + break; \ + case 0x5e: \ + out = D ^ (P | (S & ~D)); \ + break; \ + case 0x5f: \ + out = ~(D & P); \ + break; \ + case 0x60: \ + out = P & (D ^ S); \ + break; \ + case 0x61: \ + out = ~(D ^ (S ^ (P | (D & S)))); \ + break; \ + case 0x62: \ + out = D ^ (S & (P | D)); \ + break; \ + case 0x63: \ + out = S ^ (D | ~P); \ + break; \ + case 0x64: \ + out = S ^ (D & (P | S)); \ + break; \ + case 0x65: \ + out = D ^ (S | ~P); \ + break; \ + case 0x66: \ + out = D ^ S; \ + break; \ + case 0x67: \ + out = S ^ (D | ~(P | S)); \ + break; \ + case 0x68: \ + out = ~(D ^ (S ^ (P | ~(D | S)))); \ + break; \ + case 0x69: \ + out = ~(P ^ (D ^ S)); \ + break; \ + case 0x6a: \ + out = D ^ (P & S); \ + break; \ + case 0x6b: \ + out = ~(P ^ (S ^ (D & (P | S)))); \ + break; \ + case 0x6c: \ + out = S ^ (D & P); \ + break; \ + case 0x6d: \ + out = ~(P ^ (D ^ (S & (P | D)))); \ + break; \ + case 0x6e: \ + out = S ^ (D & (P | ~S)); \ + break; \ + case 0x6f: \ + out = ~(P & ~(D ^ S)); \ + break; \ + case 0x70: \ + out = P & ~(D & S); \ + break; \ + case 0x71: \ + out = ~(S ^ ((S ^ D) & (P ^ D))); \ + break; \ + case 0x72: \ + out = S ^ (D | (P ^ S)); \ + break; \ + case 0x73: \ + out = ~(S & (D | ~P)); \ + break; \ + case 0x74: \ + out = D ^ (S | (P ^ D)); \ + break; \ + case 0x75: \ + out = ~(D & (S | ~P)); \ + break; \ + case 0x76: \ + out = S ^ (D | (P & ~S)); \ + break; \ + case 0x77: \ + out = ~(D & S); \ + break; \ + case 0x78: \ + out = P ^ (D & S); \ + break; \ + case 0x79: \ + out = ~(D ^ (S ^ (P & (D | S)))); \ + break; \ + case 0x7a: \ + out = D ^ (P & (S | ~D)); \ + break; \ + case 0x7b: \ + out = ~(S & ~(D ^ P)); \ + break; \ + case 0x7c: \ + out = S ^ (P & (D | ~S)); \ + break; \ + case 0x7d: \ + out = ~(D & ~(P ^ S)); \ + break; \ + case 0x7e: \ + out = (S ^ P) | (D ^ S); \ + break; \ + case 0x7f: \ + out = ~(D & (P & S)); \ + break; \ + case 0x80: \ + out = D & (P & S); \ + break; \ + case 0x81: \ + out = ~((S ^ P) | (D ^ S)); \ + break; \ + case 0x82: \ + out = D & ~(P ^ S); \ + break; \ + case 0x83: \ + out = ~(S ^ (P & (D | ~S))); \ + break; \ + case 0x84: \ + out = S & ~(D ^ P); \ + break; \ + case 0x85: \ + out = ~(P ^ (D & (S | ~P))); \ + break; \ + case 0x86: \ + out = D ^ (S ^ (P & (D | S))); \ + break; \ + case 0x87: \ + out = ~(P ^ (D & S)); \ + break; \ + case 0x88: \ + out = D & S; \ + break; \ + case 0x89: \ + out = ~(S ^ (D | (P & ~S))); \ + break; \ + case 0x8a: \ + out = D & (S | ~P); \ + break; \ + case 0x8b: \ + out = ~(D ^ (S | (P ^ D))); \ + break; \ + case 0x8c: \ + out = S & (D | ~P); \ + break; \ + case 0x8d: \ + out = ~(S ^ (D | (P ^ S))); \ + break; \ + case 0x8e: \ + out = S ^ ((S ^ D) & (P ^ D)); \ + break; \ + case 0x8f: \ + out = ~(P & ~(D & S)); \ + break; \ + case 0x90: \ + out = P & ~(D ^ S); \ + break; \ + case 0x91: \ + out = ~(S ^ (D & (P | ~S))); \ + break; \ + case 0x92: \ + out = D ^ (P ^ (S & (D | P))); \ + break; \ + case 0x93: \ + out = ~(S ^ (P & D)); \ + break; \ + case 0x94: \ + out = P ^ (S ^ (D & (P | S))); \ + break; \ + case 0x95: \ + out = ~(D ^ (P & S)); \ + break; \ + case 0x96: \ + out = D ^ (P ^ S); \ + break; \ + case 0x97: \ + out = P ^ (S ^ (D | ~(P | S))); \ + break; \ + case 0x98: \ + out = ~(S ^ (D | ~(P | S))); \ + break; \ + case 0x99: \ + out = ~(D ^ S); \ + break; \ + case 0x9a: \ + out = D ^ (P & ~S); \ + break; \ + case 0x9b: \ + out = ~(S ^ (D & (P | S))); \ + break; \ + case 0x9c: \ + out = S ^ (P & ~D); \ + break; \ + case 0x9d: \ + out = ~(D ^ (S & (P | D))); \ + break; \ + case 0x9e: \ + out = D ^ (S ^ (P | (D & S))); \ + break; \ + case 0x9f: \ + out = ~(P & (D ^ S)); \ + break; \ + case 0xa0: \ + out = D & P; \ + break; \ + case 0xa1: \ + out = ~(P ^ (D | (S & ~P))); \ + break; \ + case 0xa2: \ + out = D & (P | ~S); \ + break; \ + case 0xa3: \ + out = ~(D ^ (P | (S ^ D))); \ + break; \ + case 0xa4: \ + out = ~(P ^ (D | ~(S | P))); \ + break; \ + case 0xa5: \ + out = ~(P ^ D); \ + break; \ + case 0xa6: \ + out = D ^ (S & ~P); \ + break; \ + case 0xa7: \ + out = ~(P ^ (D & (S | P))); \ + break; \ + case 0xa8: \ + out = D & (P | S); \ + break; \ + case 0xa9: \ + out = ~(D ^ (P | S)); \ + break; \ + case 0xaa: \ + out = D; \ + break; \ + case 0xab: \ + out = D | ~(P | S); \ + break; \ + case 0xac: \ + out = S ^ (P & (D ^ S)); \ + break; \ + case 0xad: \ + out = ~(D ^ (P | (S & D))); \ + break; \ + case 0xae: \ + out = D | (S & ~P); \ + break; \ + case 0xaf: \ + out = D | ~P; \ + break; \ + case 0xb0: \ + out = P & (D | ~S); \ + break; \ + case 0xb1: \ + out = ~(P ^ (D | (S ^ P))); \ + break; \ + case 0xb2: \ + out = S ^ ((S ^ P) | (D ^ S)); \ + break; \ + case 0xb3: \ + out = ~(S & ~(D & P)); \ + break; \ + case 0xb4: \ + out = P ^ (S & ~D); \ + break; \ + case 0xb5: \ + out = ~(D ^ (P & (S | D))); \ + break; \ + case 0xb6: \ + out = D ^ (P ^ (S | (D & P))); \ + break; \ + case 0xb7: \ + out = ~(S & (D ^ P)); \ + break; \ + case 0xb8: \ + out = P ^ (S & (D ^ P)); \ + break; \ + case 0xb9: \ + out = ~(D ^ (S | (P & D))); \ + break; \ + case 0xba: \ + out = D | (P & ~S); \ + break; \ + case 0xbb: \ + out = D | ~S; \ + break; \ + case 0xbc: \ + out = S ^ (P & ~(D & S)); \ + break; \ + case 0xbd: \ + out = ~((S ^ D) & (P ^ D)); \ + break; \ + case 0xbe: \ + out = D | (P ^ S); \ + break; \ + case 0xbf: \ + out = D | ~(P & S); \ + break; \ + case 0xc0: \ + out = P & S; \ + break; \ + case 0xc1: \ + out = ~(S ^ (P | (D & ~S))); \ + break; \ + case 0xc2: \ + out = ~(S ^ (P | ~(D | S))); \ + break; \ + case 0xc3: \ + out = ~(P ^ S); \ + break; \ + case 0xc4: \ + out = S & (P | ~D); \ + break; \ + case 0xc5: \ + out = ~(S ^ (P | (D ^ S))); \ + break; \ + case 0xc6: \ + out = S ^ (D & ~P); \ + break; \ + case 0xc7: \ + out = ~(P ^ (S & (D | P))); \ + break; \ + case 0xc8: \ + out = S & (D | P); \ + break; \ + case 0xc9: \ + out = ~(S ^ (P | D)); \ + break; \ + case 0xca: \ + out = D ^ (P & (S ^ D)); \ + break; \ + case 0xcb: \ + out = ~(S ^ (P | (D & S))); \ + break; \ + case 0xcc: \ + out = S; \ + break; \ + case 0xcd: \ + out = S | ~(D | P); \ + break; \ + case 0xce: \ + out = S | (D & ~P); \ + break; \ + case 0xcf: \ + out = S | ~P; \ + break; \ + case 0xd0: \ + out = P & (S | ~D); \ + break; \ + case 0xd1: \ + out = ~(P ^ (S | (D ^ P))); \ + break; \ + case 0xd2: \ + out = P ^ (D & ~S); \ + break; \ + case 0xd3: \ + out = ~(S ^ (P & (D | S))); \ + break; \ + case 0xd4: \ + out = S ^ ((S ^ P) & (P ^ D)); \ + break; \ + case 0xd5: \ + out = ~(D & ~(P & S)); \ + break; \ + case 0xd6: \ + out = P ^ (S ^ (D | (P & S))); \ + break; \ + case 0xd7: \ + out = ~(D & (P ^ S)); \ + break; \ + case 0xd8: \ + out = P ^ (D & (S ^ P)); \ + break; \ + case 0xd9: \ + out = ~(S ^ (D | (P & S))); \ + break; \ + case 0xda: \ + out = D ^ (P & ~(S & D)); \ + break; \ + case 0xdb: \ + out = ~((S ^ P) & (D ^ S)); \ + break; \ + case 0xdc: \ + out = S | (P & ~D); \ + break; \ + case 0xdd: \ + out = S | ~D; \ + break; \ + case 0xde: \ + out = S | (D ^ P); \ + break; \ + case 0xdf: \ + out = S | ~(D & P); \ + break; \ + case 0xe0: \ + out = P & (D | S); \ + break; \ + case 0xe1: \ + out = ~(P ^ (D | S)); \ + break; \ + case 0xe2: \ + out = D ^ (S & (P ^ D)); \ + break; \ + case 0xe3: \ + out = ~(P ^ (S | (D & P))); \ + break; \ + case 0xe4: \ + out = S ^ (D & (P ^ S)); \ + break; \ + case 0xe5: \ + out = ~(P ^ (D | (S & P))); \ + break; \ + case 0xe6: \ + out = S ^ (D & ~(P & S)); \ + break; \ + case 0xe7: \ + out = ~((S ^ P) & (P ^ D)); \ + break; \ + case 0xe8: \ + out = S ^ ((S ^ P) & (D ^ S)); \ + break; \ + case 0xe9: \ + out = ~(D ^ (S ^ (P & ~(D & S)))); \ + break; \ + case 0xea: \ + out = D | (P & S); \ + break; \ + case 0xeb: \ + out = D | ~(P ^ S); \ + break; \ + case 0xec: \ + out = S | (D & P); \ + break; \ + case 0xed: \ + out = S | ~(D ^ P); \ + break; \ + case 0xee: \ + out = D | S; \ + break; \ + case 0xef: \ + out = S | (D | ~P); \ + break; \ + case 0xf0: \ + out = P; \ + break; \ + case 0xf1: \ + out = P | ~(D | S); \ + break; \ + case 0xf2: \ + out = P | (D & ~S); \ + break; \ + case 0xf3: \ + out = P | ~S; \ + break; \ + case 0xf4: \ + out = P | (S & ~D); \ + break; \ + case 0xf5: \ + out = P | ~D; \ + break; \ + case 0xf6: \ + out = P | (D ^ S); \ + break; \ + case 0xf7: \ + out = P | ~(D & S); \ + break; \ + case 0xf8: \ + out = P | (D & S); \ + break; \ + case 0xf9: \ + out = P | ~(D ^ S); \ + break; \ + case 0xfa: \ + out = D | P; \ + break; \ + case 0xfb: \ + out = D | (P | ~S); \ + break; \ + case 0xfc: \ + out = P | S; \ + break; \ + case 0xfd: \ + out = P | (S | ~D); \ + break; \ + case 0xfe: \ + out = D | (P | S); \ + break; \ + case 0xff: \ + out = ~0; \ + break; \ + } \ + } static void et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4000w32p_t *et4000) @@ -1472,104 +2027,104 @@ et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4 svga_t *svga = &et4000->svga; uint8_t pattern, source, dest; uint8_t rop; - uint8_t out; - int mixmap; + uint8_t out; + int mixmap; - while (count-- && et4000->acl.y_count >= 0) { - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; + while (count-- && et4000->acl.y_count >= 0) { + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; - if (cpu_input == 1) { - source = src_dat & 0xff; - src_dat >>= 8; - } else /*The source data is from the display memory if the Control Routing register is not set to 1*/ - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; + if (cpu_input == 1) { + source = src_dat & 0xff; + src_dat >>= 8; + } else /*The source data is from the display memory if the Control Routing register is not set to 1*/ + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; - dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; - mixmap = mix_dat & 1; + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + mixmap = mix_dat & 1; - /*Now determine the Raster Operation*/ - rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - mix_dat >>= 1; - mix_dat |= 0x80000000; + /*Now determine the Raster Operation*/ + rop = mixmap ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + mix_dat >>= 1; + mix_dat |= 0x80000000; - ROPMIX(rop, dest, pattern, source, out); + ROPMIX(rop, dest, pattern, source, out); - /*Write the data*/ - svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; - svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + /*Write the data*/ + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; - if (et4000->acl.internal.xy_dir & 1) { - et4000->acl.dest_addr--; - et4000->acl.pattern_x--; - et4000->acl.source_x--; - if (et4000->acl.pattern_x < 0) - et4000->acl.pattern_x += (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); - if (et4000->acl.source_x < 0) - et4000->acl.source_x += (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); - } else { - et4000->acl.dest_addr++; - et4000->acl.pattern_x++; - et4000->acl.source_x++; - if (et4000->acl.pattern_x >= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) - et4000->acl.pattern_x -= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); - if (et4000->acl.source_x >= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) - et4000->acl.source_x -= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); - } + if (et4000->acl.internal.xy_dir & 1) { + et4000->acl.dest_addr--; + et4000->acl.pattern_x--; + et4000->acl.source_x--; + if (et4000->acl.pattern_x < 0) + et4000->acl.pattern_x += (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); + if (et4000->acl.source_x < 0) + et4000->acl.source_x += (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); + } else { + et4000->acl.dest_addr++; + et4000->acl.pattern_x++; + et4000->acl.source_x++; + if (et4000->acl.pattern_x >= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) + et4000->acl.pattern_x -= (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1); + if (et4000->acl.source_x >= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) + et4000->acl.source_x -= (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1); + } - et4000->acl.x_count--; - if (et4000->acl.x_count == 0xffff) { - et4000->acl.x_count = et4000->acl.internal.count_x; + et4000->acl.x_count--; + if (et4000->acl.x_count == 0xffff) { + et4000->acl.x_count = et4000->acl.internal.count_x; - if (et4000->acl.internal.xy_dir & 2) { - et4000->acl.pattern_addr -= (et4000->acl.internal.pattern_off + 1); - et4000->acl.source_addr -= (et4000->acl.internal.source_off + 1); - et4000->acl.dest_addr -= (et4000->acl.internal.dest_off + 1); - et4000->acl.pattern_y--; - if ((et4000->acl.pattern_y < 0) && !(et4000->acl.internal.pattern_wrap & 0x40)) { - et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; - et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); - } - et4000->acl.source_y--; - if ((et4000->acl.source_y < 0) && !(et4000->acl.internal.source_wrap & 0x40)) { - et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; - et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); - } - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); - } else { - et4000->acl.pattern_addr += (et4000->acl.internal.pattern_off + 1); - et4000->acl.source_addr += (et4000->acl.internal.source_off + 1); - et4000->acl.dest_addr += (et4000->acl.internal.dest_off + 1); - et4000->acl.pattern_y++; - if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { - et4000->acl.pattern_y = 0; - et4000->acl.pattern_addr = et4000->acl.pattern_back; - } - et4000->acl.source_y++; - if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { - et4000->acl.source_y = 0; - et4000->acl.source_addr = et4000->acl.source_back; - } - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + (et4000->acl.internal.dest_off + 1); - } + if (et4000->acl.internal.xy_dir & 2) { + et4000->acl.pattern_addr -= (et4000->acl.internal.pattern_off + 1); + et4000->acl.source_addr -= (et4000->acl.internal.source_off + 1); + et4000->acl.dest_addr -= (et4000->acl.internal.dest_off + 1); + et4000->acl.pattern_y--; + if ((et4000->acl.pattern_y < 0) && !(et4000->acl.internal.pattern_wrap & 0x40)) { + et4000->acl.pattern_y = et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1; + et4000->acl.pattern_addr = et4000->acl.pattern_back + (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1)); + } + et4000->acl.source_y--; + if ((et4000->acl.source_y < 0) && !(et4000->acl.internal.source_wrap & 0x40)) { + et4000->acl.source_y = et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1; + et4000->acl.source_addr = et4000->acl.source_back + (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] * (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1)); + } + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000->acl.pattern_addr += (et4000->acl.internal.pattern_off + 1); + et4000->acl.source_addr += (et4000->acl.internal.source_off + 1); + et4000->acl.dest_addr += (et4000->acl.internal.dest_off + 1); + et4000->acl.pattern_y++; + if (et4000->acl.pattern_y == et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) { + et4000->acl.pattern_y = 0; + et4000->acl.pattern_addr = et4000->acl.pattern_back; + } + et4000->acl.source_y++; + if (et4000->acl.source_y == et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) { + et4000->acl.source_y = 0; + et4000->acl.source_addr = et4000->acl.source_back; + } + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + (et4000->acl.internal.dest_off + 1); + } - et4000->acl.pattern_x = et4000->acl.pattern_x_back; - et4000->acl.source_x = et4000->acl.source_x_back; + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; - et4000->acl.y_count--; - if (et4000->acl.y_count == 0xffff) { - et4000->acl.status &= ~ACL_XYST; - if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { - et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); - et4000->acl.status &= ~ACL_SSO; - } - et4000->acl.cpu_input_num = 0; - return; - } + et4000->acl.y_count--; + if (et4000->acl.y_count == 0xffff) { + et4000->acl.status &= ~ACL_XYST; + if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) { + et4000w32_log("W32i: end blit, xcount = %i\n", et4000->acl.x_count); + et4000->acl.status &= ~ACL_SSO; + } + et4000->acl.cpu_input_num = 0; + return; + } - if (cpu_input) - return; - } - } + if (cpu_input) + return; + } + } } static void @@ -1578,251 +2133,267 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32 svga_t *svga = &et4000->svga; uint8_t pattern, source, dest, out; uint8_t rop; - int mixdat; + int mixdat; if (!(et4000->acl.status & ACL_XYST)) { - et4000w32_log("XY Block not started\n"); - return; - } + et4000w32_log("XY Block not started\n"); + return; + } - if (et4000->acl.internal.xy_dir & 0x80) { /* Line draw */ - et4000w32_log("Line draw\n"); - while (count--) { - et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; - et4000w32_log("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask, (et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask); - if (cpu_input == 2) { - source = sdat & 0xff; - sdat >>= 8; - } - dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; - out = 0; - et4000w32_log("%06X ", et4000->acl.dest_addr); - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { - mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); - et4000w32_log("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask]); - } else { - mixdat = mix & 1; - mix >>= 1; - mix |= 0x80000000; - } - et4000->acl.mix_addr++; - rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + if (et4000->acl.internal.xy_dir & 0x80) { /* Line draw */ + et4000w32_log("Line draw\n"); + while (count--) { + et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y); + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; + et4000w32_log("%06X %06X ", (et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask, (et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask); + if (cpu_input == 2) { + source = sdat & 0xff; + sdat >>= 8; + } + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + out = 0; + et4000w32_log("%06X ", et4000->acl.dest_addr); + if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { + mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); + et4000w32_log("%06X %02X ", et4000->acl.mix_addr, svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask]); + } else { + mixdat = mix & 1; + mix >>= 1; + mix |= 0x80000000; + } + et4000->acl.mix_addr++; + rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - ROPMIX(rop, dest, pattern, source, out); + ROPMIX(rop, dest, pattern, source, out); - et4000w32_log("%06X = %02X\n", et4000->acl.dest_addr & et4000->vram_mask, out); - if (!(et4000->acl.internal.ctrl_routing & 0x40)) { - svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; - svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; - } else { - et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); - et4000->acl.cpu_dat_pos++; - } + et4000w32_log("%06X = %02X\n", et4000->acl.dest_addr & et4000->vram_mask, out); + if (!(et4000->acl.internal.ctrl_routing & 0x40)) { + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + } else { + et4000->acl.cpu_dat |= ((uint64_t) out << (et4000->acl.cpu_dat_pos * 8)); + et4000->acl.cpu_dat_pos++; + } - et4000->acl.pix_pos++; - et4000->acl.internal.pos_x++; - if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3)) { - if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000); - else et4000w32_incx(1, et4000); - } else { - if (et4000->acl.internal.xy_dir & 1) - et4000w32_incx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); - else - et4000w32_decx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); - et4000->acl.pix_pos = 0; + et4000->acl.pix_pos++; + et4000->acl.internal.pos_x++; + if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3)) { + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); + } else { + if (et4000->acl.internal.xy_dir & 1) + et4000w32_incx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); + else + et4000w32_decx((et4000->acl.internal.pixel_depth >> 4) & 3, et4000); + et4000->acl.pix_pos = 0; - /*Next pixel*/ - switch (et4000->acl.internal.xy_dir & 7) { - case 0: case 1: /* Y+ */ - et4000w32_incy(et4000); - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; - break; - case 2: case 3: /* Y- */ - et4000w32_decy(et4000); - et4000->acl.internal.pos_y++; - et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; - break; - case 4: case 6: /* X+ */ - et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - break; - case 5: case 7: /* X- */ - et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - break; - } - et4000->acl.internal.error += et4000->acl.internal.dmin; - if (et4000->acl.internal.error > et4000->acl.internal.dmaj) { - et4000->acl.internal.error -= et4000->acl.internal.dmaj; - switch (et4000->acl.internal.xy_dir & 7) { - case 0: case 2: /* X+ */ - et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - et4000->acl.internal.pos_x++; - break; - case 1: case 3: /* X- */ - et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - et4000->acl.internal.pos_x++; - break; - case 4: case 5: /* Y+ */ - et4000w32_incy(et4000); - et4000->acl.internal.pos_y++; - break; - case 6: case 7: /* Y- */ - et4000w32_decy(et4000); - et4000->acl.internal.pos_y++; - break; - } - } - if ((et4000->acl.internal.pos_x > et4000->acl.internal.count_x) || - (et4000->acl.internal.pos_y > et4000->acl.internal.count_y)) { - et4000w32_log("ACL status linedraw 0\n"); - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); - return; - } - } - } + /*Next pixel*/ + switch (et4000->acl.internal.xy_dir & 7) { + case 0: + case 1: /* Y+ */ + et4000w32_incy(et4000); + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; + break; + case 2: + case 3: /* Y- */ + et4000w32_decy(et4000); + et4000->acl.internal.pos_y++; + et4000->acl.internal.pos_x -= ((et4000->acl.internal.pixel_depth >> 4) & 3) + 1; + break; + case 4: + case 6: /* X+ */ + et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + break; + case 5: + case 7: /* X- */ + et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + break; + } + et4000->acl.internal.error += et4000->acl.internal.dmin; + if (et4000->acl.internal.error > et4000->acl.internal.dmaj) { + et4000->acl.internal.error -= et4000->acl.internal.dmaj; + switch (et4000->acl.internal.xy_dir & 7) { + case 0: + case 2: /* X+ */ + et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + et4000->acl.internal.pos_x++; + break; + case 1: + case 3: /* X- */ + et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); + et4000->acl.internal.pos_x++; + break; + case 4: + case 5: /* Y+ */ + et4000w32_incy(et4000); + et4000->acl.internal.pos_y++; + break; + case 6: + case 7: /* Y- */ + et4000w32_decy(et4000); + et4000->acl.internal.pos_y++; + break; + } + } + if ((et4000->acl.internal.pos_x > et4000->acl.internal.count_x) || (et4000->acl.internal.pos_y > et4000->acl.internal.count_y)) { + et4000w32_log("ACL status linedraw 0\n"); + et4000->acl.status &= ~(ACL_XYST | ACL_SSO); + return; + } + } + } } else { - et4000w32_log("BitBLT: count = %i\n", count); - while (count-- && et4000->acl.y_count >= 0) { - pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; + et4000w32_log("BitBLT: count = %i\n", count); + while (count-- && et4000->acl.y_count >= 0) { + pattern = svga->vram[(et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask]; - if (cpu_input == 2) { - source = sdat & 0xff; - sdat >>= 8; - } else - source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; + if (cpu_input == 2) { + source = sdat & 0xff; + sdat >>= 8; + } else + source = svga->vram[(et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask]; - dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; - out = 0; + dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask]; + out = 0; - if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { - mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); - } else { - mixdat = mix & 1; - mix >>= 1; - mix |= 0x80000000; - } + if ((et4000->acl.internal.ctrl_routing & 0xa) == 8) { + mixdat = svga->vram[(et4000->acl.mix_addr >> 3) & et4000->vram_mask] & (1 << (et4000->acl.mix_addr & 7)); + } else { + mixdat = mix & 1; + mix >>= 1; + mix |= 0x80000000; + } - rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; + rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg; - ROPMIX(rop, dest, pattern, source, out); + ROPMIX(rop, dest, pattern, source, out); - if (!(et4000->acl.internal.ctrl_routing & 0x40)) { - svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; - svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; - } else { - et4000->acl.cpu_dat |= ((uint64_t)out << (et4000->acl.cpu_dat_pos * 8)); - et4000->acl.cpu_dat_pos++; - } + if (!(et4000->acl.internal.ctrl_routing & 0x40)) { + svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = out; + svga->changedvram[(et4000->acl.dest_addr & et4000->vram_mask) >> 12] = changeframecount; + } else { + et4000->acl.cpu_dat |= ((uint64_t) out << (et4000->acl.cpu_dat_pos * 8)); + et4000->acl.cpu_dat_pos++; + } - if (et4000->acl.internal.xy_dir & 1) - et4000w32_decx(1, et4000); - else - et4000w32_incx(1, et4000); + if (et4000->acl.internal.xy_dir & 1) + et4000w32_decx(1, et4000); + else + et4000w32_incx(1, et4000); - et4000->acl.x_count--; - if (et4000->acl.x_count == 0xffff) { - if (et4000->acl.internal.xy_dir & 2) { - et4000w32_decy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); - } else { - et4000w32_incy(et4000); - et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; - et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; - } + et4000->acl.x_count--; + if (et4000->acl.x_count == 0xffff) { + if (et4000->acl.internal.xy_dir & 2) { + et4000w32_decy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back - (et4000->acl.internal.mix_off + 1); + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back - (et4000->acl.internal.dest_off + 1); + } else { + et4000w32_incy(et4000); + et4000->acl.mix_back = et4000->acl.mix_addr = et4000->acl.mix_back + et4000->acl.internal.mix_off + 1; + et4000->acl.dest_back = et4000->acl.dest_addr = et4000->acl.dest_back + et4000->acl.internal.dest_off + 1; + } - et4000->acl.pattern_x = et4000->acl.pattern_x_back; - et4000->acl.source_x = et4000->acl.source_x_back; + et4000->acl.pattern_x = et4000->acl.pattern_x_back; + et4000->acl.source_x = et4000->acl.source_x_back; - et4000->acl.y_count--; - et4000->acl.x_count = et4000->acl.internal.count_x; - if (et4000->acl.y_count == 0xffff) { - et4000w32_log("BitBLT end\n"); - et4000->acl.status &= ~(ACL_XYST | ACL_SSO); - return; - } + et4000->acl.y_count--; + et4000->acl.x_count = et4000->acl.internal.count_x; + if (et4000->acl.y_count == 0xffff) { + et4000w32_log("BitBLT end\n"); + et4000->acl.status &= ~(ACL_XYST | ACL_SSO); + return; + } - if (cpu_input) - return; + if (cpu_input) + return; - if (et4000->acl.internal.ctrl_routing & 0x40) { - if (et4000->acl.cpu_dat_pos & 3) - et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); - return; - } - } - } + if (et4000->acl.internal.ctrl_routing & 0x40) { + if (et4000->acl.cpu_dat_pos & 3) + et4000->acl.cpu_dat_pos += 4 - (et4000->acl.cpu_dat_pos & 3); + return; + } + } + } } } - void et4000w32p_hwcursor_draw(svga_t *svga, int displine) { - et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; - int x, offset, xx, xx2; - int shift = (et4000->adjust_cursor + 1); - int width = (svga->hwcursor_latch.cur_xsize - svga->hwcursor_latch.xoff); - int pitch = (svga->hwcursor_latch.cur_xsize == 128) ? 32 : 16; - int x_acc = 4; - int minus_width = 0; - uint8_t dat; + et4000w32p_t *et4000 = (et4000w32p_t *) svga->p; + int x, offset, xx, xx2; + int shift = (et4000->adjust_cursor + 1); + int width = (svga->hwcursor_latch.cur_xsize - svga->hwcursor_latch.xoff); + int pitch = (svga->hwcursor_latch.cur_xsize == 128) ? 32 : 16; + int x_acc = 4; + int minus_width = 0; + uint8_t dat; offset = svga->hwcursor_latch.xoff; - if (et4000->type == ET4000W32) { - switch (svga->bpp) { - case 8: - minus_width = 0; - x_acc = 2; - break; - case 15: case 16: - minus_width = 64; - x_acc = 2; - break; - } - } - - for (x = 0; x < (width - minus_width); x += x_acc) { - dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - - xx = svga->hwcursor_latch.x + svga->x_add + x; - - if (!(xx % shift)) { - xx2 = xx / shift; - if (!(dat & 2)) buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][xx2] ^= 0xFFFFFF; - } - dat >>= 2; - xx++; - if (!(xx % shift)) { - xx2 = xx / shift; - if (!(dat & 2)) buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][xx2] ^= 0xFFFFFF; - } - dat >>= 2; - xx++; - if (!(xx % shift)) { - xx2 = xx / shift; - if (!(dat & 2)) buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][xx2] ^= 0xFFFFFF; - } - dat >>= 2; - xx++; - if (!(xx % shift)) { - xx2 = xx / shift; - if (!(dat & 2)) buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) buffer32->line[displine][xx2] ^= 0xFFFFFF; - } - dat >>= 2; - - offset += 4; + if (et4000->type == ET4000W32) { + switch (svga->bpp) { + case 8: + minus_width = 0; + x_acc = 2; + break; + case 15: + case 16: + minus_width = 64; + x_acc = 2; + break; + } } - svga->hwcursor_latch.addr += pitch; -} + for (x = 0; x < (width - minus_width); x += x_acc) { + dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; + xx = svga->hwcursor_latch.x + svga->x_add + x; + + if (!(xx % shift)) { + xx2 = xx / shift; + if (!(dat & 2)) + buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + buffer32->line[displine][xx2] ^= 0xFFFFFF; + } + dat >>= 2; + xx++; + if (!(xx % shift)) { + xx2 = xx / shift; + if (!(dat & 2)) + buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + buffer32->line[displine][xx2] ^= 0xFFFFFF; + } + dat >>= 2; + xx++; + if (!(xx % shift)) { + xx2 = xx / shift; + if (!(dat & 2)) + buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + buffer32->line[displine][xx2] ^= 0xFFFFFF; + } + dat >>= 2; + xx++; + if (!(xx % shift)) { + xx2 = xx / shift; + if (!(dat & 2)) + buffer32->line[displine][xx2] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) + buffer32->line[displine][xx2] ^= 0xFFFFFF; + } + dat >>= 2; + + offset += 4; + } + + svga->hwcursor_latch.addr += pitch; +} static void et4000w32p_io_remove(et4000w32p_t *et4000) @@ -1839,7 +2410,6 @@ et4000w32p_io_remove(et4000w32p_t *et4000) io_removehandler(0x217a, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); } - static void et4000w32p_io_set(et4000w32p_t *et4000) { @@ -1857,234 +2427,251 @@ et4000w32p_io_set(et4000w32p_t *et4000) io_sethandler(0x217a, 0x0002, et4000w32p_in, NULL, NULL, et4000w32p_out, NULL, NULL, et4000); } - uint8_t et4000w32p_pci_read(int func, int addr, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *) p; addr &= 0xff; switch (addr) { - case 0x00: return 0x0c; /* Tseng Labs */ - case 0x01: return 0x10; + case 0x00: + return 0x0c; /* Tseng Labs */ + case 0x01: + return 0x10; - case 0x02: return (et4000->rev); - case 0x03: return 0x32; + case 0x02: + return (et4000->rev); + case 0x03: + return 0x32; - case PCI_REG_COMMAND: - return et4000->pci_regs[PCI_REG_COMMAND] | 0x80; /* Respond to IO and memory accesses */ + case PCI_REG_COMMAND: + return et4000->pci_regs[PCI_REG_COMMAND] | 0x80; /* Respond to IO and memory accesses */ - case 0x07: return 1 << 1; /* Medium DEVSEL timing */ + case 0x07: + return 1 << 1; /* Medium DEVSEL timing */ - case 0x08: return (et4000->rev); /* Revision ID */ - case 0x09: return 0; /* Programming interface */ + case 0x08: + return (et4000->rev); /* Revision ID */ + case 0x09: + return 0; /* Programming interface */ - case 0x0a: return 0x00; /* Supports VGA interface */ - case 0x0b: return 0x03; /* This has to be done in order to make this card work with the two 486 PCI machines. */ + case 0x0a: + return 0x00; /* Supports VGA interface */ + case 0x0b: + return 0x03; /* This has to be done in order to make this card work with the two 486 PCI machines. */ - case 0x10: return 0x00; /* Linear frame buffer address */ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return (et4000->linearbase >> 24); + case 0x10: + return 0x00; /* Linear frame buffer address */ + case 0x11: + return 0x00; + case 0x12: + return 0x00; + case 0x13: + return (et4000->linearbase >> 24); - case 0x30: return et4000->pci_regs[0x30] & 0x01; /* BIOS ROM address */ - case 0x31: return 0x00; - case 0x32: return 0x00; - case 0x33: return et4000->pci_regs[0x33] & 0xf0; + case 0x30: + return et4000->pci_regs[0x30] & 0x01; /* BIOS ROM address */ + case 0x31: + return 0x00; + case 0x32: + return 0x00; + case 0x33: + return et4000->pci_regs[0x33] & 0xf0; } return 0; } - void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; + et4000w32p_t *et4000 = (et4000w32p_t *) p; + svga_t *svga = &et4000->svga; addr &= 0xff; switch (addr) { - case PCI_REG_COMMAND: - et4000->pci_regs[PCI_REG_COMMAND] = (val & 0x23) | 0x80; - if (val & PCI_COMMAND_IO) - et4000w32p_io_set(et4000); - else - et4000w32p_io_remove(et4000); - et4000w32p_recalcmapping(et4000); - break; + case PCI_REG_COMMAND: + et4000->pci_regs[PCI_REG_COMMAND] = (val & 0x23) | 0x80; + if (val & PCI_COMMAND_IO) + et4000w32p_io_set(et4000); + else + et4000w32p_io_remove(et4000); + et4000w32p_recalcmapping(et4000); + break; - case 0x13: - et4000->linearbase &= 0x00c00000; - et4000->linearbase |= (et4000->pci_regs[0x13] << 24); - svga->crtc[0x30] &= 3; - svga->crtc[0x30] |= ((et4000->linearbase & 0x3f000000) >> 22); - et4000w32p_recalcmapping(et4000); - break; + case 0x13: + et4000->linearbase &= 0x00c00000; + et4000->linearbase |= (et4000->pci_regs[0x13] << 24); + svga->crtc[0x30] &= 3; + svga->crtc[0x30] |= ((et4000->linearbase & 0x3f000000) >> 22); + et4000w32p_recalcmapping(et4000); + break; - case 0x30: case 0x31: case 0x32: case 0x33: - et4000->pci_regs[addr] = val; - et4000->pci_regs[0x30] = 1; - et4000->pci_regs[0x31] = 0; - et4000->pci_regs[0x32] = 0; - et4000->pci_regs[0x33] &= 0xf0; - if (et4000->pci_regs[0x30] & 0x01) { - uint32_t biosaddr = (et4000->pci_regs[0x33] << 24); - if (!biosaddr) - biosaddr = 0xc0000; - et4000w32_log("ET4000 bios_rom enabled at %08x\n", biosaddr); - mem_mapping_set_addr(&et4000->bios_rom.mapping, biosaddr, 0x8000); - } else { - et4000w32_log("ET4000 bios_rom disabled\n"); - mem_mapping_disable(&et4000->bios_rom.mapping); - } - return; + case 0x30: + case 0x31: + case 0x32: + case 0x33: + et4000->pci_regs[addr] = val; + et4000->pci_regs[0x30] = 1; + et4000->pci_regs[0x31] = 0; + et4000->pci_regs[0x32] = 0; + et4000->pci_regs[0x33] &= 0xf0; + if (et4000->pci_regs[0x30] & 0x01) { + uint32_t biosaddr = (et4000->pci_regs[0x33] << 24); + if (!biosaddr) + biosaddr = 0xc0000; + et4000w32_log("ET4000 bios_rom enabled at %08x\n", biosaddr); + mem_mapping_set_addr(&et4000->bios_rom.mapping, biosaddr, 0x8000); + } else { + et4000w32_log("ET4000 bios_rom disabled\n"); + mem_mapping_disable(&et4000->bios_rom.mapping); + } + return; } } - void * et4000w32p_init(const device_t *info) { - int vram_size; + int vram_size; et4000w32p_t *et4000 = malloc(sizeof(et4000w32p_t)); memset(et4000, 0, sizeof(et4000w32p_t)); et4000->pci = (info->flags & DEVICE_PCI) ? 0x80 : 0x00; et4000->vlb = (info->flags & DEVICE_VLB) ? 0x40 : 0x00; - /*The ET4000/W32i ISA BIOS seems to not support 2MB of VRAM*/ - if ((info->local == ET4000W32) || ((info->local == ET4000W32I) && !(et4000->vlb))) - vram_size = 1; - else - vram_size = device_get_config_int("memory"); + /*The ET4000/W32i ISA BIOS seems to not support 2MB of VRAM*/ + if ((info->local == ET4000W32) || ((info->local == ET4000W32I) && !(et4000->vlb))) + vram_size = 1; + else + vram_size = device_get_config_int("memory"); - /*The interleaved VRAM was introduced by the ET4000/W32i*/ + /*The interleaved VRAM was introduced by the ET4000/W32i*/ et4000->interleaved = ((vram_size == 2) && (info->local != ET4000W32)) ? 1 : 0; if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_pci); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_pci); else if (info->flags & DEVICE_VLB) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_vlb); else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_isa); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_et4000w32_isa); svga_init(info, &et4000->svga, et4000, vram_size << 20, - et4000w32p_recalctimings, - et4000w32p_in, et4000w32p_out, - et4000w32p_hwcursor_draw, - NULL); + et4000w32p_recalctimings, + et4000w32p_in, et4000w32p_out, + et4000w32p_hwcursor_draw, + NULL); - et4000->vram_mask = (vram_size << 20) - 1; - et4000->svga.decode_mask = (vram_size << 20) - 1; + et4000->vram_mask = (vram_size << 20) - 1; + et4000->svga.decode_mask = (vram_size << 20) - 1; et4000->type = info->local; - switch(et4000->type) { - case ET4000W32: - /* ET4000/W32 */ - et4000->rev = 0; + switch (et4000->type) { + case ET4000W32: + /* ET4000/W32 */ + et4000->rev = 0; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = sdac_getclock; - break; + et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = sdac_getclock; + break; - case ET4000W32I: - /* ET4000/W32i rev B */ - et4000->rev = 3; + case ET4000W32I: + /* ET4000/W32i rev B */ + et4000->rev = 3; - if (et4000->vlb) { - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_VLB, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); - } else { - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_ISA, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); - } + if (et4000->vlb) { + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_VLB, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); + } else { + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32I_ISA, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); + } - et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = sdac_getclock; - break; + et4000->svga.ramdac = device_add(&tseng_ics5301_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = sdac_getclock; + break; - case ET4000W32P_VIDEOMAGIC_REVB: - /* ET4000/W32p rev B */ - et4000->rev = 5; + case ET4000W32P_VIDEOMAGIC_REVB: + /* ET4000/W32p rev B */ + et4000->rev = 5; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; - break; + et4000->svga.ramdac = device_add(&stg_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = stg_getclock; + et4000->svga.adv_flags |= FLAG_NOSKEW; + break; - case ET4000W32P_REVC: - /* ET4000/W32p rev C */ - et4000->rev = 7; + case ET4000W32P_REVC: + /* ET4000/W32p rev C */ + et4000->rev = 7; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVC, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P_REVC, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&tseng_ics5341_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = sdac_getclock; - break; + et4000->svga.ramdac = device_add(&tseng_ics5341_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = sdac_getclock; + break; - case ET4000W32P: - /* ET4000/W32p rev D */ - et4000->rev = 6; + case ET4000W32P: + /* ET4000/W32p rev D */ + et4000->rev = 6; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_W32P, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; - break; + et4000->svga.ramdac = device_add(&stg_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = stg_getclock; + et4000->svga.adv_flags |= FLAG_NOSKEW; + break; - case ET4000W32P_CARDEX: - /* ET4000/W32p rev D */ - et4000->rev = 6; + case ET4000W32P_CARDEX: + /* ET4000/W32p rev D */ + et4000->rev = 6; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_CARDEX, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); - et4000->svga.clock_gen = et4000->svga.ramdac; - et4000->svga.getclock = stg_getclock; - et4000->svga.adv_flags |= FLAG_NOSKEW; - break; + et4000->svga.ramdac = device_add(&stg_ramdac_device); + et4000->svga.clock_gen = et4000->svga.ramdac; + et4000->svga.getclock = stg_getclock; + et4000->svga.adv_flags |= FLAG_NOSKEW; + break; - case ET4000W32P_DIAMOND: - /* ET4000/W32p rev D */ - et4000->rev = 6; + case ET4000W32P_DIAMOND: + /* ET4000/W32p rev D */ + et4000->rev = 6; - rom_init(&et4000->bios_rom, BIOS_ROM_PATH_DIAMOND, 0xc0000, 0x8000, 0x7fff, 0, - MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, BIOS_ROM_PATH_DIAMOND, 0xc0000, 0x8000, 0x7fff, 0, + MEM_MAPPING_EXTERNAL); - et4000->svga.ramdac = device_add(&stg_ramdac_device); - et4000->svga.clock_gen = device_add(&icd2061_device); - et4000->svga.getclock = icd2061_getclock; - break; + et4000->svga.ramdac = device_add(&stg_ramdac_device); + et4000->svga.clock_gen = device_add(&icd2061_device); + et4000->svga.getclock = icd2061_getclock; + break; } if (info->flags & DEVICE_PCI) - mem_mapping_disable(&et4000->bios_rom.mapping); + mem_mapping_disable(&et4000->bios_rom.mapping); mem_mapping_add(&et4000->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, MEM_MAPPING_EXTERNAL, &et4000->svga); - mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, et4000); + mem_mapping_add(&et4000->mmu_mapping, 0, 0, et4000w32p_mmu_read, NULL, NULL, et4000w32p_mmu_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, et4000); et4000w32p_io_set(et4000); if (info->flags & DEVICE_PCI) - pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000); + pci_add_card(PCI_ADD_VIDEO, et4000w32p_pci_read, et4000w32p_pci_write, et4000); /* Hardwired bits: 00000000 1xx0x0xx */ /* R/W bits: xx xxxx */ @@ -2101,26 +2688,23 @@ et4000w32p_init(const device_t *info) et4000->pci_regs[0x32] = 0x00; et4000->pci_regs[0x33] = 0xf0; - et4000->svga.packed_chain4 = 1; + et4000->svga.packed_chain4 = 1; return et4000; } - int et4000w32_available(void) { return rom_present(BIOS_ROM_PATH_W32); } - int et4000w32i_isa_available(void) { return rom_present(BIOS_ROM_PATH_W32I_ISA); } - int et4000w32i_vlb_available(void) { @@ -2133,65 +2717,58 @@ et4000w32p_videomagic_revb_vlb_available(void) return rom_present(BIOS_ROM_PATH_W32P_VIDEOMAGIC_REVB_VLB); } - int et4000w32p_revc_available(void) { return rom_present(BIOS_ROM_PATH_W32P_REVC); } - int et4000w32p_noncardex_available(void) { return rom_present(BIOS_ROM_PATH_W32P); } - int et4000w32p_available(void) { return rom_present(BIOS_ROM_PATH_DIAMOND); } - int et4000w32p_cardex_available(void) { return rom_present(BIOS_ROM_PATH_CARDEX); } - void et4000w32p_close(void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *) p; svga_close(&et4000->svga); free(et4000); } - void et4000w32p_speed_changed(void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *) p; svga_recalctimings(&et4000->svga); } - void et4000w32p_force_redraw(void *p) { - et4000w32p_t *et4000 = (et4000w32p_t *)p; + et4000w32p_t *et4000 = (et4000w32p_t *) p; et4000->svga.fullchange = changeframecount; } static const device_config_t et4000w32p_config[] = { -// clang-format off + // clang-format off { .name = "memory", .description = "Memory size", @@ -2218,183 +2795,197 @@ static const device_config_t et4000w32p_config[] = { }; const device_t et4000w32_device = { - .name = "Tseng Labs ET4000/w32 ISA", + .name = "Tseng Labs ET4000/w32 ISA", .internal_name = "et4000w32", - .flags = DEVICE_ISA | DEVICE_AT, ET4000W32, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = ET4000W32, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = NULL + .force_redraw = et4000w32p_force_redraw, + .config = NULL }; const device_t et4000w32_onboard_device = { - .name = "Tseng Labs ET4000/w32 (ISA) (On-Board)", + .name = "Tseng Labs ET4000/w32 (ISA) (On-Board)", .internal_name = "et4000w32_onboard", - .flags = DEVICE_ISA | DEVICE_AT, ET4000W32, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = ET4000W32, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = NULL + .force_redraw = et4000w32p_force_redraw, + .config = NULL }; const device_t et4000w32i_isa_device = { - .name = "Tseng Labs ET4000/w32i Rev. B ISA", + .name = "Tseng Labs ET4000/w32i Rev. B ISA", .internal_name = "et4000w32i", - .flags = DEVICE_ISA | DEVICE_AT, ET4000W32I, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = ET4000W32I, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32i_isa_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = NULL + .force_redraw = et4000w32p_force_redraw, + .config = NULL }; const device_t et4000w32i_vlb_device = { - .name = "Tseng Labs ET4000/w32i Rev. B VLB", + .name = "Tseng Labs ET4000/w32i Rev. B VLB", .internal_name = "et4000w32i_vlb", - .flags = DEVICE_VLB, ET4000W32I, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = ET4000W32I, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32i_vlb_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_videomagic_revb_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. B VLB (VideoMagic)", + .name = "Tseng Labs ET4000/w32p Rev. B VLB (VideoMagic)", .internal_name = "et4000w32p_videomagic_revb_vlb", - .flags = DEVICE_VLB, ET4000W32P_VIDEOMAGIC_REVB, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = ET4000W32P_VIDEOMAGIC_REVB, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_videomagic_revb_vlb_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_videomagic_revb_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. B PCI (VideoMagic)", + .name = "Tseng Labs ET4000/w32p Rev. B PCI (VideoMagic)", .internal_name = "et4000w32p_videomagic_revb_pci", - .flags = DEVICE_PCI, ET4000W32P_VIDEOMAGIC_REVB, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = ET4000W32P_VIDEOMAGIC_REVB, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_videomagic_revb_vlb_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_revc_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. C VLB (Cardex)", + .name = "Tseng Labs ET4000/w32p Rev. C VLB (Cardex)", .internal_name = "et4000w32p_revc_vlb", - .flags = DEVICE_VLB, ET4000W32P_REVC, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = ET4000W32P_REVC, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_revc_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_revc_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. C PCI (Cardex)", + .name = "Tseng Labs ET4000/w32p Rev. C PCI (Cardex)", .internal_name = "et4000w32p_revc_pci", - .flags = DEVICE_PCI, ET4000W32P_REVC, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = ET4000W32P_REVC, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_revc_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_noncardex_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. D VLB", + .name = "Tseng Labs ET4000/w32p Rev. D VLB", .internal_name = "et4000w32p_nc_vlb", - .flags = DEVICE_VLB, ET4000W32P, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = ET4000W32P, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_noncardex_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_noncardex_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. D PCI", + .name = "Tseng Labs ET4000/w32p Rev. D PCI", .internal_name = "et4000w32p_nc_pci", - .flags = DEVICE_PCI, ET4000W32P, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = ET4000W32P, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_noncardex_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_cardex_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. D VLB (Cardex)", + .name = "Tseng Labs ET4000/w32p Rev. D VLB (Cardex)", .internal_name = "et4000w32p_vlb", - .flags = DEVICE_VLB, ET4000W32P_CARDEX, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = ET4000W32P_CARDEX, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_cardex_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_cardex_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. D PCI (Cardex)", + .name = "Tseng Labs ET4000/w32p Rev. D PCI (Cardex)", .internal_name = "et4000w32p_pci", - .flags = DEVICE_PCI, ET4000W32P_CARDEX, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = ET4000W32P_CARDEX, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_cardex_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_vlb_device = { - .name = "Tseng Labs ET4000/w32p Rev. D VLB (Diamond Stealth32)", + .name = "Tseng Labs ET4000/w32p Rev. D VLB (Diamond Stealth32)", .internal_name = "stealth32_vlb", - .flags = DEVICE_VLB, ET4000W32P_DIAMOND, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = ET4000W32P_DIAMOND, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; const device_t et4000w32p_pci_device = { - .name = "Tseng Labs ET4000/w32p Rev. D PCI (Diamond Stealth32)", + .name = "Tseng Labs ET4000/w32p Rev. D PCI (Diamond Stealth32)", .internal_name = "stealth32_pci", - .flags = DEVICE_PCI, ET4000W32P_DIAMOND, - .init = et4000w32p_init, - .close = et4000w32p_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = ET4000W32P_DIAMOND, + .init = et4000w32p_init, + .close = et4000w32p_close, + .reset = NULL, { .available = et4000w32p_available }, .speed_changed = et4000w32p_speed_changed, - .force_redraw = et4000w32p_force_redraw, - .config = et4000w32p_config + .force_redraw = et4000w32p_force_redraw, + .config = et4000w32p_config }; diff --git a/src/video/vid_f82c425.c b/src/video/vid_f82c425.c index 1e36ea5aa..0d1b9f1d7 100644 --- a/src/video/vid_f82c425.c +++ b/src/video/vid_f82c425.c @@ -71,101 +71,103 @@ static uint32_t smartmap[256][2]; static uint32_t colormap[4]; -static video_timings_t timing_f82c425 = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_f82c425 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static uint8_t st_video_options; -static uint8_t st_enabled = 1; -static int8_t st_display_internal = -1; +static uint8_t st_enabled = 1; +static int8_t st_display_internal = -1; -void f82c425_video_options_set(uint8_t options) +void +f82c425_video_options_set(uint8_t options) { - st_video_options = options; + st_video_options = options; } -void f82c425_video_enable(uint8_t enabled) +void +f82c425_video_enable(uint8_t enabled) { - st_enabled = enabled; + st_enabled = enabled; } -void f82c425_display_set(uint8_t internal) +void +f82c425_display_set(uint8_t internal) { - st_display_internal = (int8_t)internal; + st_display_internal = (int8_t) internal; } -uint8_t f82c425_display_get() +uint8_t +f82c425_display_get() { - return (uint8_t)st_display_internal; + return (uint8_t) st_display_internal; } +typedef struct f82c425_t { + mem_mapping_t mapping; + cga_t cga; + uint8_t crtcreg; -typedef struct f82c425_t -{ - mem_mapping_t mapping; - cga_t cga; - uint8_t crtcreg; + uint64_t dispontime, dispofftime; - uint64_t dispontime, dispofftime; + int linepos, displine; + int dispon; + uint8_t video_options; - int linepos, displine; - int dispon; - uint8_t video_options; + uint8_t *vram; - uint8_t *vram; - - /* Registers specific to 82C425. */ - uint8_t ac_limit; - uint8_t threshold; - uint8_t shift; - uint8_t hsync; - uint8_t vsync_blink; - uint8_t timing; - uint8_t function; + /* Registers specific to 82C425. */ + uint8_t ac_limit; + uint8_t threshold; + uint8_t shift; + uint8_t hsync; + uint8_t vsync_blink; + uint8_t timing; + uint8_t function; } f82c425_t; - /* Convert IRGB representation to RGBI, * useful in SMARTMAP calculations. */ -static inline uint8_t f82c425_rgbi(uint8_t irgb) +static inline uint8_t +f82c425_rgbi(uint8_t irgb) { - return ((irgb & 0x7) << 1) | (irgb >> 3); + return ((irgb & 0x7) << 1) | (irgb >> 3); } /* Convert IRGB SMARTMAP output to a RGB representation of one of 4/8 grey * shades we'd see on an actual V86P display: with some bias toward lighter * shades and a backlight with yellow/green-ish tint. */ -static inline uint32_t f82c425_makecol(uint8_t rgbi, int gs4, int inv) +static inline uint32_t +f82c425_makecol(uint8_t rgbi, int gs4, int inv) { - uint8_t c; + uint8_t c; - gs4 = 1 + !!gs4; - if (!inv) - { - rgbi = 15 - rgbi; - } - c = 0x10 * gs4 * ((rgbi >> gs4) + 2); + gs4 = 1 + !!gs4; + if (!inv) { + rgbi = 15 - rgbi; + } + c = 0x10 * gs4 * ((rgbi >> gs4) + 2); #ifdef NO_BLUE - return makecol(c, c + 0x08, c - 0x20); + return makecol(c, c + 0x08, c - 0x20); #else - return makecol(c, c + 0x08, 0x70); + return makecol(c, c + 0x08, 0x70); #endif } /* Saturating/non-saturating addition for SMARTMAP(see below). */ -static inline int f82c425_smartmap_add(int a, int b, int sat) +static inline int +f82c425_smartmap_add(int a, int b, int sat) { - int c = a + b; + int c = a + b; - /* (SATURATING OR NON SATURATING) */ - if (sat) - { - if (c < 0) - c = 0; - else if (c > 15) - c = 15; - } + /* (SATURATING OR NON SATURATING) */ + if (sat) { + if (c < 0) + c = 0; + else if (c > 15) + c = 15; + } - return c & 0xf; + return c & 0xf; } /* Calculate and cache mapping of CGA text color attribute to a @@ -174,503 +176,454 @@ static inline int f82c425_smartmap_add(int a, int b, int sat) * This is a straightforward implementation of the algorithm as described * in U.S. Patent 4,977,398 [2]. The comments in capitals refer to portions * of a figure on page 4. */ -static void f82c425_smartmap(f82c425_t *f82c425) +static void +f82c425_smartmap(f82c425_t *f82c425) { - int i; + int i; - for (i = 0; i < 256; i++) { - uint8_t bg = f82c425_rgbi(i >> 4); - uint8_t fg = f82c425_rgbi(i & 0xf); + for (i = 0; i < 256; i++) { + uint8_t bg = f82c425_rgbi(i >> 4); + uint8_t fg = f82c425_rgbi(i & 0xf); - /* FIG._4. */ - if (abs(bg - fg) <= (f82c425->threshold & 0x0f)) - { - /* FOREGROUND=BACKGROUND */ - if (bg == fg) - { - /* SPECIAL CASE */ - if (f82c425->shift == 0xff) - { - /* CHECK MOST SIGNIFICANT BIT */ - if (fg & 0x8) - { - /* FULL WHITE */ - fg = bg = 15; - } - else - { - /* FULL BLACK */ - fg = bg = 0; - } - } - } - else - { - uint8_t sat = f82c425->threshold & 0x10; + /* FIG._4. */ + if (abs(bg - fg) <= (f82c425->threshold & 0x0f)) { + /* FOREGROUND=BACKGROUND */ + if (bg == fg) { + /* SPECIAL CASE */ + if (f82c425->shift == 0xff) { + /* CHECK MOST SIGNIFICANT BIT */ + if (fg & 0x8) { + /* FULL WHITE */ + fg = bg = 15; + } else { + /* FULL BLACK */ + fg = bg = 0; + } + } + } else { + uint8_t sat = f82c425->threshold & 0x10; - /* DETERMINE WHICH IS LIGHT */ - if (fg > bg) - { - fg = f82c425_smartmap_add(fg, f82c425->shift & 0x0f, sat); - bg = f82c425_smartmap_add(bg, -(f82c425->shift >> 4), sat); - } - else - { - fg = f82c425_smartmap_add(fg, -(f82c425->shift & 0x0f), sat); - bg = f82c425_smartmap_add(bg, f82c425->shift >> 4, sat); - } - } - } + /* DETERMINE WHICH IS LIGHT */ + if (fg > bg) { + fg = f82c425_smartmap_add(fg, f82c425->shift & 0x0f, sat); + bg = f82c425_smartmap_add(bg, -(f82c425->shift >> 4), sat); + } else { + fg = f82c425_smartmap_add(fg, -(f82c425->shift & 0x0f), sat); + bg = f82c425_smartmap_add(bg, f82c425->shift >> 4, sat); + } + } + } - smartmap[i][0] = f82c425_makecol(bg, f82c425->threshold & 0x20, f82c425->function & 0x80); - smartmap[i][1] = f82c425_makecol(fg, f82c425->threshold & 0x20, f82c425->function & 0x80); - } + smartmap[i][0] = f82c425_makecol(bg, f82c425->threshold & 0x20, f82c425->function & 0x80); + smartmap[i][1] = f82c425_makecol(fg, f82c425->threshold & 0x20, f82c425->function & 0x80); + } } /* Calculate mapping of 320x200 graphical mode colors. */ -static void f82c425_colormap(f82c425_t *f82c425) +static void +f82c425_colormap(f82c425_t *f82c425) { - int i; + int i; - for (i = 0; i < 4; i++) - colormap[i] = f82c425_makecol(5 * i, 0, f82c425->function & 0x80); + for (i = 0; i < 4; i++) + colormap[i] = f82c425_makecol(5 * i, 0, f82c425->function & 0x80); } -static void f82c425_out(uint16_t addr, uint8_t val, void *p) +static void +f82c425_out(uint16_t addr, uint8_t val, void *p) { - f82c425_t *f82c425 = (f82c425_t *)p; + f82c425_t *f82c425 = (f82c425_t *) p; - if (addr == 0x3d4) - f82c425->crtcreg = val; + if (addr == 0x3d4) + f82c425->crtcreg = val; - if (((f82c425->function & 0x01) == 0) && ((f82c425->crtcreg != 0xdf) || (addr != 0x3d5))) - return; + if (((f82c425->function & 0x01) == 0) && ((f82c425->crtcreg != 0xdf) || (addr != 0x3d5))) + return; - if (addr != 0x3d5 || f82c425->crtcreg <= 31) - { - cga_out(addr, val, &f82c425->cga); - return; - } + if (addr != 0x3d5 || f82c425->crtcreg <= 31) { + cga_out(addr, val, &f82c425->cga); + return; + } - switch (f82c425->crtcreg) - { - case 0xd9: - f82c425->ac_limit = val; - break; - case 0xda: - f82c425->threshold = val; - f82c425_smartmap(f82c425); - break; - case 0xdb: - f82c425->shift = val; - f82c425_smartmap(f82c425); - break; - case 0xdc: - f82c425->hsync = val; - break; - case 0xdd: - f82c425->vsync_blink = val; - break; - case 0xde: - f82c425->timing = val; - break; - case 0xdf: - f82c425->function = val; - f82c425_smartmap(f82c425); - f82c425_colormap(f82c425); - break; - } + switch (f82c425->crtcreg) { + case 0xd9: + f82c425->ac_limit = val; + break; + case 0xda: + f82c425->threshold = val; + f82c425_smartmap(f82c425); + break; + case 0xdb: + f82c425->shift = val; + f82c425_smartmap(f82c425); + break; + case 0xdc: + f82c425->hsync = val; + break; + case 0xdd: + f82c425->vsync_blink = val; + break; + case 0xde: + f82c425->timing = val; + break; + case 0xdf: + f82c425->function = val; + f82c425_smartmap(f82c425); + f82c425_colormap(f82c425); + break; + } } -static uint8_t f82c425_in(uint16_t addr, void *p) +static uint8_t +f82c425_in(uint16_t addr, void *p) { - f82c425_t *f82c425 = (f82c425_t *)p; + f82c425_t *f82c425 = (f82c425_t *) p; - if ((f82c425->function & 0x01) == 0) - return 0xff; + if ((f82c425->function & 0x01) == 0) + return 0xff; - if (addr == 0x3d4) - return f82c425->crtcreg; + if (addr == 0x3d4) + return f82c425->crtcreg; - if (addr != 0x3d5 || f82c425->crtcreg <= 31) - return cga_in(addr, &f82c425->cga); + if (addr != 0x3d5 || f82c425->crtcreg <= 31) + return cga_in(addr, &f82c425->cga); - switch (f82c425->crtcreg) - { - case 0xd9: - return f82c425->ac_limit; - case 0xda: - return f82c425->threshold; - case 0xdb: - return f82c425->shift; - case 0xdc: - return f82c425->hsync; - case 0xdd: - return f82c425->vsync_blink; - case 0xde: - return f82c425->timing; - case 0xdf: - return f82c425->function; - } + switch (f82c425->crtcreg) { + case 0xd9: + return f82c425->ac_limit; + case 0xda: + return f82c425->threshold; + case 0xdb: + return f82c425->shift; + case 0xdc: + return f82c425->hsync; + case 0xdd: + return f82c425->vsync_blink; + case 0xde: + return f82c425->timing; + case 0xdf: + return f82c425->function; + } - return 0xff; + return 0xff; } -static void f82c425_write(uint32_t addr, uint8_t val, void *p) +static void +f82c425_write(uint32_t addr, uint8_t val, void *p) { - f82c425_t *f82c425 = (f82c425_t *)p; + f82c425_t *f82c425 = (f82c425_t *) p; - f82c425->vram[addr & 0x3fff] = val; - cycles -= 4; + f82c425->vram[addr & 0x3fff] = val; + cycles -= 4; } -static uint8_t f82c425_read(uint32_t addr, void *p) +static uint8_t +f82c425_read(uint32_t addr, void *p) { - f82c425_t *f82c425 = (f82c425_t *)p; - cycles -= 4; + f82c425_t *f82c425 = (f82c425_t *) p; + cycles -= 4; - return f82c425->vram[addr & 0x3fff]; + return f82c425->vram[addr & 0x3fff]; } -static void f82c425_recalctimings(f82c425_t *f82c425) +static void +f82c425_recalctimings(f82c425_t *f82c425) { - double disptime; - double _dispontime, _dispofftime; + double disptime; + double _dispontime, _dispofftime; - if (f82c425->function & 0x08) - { - cga_recalctimings(&f82c425->cga); - return; - } + if (f82c425->function & 0x08) { + cga_recalctimings(&f82c425->cga); + return; + } - disptime = 651; - _dispontime = 640; - _dispofftime = disptime - _dispontime; - f82c425->dispontime = (uint64_t)(_dispontime * xt_cpu_multi); - f82c425->dispofftime = (uint64_t)(_dispofftime * xt_cpu_multi); + disptime = 651; + _dispontime = 640; + _dispofftime = disptime - _dispontime; + f82c425->dispontime = (uint64_t) (_dispontime * xt_cpu_multi); + f82c425->dispofftime = (uint64_t) (_dispofftime * xt_cpu_multi); } /* Draw a row of text. */ -static void f82c425_text_row(f82c425_t *f82c425) +static void +f82c425_text_row(f82c425_t *f82c425) { - uint32_t colors[2]; - int x, c; - uint8_t chr, attr; - int drawcursor; - int cursorline; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; - uint16_t ca = (f82c425->cga.crtc[0x0f] | (f82c425->cga.crtc[0x0e] << 8)) & 0x3fff; - uint8_t sl = f82c425->cga.crtc[9] + 1; - int columns = f82c425->cga.crtc[1]; + uint32_t colors[2]; + int x, c; + uint8_t chr, attr; + int drawcursor; + int cursorline; + int blink; + uint16_t addr; + uint8_t sc; + uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; + uint16_t ca = (f82c425->cga.crtc[0x0f] | (f82c425->cga.crtc[0x0e] << 8)) & 0x3fff; + uint8_t sl = f82c425->cga.crtc[9] + 1; + int columns = f82c425->cga.crtc[1]; - sc = (f82c425->displine) & 7; - addr = ((ma & ~1) + (f82c425->displine >> 3) * columns) * 2; - ma += (f82c425->displine >> 3) * columns; + sc = (f82c425->displine) & 7; + addr = ((ma & ~1) + (f82c425->displine >> 3) * columns) * 2; + ma += (f82c425->displine >> 3) * columns; - if ((f82c425->cga.crtc[0x0a] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((f82c425->cga.crtc[0x0a] & 0x0F) <= sc) && - ((f82c425->cga.crtc[0x0b] & 0x0F) >= sc); - } + if ((f82c425->cga.crtc[0x0a] & 0x60) == 0x20) { + cursorline = 0; + } else { + cursorline = ((f82c425->cga.crtc[0x0a] & 0x0F) <= sc) && ((f82c425->cga.crtc[0x0b] & 0x0F) >= sc); + } - for (x = 0; x < columns; x++) - { - chr = f82c425->vram[(addr + 2 * x) & 0x3FFF]; - attr = f82c425->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && - (f82c425->cga.cgamode & 0x8) && (f82c425->cga.cgablink & 0x10)); + for (x = 0; x < columns; x++) { + chr = f82c425->vram[(addr + 2 * x) & 0x3FFF]; + attr = f82c425->vram[(addr + 2 * x + 1) & 0x3FFF]; + drawcursor = ((ma == ca) && cursorline && (f82c425->cga.cgamode & 0x8) && (f82c425->cga.cgablink & 0x10)); - blink = ((f82c425->cga.cgablink & 0x10) && (f82c425->cga.cgamode & 0x20) && - (attr & 0x80) && !drawcursor); + blink = ((f82c425->cga.cgablink & 0x10) && (f82c425->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - if (drawcursor) - { - colors[0] = smartmap[~attr & 0xff][0]; - colors[1] = smartmap[~attr & 0xff][1]; - } - else - { - colors[0] = smartmap[attr][0]; - colors[1] = smartmap[attr][1]; - } + if (drawcursor) { + colors[0] = smartmap[~attr & 0xff][0]; + colors[1] = smartmap[~attr & 0xff][1]; + } else { + colors[0] = smartmap[attr][0]; + colors[1] = smartmap[attr][1]; + } - if (blink) - colors[1] = colors[0]; + if (blink) + colors[1] = colors[0]; - if (f82c425->cga.cgamode & 0x01) - { - /* High resolution (80 cols) */ - for (c = 0; c < sl; c++) - { - ((uint32_t *)buffer32->line[f82c425->displine])[(x << 3) + c] = - colors[(fontdat[chr][sc] & (1 <<(c ^ 7))) ? 1 : 0]; - } - } - else - { - /* Low resolution (40 columns, stretch pixels horizontally) */ - for (c = 0; c < sl; c++) - { - ((uint32_t *)buffer32->line[f82c425->displine])[(x << 4) + c*2] = - ((uint32_t *)buffer32->line[f82c425->displine])[(x << 4) + c*2+1] = - colors[(fontdat[chr][sc] & (1 <<(c ^ 7))) ? 1 : 0]; - } - } + if (f82c425->cga.cgamode & 0x01) { + /* High resolution (80 cols) */ + for (c = 0; c < sl; c++) { + ((uint32_t *) buffer32->line[f82c425->displine])[(x << 3) + c] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + } else { + /* Low resolution (40 columns, stretch pixels horizontally) */ + for (c = 0; c < sl; c++) { + ((uint32_t *) buffer32->line[f82c425->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[f82c425->displine])[(x << 4) + c * 2 + 1] = colors[(fontdat[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + } - ++ma; - } + ++ma; + } } /* Draw a line in CGA 640x200 mode */ -static void f82c425_cgaline6(f82c425_t *f82c425) +static void +f82c425_cgaline6(f82c425_t *f82c425) { - int x, c; - uint8_t dat; - uint16_t addr; + int x, c; + uint8_t dat; + uint16_t addr; - uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; + uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; - addr = ((f82c425->displine) & 1) * 0x2000 + - (f82c425->displine >> 1) * 80 + - ((ma & ~1) << 1); + addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((ma & ~1) << 1); - for (x = 0; x < 80; x++) - { - dat = f82c425->vram[addr & 0x3FFF]; - addr++; + for (x = 0; x < 80; x++) { + dat = f82c425->vram[addr & 0x3FFF]; + addr++; - for (c = 0; c < 8; c++) - { - ((uint32_t *)buffer32->line[f82c425->displine])[x*8+c] = - colormap[dat & 0x80 ? 3 : 0]; + for (c = 0; c < 8; c++) { + ((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + c] = colormap[dat & 0x80 ? 3 : 0]; - dat = dat << 1; - } - } + dat = dat << 1; + } + } } /* Draw a line in CGA 320x200 mode. */ -static void f82c425_cgaline4(f82c425_t *f82c425) +static void +f82c425_cgaline4(f82c425_t *f82c425) { - int x, c; - uint8_t dat, pattern; - uint16_t addr; + int x, c; + uint8_t dat, pattern; + uint16_t addr; - uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; - addr = ((f82c425->displine) & 1) * 0x2000 + - (f82c425->displine >> 1) * 80 + - ((ma & ~1) << 1); + uint16_t ma = (f82c425->cga.crtc[0x0d] | (f82c425->cga.crtc[0x0c] << 8)) & 0x3fff; + addr = ((f82c425->displine) & 1) * 0x2000 + (f82c425->displine >> 1) * 80 + ((ma & ~1) << 1); - for (x = 0; x < 80; x++) - { - dat = f82c425->vram[addr & 0x3FFF]; - addr++; + for (x = 0; x < 80; x++) { + dat = f82c425->vram[addr & 0x3FFF]; + addr++; - for (c = 0; c < 4; c++) - { - pattern = (dat & 0xC0) >> 6; - if (!(f82c425->cga.cgamode & 0x08)) pattern = 0; + for (c = 0; c < 4; c++) { + pattern = (dat & 0xC0) >> 6; + if (!(f82c425->cga.cgamode & 0x08)) + pattern = 0; - ((uint32_t *)buffer32->line[f82c425->displine])[x*8+2*c] = - ((uint32_t *)buffer32->line[f82c425->displine])[x*8+2*c+1] = - colormap[pattern & 3]; + ((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + 2 * c] = ((uint32_t *) buffer32->line[f82c425->displine])[x * 8 + 2 * c + 1] = colormap[pattern & 3]; - dat = dat << 2; - } - } + dat = dat << 2; + } + } } -static void f82c425_poll(void *p) +static void +f82c425_poll(void *p) { - f82c425_t *f82c425 = (f82c425_t *)p; + f82c425_t *f82c425 = (f82c425_t *) p; - if (f82c425->video_options != st_video_options || - !!(f82c425->function & 1) != st_enabled) - { - f82c425->video_options = st_video_options; - f82c425->function &= ~1; - f82c425->function |= st_enabled ? 1 : 0; + if (f82c425->video_options != st_video_options || !!(f82c425->function & 1) != st_enabled) { + f82c425->video_options = st_video_options; + f82c425->function &= ~1; + f82c425->function |= st_enabled ? 1 : 0; - if (f82c425->function & 0x01) - mem_mapping_enable(&f82c425->mapping); - else - mem_mapping_disable(&f82c425->mapping); - } - /* Switch between internal LCD and external CRT display. */ - if (st_display_internal != -1 && st_display_internal != !!(f82c425->function & 0x08)) - { - if (st_display_internal) - { - f82c425->function &= ~0x08; - f82c425->timing &= ~0x20; - } - else - { - f82c425->function |= 0x08; - f82c425->timing |= 0x20; - } - f82c425_recalctimings(f82c425); - } + if (f82c425->function & 0x01) + mem_mapping_enable(&f82c425->mapping); + else + mem_mapping_disable(&f82c425->mapping); + } + /* Switch between internal LCD and external CRT display. */ + if (st_display_internal != -1 && st_display_internal != !!(f82c425->function & 0x08)) { + if (st_display_internal) { + f82c425->function &= ~0x08; + f82c425->timing &= ~0x20; + } else { + f82c425->function |= 0x08; + f82c425->timing |= 0x20; + } + f82c425_recalctimings(f82c425); + } - if (f82c425->function & 0x08) - { - cga_poll(&f82c425->cga); - return; - } + if (f82c425->function & 0x08) { + cga_poll(&f82c425->cga); + return; + } - if (!f82c425->linepos) - { - timer_advance_u64(&f82c425->cga.timer, f82c425->dispofftime); - f82c425->cga.cgastat |= 1; - f82c425->linepos = 1; - if (f82c425->dispon) - { - if (f82c425->displine == 0) - { - video_wait_for_buffer(); - } + if (!f82c425->linepos) { + timer_advance_u64(&f82c425->cga.timer, f82c425->dispofftime); + f82c425->cga.cgastat |= 1; + f82c425->linepos = 1; + if (f82c425->dispon) { + if (f82c425->displine == 0) { + video_wait_for_buffer(); + } - switch (f82c425->cga.cgamode & 0x13) - { - case 0x12: - f82c425_cgaline6(f82c425); - break; - case 0x02: - f82c425_cgaline4(f82c425); - break; - case 0x00: - case 0x01: - f82c425_text_row(f82c425); - break; - } - } - f82c425->displine++; + switch (f82c425->cga.cgamode & 0x13) { + case 0x12: + f82c425_cgaline6(f82c425); + break; + case 0x02: + f82c425_cgaline4(f82c425); + break; + case 0x00: + case 0x01: + f82c425_text_row(f82c425); + break; + } + } + f82c425->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (f82c425->displine >= 216) - { - /* End of VSYNC */ - f82c425->displine = 0; - f82c425->cga.cgastat &= ~8; - f82c425->dispon = 1; - } - else - if (f82c425->displine == (f82c425->cga.crtc[9] + 1) * f82c425->cga.crtc[6]) - { - /* Start of VSYNC */ - f82c425->cga.cgastat |= 8; - f82c425->dispon = 0; - } - } - else - { - if (f82c425->dispon) - f82c425->cga.cgastat &= ~1; - timer_advance_u64(&f82c425->cga.timer, f82c425->dispontime); - f82c425->linepos = 0; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (f82c425->displine >= 216) { + /* End of VSYNC */ + f82c425->displine = 0; + f82c425->cga.cgastat &= ~8; + f82c425->dispon = 1; + } else if (f82c425->displine == (f82c425->cga.crtc[9] + 1) * f82c425->cga.crtc[6]) { + /* Start of VSYNC */ + f82c425->cga.cgastat |= 8; + f82c425->dispon = 0; + } + } else { + if (f82c425->dispon) + f82c425->cga.cgastat &= ~1; + timer_advance_u64(&f82c425->cga.timer, f82c425->dispontime); + f82c425->linepos = 0; - if (f82c425->displine == 200) - { - /* Hardcode 640x200 window size */ - if ((F82C425_XSIZE != xsize) || (F82C425_YSIZE != ysize) || video_force_resize_get()) - { - xsize = F82C425_XSIZE; - ysize = F82C425_YSIZE; - set_screen_size(xsize, ysize); + if (f82c425->displine == 200) { + /* Hardcode 640x200 window size */ + if ((F82C425_XSIZE != xsize) || (F82C425_YSIZE != ysize) || video_force_resize_get()) { + xsize = F82C425_XSIZE; + ysize = F82C425_YSIZE; + set_screen_size(xsize, ysize); - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen(0, 0, xsize, ysize); - frames++; + if (video_force_resize_get()) + video_force_resize_set(0); + } + video_blit_memtoscreen(0, 0, xsize, ysize); + frames++; - /* Fixed 640x200 resolution */ - video_res_x = F82C425_XSIZE; - video_res_y = F82C425_YSIZE; + /* Fixed 640x200 resolution */ + video_res_x = F82C425_XSIZE; + video_res_y = F82C425_YSIZE; - switch (f82c425->cga.cgamode & 0x12) - { - case 0x12: - video_bpp = 1; - break; - case 0x02: - video_bpp = 2; - break; - default: - video_bpp = 0; - } + switch (f82c425->cga.cgamode & 0x12) { + case 0x12: + video_bpp = 1; + break; + case 0x02: + video_bpp = 2; + break; + default: + video_bpp = 0; + } - f82c425->cga.cgablink++; - } - } + f82c425->cga.cgablink++; + } + } } -static void *f82c425_init(const device_t *info) +static void * +f82c425_init(const device_t *info) { - f82c425_t *f82c425 = malloc(sizeof(f82c425_t)); - memset(f82c425, 0, sizeof(f82c425_t)); - cga_init(&f82c425->cga); - video_inform(VIDEO_FLAG_TYPE_CGA, &timing_f82c425); + f82c425_t *f82c425 = malloc(sizeof(f82c425_t)); + memset(f82c425, 0, sizeof(f82c425_t)); + cga_init(&f82c425->cga); + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_f82c425); - /* Initialize registers that don't default to zero. */ - f82c425->hsync = 0x40; - f82c425->vsync_blink = 0x72; + /* Initialize registers that don't default to zero. */ + f82c425->hsync = 0x40; + f82c425->vsync_blink = 0x72; - /* 16k video RAM */ - f82c425->vram = malloc(0x4000); + /* 16k video RAM */ + f82c425->vram = malloc(0x4000); - timer_set_callback(&f82c425->cga.timer, f82c425_poll); - timer_set_p(&f82c425->cga.timer, f82c425); + timer_set_callback(&f82c425->cga.timer, f82c425_poll); + timer_set_p(&f82c425->cga.timer, f82c425); - /* Occupy memory between 0xB8000 and 0xBFFFF */ - mem_mapping_add(&f82c425->mapping, 0xb8000, 0x8000, f82c425_read, NULL, NULL, f82c425_write, NULL, NULL, NULL, 0, f82c425); - /* Respond to CGA I/O ports */ - io_sethandler(0x03d0, 0x000c, f82c425_in, NULL, NULL, f82c425_out, NULL, NULL, f82c425); + /* Occupy memory between 0xB8000 and 0xBFFFF */ + mem_mapping_add(&f82c425->mapping, 0xb8000, 0x8000, f82c425_read, NULL, NULL, f82c425_write, NULL, NULL, NULL, 0, f82c425); + /* Respond to CGA I/O ports */ + io_sethandler(0x03d0, 0x000c, f82c425_in, NULL, NULL, f82c425_out, NULL, NULL, f82c425); - /* Initialize color maps for text & graphic modes */ - f82c425_smartmap(f82c425); - f82c425_colormap(f82c425); + /* Initialize color maps for text & graphic modes */ + f82c425_smartmap(f82c425); + f82c425_colormap(f82c425); - /* Start off in 80x25 text mode */ - f82c425->cga.cgastat = 0xF4; - f82c425->cga.vram = f82c425->vram; - f82c425->video_options = 0x01; + /* Start off in 80x25 text mode */ + f82c425->cga.cgastat = 0xF4; + f82c425->cga.vram = f82c425->vram; + f82c425->video_options = 0x01; - return f82c425; + return f82c425; } -static void f82c425_close(void *p) +static void +f82c425_close(void *p) { - f82c425_t *f82c425 = (f82c425_t *)p; + f82c425_t *f82c425 = (f82c425_t *) p; - free(f82c425->vram); - free(f82c425); + free(f82c425->vram); + free(f82c425); } -static void f82c425_speed_changed(void *p) +static void +f82c425_speed_changed(void *p) { - f82c425_t *f82c425 = (f82c425_t *)p; + f82c425_t *f82c425 = (f82c425_t *) p; - f82c425_recalctimings(f82c425); + f82c425_recalctimings(f82c425); } const device_t f82c425_video_device = { - .name = "82C425 CGA LCD/CRT Controller", + .name = "82C425 CGA LCD/CRT Controller", .internal_name = "f82c425_video", - .flags = 0, - .local = 0, - .init = f82c425_init, - .close = f82c425_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = f82c425_init, + .close = f82c425_close, + .reset = NULL, { .available = NULL }, .speed_changed = f82c425_speed_changed, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_genius.c b/src/video/vid_genius.c index c275eeb35..643aaa643 100644 --- a/src/video/vid_genius.c +++ b/src/video/vid_genius.c @@ -32,18 +32,14 @@ #include <86box/plat.h> #include <86box/video.h> +#define BIOS_ROM_PATH "roms/video/genius/8x12.bin" -#define BIOS_ROM_PATH "roms/video/genius/8x12.bin" - - -#define GENIUS_XSIZE 728 -#define GENIUS_YSIZE 1008 - +#define GENIUS_XSIZE 728 +#define GENIUS_YSIZE 1008 extern uint8_t fontdat8x12[256][16]; -static video_timings_t timing_genius = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; - +static video_timings_t timing_genius = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; /* I'm at something of a disadvantage writing this emulation: I don't have an * MDSI Genius card, nor do I have the BIOS extension (VHRBIOS.SYS) that came @@ -95,48 +91,45 @@ static video_timings_t timing_genius = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; * in an 8x12 cell if necessary. */ +typedef struct genius_t { + mem_mapping_t mapping; + uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */ + int mda_crtcreg; /* Current CRTC register */ + uint8_t cga_crtc[32]; /* The 'CRTC' as the host PC sees it */ + int cga_crtcreg; /* Current CRTC register */ + uint8_t genius_control; /* Native control register + * I think bit 0 enables the full + * framebuffer. + */ + uint8_t genius_charh; /* Native character height register: + * 00h => chars are 15 pixels high + * 81h => chars are 14 pixels high + * 83h => chars are 12 pixels high + * 90h => chars are 30 pixels high [15 x 2] + * 93h => chars are 24 pixels high [12 x 2] + */ + uint8_t genius_mode; /* Current mode (see list at top of file) */ + uint8_t cga_ctrl; /* Emulated CGA control register */ + uint8_t mda_ctrl; /* Emulated MDA control register */ + uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ -typedef struct genius_t -{ - mem_mapping_t mapping; + uint8_t mda_stat; /* MDA status (IN 0x3BA) */ + uint8_t cga_stat; /* CGA status (IN 0x3DA) */ - uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */ - int mda_crtcreg; /* Current CRTC register */ - uint8_t cga_crtc[32]; /* The 'CRTC' as the host PC sees it */ - int cga_crtcreg; /* Current CRTC register */ - uint8_t genius_control; /* Native control register - * I think bit 0 enables the full - * framebuffer. - */ - uint8_t genius_charh; /* Native character height register: - * 00h => chars are 15 pixels high - * 81h => chars are 14 pixels high - * 83h => chars are 12 pixels high - * 90h => chars are 30 pixels high [15 x 2] - * 93h => chars are 24 pixels high [12 x 2] - */ - uint8_t genius_mode; /* Current mode (see list at top of file) */ - uint8_t cga_ctrl; /* Emulated CGA control register */ - uint8_t mda_ctrl; /* Emulated MDA control register */ - uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ + int font; /* Current font, 0 or 1 */ + int enabled; /* Display enabled, 0 or 1 */ + int detach; /* Detach cursor, 0 or 1 */ - uint8_t mda_stat; /* MDA status (IN 0x3BA) */ - uint8_t cga_stat; /* CGA status (IN 0x3DA) */ + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int font; /* Current font, 0 or 1 */ - int enabled; /* Display enabled, 0 or 1 */ - int detach; /* Detach cursor, 0 or 1 */ + int linepos, displine; + int vc; + int dispon, blink; + int vsynctime; - uint64_t dispontime, dispofftime; - pc_timer_t timer; - - int linepos, displine; - int vc; - int dispon, blink; - int vsynctime; - - uint8_t *vram; + uint8_t *vram; } genius_t; static uint8_t genius_pal[4]; @@ -144,247 +137,261 @@ static uint8_t genius_pal[4]; /* Mapping of attributes to colours, in MDA emulation mode */ static uint8_t mdaattr[256][2][2]; -void genius_recalctimings(genius_t *genius); -void genius_write(uint32_t addr, uint8_t val, void *p); +void genius_recalctimings(genius_t *genius); +void genius_write(uint32_t addr, uint8_t val, void *p); uint8_t genius_read(uint32_t addr, void *p); - void genius_out(uint16_t addr, uint8_t val, void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *) p; switch (addr) { - case 0x3b0: /* Command / control register */ - genius->genius_control = val; - if (val & 1) - mem_mapping_set_addr(&genius->mapping, 0xa0000, 0x28000); - else - mem_mapping_set_addr(&genius->mapping, 0xb0000, 0x10000); - break; + case 0x3b0: /* Command / control register */ + genius->genius_control = val; + if (val & 1) + mem_mapping_set_addr(&genius->mapping, 0xa0000, 0x28000); + else + mem_mapping_set_addr(&genius->mapping, 0xb0000, 0x10000); + break; - case 0x3b1: - genius->genius_charh = val; - break; + case 0x3b1: + genius->genius_charh = val; + break; - /* Emulated CRTC, register select */ - case 0x3b2: case 0x3b4: case 0x3b6: - genius->mda_crtcreg = val & 31; - break; + /* Emulated CRTC, register select */ + case 0x3b2: + case 0x3b4: + case 0x3b6: + genius->mda_crtcreg = val & 31; + break; - /* Emulated CRTC, value */ - case 0x3b3: case 0x3b5: case 0x3b7: - genius->mda_crtc[genius->mda_crtcreg] = val; - genius_recalctimings(genius); - return; + /* Emulated CRTC, value */ + case 0x3b3: + case 0x3b5: + case 0x3b7: + genius->mda_crtc[genius->mda_crtcreg] = val; + genius_recalctimings(genius); + return; - /* Emulated MDA control register */ - case 0x3b8: - genius->mda_ctrl = val; - return; + /* Emulated MDA control register */ + case 0x3b8: + genius->mda_ctrl = val; + return; - /* Emulated CRTC, register select */ - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - genius->cga_crtcreg = val & 31; - break; + /* Emulated CRTC, register select */ + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + genius->cga_crtcreg = val & 31; + break; - /* Emulated CRTC, value */ - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - genius->cga_crtc[genius->cga_crtcreg] = val; - genius_recalctimings(genius); - return; + /* Emulated CRTC, value */ + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + genius->cga_crtc[genius->cga_crtcreg] = val; + genius_recalctimings(genius); + return; - /* Emulated CGA control register */ - case 0x3d8: - genius->cga_ctrl = val; - return; - /* Emulated CGA colour register */ - case 0x3d9: - genius->cga_colour = val; - return; + /* Emulated CGA control register */ + case 0x3d8: + genius->cga_ctrl = val; + return; + /* Emulated CGA colour register */ + case 0x3d9: + genius->cga_colour = val; + return; } } - uint8_t genius_in(uint16_t addr, void *p) { - genius_t *genius = (genius_t *)p; - uint8_t ret = 0xff; + genius_t *genius = (genius_t *) p; + uint8_t ret = 0xff; switch (addr) { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - ret = genius->mda_crtcreg; - break; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - ret = genius->mda_crtc[genius->mda_crtcreg]; - break; - case 0x3b8: - ret = genius->mda_ctrl; - break; - case 0x3ba: - ret = genius->mda_stat; - break; - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - ret = genius->cga_crtcreg; - break; - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - ret = genius->cga_crtc[genius->cga_crtcreg]; - break; - case 0x3d8: - ret = genius->cga_ctrl; - break; - case 0x3d9: - ret = genius->cga_colour; - break; - case 0x3da: - ret = genius->cga_stat; - break; + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + ret = genius->mda_crtcreg; + break; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + ret = genius->mda_crtc[genius->mda_crtcreg]; + break; + case 0x3b8: + ret = genius->mda_ctrl; + break; + case 0x3ba: + ret = genius->mda_stat; + break; + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + ret = genius->cga_crtcreg; + break; + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + ret = genius->cga_crtc[genius->cga_crtcreg]; + break; + case 0x3d8: + ret = genius->cga_ctrl; + break; + case 0x3d9: + ret = genius->cga_colour; + break; + case 0x3da: + ret = genius->cga_stat; + break; } return ret; } - static void genius_waitstates(void) { - int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8}; + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; ws = ws_array[cycles & 0xf]; cycles -= ws; } - void genius_write(uint32_t addr, uint8_t val, void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *) p; genius_waitstates(); if (genius->genius_control & 1) { - if ((addr >= 0xa0000) && (addr < 0xb0000)) - addr = (addr - 0xa0000) & 0xffff; - else if ((addr >= 0xb0000) && (addr < 0xb8000)) - addr = ((addr - 0xb0000) & 0x7fff) + 0x10000; - else - addr = ((addr - 0xb8000) & 0xffff) + 0x18000; + if ((addr >= 0xa0000) && (addr < 0xb0000)) + addr = (addr - 0xa0000) & 0xffff; + else if ((addr >= 0xb0000) && (addr < 0xb8000)) + addr = ((addr - 0xb0000) & 0x7fff) + 0x10000; + else + addr = ((addr - 0xb8000) & 0xffff) + 0x18000; } else { - /* If hi-res memory is disabled, only visible in the B000 segment */ - if (addr >= 0xb8000) - addr = (addr & 0x3FFF) + 0x18000; - else - addr = (addr & 0x7FFF) + 0x10000; + /* If hi-res memory is disabled, only visible in the B000 segment */ + if (addr >= 0xb8000) + addr = (addr & 0x3FFF) + 0x18000; + else + addr = (addr & 0x7FFF) + 0x10000; } genius->vram[addr] = val; } - uint8_t genius_read(uint32_t addr, void *p) { - genius_t *genius = (genius_t *)p; - uint8_t ret; + genius_t *genius = (genius_t *) p; + uint8_t ret; genius_waitstates(); if (genius->genius_control & 1) { - if ((addr >= 0xa0000) && (addr < 0xb0000)) - addr = (addr - 0xa0000) & 0xffff; - else if ((addr >= 0xb0000) && (addr < 0xb8000)) - addr = ((addr - 0xb0000) & 0x7fff) + 0x10000; - else - addr = ((addr - 0xb8000) & 0xffff) + 0x18000; + if ((addr >= 0xa0000) && (addr < 0xb0000)) + addr = (addr - 0xa0000) & 0xffff; + else if ((addr >= 0xb0000) && (addr < 0xb8000)) + addr = ((addr - 0xb0000) & 0x7fff) + 0x10000; + else + addr = ((addr - 0xb8000) & 0xffff) + 0x18000; } else { - /* If hi-res memory is disabled, only visible in the B000 segment */ - if (addr >= 0xb8000) - addr = (addr & 0x3FFF) + 0x18000; - else - addr = (addr & 0x7FFF) + 0x10000; + /* If hi-res memory is disabled, only visible in the B000 segment */ + if (addr >= 0xb8000) + addr = (addr & 0x3FFF) + 0x18000; + else + addr = (addr & 0x7FFF) + 0x10000; } ret = genius->vram[addr]; return ret; } - void genius_recalctimings(genius_t *genius) { double disptime; double _dispontime, _dispofftime; - disptime = 0x31; - _dispontime = 0x28; + disptime = 0x31; + _dispontime = 0x28; _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; + _dispontime *= MDACONST; _dispofftime *= MDACONST; - genius->dispontime = (uint64_t)(_dispontime); - genius->dispofftime = (uint64_t)(_dispofftime); + genius->dispontime = (uint64_t) (_dispontime); + genius->dispofftime = (uint64_t) (_dispofftime); } - static int genius_lines(genius_t *genius) { int ret = 350; switch (genius->genius_charh & 0x13) { - case 0x00: - ret = 990; /* 80x66 */ - break; - case 0x01: - ret = 980; /* 80x70 */ - break; - case 0x02: - ret = 988; /* Guess: 80x76 */ - break; - case 0x03: - ret = 984; /* 80x82 */ - break; - case 0x10: - ret = 375; /* Logic says 80x33 but it appears to be 80x25 */ - break; - case 0x11: - ret = 490; /* Guess: 80x35, fits the logic as well, half of 80x70 */ - break; - case 0x12: - ret = 494; /* Guess: 80x38 */ - break; - case 0x13: - ret = 492; /* 80x41 */ - break; + case 0x00: + ret = 990; /* 80x66 */ + break; + case 0x01: + ret = 980; /* 80x70 */ + break; + case 0x02: + ret = 988; /* Guess: 80x76 */ + break; + case 0x03: + ret = 984; /* 80x82 */ + break; + case 0x10: + ret = 375; /* Logic says 80x33 but it appears to be 80x25 */ + break; + case 0x11: + ret = 490; /* Guess: 80x35, fits the logic as well, half of 80x70 */ + break; + case 0x12: + ret = 494; /* Guess: 80x38 */ + break; + case 0x13: + ret = 492; /* 80x41 */ + break; } return ret; } - /* Draw a single line of the screen in either text mode */ static void genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) { - int w = 80; /* 80 characters across */ - int cw = 9; /* Each character is 9 pixels wide */ - uint8_t chr, attr, sc, ctrl; - uint8_t *crtc, bitmap[2]; - int x, blink, c, row, charh; - int drawcursor, cursorline; - uint16_t addr; - uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; - uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; + int w = 80; /* 80 characters across */ + int cw = 9; /* Each character is 9 pixels wide */ + uint8_t chr, attr, sc, ctrl; + uint8_t *crtc, bitmap[2]; + int x, blink, c, row, charh; + int drawcursor, cursorline; + uint16_t addr; + uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; + uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; unsigned char *framebuf = genius->vram + 0x10000; - uint32_t col, dl = genius->displine; + uint32_t col, dl = genius->displine; /* Character height is 12-15 */ if (mda) { - if (genius->displine >= genius_lines(genius)) - return; + if (genius->displine >= genius_lines(genius)) + return; - crtc = genius->mda_crtc; - ctrl = genius->mda_ctrl; - charh = 15 - (genius->genius_charh & 3); + crtc = genius->mda_crtc; + ctrl = genius->mda_ctrl; + charh = 15 - (genius->genius_charh & 3); #if 0 if (genius->genius_charh & 0x10) { @@ -395,24 +402,24 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) sc = (dl % charh); } #else - row = (dl / charh); - sc = (dl % charh); + row = (dl / charh); + sc = (dl % charh); #endif } else { - if ((genius->displine < 512) || (genius->displine >= 912)) - return; + if ((genius->displine < 512) || (genius->displine >= 912)) + return; - crtc = genius->cga_crtc; - ctrl = genius->cga_ctrl; - framebuf += 0x08000; + crtc = genius->cga_crtc; + ctrl = genius->cga_ctrl; + framebuf += 0x08000; - dl -= 512; - w = crtc[1]; - cw = 8; - charh = crtc[9] + 1; + dl -= 512; + w = crtc[1]; + cw = 8; + charh = crtc[9] + 1; - row = ((dl >> 1) / charh); - sc = ((dl >> 1) % charh); + row = ((dl >> 1) / charh); + sc = ((dl >> 1) % charh); } ma = (crtc[13] | (crtc[12] << 8)) & 0x3fff; @@ -421,14 +428,14 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) addr = ((ma & ~1) + row * w) * 2; if (!mda) - dl += 512; + dl += 512; ma += (row * w); if ((crtc[10] & 0x60) == 0x20) - cursorline = 0; + cursorline = 0; else - cursorline = ((crtc[10] & 0x1F) <= sc) && ((crtc[11] & 0x1F) >= sc); + cursorline = ((crtc[10] & 0x1F) <= sc) && ((crtc[11] & 0x1F) >= sc); for (x = 0; x < w; x++) { #if 0 @@ -437,275 +444,275 @@ genius_textline(genius_t *genius, uint8_t background, int mda, int cols80) if ((genius->genius_charh & 0x10) && ((addr + 2 * x + 1) > 0x0FFF)) attr = 0x00; #endif - chr = framebuf[(addr + 2 * x) & 0x3FFF]; - attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; + chr = framebuf[(addr + 2 * x) & 0x3FFF]; + attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && genius->enabled && (ctrl & 8)); + drawcursor = ((ma == ca) && cursorline && genius->enabled && (ctrl & 8)); - switch (crtc[10] & 0x60) { - case 0x00: drawcursor = drawcursor && (genius->blink & 16); break; - case 0x60: drawcursor = drawcursor && (genius->blink & 32); break; - } + switch (crtc[10] & 0x60) { + case 0x00: + drawcursor = drawcursor && (genius->blink & 16); + break; + case 0x60: + drawcursor = drawcursor && (genius->blink & 32); + break; + } - blink = ((genius->blink & 16) && (ctrl & 0x20) && (attr & 0x80) && !drawcursor); + blink = ((genius->blink & 16) && (ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (ctrl & 0x20) attr &= 0x7F; + if (ctrl & 0x20) + attr &= 0x7F; - /* MDA underline */ - if (mda && (sc == charh) && ((attr & 7) == 1)) { - col = mdaattr[attr][blink][1]; + /* MDA underline */ + if (mda && (sc == charh) && ((attr & 7) == 1)) { + col = mdaattr[attr][blink][1]; - if (genius->genius_control & 0x20) - col ^= 15; + if (genius->genius_control & 0x20) + col ^= 15; - for (c = 0; c < cw; c++) { - if (col != background) { - if (cols80) - buffer32->line[dl][(x * cw) + c] = col; - else { - buffer32->line[dl][((x * cw) << 1) + (c << 1)] = - buffer32->line[dl][((x * cw) << 1) + (c << 1) + 1] = col; - } - } - } - } else { /* Draw 8 pixels of character */ - if (mda) - bitmap[0] = fontdat8x12[chr][sc]; - else - bitmap[0] = fontdat[chr][sc]; + for (c = 0; c < cw; c++) { + if (col != background) { + if (cols80) + buffer32->line[dl][(x * cw) + c] = col; + else { + buffer32->line[dl][((x * cw) << 1) + (c << 1)] = buffer32->line[dl][((x * cw) << 1) + (c << 1) + 1] = col; + } + } + } + } else { /* Draw 8 pixels of character */ + if (mda) + bitmap[0] = fontdat8x12[chr][sc]; + else + bitmap[0] = fontdat[chr][sc]; - for (c = 0; c < 8; c++) { - col = mdaattr[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; - if (!(genius->enabled) || !(ctrl & 8)) - col = mdaattr[0][0][0]; + for (c = 0; c < 8; c++) { + col = mdaattr[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; + if (!(genius->enabled) || !(ctrl & 8)) + col = mdaattr[0][0][0]; - if (genius->genius_control & 0x20) - col ^= 15; + if (genius->genius_control & 0x20) + col ^= 15; - if (col != background) { - if (cols80) - buffer32->line[dl][(x * cw) + c] = col; - else { - buffer32->line[dl][((x * cw) << 1) + (c << 1)] = - buffer32->line[dl][((x * cw) << 1) + (c << 1) + 1] = col; - } - } - } + if (col != background) { + if (cols80) + buffer32->line[dl][(x * cw) + c] = col; + else { + buffer32->line[dl][((x * cw) << 1) + (c << 1)] = buffer32->line[dl][((x * cw) << 1) + (c << 1) + 1] = col; + } + } + } - if (cw == 9) { - /* The ninth pixel column... */ - if ((chr & ~0x1f) == 0xc0) { - /* Echo column 8 for the graphics chars */ - if (cols80) { - col = buffer32->line[dl][(x * cw) + 7]; - if (col != background) - buffer32->line[dl][(x * cw) + 8] = col; - } else { - col = buffer32->line[dl][((x * cw) << 1) + 14]; - if (col != background) { - buffer32->line[dl][((x * cw) << 1) + 16] = - buffer32->line[dl][((x * cw) << 1) + 17] = col; - } - } - } else { /* Otherwise fill with background */ - col = mdaattr[attr][blink][0]; - if (genius->genius_control & 0x20) - col ^= 15; - if (col != background) { - if (cols80) - buffer32->line[dl][(x * cw) + 8] = col; - else { - buffer32->line[dl][((x * cw) << 1) + 16] = - buffer32->line[dl][((x * cw) << 1) + 17] = col; - } - } - } - } + if (cw == 9) { + /* The ninth pixel column... */ + if ((chr & ~0x1f) == 0xc0) { + /* Echo column 8 for the graphics chars */ + if (cols80) { + col = buffer32->line[dl][(x * cw) + 7]; + if (col != background) + buffer32->line[dl][(x * cw) + 8] = col; + } else { + col = buffer32->line[dl][((x * cw) << 1) + 14]; + if (col != background) { + buffer32->line[dl][((x * cw) << 1) + 16] = buffer32->line[dl][((x * cw) << 1) + 17] = col; + } + } + } else { /* Otherwise fill with background */ + col = mdaattr[attr][blink][0]; + if (genius->genius_control & 0x20) + col ^= 15; + if (col != background) { + if (cols80) + buffer32->line[dl][(x * cw) + 8] = col; + else { + buffer32->line[dl][((x * cw) << 1) + 16] = buffer32->line[dl][((x * cw) << 1) + 17] = col; + } + } + } + } - if (drawcursor) { - for (c = 0; c < cw; c++) { - if (cols80) - buffer32->line[dl][(x * cw) + c] ^= mdaattr[attr][0][1]; - else { - buffer32->line[dl][((x * cw) << 1) + (c << 1)] ^= mdaattr[attr][0][1]; - buffer32->line[dl][((x * cw) << 1) + (c << 1) + 1] ^= mdaattr[attr][0][1]; - } - } - } - ++ma; - } + if (drawcursor) { + for (c = 0; c < cw; c++) { + if (cols80) + buffer32->line[dl][(x * cw) + c] ^= mdaattr[attr][0][1]; + else { + buffer32->line[dl][((x * cw) << 1) + (c << 1)] ^= mdaattr[attr][0][1]; + buffer32->line[dl][((x * cw) << 1) + (c << 1) + 1] ^= mdaattr[attr][0][1]; + } + } + } + ++ma; + } } } - /* Draw a line in the CGA 640x200 mode */ void genius_cgaline(genius_t *genius) { - int x, c; + int x, c; uint32_t dat, addr; - uint8_t ink_f, ink_b; + uint8_t ink_f, ink_b; ink_f = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; ink_b = (genius->genius_control & 0x20) ? genius_pal[3] : genius_pal[0]; /* We draw the CGA at row 512 */ if ((genius->displine < 512) || (genius->displine >= 912)) - return; + return; addr = 0x18000 + 80 * ((genius->displine - 512) >> 2); if ((genius->displine - 512) & 2) - addr += 0x2000; + addr += 0x2000; for (x = 0; x < 80; x++) { - dat = genius->vram[addr]; - addr++; + dat = genius->vram[addr]; + addr++; - for (c = 0; c < 8; c++) { - if (dat & 0x80) - buffer32->line[genius->displine][(x << 3) + c] = ink_f; - else - buffer32->line[genius->displine][(x << 3) + c] = ink_b; + for (c = 0; c < 8; c++) { + if (dat & 0x80) + buffer32->line[genius->displine][(x << 3) + c] = ink_f; + else + buffer32->line[genius->displine][(x << 3) + c] = ink_b; - dat = dat << 1; - } + dat = dat << 1; + } } } - /* Draw a line in the native high-resolution mode */ void genius_hiresline(genius_t *genius) { - int x, c; + int x, c; uint32_t dat, addr; - uint8_t ink_f, ink_b; + uint8_t ink_f, ink_b; ink_f = (genius->genius_control & 0x20) ? genius_pal[0] : genius_pal[3]; ink_b = (genius->genius_control & 0x20) ? genius_pal[3] : genius_pal[0]; /* The first 512 lines live at A0000 */ if (genius->displine < 512) - addr = 128 * genius->displine; - else /* The second 496 live at B8000 */ - addr = 0x18000 + (128 * (genius->displine - 512)); + addr = 128 * genius->displine; + else /* The second 496 live at B8000 */ + addr = 0x18000 + (128 * (genius->displine - 512)); for (x = 0; x < 91; x++) { - dat = genius->vram[addr + x]; + dat = genius->vram[addr + x]; - for (c = 0; c < 8; c++) { - if (dat & 0x80) - buffer32->line[genius->displine][(x << 3) + c] = ink_f; - else - buffer32->line[genius->displine][(x << 3) + c] = ink_b; + for (c = 0; c < 8; c++) { + if (dat & 0x80) + buffer32->line[genius->displine][(x << 3) + c] = ink_f; + else + buffer32->line[genius->displine][(x << 3) + c] = ink_b; - dat = dat << 1; - } + dat = dat << 1; + } } } - void genius_poll(void *p) { - genius_t *genius = (genius_t *)p; - int x; - uint8_t background; + genius_t *genius = (genius_t *) p; + int x; + uint8_t background; if (!genius->linepos) { - timer_advance_u64(&genius->timer, genius->dispofftime); - genius->cga_stat |= 1; - genius->mda_stat |= 1; - genius->linepos = 1; + timer_advance_u64(&genius->timer, genius->dispofftime); + genius->cga_stat |= 1; + genius->mda_stat |= 1; + genius->linepos = 1; - if (genius->dispon) { - if (genius->genius_control & 0x20) - background = genius_pal[3]; - else - background = genius_pal[0]; + if (genius->dispon) { + if (genius->genius_control & 0x20) + background = genius_pal[3]; + else + background = genius_pal[0]; - if (genius->displine == 0) - video_wait_for_buffer(); + if (genius->displine == 0) + video_wait_for_buffer(); - /* Start off with a blank line */ - for (x = 0; x < GENIUS_XSIZE; x++) - buffer32->line[genius->displine][x] = background; + /* Start off with a blank line */ + for (x = 0; x < GENIUS_XSIZE; x++) + buffer32->line[genius->displine][x] = background; - /* If graphics display enabled, draw graphics on top - * of the blanked line */ - if (genius->cga_ctrl & 8) { - if (((genius->genius_control & 0x11) == 0x00) || (genius->genius_control & 0x08)) - genius_cgaline(genius); - else if ((genius->genius_control & 0x11) == 0x01) - genius_hiresline(genius); - else { - if (genius->cga_ctrl & 2) - genius_cgaline(genius); - else { - if (genius->cga_ctrl & 1) - genius_textline(genius, background, 0, 1); - else - genius_textline(genius, background, 0, 0); - } - } - } + /* If graphics display enabled, draw graphics on top + * of the blanked line */ + if (genius->cga_ctrl & 8) { + if (((genius->genius_control & 0x11) == 0x00) || (genius->genius_control & 0x08)) + genius_cgaline(genius); + else if ((genius->genius_control & 0x11) == 0x01) + genius_hiresline(genius); + else { + if (genius->cga_ctrl & 2) + genius_cgaline(genius); + else { + if (genius->cga_ctrl & 1) + genius_textline(genius, background, 0, 1); + else + genius_textline(genius, background, 0, 0); + } + } + } - /* If MDA display is enabled, draw MDA text on top - * of the lot */ - if (genius->mda_ctrl & 8) - genius_textline(genius, background, 1, 1); - } - genius->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (genius->displine == 1008) { /* Start of VSYNC */ - genius->cga_stat |= 8; - genius->mda_stat |= 8; - genius->dispon = 0; - } - if (genius->displine == 1040) { /* End of VSYNC */ - genius->displine = 0; - genius->cga_stat &= ~8; - genius->mda_stat &= ~8; - genius->dispon = 1; - } + /* If MDA display is enabled, draw MDA text on top + * of the lot */ + if (genius->mda_ctrl & 8) + genius_textline(genius, background, 1, 1); + } + genius->displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (genius->displine == 1008) { /* Start of VSYNC */ + genius->cga_stat |= 8; + genius->mda_stat |= 8; + genius->dispon = 0; + } + if (genius->displine == 1040) { /* End of VSYNC */ + genius->displine = 0; + genius->cga_stat &= ~8; + genius->mda_stat &= ~8; + genius->dispon = 1; + } } else { - if (genius->dispon) { - genius->cga_stat &= ~1; - genius->mda_stat &= ~1; - } - timer_advance_u64(&genius->timer, genius->dispontime); - genius->linepos = 0; + if (genius->dispon) { + genius->cga_stat &= ~1; + genius->mda_stat &= ~1; + } + timer_advance_u64(&genius->timer, genius->dispontime); + genius->linepos = 0; - if (genius->displine == 1008) { -/* Hardcode GENIUS_XSIZE * GENIUS_YSIZE window size */ - if (GENIUS_XSIZE != xsize || GENIUS_YSIZE != ysize) { - xsize = GENIUS_XSIZE; - ysize = GENIUS_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); + if (genius->displine == 1008) { + /* Hardcode GENIUS_XSIZE * GENIUS_YSIZE window size */ + if (GENIUS_XSIZE != xsize || GENIUS_YSIZE != ysize) { + xsize = GENIUS_XSIZE; + ysize = GENIUS_YSIZE; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + set_screen_size(xsize, ysize); - if (video_force_resize_get()) - video_force_resize_set(0); - } + if (video_force_resize_get()) + video_force_resize_set(0); + } - video_blit_memtoscreen_8(0, 0, xsize, ysize); + video_blit_memtoscreen_8(0, 0, xsize, ysize); - frames++; - /* Fixed 728x1008 resolution */ - video_res_x = GENIUS_XSIZE; - video_res_y = GENIUS_YSIZE; - video_bpp = 1; - genius->blink++; - } + frames++; + /* Fixed 728x1008 resolution */ + video_res_x = GENIUS_XSIZE; + video_res_y = GENIUS_YSIZE; + video_bpp = 1; + genius->blink++; + } } } - void -*genius_init(const device_t *info) + * + genius_init(const device_t *info) { - int c; + int c; genius_t *genius = malloc(sizeof(genius_t)); memset(genius, 0, sizeof(genius_t)); @@ -721,83 +728,82 @@ void /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ - mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, genius); + mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, genius); /* Respond to both MDA and CGA I/O ports */ io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); - genius_pal[0] = 0 + 16; /* 0 */ - genius_pal[1] = 8 + 16; /* 8 */ - genius_pal[2] = 7 + 16; /* 7 */ - genius_pal[3] = 15 + 16; /* F */ + genius_pal[0] = 0 + 16; /* 0 */ + genius_pal[1] = 8 + 16; /* 8 */ + genius_pal[2] = 7 + 16; /* 7 */ + genius_pal[3] = 15 + 16; /* F */ /* MDA attributes */ /* I don't know if the Genius's MDA emulation actually does * emulate bright / non-bright. For the time being pretend it does. */ for (c = 0; c < 256; c++) { - mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = genius_pal[0]; - if (c & 8) mdaattr[c][0][1] = genius_pal[3]; - else mdaattr[c][0][1] = genius_pal[2]; + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = genius_pal[0]; + if (c & 8) + mdaattr[c][0][1] = genius_pal[3]; + else + mdaattr[c][0][1] = genius_pal[2]; } mdaattr[0x70][0][1] = genius_pal[0]; mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = genius_pal[3]; - mdaattr[0xF0][0][1] = genius_pal[0]; + mdaattr[0xF0][0][1] = genius_pal[0]; mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = genius_pal[3]; - mdaattr[0x78][0][1] = genius_pal[2]; + mdaattr[0x78][0][1] = genius_pal[2]; mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = genius_pal[3]; - mdaattr[0xF8][0][1] = genius_pal[2]; + mdaattr[0xF8][0][1] = genius_pal[2]; mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = genius_pal[3]; mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = genius_pal[0]; mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = genius_pal[0]; mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = genius_pal[0]; mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = genius_pal[0]; -/* Start off in 80x25 text mode */ - genius->cga_stat = 0xF4; - genius->genius_mode = 2; - genius->enabled = 1; + /* Start off in 80x25 text mode */ + genius->cga_stat = 0xF4; + genius->genius_mode = 2; + genius->enabled = 1; genius->genius_charh = 0x90; /* Native character height register */ genius->genius_control |= 0x10; return genius; } - void genius_close(void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *) p; free(genius->vram); free(genius); } - static int genius_available() { return rom_present(BIOS_ROM_PATH); } - void genius_speed_changed(void *p) { - genius_t *genius = (genius_t *)p; + genius_t *genius = (genius_t *) p; genius_recalctimings(genius); } const device_t genius_device = { - .name = "Genius VHR", + .name = "Genius VHR", .internal_name = "genius", - .flags = DEVICE_ISA, - .local = 0, - .init = genius_init, - .close = genius_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = genius_init, + .close = genius_close, + .reset = NULL, { .available = genius_available }, .speed_changed = genius_speed_changed, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index 8e1ab4f8b..c5d91e96d 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -33,9 +33,7 @@ #include <86box/video.h> #include <86box/vid_hercules.h> - -static video_timings_t timing_hercules = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; - +static video_timings_t timing_hercules = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static void recalc_timings(hercules_t *dev) @@ -43,196 +41,190 @@ recalc_timings(hercules_t *dev) double disptime; double _dispontime, _dispofftime; - disptime = dev->crtc[0] + 1; + disptime = dev->crtc[0] + 1; _dispontime = dev->crtc[1]; _dispofftime = disptime - _dispontime; - _dispontime *= HERCCONST; + _dispontime *= HERCCONST; _dispofftime *= HERCCONST; - dev->dispontime = (uint64_t)(_dispontime); - dev->dispofftime = (uint64_t)(_dispofftime); + dev->dispontime = (uint64_t) (_dispontime); + dev->dispofftime = (uint64_t) (_dispofftime); } - -static uint8_t crtcmask[32] = -{ - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +static uint8_t crtcmask[32] = { + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static void hercules_out(uint16_t addr, uint8_t val, void *priv) { - hercules_t *dev = (hercules_t *)priv; - uint8_t old; + hercules_t *dev = (hercules_t *) priv; + uint8_t old; VIDEO_MONITOR_PROLOGUE() switch (addr) { - case 0x03b0: - case 0x03b2: - case 0x03b4: - case 0x03b6: - dev->crtcreg = val & 31; - break; + case 0x03b0: + case 0x03b2: + case 0x03b4: + case 0x03b6: + dev->crtcreg = val & 31; + break; - case 0x03b1: - case 0x03b3: - case 0x03b5: - case 0x03b7: - old = dev->crtc[dev->crtcreg]; - dev->crtc[dev->crtcreg] = val & crtcmask[dev->crtcreg]; + case 0x03b1: + case 0x03b3: + case 0x03b5: + case 0x03b7: + old = dev->crtc[dev->crtcreg]; + dev->crtc[dev->crtcreg] = val & crtcmask[dev->crtcreg]; - /* - * Fix for Generic Turbo XT BIOS, which - * sets up cursor registers wrong. - */ - if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { - dev->crtc[10] = 0xb; - dev->crtc[11] = 0xc; - } + /* + * Fix for Generic Turbo XT BIOS, which + * sets up cursor registers wrong. + */ + if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { + dev->crtc[10] = 0xb; + dev->crtc[11] = 0xc; + } - if (old != val) { - if ((dev->crtcreg < 0xe) || (dev->crtcreg > 0x10)) { - dev->fullchange = changeframecount; - recalc_timings(dev); - } - } - break; + if (old != val) { + if ((dev->crtcreg < 0xe) || (dev->crtcreg > 0x10)) { + dev->fullchange = changeframecount; + recalc_timings(dev); + } + } + break; - case 0x03b8: - old = dev->ctrl; + case 0x03b8: + old = dev->ctrl; - /* Prevent setting of bits if they are disabled in CTRL2. */ - if ((old & 0x02) && !(val & 0x02)) - dev->ctrl &= 0xfd; - else if ((val & 0x02) && (dev->ctrl2 & 0x01)) - dev->ctrl |= 0x02; + /* Prevent setting of bits if they are disabled in CTRL2. */ + if ((old & 0x02) && !(val & 0x02)) + dev->ctrl &= 0xfd; + else if ((val & 0x02) && (dev->ctrl2 & 0x01)) + dev->ctrl |= 0x02; - if ((old & 0x80) && !(val & 0x80)) - dev->ctrl &= 0x7f; - else if ((val & 0x80) && (dev->ctrl2 & 0x02)) - dev->ctrl |= 0x80; + if ((old & 0x80) && !(val & 0x80)) + dev->ctrl &= 0x7f; + else if ((val & 0x80) && (dev->ctrl2 & 0x02)) + dev->ctrl |= 0x80; - dev->ctrl = (dev->ctrl & 0x82) | (val & 0x7d); + dev->ctrl = (dev->ctrl & 0x82) | (val & 0x7d); - if (old ^ val) - recalc_timings(dev); - break; + if (old ^ val) + recalc_timings(dev); + break; - case 0x03b9: - case 0x03bb: - dev->lp_ff = !(addr & 0x0002); - break; + case 0x03b9: + case 0x03bb: + dev->lp_ff = !(addr & 0x0002); + break; - case 0x03bf: - old = dev->ctrl2; - dev->ctrl2 = val; - /* According to the Programmer's guide to the Hercules graphics cars - by David B. Doty from 1988, the CTRL2 modes (bits 1,0) are as follow: - - 00: DIAG: Text mode only, only page 0 accessible; - - 01: HALF: Graphics mode allowed, only page 0 accessible; - - 11: FULL: Graphics mode allowed, both pages accessible. */ - if (val & 0x01) - mem_mapping_set_exec(&dev->mapping, dev->vram); - else - mem_mapping_set_exec(&dev->mapping, NULL); - if (val & 0x02) - mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); - if (old ^ val) - recalc_timings(dev); - break; + case 0x03bf: + old = dev->ctrl2; + dev->ctrl2 = val; + /* According to the Programmer's guide to the Hercules graphics cars + by David B. Doty from 1988, the CTRL2 modes (bits 1,0) are as follow: + - 00: DIAG: Text mode only, only page 0 accessible; + - 01: HALF: Graphics mode allowed, only page 0 accessible; + - 11: FULL: Graphics mode allowed, both pages accessible. */ + if (val & 0x01) + mem_mapping_set_exec(&dev->mapping, dev->vram); + else + mem_mapping_set_exec(&dev->mapping, NULL); + if (val & 0x02) + mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000); + else + mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); + if (old ^ val) + recalc_timings(dev); + break; - default: - break; + default: + break; } VIDEO_MONITOR_EPILOGUE() } - static uint8_t hercules_in(uint16_t addr, void *priv) { - hercules_t *dev = (hercules_t *)priv; - uint8_t ret = 0xff; + hercules_t *dev = (hercules_t *) priv; + uint8_t ret = 0xff; switch (addr) { - case 0x03b0: - case 0x03b2: - case 0x03b4: - case 0x03b6: - ret = dev->crtcreg; - break; + case 0x03b0: + case 0x03b2: + case 0x03b4: + case 0x03b6: + ret = dev->crtcreg; + break; - case 0x03b1: - case 0x03b3: - case 0x03b5: - case 0x03b7: - if (dev->crtcreg == 0x0c) - ret = (dev->ma >> 8) & 0x3f; - else if (dev->crtcreg == 0x0d) - ret = dev->ma & 0xff; - else - ret = dev->crtc[dev->crtcreg]; - break; + case 0x03b1: + case 0x03b3: + case 0x03b5: + case 0x03b7: + if (dev->crtcreg == 0x0c) + ret = (dev->ma >> 8) & 0x3f; + else if (dev->crtcreg == 0x0d) + ret = dev->ma & 0xff; + else + ret = dev->crtc[dev->crtcreg]; + break; - case 0x03ba: - ret = 0x70; /* Hercules ident */ - ret |= (dev->lp_ff ? 2 : 0); - ret |= (dev->stat & 0x01); - if (dev->stat & 0x08) - ret |= 0x80; - if ((ret & 0x81) == 0x80) - ret |= 0x08; - break; + case 0x03ba: + ret = 0x70; /* Hercules ident */ + ret |= (dev->lp_ff ? 2 : 0); + ret |= (dev->stat & 0x01); + if (dev->stat & 0x08) + ret |= 0x80; + if ((ret & 0x81) == 0x80) + ret |= 0x08; + break; - default: - break; + default: + break; } - return(ret); + return (ret); } - static void hercules_waitstates(void *p) { - int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8}; + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; ws = ws_array[cycles & 0xf]; cycles -= ws; } - static void hercules_write(uint32_t addr, uint8_t val, void *priv) { - hercules_t *dev = (hercules_t *)priv; + hercules_t *dev = (hercules_t *) priv; if (dev->ctrl2 & 0x01) - addr &= 0xffff; + addr &= 0xffff; else - addr &= 0x0fff; + addr &= 0x0fff; dev->vram[addr] = val; hercules_waitstates(dev); } - static uint8_t hercules_read(uint32_t addr, void *priv) { - hercules_t *dev = (hercules_t *)priv; - uint8_t ret = 0xff; + hercules_t *dev = (hercules_t *) priv; + uint8_t ret = 0xff; if (dev->ctrl2 & 0x01) - addr &= 0xffff; + addr &= 0xffff; else - addr &= 0x0fff; + addr &= 0x0fff; hercules_waitstates(dev); @@ -241,333 +233,325 @@ hercules_read(uint32_t addr, void *priv) return ret; } - static void hercules_render_overscan_left(hercules_t *dev) { - int i; + int i; uint32_t width; if (dev->ctrl & 0x02) - width = (((uint32_t) dev->crtc[1]) << 4); + width = (((uint32_t) dev->crtc[1]) << 4); else - width = (((uint32_t) dev->crtc[1]) * 9); + width = (((uint32_t) dev->crtc[1]) * 9); if ((dev->displine + 14) < 0) - return; + return; if (width == 0) - return; + return; for (i = 0; i < 8; i++) - buffer32->line[dev->displine + 14][i] = 0x00000000; + buffer32->line[dev->displine + 14][i] = 0x00000000; } - static void hercules_render_overscan_right(hercules_t *dev) { - int i; + int i; uint32_t width; if (dev->ctrl & 0x02) - width = (((uint32_t) dev->crtc[1]) << 4); + width = (((uint32_t) dev->crtc[1]) << 4); else - width = (((uint32_t) dev->crtc[1]) * 9); + width = (((uint32_t) dev->crtc[1]) * 9); if ((dev->displine + 14) < 0) - return; + return; if (width == 0) - return; + return; for (i = 0; i < 8; i++) - buffer32->line[dev->displine + 14][8 + width + i] = 0x00000000; + buffer32->line[dev->displine + 14][8 + width + i] = 0x00000000; } - static void hercules_poll(void *priv) { - hercules_t *dev = (hercules_t *)priv; - uint8_t chr, attr; - uint16_t ca, dat; - uint16_t pa; - int oldsc, blink; - int x, xx, y, yy, c, oldvc; - int drawcursor; - uint32_t *p; + hercules_t *dev = (hercules_t *) priv; + uint8_t chr, attr; + uint16_t ca, dat; + uint16_t pa; + int oldsc, blink; + int x, xx, y, yy, c, oldvc; + int drawcursor; + uint32_t *p; VIDEO_MONITOR_PROLOGUE() ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; - if (! dev->linepos) { - timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; - dev->linepos = 1; - oldsc = dev->sc; + if (!dev->linepos) { + timer_advance_u64(&dev->timer, dev->dispofftime); + dev->stat |= 1; + dev->linepos = 1; + oldsc = dev->sc; - if ((dev->crtc[8] & 3) == 3) - dev->sc = (dev->sc << 1) & 7; + if ((dev->crtc[8] & 3) == 3) + dev->sc = (dev->sc << 1) & 7; - if (dev->dispon) { - if (dev->displine < dev->firstline) { - dev->firstline = dev->displine; - video_wait_for_buffer(); - } - dev->lastline = dev->displine; + if (dev->dispon) { + if (dev->displine < dev->firstline) { + dev->firstline = dev->displine; + video_wait_for_buffer(); + } + dev->lastline = dev->displine; - hercules_render_overscan_left(dev); + hercules_render_overscan_left(dev); - if (dev->ctrl & 0x02) { - ca = (dev->sc & 3) * 0x2000; - if (dev->ctrl & 0x80) - ca += 0x8000; + if (dev->ctrl & 0x02) { + ca = (dev->sc & 3) * 0x2000; + if (dev->ctrl & 0x80) + ca += 0x8000; - for (x = 0; x < dev->crtc[1]; x++) { - if (dev->ctrl & 8) - dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1]; - else - dat = 0; - dev->ma++; - for (c = 0; c < 16; c++) - buffer32->line[dev->displine + 14][(x << 4) + c + 8] = (dat & (32768 >> c)) ? 7 : 0; - for (c = 0; c < 16; c += 8) - video_blend((x << 4) + c + 8, dev->displine + 14); - } - } else { - for (x = 0; x < dev->crtc[1]; x++) { - if (dev->ctrl & 8) { - /* Undocumented behavior: page 1 in text mode means characters are read - from page 1 and attributes from page 0. */ - chr = dev->charbuffer[x << 1]; - attr = dev->charbuffer[(x << 1) + 1]; - } else - chr = attr = 0; - drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); - blink = ((dev->blink & 16) && (dev->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + for (x = 0; x < dev->crtc[1]; x++) { + if (dev->ctrl & 8) + dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1]; + else + dat = 0; + dev->ma++; + for (c = 0; c < 16; c++) + buffer32->line[dev->displine + 14][(x << 4) + c + 8] = (dat & (32768 >> c)) ? 7 : 0; + for (c = 0; c < 16; c += 8) + video_blend((x << 4) + c + 8, dev->displine + 14); + } + } else { + for (x = 0; x < dev->crtc[1]; x++) { + if (dev->ctrl & 8) { + /* Undocumented behavior: page 1 in text mode means characters are read + from page 1 and attributes from page 0. */ + chr = dev->charbuffer[x << 1]; + attr = dev->charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); + blink = ((dev->blink & 16) && (dev->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (dev->sc == 12 && ((attr & 7) == 1)) { - for (c = 0; c < 9; c++) - buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][1]; - } else { - for (c = 0; c < 8; c++) - buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if (dev->sc == 12 && ((attr & 7) == 1)) { + for (c = 0; c < 9; c++) + buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][1]; + } else { + for (c = 0; c < 8; c++) + buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) - buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1]; - else - buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][0]; - } - if (dev->ctrl2 & 0x01) - dev->ma = (dev->ma + 1) & 0x3fff; - else - dev->ma = (dev->ma + 1) & 0x7ff; + if ((chr & ~0x1f) == 0xc0) + buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1]; + else + buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][0]; + } + if (dev->ctrl2 & 0x01) + dev->ma = (dev->ma + 1) & 0x3fff; + else + dev->ma = (dev->ma + 1) & 0x7ff; - if (drawcursor) { - for (c = 0; c < 9; c++) - buffer32->line[dev->displine + 14][(x * 9) + c + 8] ^= dev->cols[attr][0][1]; - } - } - } + if (drawcursor) { + for (c = 0; c < 9; c++) + buffer32->line[dev->displine + 14][(x * 9) + c + 8] ^= dev->cols[attr][0][1]; + } + } + } - hercules_render_overscan_right(dev); - } - dev->sc = oldsc; + hercules_render_overscan_right(dev); + } + dev->sc = oldsc; - if (dev->vc == dev->crtc[7] && !dev->sc) - dev->stat |= 8; - dev->displine++; - if (dev->displine >= 500) - dev->displine = 0; + if (dev->vc == dev->crtc[7] && !dev->sc) + dev->stat |= 8; + dev->displine++; + if (dev->displine >= 500) + dev->displine = 0; } else { - timer_advance_u64(&dev->timer, dev->dispontime); + timer_advance_u64(&dev->timer, dev->dispontime); - if (dev->dispon) - dev->stat &= ~1; + if (dev->dispon) + dev->stat &= ~1; - dev->linepos = 0; - if (dev->vsynctime) { - dev->vsynctime--; - if (! dev->vsynctime) - dev->stat &= ~8; - } + dev->linepos = 0; + if (dev->vsynctime) { + dev->vsynctime--; + if (!dev->vsynctime) + dev->stat &= ~8; + } - if (dev->sc == (dev->crtc[11] & 31) || - ((dev->crtc[8] & 3)==3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { - dev->con = 0; - dev->coff = 1; - } + if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { + dev->con = 0; + dev->coff = 1; + } - if (dev->vadj) { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; - dev->vadj--; - if (! dev->vadj) { - dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - dev->sc = 0; - } - } else if (((dev->crtc[8] & 3) != 3 && dev->sc == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { - dev->maback = dev->ma; - dev->sc = 0; - oldvc = dev->vc; - dev->vc++; - dev->vc &= 127; + if (dev->vadj) { + dev->sc++; + dev->sc &= 31; + dev->ma = dev->maback; + dev->vadj--; + if (!dev->vadj) { + dev->dispon = 1; + dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->sc = 0; + } + } else if (((dev->crtc[8] & 3) != 3 && dev->sc == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { + dev->maback = dev->ma; + dev->sc = 0; + oldvc = dev->vc; + dev->vc++; + dev->vc &= 127; - if (dev->vc == dev->crtc[6]) - dev->dispon = 0; + if (dev->vc == dev->crtc[6]) + dev->dispon = 0; - if (oldvc == dev->crtc[4]) { - dev->vc = 0; - dev->vadj = dev->crtc[5]; - if (! dev->vadj) { - dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - } - switch (dev->crtc[10] & 0x60) { - case 0x20: - dev->cursoron = 0; - break; - case 0x60: - dev->cursoron = dev->blink & 0x10; - break; - default: - dev->cursoron = dev->blink & 0x08; - break; - } - } + if (oldvc == dev->crtc[4]) { + dev->vc = 0; + dev->vadj = dev->crtc[5]; + if (!dev->vadj) { + dev->dispon = 1; + dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + } + switch (dev->crtc[10] & 0x60) { + case 0x20: + dev->cursoron = 0; + break; + case 0x60: + dev->cursoron = dev->blink & 0x10; + break; + default: + dev->cursoron = dev->blink & 0x08; + break; + } + } - if (dev->vc == dev->crtc[7]) { - dev->dispon = 0; - dev->displine = 0; - if ((dev->crtc[8] & 3) == 3) - dev->vsynctime = ((int32_t)dev->crtc[4] * ((dev->crtc[9] >> 1) + 1)) + dev->crtc[5] - dev->crtc[7] + 1; - else - dev->vsynctime = ((int32_t)dev->crtc[4] * (dev->crtc[9] + 1)) + dev->crtc[5] - dev->crtc[7] + 1; - if (dev->crtc[7]) { - if (dev->ctrl & 0x02) - x = dev->crtc[1] << 4; - else - x = dev->crtc[1] * 9; + if (dev->vc == dev->crtc[7]) { + dev->dispon = 0; + dev->displine = 0; + if ((dev->crtc[8] & 3) == 3) + dev->vsynctime = ((int32_t) dev->crtc[4] * ((dev->crtc[9] >> 1) + 1)) + dev->crtc[5] - dev->crtc[7] + 1; + else + dev->vsynctime = ((int32_t) dev->crtc[4] * (dev->crtc[9] + 1)) + dev->crtc[5] - dev->crtc[7] + 1; + if (dev->crtc[7]) { + if (dev->ctrl & 0x02) + x = dev->crtc[1] << 4; + else + x = dev->crtc[1] * 9; - dev->lastline++; - y = (dev->lastline - dev->firstline); + dev->lastline++; + y = (dev->lastline - dev->firstline); - if ((dev->ctrl & 8) && x && y && ((x != xsize) || (y != ysize) || video_force_resize_get())) { - xsize = x; - ysize = y; - if (xsize < 64) xsize = enable_overscan ? 640 : 656; - if (ysize < 32) ysize = 200; + if ((dev->ctrl & 8) && x && y && ((x != xsize) || (y != ysize) || video_force_resize_get())) { + xsize = x; + ysize = y; + if (xsize < 64) + xsize = enable_overscan ? 640 : 656; + if (ysize < 32) + ysize = 200; - set_screen_size(xsize + (enable_overscan ? 16 : 0), ysize + (enable_overscan ? 28 : 0)); + set_screen_size(xsize + (enable_overscan ? 16 : 0), ysize + (enable_overscan ? 28 : 0)); - if (video_force_resize_get()) - video_force_resize_set(0); - } + if (video_force_resize_get()) + video_force_resize_set(0); + } - if ((x >= 160) && ((y + 1) >= 120)) { - /* Draw (overscan_size) lines of overscan on top and bottom. */ - for (yy = 0; yy < 14; yy++) { - p = &(buffer32->line[(dev->firstline + yy) & 0x7ff][0]); + if ((x >= 160) && ((y + 1) >= 120)) { + /* Draw (overscan_size) lines of overscan on top and bottom. */ + for (yy = 0; yy < 14; yy++) { + p = &(buffer32->line[(dev->firstline + yy) & 0x7ff][0]); - for (xx = 0; xx < (x + 16); xx++) - p[xx] = 0x00000000; - } + for (xx = 0; xx < (x + 16); xx++) + p[xx] = 0x00000000; + } - for (yy = 0; yy < 14; yy++) { - p = &(buffer32->line[(dev->firstline + 14 + y + yy) & 0x7ff][0]); + for (yy = 0; yy < 14; yy++) { + p = &(buffer32->line[(dev->firstline + 14 + y + yy) & 0x7ff][0]); - for (xx = 0; xx < (x + 16); xx++) - p[xx] = 0x00000000; - } - } + for (xx = 0; xx < (x + 16); xx++) + p[xx] = 0x00000000; + } + } - if (enable_overscan) - video_blit_memtoscreen_8(0, dev->firstline, xsize + 16, ysize + 28); - else - video_blit_memtoscreen_8(8, dev->firstline + 14, xsize, ysize); - frames++; - // if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) { - if (dev->ctrl & 0x02) { - video_res_x = dev->crtc[1] * 16; - video_res_y = dev->crtc[6] * 4; - video_bpp = 1; - } else { - video_res_x = dev->crtc[1]; - video_res_y = dev->crtc[6]; - video_bpp = 0; - } - } - dev->firstline = 1000; - dev->lastline = 0; - dev->blink++; - } - } else { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; - } + if (enable_overscan) + video_blit_memtoscreen_8(0, dev->firstline, xsize + 16, ysize + 28); + else + video_blit_memtoscreen_8(8, dev->firstline + 14, xsize, ysize); + frames++; + // if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) { + if (dev->ctrl & 0x02) { + video_res_x = dev->crtc[1] * 16; + video_res_y = dev->crtc[6] * 4; + video_bpp = 1; + } else { + video_res_x = dev->crtc[1]; + video_res_y = dev->crtc[6]; + video_bpp = 0; + } + } + dev->firstline = 1000; + dev->lastline = 0; + dev->blink++; + } + } else { + dev->sc++; + dev->sc &= 31; + dev->ma = dev->maback; + } - if ((dev->sc == (dev->crtc[10] & 31) || - ((dev->crtc[8] & 3)==3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) - dev->con = 1; - if (dev->dispon && !(dev->ctrl & 0x02)) { - for (x = 0; x < (dev->crtc[1] << 1); x++) { - pa = (dev->ctrl & 0x80) ? ((x & 1) ? 0x0000 : 0x8000) : 0x0000; - dev->charbuffer[x] = dev->vram[(((dev->ma << 1) + x) & 0x3fff) + pa]; - } - } + if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) + dev->con = 1; + if (dev->dispon && !(dev->ctrl & 0x02)) { + for (x = 0; x < (dev->crtc[1] << 1); x++) { + pa = (dev->ctrl & 0x80) ? ((x & 1) ? 0x0000 : 0x8000) : 0x0000; + dev->charbuffer[x] = dev->vram[(((dev->ma << 1) + x) & 0x3fff) + pa]; + } + } } VIDEO_MONITOR_EPILOGUE() } - static void * hercules_init(const device_t *info) { hercules_t *dev; - int c; + int c; - dev = (hercules_t *)malloc(sizeof(hercules_t)); + dev = (hercules_t *) malloc(sizeof(hercules_t)); memset(dev, 0x00, sizeof(hercules_t)); dev->monitor_index = monitor_index_global; overscan_x = 16; overscan_y = 28; - dev->vram = (uint8_t *)malloc(0x10000); + dev->vram = (uint8_t *) malloc(0x10000); timer_add(&dev->timer, hercules_poll, dev, 1); mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, - hercules_read,NULL,NULL, hercules_write,NULL,NULL, - NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev); + hercules_read, NULL, NULL, hercules_write, NULL, NULL, + NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev); io_sethandler(0x03b0, 16, - hercules_in,NULL,NULL, hercules_out,NULL,NULL, dev); + hercules_in, NULL, NULL, hercules_out, NULL, NULL, dev); for (c = 0; c < 256; c++) { - dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16; + dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16; - if (c & 0x08) - dev->cols[c][0][1] = 15 + 16; - else - dev->cols[c][0][1] = 7 + 16; + if (c & 0x08) + dev->cols[c][0][1] = 15 + 16; + else + dev->cols[c][0][1] = 7 + 16; } dev->cols[0x70][0][1] = 16; - dev->cols[0x70][0][0] = dev->cols[0x70][1][0] = - dev->cols[0x70][1][1] = 16 + 15; - dev->cols[0xF0][0][1] = 16; - dev->cols[0xF0][0][0] = dev->cols[0xF0][1][0] = - dev->cols[0xF0][1][1] = 16 + 15; - dev->cols[0x78][0][1] = 16 + 7; - dev->cols[0x78][0][0] = dev->cols[0x78][1][0] = - dev->cols[0x78][1][1] = 16 + 15; - dev->cols[0xF8][0][1] = 16 + 7; - dev->cols[0xF8][0][0] = dev->cols[0xF8][1][0] = - dev->cols[0xF8][1][1] = 16 + 15; + dev->cols[0x70][0][0] = dev->cols[0x70][1][0] = dev->cols[0x70][1][1] = 16 + 15; + dev->cols[0xF0][0][1] = 16; + dev->cols[0xF0][0][0] = dev->cols[0xF0][1][0] = dev->cols[0xF0][1][1] = 16 + 15; + dev->cols[0x78][0][1] = 16 + 7; + dev->cols[0x78][0][0] = dev->cols[0x78][1][0] = dev->cols[0x78][1][1] = 16 + 15; + dev->cols[0xF8][0][1] = 16 + 7; + dev->cols[0xF8][0][0] = dev->cols[0xF8][1][0] = dev->cols[0xF8][1][1] = 16 + 15; dev->cols[0x00][0][1] = dev->cols[0x00][1][1] = 16; dev->cols[0x08][0][1] = dev->cols[0x08][1][1] = 16; dev->cols[0x80][0][1] = dev->cols[0x80][1][1] = 16; @@ -577,7 +561,7 @@ hercules_init(const device_t *info) cga_palette = device_get_config_int("rgb_type") << 1; if (cga_palette > 6) - cga_palette = 0; + cga_palette = 0; cgapal_rebuild(); herc_blend = device_get_config_int("blend"); @@ -587,35 +571,33 @@ hercules_init(const device_t *info) /* Force the LPT3 port to be enabled. */ lpt3_init(0x3BC); - return(dev); + return (dev); } - static void hercules_close(void *priv) { - hercules_t *dev = (hercules_t *)priv; + hercules_t *dev = (hercules_t *) priv; if (!dev) - return; + return; if (dev->vram) - free(dev->vram); + free(dev->vram); free(dev); } - static void speed_changed(void *priv) { - hercules_t *dev = (hercules_t *)priv; + hercules_t *dev = (hercules_t *) priv; recalc_timings(dev); } static const device_config_t hercules_config[] = { -// clang-format off + // clang-format off { .name = "rgb_type", .description = "Display type", @@ -656,15 +638,15 @@ static const device_config_t hercules_config[] = { }; const device_t hercules_device = { - .name = "Hercules", + .name = "Hercules", .internal_name = "hercules", - .flags = DEVICE_ISA, - .local = 0, - .init = hercules_init, - .close = hercules_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = hercules_init, + .close = hercules_close, + .reset = NULL, { .available = NULL }, .speed_changed = speed_changed, - .force_redraw = NULL, - .config = hercules_config + .force_redraw = NULL, + .config = hercules_config }; diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index b4a514422..e54c715b9 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -31,27 +31,26 @@ #include <86box/device.h> #include <86box/video.h> - /* extended CRTC registers */ -#define HERCULESPLUS_CRTC_XMODE 20 /* xMode register */ -#define HERCULESPLUS_CRTC_UNDER 21 /* Underline */ -#define HERCULESPLUS_CRTC_OVER 22 /* Overstrike */ +#define HERCULESPLUS_CRTC_XMODE 20 /* xMode register */ +#define HERCULESPLUS_CRTC_UNDER 21 /* Underline */ +#define HERCULESPLUS_CRTC_OVER 22 /* Overstrike */ /* character width */ -#define HERCULESPLUS_CW ((dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) ? 8 : 9) +#define HERCULESPLUS_CW ((dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) ? 8 : 9) /* mode control register */ -#define HERCULESPLUS_CTRL_GRAPH 0x02 -#define HERCULESPLUS_CTRL_ENABLE 0x08 -#define HERCULESPLUS_CTRL_BLINK 0x20 -#define HERCULESPLUS_CTRL_PAGE1 0x80 +#define HERCULESPLUS_CTRL_GRAPH 0x02 +#define HERCULESPLUS_CTRL_ENABLE 0x08 +#define HERCULESPLUS_CTRL_BLINK 0x20 +#define HERCULESPLUS_CTRL_PAGE1 0x80 /* CRTC status register */ -#define HERCULESPLUS_STATUS_HSYNC 0x01 /* horizontal sync */ +#define HERCULESPLUS_STATUS_HSYNC 0x01 /* horizontal sync */ #define HERCULESPLUS_STATUS_LIGHT 0x02 #define HERCULESPLUS_STATUS_VIDEO 0x08 -#define HERCULESPLUS_STATUS_ID 0x10 /* Card identification */ -#define HERCULESPLUS_STATUS_VSYNC 0x80 /* -vertical sync */ +#define HERCULESPLUS_STATUS_ID 0x10 /* Card identification */ +#define HERCULESPLUS_STATUS_VSYNC 0x80 /* -vertical sync */ /* configuration switch register */ #define HERCULESPLUS_CTRL2_GRAPH 0x01 @@ -61,39 +60,44 @@ #define HERCULESPLUS_XMODE_RAMFONT 0x01 #define HERCULESPLUS_XMODE_90COL 0x02 - typedef struct { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, stat; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int firstline, lastline; + int firstline, lastline; - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int vsynctime; - int vadj; - int monitor_index, prev_monitor_index; + int linepos, displine; + int vc, sc; + uint16_t ma, maback; + int con, coff, cursoron; + int dispon, blink; + int vsynctime; + int vadj; + int monitor_index, prev_monitor_index; - int cols[256][2][2]; + int cols[256][2][2]; - uint8_t *vram; + uint8_t *vram; } herculesplus_t; -#define VIDEO_MONITOR_PROLOGUE() { dev->prev_monitor_index = monitor_index_global; monitor_index_global = dev->monitor_index; } -#define VIDEO_MONITOR_EPILOGUE() { monitor_index_global = dev->prev_monitor_index; } - -static video_timings_t timing_herculesplus = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +#define VIDEO_MONITOR_PROLOGUE() \ + { \ + dev->prev_monitor_index = monitor_index_global; \ + monitor_index_global = dev->monitor_index; \ + } +#define VIDEO_MONITOR_EPILOGUE() \ + { \ + monitor_index_global = dev->prev_monitor_index; \ + } +static video_timings_t timing_herculesplus = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static void recalc_timings(herculesplus_t *dev) @@ -101,558 +105,550 @@ recalc_timings(herculesplus_t *dev) double disptime; double _dispontime, _dispofftime; - disptime = dev->crtc[0] + 1; + disptime = dev->crtc[0] + 1; _dispontime = dev->crtc[1]; _dispofftime = disptime - _dispontime; - _dispontime *= HERCCONST; + _dispontime *= HERCCONST; _dispofftime *= HERCCONST; - dev->dispontime = (uint64_t)(_dispontime); - dev->dispofftime = (uint64_t)(_dispofftime); + dev->dispontime = (uint64_t) (_dispontime); + dev->dispofftime = (uint64_t) (_dispofftime); } - static void herculesplus_out(uint16_t port, uint8_t val, void *priv) { - herculesplus_t *dev = (herculesplus_t *)priv; - uint8_t old; + herculesplus_t *dev = (herculesplus_t *) priv; + uint8_t old; switch (port) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - dev->crtcreg = val & 31; - return; + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + dev->crtcreg = val & 31; + return; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - if (dev->crtcreg > 22) return; - old = dev->crtc[dev->crtcreg]; - dev->crtc[dev->crtcreg] = val; - if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { - /*Fix for Generic Turbo XT BIOS, - *which sets up cursor registers wrong*/ - dev->crtc[10] = 0xb; - dev->crtc[11] = 0xc; - } - if (old ^ val) - recalc_timings(dev); - return; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + if (dev->crtcreg > 22) + return; + old = dev->crtc[dev->crtcreg]; + dev->crtc[dev->crtcreg] = val; + if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { + /*Fix for Generic Turbo XT BIOS, + *which sets up cursor registers wrong*/ + dev->crtc[10] = 0xb; + dev->crtc[11] = 0xc; + } + if (old ^ val) + recalc_timings(dev); + return; - case 0x3b8: - old = dev->ctrl; - dev->ctrl = val; - if (old ^ val) - recalc_timings(dev); - return; + case 0x3b8: + old = dev->ctrl; + dev->ctrl = val; + if (old ^ val) + recalc_timings(dev); + return; - case 0x3bf: - dev->ctrl2 = val; - if (val & 2) - mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); - return; - } + case 0x3bf: + dev->ctrl2 = val; + if (val & 2) + mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000); + else + mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); + return; + } } - static uint8_t herculesplus_in(uint16_t port, void *priv) { - herculesplus_t *dev = (herculesplus_t *)priv; - uint8_t ret = 0xff; + herculesplus_t *dev = (herculesplus_t *) priv; + uint8_t ret = 0xff; switch (port) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - ret = dev->crtcreg; - break; + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + ret = dev->crtcreg; + break; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - if (dev->crtcreg <= 22) - ret = dev->crtc[dev->crtcreg]; - break; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + if (dev->crtcreg <= 22) + ret = dev->crtc[dev->crtcreg]; + break; - case 0x3ba: - /* 0x10: Hercules Plus card identity */ - ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x10; - break; + case 0x3ba: + /* 0x10: Hercules Plus card identity */ + ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x10; + break; } return ret; } - static void herculesplus_write(uint32_t addr, uint8_t val, void *priv) { - herculesplus_t *dev = (herculesplus_t *)priv; + herculesplus_t *dev = (herculesplus_t *) priv; dev->vram[addr & 0xffff] = val; } - static uint8_t herculesplus_read(uint32_t addr, void *priv) { - herculesplus_t *dev = (herculesplus_t *)priv; + herculesplus_t *dev = (herculesplus_t *) priv; return dev->vram[addr & 0xffff]; } - static void draw_char_rom(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) { - unsigned ull, val, ifg, ibg; + unsigned ull, val, ifg, ibg; const uint8_t *fnt; - int i, elg, blk; - int cw = HERCULESPLUS_CW; + int i, elg, blk; + int cw = HERCULESPLUS_CW; blk = 0; if (dev->ctrl & HERCULESPLUS_CTRL_BLINK) { - if (attr & 0x80) - blk = (dev->blink & 16); - attr &= 0x7f; + if (attr & 0x80) + blk = (dev->blink & 16); + attr &= 0x7f; } /* MDA-compatible attributes */ ibg = 0; ifg = 7; - if ((attr & 0x77) == 0x70) { /* Invert */ - ifg = 0; - ibg = 7; + if ((attr & 0x77) == 0x70) { /* Invert */ + ifg = 0; + ibg = 7; } if (attr & 8) - ifg |= 8; /* High intensity FG */ + ifg |= 8; /* High intensity FG */ if (attr & 0x80) - ibg |= 8; /* High intensity BG */ - if ((attr & 0x77) == 0) /* Blank */ - ifg = ibg; + ibg |= 8; /* High intensity BG */ + if ((attr & 0x77) == 0) /* Blank */ + ifg = ibg; ull = ((attr & 0x07) == 1) ? 13 : 0xffff; if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) - elg = 0; - else - elg = ((chr >= 0xc0) && (chr <= 0xdf)); + elg = 0; + else + elg = ((chr >= 0xc0) && (chr <= 0xdf)); fnt = &(fontdatm[chr][dev->sc]); if (blk) { - val = 0x000; /* Blinking, draw all background */ - } else if (dev->sc == ull) { - val = 0x1ff; /* Underscore, draw all foreground */ + val = 0x000; /* Blinking, draw all background */ + } else if (dev->sc == ull) { + val = 0x1ff; /* Underscore, draw all foreground */ } else { - val = fnt[0] << 1; + val = fnt[0] << 1; - if (elg) - val |= (val >> 1) & 1; + if (elg) + val |= (val >> 1) & 1; } for (i = 0; i < cw; i++) { - buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg; - val = val << 1; + buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? ifg : ibg; + val = val << 1; } } - static void draw_char_ram4(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) { - unsigned ull, val, ibg, cfg; + unsigned ull, val, ibg, cfg; const uint8_t *fnt; - int i, elg, blk; - int cw = HERCULESPLUS_CW; - int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; + int i, elg, blk; + int cw = HERCULESPLUS_CW; + int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; blk = 0; if (blink) { - if (attr & 0x80) - blk = (dev->blink & 16); - attr &= 0x7f; + if (attr & 0x80) + blk = (dev->blink & 16); + attr &= 0x7f; } /* MDA-compatible attributes */ ibg = 0; - if ((attr & 0x77) == 0x70) { /* Invert */ - ibg = 7; + if ((attr & 0x77) == 0x70) { /* Invert */ + ibg = 7; } if (attr & 8) - if (attr & 0x80) - ibg |= 8; /* High intensity BG */ - if ((attr & 0x77) == 0) /* Blank */ - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + if (attr & 0x80) + ibg |= 8; /* High intensity BG */ + if ((attr & 0x77) == 0) /* Blank */ + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) - elg = 0; + elg = 0; else - elg = ((chr >= 0xc0) && (chr <= 0xdf)); + elg = ((chr >= 0xc0) && (chr <= 0xdf)); fnt = dev->vram + 0x4000 + 16 * chr + dev->sc; if (blk) { - /* Blinking, draw all background */ - val = 0x000; + /* Blinking, draw all background */ + val = 0x000; } else if (dev->sc == ull) { - /* Underscore, draw all foreground */ - val = 0x1ff; + /* Underscore, draw all foreground */ + val = 0x1ff; } else { - val = fnt[0x00000] << 1; + val = fnt[0x00000] << 1; - if (elg) - val |= (val >> 1) & 1; + if (elg) + val |= (val >> 1) & 1; } for (i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = 0; + /* Generate pixel colour */ + cfg = 0; - /* cfg = colour of foreground pixels */ - if ((attr & 0x77) == 0) - cfg = ibg; /* 'blank' attribute */ + /* cfg = colour of foreground pixels */ + if ((attr & 0x77) == 0) + cfg = ibg; /* 'blank' attribute */ - buffer32->line[dev->displine][x * cw + i] = dev->cols[attr][blink][cfg]; - val = val << 1; + buffer32->line[dev->displine][x * cw + i] = dev->cols[attr][blink][cfg]; + val = val << 1; } } - static void draw_char_ram48(herculesplus_t *dev, int x, uint8_t chr, uint8_t attr) { - int i, elg, blk, ul, ol, bld; - unsigned ull, oll, ulc = 0, olc = 0; - unsigned val, ibg, cfg; + int i, elg, blk, ul, ol, bld; + unsigned ull, oll, ulc = 0, olc = 0; + unsigned val, ibg, cfg; const unsigned char *fnt; - int cw = HERCULESPLUS_CW; - int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; - int font = (attr & 0x0F); + int cw = HERCULESPLUS_CW; + int blink = dev->ctrl & HERCULESPLUS_CTRL_BLINK; + int font = (attr & 0x0F); - if (font >= 12) font &= 7; + if (font >= 12) + font &= 7; blk = 0; if (blink) { - if (attr & 0x40) - blk = (dev->blink & 16); - attr &= 0x7f; + if (attr & 0x40) + blk = (dev->blink & 16); + attr &= 0x7f; } /* MDA-compatible attributes */ if (blink) { - ibg = (attr & 0x80) ? 8 : 0; - bld = 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; + ibg = (attr & 0x80) ? 8 : 0; + bld = 0; + ol = (attr & 0x20) ? 1 : 0; + ul = (attr & 0x10) ? 1 : 0; } else { - bld = (attr & 0x80) ? 1 : 0; - ibg = (attr & 0x40) ? 0x0F : 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; + bld = (attr & 0x80) ? 1 : 0; + ibg = (attr & 0x40) ? 0x0F : 0; + ol = (attr & 0x20) ? 1 : 0; + ul = (attr & 0x10) ? 1 : 0; } if (ul) { - ull = dev->crtc[HERCULESPLUS_CRTC_UNDER] & 0x0F; - ulc = (dev->crtc[HERCULESPLUS_CRTC_UNDER] >> 4) & 0x0F; - if (ulc == 0) ulc = 7; + ull = dev->crtc[HERCULESPLUS_CRTC_UNDER] & 0x0F; + ulc = (dev->crtc[HERCULESPLUS_CRTC_UNDER] >> 4) & 0x0F; + if (ulc == 0) + ulc = 7; } else { - ull = 0xFFFF; + ull = 0xFFFF; } if (ol) { - oll = dev->crtc[HERCULESPLUS_CRTC_OVER] & 0x0F; - olc = (dev->crtc[HERCULESPLUS_CRTC_OVER] >> 4) & 0x0F; - if (olc == 0) olc = 7; + oll = dev->crtc[HERCULESPLUS_CRTC_OVER] & 0x0F; + olc = (dev->crtc[HERCULESPLUS_CRTC_OVER] >> 4) & 0x0F; + if (olc == 0) + olc = 7; } else { - oll = 0xFFFF; + oll = 0xFFFF; } if (dev->crtc[HERCULESPLUS_CRTC_XMODE] & HERCULESPLUS_XMODE_90COL) - elg = 0; + elg = 0; else - elg = ((chr >= 0xc0) && (chr <= 0xdf)); + elg = ((chr >= 0xc0) && (chr <= 0xdf)); fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc; if (blk) { /* Blinking, draw all background */ - val = 0x000; + val = 0x000; } else if (dev->sc == ull) { - /* Underscore, draw all foreground */ - val = 0x1ff; + /* Underscore, draw all foreground */ + val = 0x1ff; } else { - val = fnt[0x00000] << 1; + val = fnt[0x00000] << 1; - if (elg) - val |= (val >> 1) & 1; - if (bld) - val |= (val >> 1); + if (elg) + val |= (val >> 1) & 1; + if (bld) + val |= (val >> 1); } for (i = 0; i < cw; i++) { - /* Generate pixel colour */ - cfg = val & 0x100; - if (dev->sc == oll) - cfg = olc ^ ibg; /* Strikethrough */ - else if (dev->sc == ull) - cfg = ulc ^ ibg; /* Underline */ - else - cfg |= ibg; + /* Generate pixel colour */ + cfg = val & 0x100; + if (dev->sc == oll) + cfg = olc ^ ibg; /* Strikethrough */ + else if (dev->sc == ull) + cfg = ulc ^ ibg; /* Underline */ + else + cfg |= ibg; - buffer32->line[dev->displine][(x * cw) + i] = dev->cols[attr][blink][cfg]; - val = val << 1; + buffer32->line[dev->displine][(x * cw) + i] = dev->cols[attr][blink][cfg]; + val = val << 1; } } - static void text_line(herculesplus_t *dev, uint16_t ca) { - int drawcursor; - int x, c; - uint8_t chr, attr; + int drawcursor; + int x, c; + uint8_t chr, attr; uint32_t col; for (x = 0; x < dev->crtc[1]; x++) { - if (dev->ctrl & 8) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; - } else - chr = attr = 0; + if (dev->ctrl & 8) { + chr = dev->vram[(dev->ma << 1) & 0xfff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + } else + chr = attr = 0; - drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); + drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); - switch (dev->crtc[HERCULESPLUS_CRTC_XMODE] & 5) { - case 0: - case 4: /* ROM font */ - draw_char_rom(dev, x, chr, attr); - break; + switch (dev->crtc[HERCULESPLUS_CRTC_XMODE] & 5) { + case 0: + case 4: /* ROM font */ + draw_char_rom(dev, x, chr, attr); + break; - case 1: /* 4k RAMfont */ - draw_char_ram4(dev, x, chr, attr); - break; + case 1: /* 4k RAMfont */ + draw_char_ram4(dev, x, chr, attr); + break; - case 5: /* 48k RAMfont */ - draw_char_ram48(dev, x, chr, attr); - break; - } - ++dev->ma; + case 5: /* 48k RAMfont */ + draw_char_ram48(dev, x, chr, attr); + break; + } + ++dev->ma; - if (drawcursor) { - int cw = HERCULESPLUS_CW; + if (drawcursor) { + int cw = HERCULESPLUS_CW; - col = dev->cols[attr][0][1]; - for (c = 0; c < cw; c++) - buffer32->line[dev->displine][x * cw + c] = col; - } + col = dev->cols[attr][0][1]; + for (c = 0; c < cw; c++) + buffer32->line[dev->displine][x * cw + c] = col; + } } } - static void graphics_line(herculesplus_t *dev) { uint16_t ca; - int x, c, plane = 0; + int x, c, plane = 0; uint16_t val; /* Graphics mode. */ ca = (dev->sc & 3) * 0x2000; if ((dev->ctrl & HERCULESPLUS_CTRL_PAGE1) && (dev->ctrl2 & HERCULESPLUS_CTRL2_PAGE1)) - ca += 0x8000; + ca += 0x8000; for (x = 0; x < dev->crtc[1]; x++) { - if (dev->ctrl & 8) - val = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) - | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; - else - val = 0; + if (dev->ctrl & 8) + val = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) + | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + else + val = 0; - dev->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[dev->displine][(x << 4) + c] = (val & 0x8000) ? 7 : 0; + dev->ma++; + for (c = 0; c < 16; c++) { + buffer32->line[dev->displine][(x << 4) + c] = (val & 0x8000) ? 7 : 0; - val <<= 1; - } + val <<= 1; + } - for (c = 0; c < 16; c += 8) - video_blend((x << 4) + c, dev->displine); + for (c = 0; c < 16; c += 8) + video_blend((x << 4) + c, dev->displine); } } - static void herculesplus_poll(void *priv) { - herculesplus_t *dev = (herculesplus_t *)priv; - uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; - int x, oldvc, oldsc; + herculesplus_t *dev = (herculesplus_t *) priv; + uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; + int x, oldvc, oldsc; VIDEO_MONITOR_PROLOGUE(); - if (! dev->linepos) { - timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; - dev->linepos = 1; - oldsc = dev->sc; - if ((dev->crtc[8] & 3) == 3) - dev->sc = (dev->sc << 1) & 7; - if (dev->dispon) { - if (dev->displine < dev->firstline) { - dev->firstline = dev->displine; - video_wait_for_buffer(); - } - dev->lastline = dev->displine; - if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) - graphics_line(dev); - else - text_line(dev, ca); - } - dev->sc = oldsc; - if (dev->vc == dev->crtc[7] && !dev->sc) - dev->stat |= 8; - dev->displine++; - if (dev->displine >= 500) - dev->displine = 0; + if (!dev->linepos) { + timer_advance_u64(&dev->timer, dev->dispofftime); + dev->stat |= 1; + dev->linepos = 1; + oldsc = dev->sc; + if ((dev->crtc[8] & 3) == 3) + dev->sc = (dev->sc << 1) & 7; + if (dev->dispon) { + if (dev->displine < dev->firstline) { + dev->firstline = dev->displine; + video_wait_for_buffer(); + } + dev->lastline = dev->displine; + if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) + graphics_line(dev); + else + text_line(dev, ca); + } + dev->sc = oldsc; + if (dev->vc == dev->crtc[7] && !dev->sc) + dev->stat |= 8; + dev->displine++; + if (dev->displine >= 500) + dev->displine = 0; } else { - timer_advance_u64(&dev->timer, dev->dispontime); - if (dev->dispon) - dev->stat &= ~1; - dev->linepos = 0; - if (dev->vsynctime) { - dev->vsynctime--; - if (! dev->vsynctime) - dev->stat &= ~8; - } + timer_advance_u64(&dev->timer, dev->dispontime); + if (dev->dispon) + dev->stat &= ~1; + dev->linepos = 0; + if (dev->vsynctime) { + dev->vsynctime--; + if (!dev->vsynctime) + dev->stat &= ~8; + } - if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { - dev->con = 0; - dev->coff = 1; - } - if (dev->vadj) { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; - dev->vadj--; - if (! dev->vadj) { - dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - dev->sc = 0; - } - } else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { - dev->maback = dev->ma; - dev->sc = 0; - oldvc = dev->vc; - dev->vc++; - dev->vc &= 127; - if (dev->vc == dev->crtc[6]) - dev->dispon = 0; - if (oldvc == dev->crtc[4]) { - dev->vc = 0; - dev->vadj = dev->crtc[5]; - if (!dev->vadj) dev->dispon=1; - if (!dev->vadj) dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - if ((dev->crtc[10] & 0x60) == 0x20) - dev->cursoron = 0; - else - dev->cursoron = dev->blink & 16; - } - if (dev->vc == dev->crtc[7]) { - dev->dispon = 0; - dev->displine = 0; - dev->vsynctime = 16; - if (dev->crtc[7]) { - if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) - x = dev->crtc[1] << 4; - else - x = dev->crtc[1] * 9; - dev->lastline++; - if ((dev->ctrl & 8) && - ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { - xsize = x; - ysize = dev->lastline - dev->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); + if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { + dev->con = 0; + dev->coff = 1; + } + if (dev->vadj) { + dev->sc++; + dev->sc &= 31; + dev->ma = dev->maback; + dev->vadj--; + if (!dev->vadj) { + dev->dispon = 1; + dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->sc = 0; + } + } else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { + dev->maback = dev->ma; + dev->sc = 0; + oldvc = dev->vc; + dev->vc++; + dev->vc &= 127; + if (dev->vc == dev->crtc[6]) + dev->dispon = 0; + if (oldvc == dev->crtc[4]) { + dev->vc = 0; + dev->vadj = dev->crtc[5]; + if (!dev->vadj) + dev->dispon = 1; + if (!dev->vadj) + dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + if ((dev->crtc[10] & 0x60) == 0x20) + dev->cursoron = 0; + else + dev->cursoron = dev->blink & 16; + } + if (dev->vc == dev->crtc[7]) { + dev->dispon = 0; + dev->displine = 0; + dev->vsynctime = 16; + if (dev->crtc[7]) { + if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) + x = dev->crtc[1] << 4; + else + x = dev->crtc[1] * 9; + dev->lastline++; + if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { + xsize = x; + ysize = dev->lastline - dev->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + set_screen_size(xsize, ysize); - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen_8(0, dev->firstline, xsize, dev->lastline - dev->firstline); - frames++; - if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) { - video_res_x = dev->crtc[1] * 16; - video_res_y = dev->crtc[6] * 4; - video_bpp = 1; - } else { - video_res_x = dev->crtc[1]; - video_res_y = dev->crtc[6]; - video_bpp = 0; - } - } - dev->firstline = 1000; - dev->lastline = 0; - dev->blink++; - } - } else { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; - } + if (video_force_resize_get()) + video_force_resize_set(0); + } + video_blit_memtoscreen_8(0, dev->firstline, xsize, dev->lastline - dev->firstline); + frames++; + if ((dev->ctrl & HERCULESPLUS_CTRL_GRAPH) && (dev->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) { + video_res_x = dev->crtc[1] * 16; + video_res_y = dev->crtc[6] * 4; + video_bpp = 1; + } else { + video_res_x = dev->crtc[1]; + video_res_y = dev->crtc[6]; + video_bpp = 0; + } + } + dev->firstline = 1000; + dev->lastline = 0; + dev->blink++; + } + } else { + dev->sc++; + dev->sc &= 31; + dev->ma = dev->maback; + } - if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) - dev->con = 1; + if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) + dev->con = 1; } VIDEO_MONITOR_EPILOGUE(); } - static void * herculesplus_init(const device_t *info) { herculesplus_t *dev; - int c; + int c; - dev = (herculesplus_t *)malloc(sizeof(herculesplus_t)); + dev = (herculesplus_t *) malloc(sizeof(herculesplus_t)); memset(dev, 0, sizeof(herculesplus_t)); - dev->vram = (uint8_t *)malloc(0x10000); /* 64k VRAM */ + dev->vram = (uint8_t *) malloc(0x10000); /* 64k VRAM */ dev->monitor_index = monitor_index_global; timer_add(&dev->timer, herculesplus_poll, dev, 1); mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, - herculesplus_read,NULL,NULL, - herculesplus_write,NULL,NULL, - dev->vram, MEM_MAPPING_EXTERNAL, dev); + herculesplus_read, NULL, NULL, + herculesplus_write, NULL, NULL, + dev->vram, MEM_MAPPING_EXTERNAL, dev); io_sethandler(0x03b0, 16, - herculesplus_in,NULL, NULL, herculesplus_out,NULL,NULL, dev); + herculesplus_in, NULL, NULL, herculesplus_out, NULL, NULL, dev); for (c = 0; c < 256; c++) { - dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16; - if (c & 8) - dev->cols[c][0][1] = 15 + 16; - else - dev->cols[c][0][1] = 7 + 16; + dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16; + if (c & 8) + dev->cols[c][0][1] = 15 + 16; + else + dev->cols[c][0][1] = 7 + 16; } dev->cols[0x70][0][1] = 16; - dev->cols[0x70][0][0] = dev->cols[0x70][1][0] = - dev->cols[0x70][1][1] = 16 + 15; - dev->cols[0xF0][0][1] = 16; - dev->cols[0xF0][0][0] = dev->cols[0xF0][1][0] = - dev->cols[0xF0][1][1] = 16 + 15; - dev->cols[0x78][0][1] = 16 + 7; - dev->cols[0x78][0][0] = dev->cols[0x78][1][0] = - dev->cols[0x78][1][1] = 16 + 15; - dev->cols[0xF8][0][1] = 16 + 7; - dev->cols[0xF8][0][0] = dev->cols[0xF8][1][0] = - dev->cols[0xF8][1][1] = 16 + 15; + dev->cols[0x70][0][0] = dev->cols[0x70][1][0] = dev->cols[0x70][1][1] = 16 + 15; + dev->cols[0xF0][0][1] = 16; + dev->cols[0xF0][0][0] = dev->cols[0xF0][1][0] = dev->cols[0xF0][1][1] = 16 + 15; + dev->cols[0x78][0][1] = 16 + 7; + dev->cols[0x78][0][0] = dev->cols[0x78][1][0] = dev->cols[0x78][1][1] = 16 + 15; + dev->cols[0xF8][0][1] = 16 + 7; + dev->cols[0xF8][0][0] = dev->cols[0xF8][1][0] = dev->cols[0xF8][1][1] = 16 + 15; dev->cols[0x00][0][1] = dev->cols[0x00][1][1] = 16; dev->cols[0x08][0][1] = dev->cols[0x08][1][1] = 16; dev->cols[0x80][0][1] = dev->cols[0x80][1][1] = 16; @@ -662,7 +658,7 @@ herculesplus_init(const device_t *info) cga_palette = device_get_config_int("rgb_type") << 1; if (cga_palette > 6) - cga_palette = 0; + cga_palette = 0; cgapal_rebuild(); video_inform(VIDEO_FLAG_TYPE_MDA, &timing_herculesplus); @@ -673,32 +669,30 @@ herculesplus_init(const device_t *info) return dev; } - static void herculesplus_close(void *priv) { - herculesplus_t *dev = (herculesplus_t *)priv; + herculesplus_t *dev = (herculesplus_t *) priv; if (!dev) - return; + return; if (dev->vram) - free(dev->vram); + free(dev->vram); free(dev); } - static void speed_changed(void *priv) { - herculesplus_t *dev = (herculesplus_t *)priv; + herculesplus_t *dev = (herculesplus_t *) priv; recalc_timings(dev); } static const device_config_t herculesplus_config[] = { -// clang-format off + // clang-format off { .name = "rgb_type", .description = "Display type", @@ -739,15 +733,15 @@ static const device_config_t herculesplus_config[] = { }; const device_t herculesplus_device = { - .name = "Hercules Plus", + .name = "Hercules Plus", .internal_name = "hercules_plus", - .flags = DEVICE_ISA, - .local = 0, - .init = herculesplus_init, - .close = herculesplus_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = herculesplus_init, + .close = herculesplus_close, + .reset = NULL, { .available = NULL }, .speed_changed = speed_changed, - .force_redraw = NULL, - .config = herculesplus_config + .force_redraw = NULL, + .config = herculesplus_config }; diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 8ef6fc9e0..cf5e8f5f4 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -34,525 +34,525 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +typedef struct ht216_t { + svga_t svga; -typedef struct ht216_t -{ - svga_t svga; + mem_mapping_t linear_mapping; - mem_mapping_t linear_mapping; + rom_t bios_rom; - rom_t bios_rom; + uint32_t vram_mask, linear_base; + uint8_t adjust_cursor, monitor_type; - uint32_t vram_mask, linear_base; - uint8_t adjust_cursor, monitor_type; + int ext_reg_enable; + int isabus; + int mca; - int ext_reg_enable; - int isabus; - int mca; + uint8_t read_bank_reg[2], write_bank_reg[2]; + uint16_t id, misc; + uint32_t read_banks[2], write_banks[2]; - uint8_t read_bank_reg[2], write_bank_reg[2]; - uint16_t id, misc; - uint32_t read_banks[2], write_banks[2]; + uint8_t bg_latch[8]; + uint8_t fg_latch[4]; + uint8_t bg_plane_sel, fg_plane_sel; - uint8_t bg_latch[8]; - uint8_t fg_latch[4]; - uint8_t bg_plane_sel, fg_plane_sel; + uint8_t ht_regs[256]; + uint8_t extensions, reg_3cb; - uint8_t ht_regs[256]; - uint8_t extensions, reg_3cb; - - uint8_t pos_regs[8]; + uint8_t pos_regs[8]; } ht216_t; - #define HT_MISC_PAGE_SEL (1 << 5) /*Shifts CPU VRAM read address by 3 bits, for use with fat pixel color expansion*/ -#define HT_REG_C8_MOVSB (1 << 0) -#define HT_REG_C8_E256 (1 << 4) -#define HT_REG_C8_XLAM (1 << 6) +#define HT_REG_C8_MOVSB (1 << 0) +#define HT_REG_C8_E256 (1 << 4) +#define HT_REG_C8_XLAM (1 << 6) #define HT_REG_CD_P8PCEXP (1 << 0) #define HT_REG_CD_FP8PCEXP (1 << 1) #define HT_REG_CD_BMSKSL (3 << 2) #define HT_REG_CD_RMWMDE (1 << 5) /*Use GDC data rotate as offset when reading VRAM data into latches*/ -#define HT_REG_CD_ASTODE (1 << 6) -#define HT_REG_CD_EXALU (1 << 7) +#define HT_REG_CD_ASTODE (1 << 6) +#define HT_REG_CD_EXALU (1 << 7) -#define HT_REG_E0_SBAE (1 << 7) +#define HT_REG_E0_SBAE (1 << 7) -#define HT_REG_F9_XPSEL (1 << 0) +#define HT_REG_F9_XPSEL (1 << 0) /*Enables A[14:15] of VRAM address in chain-4 modes*/ #define HT_REG_FC_ECOLRE (1 << 2) -#define HT_REG_FE_FBRC (1 << 1) -#define HT_REG_FE_FBMC (3 << 2) -#define HT_REG_FE_FBRSL (3 << 4) - +#define HT_REG_FE_FBRC (1 << 1) +#define HT_REG_FE_FBMC (3 << 2) +#define HT_REG_FE_FBRSL (3 << 4) void ht216_remap(ht216_t *ht216); -void ht216_out(uint16_t addr, uint8_t val, void *p); +void ht216_out(uint16_t addr, uint8_t val, void *p); uint8_t ht216_in(uint16_t addr, void *p); +#define BIOS_G2_GC205_PATH "roms/video/video7/BIOS.BIN" +#define BIOS_VIDEO7_VGA_1024I_PATH "roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN" +#define BIOS_RADIUS_SVGA_MULTIVIEW_PATH "roms/video/video7/U18.BIN" +#define BIOS_HT216_32_PATH "roms/video/video7/HT21632.BIN" -#define BIOS_G2_GC205_PATH "roms/video/video7/BIOS.BIN" -#define BIOS_VIDEO7_VGA_1024I_PATH "roms/video/video7/Video Seven VGA 1024i - BIOS - v2.19 - 435-0062-05 - U17 - 27C256.BIN" -#define BIOS_RADIUS_SVGA_MULTIVIEW_PATH "roms/video/video7/U18.BIN" -#define BIOS_HT216_32_PATH "roms/video/video7/HT21632.BIN" - -static video_timings_t timing_v7vga_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; -static video_timings_t timing_v7vga_mca = {VIDEO_MCA, 4, 5, 10, 5, 5, 10}; -static video_timings_t timing_v7vga_vlb = {VIDEO_BUS, 5, 5, 9, 20, 20, 30}; - +static video_timings_t timing_v7vga_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_v7vga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_v7vga_vlb = { .type = VIDEO_BUS, .write_b = 5, .write_w = 5, .write_l = 9, .read_b = 20, .read_w = 20, .read_l = 30 }; #ifdef ENABLE_HT216_LOG int ht216_do_log = ENABLE_HT216_LOG; - static void ht216_log(const char *fmt, ...) { va_list ap; if (ht216_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ht216_log(fmt, ...) +# define ht216_log(fmt, ...) #endif /*Remap address for chain-4/doubleword style layout*/ static __inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; - return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff); + if (svga->packed_chain4) + return in_addr; + return ((in_addr & 0xfffc) << 2) | ((in_addr & 0x30000) >> 14) | (in_addr & ~0x3ffff); } static void ht216_recalc_bank_regs(ht216_t *ht216, int mode) { - svga_t *svga = &ht216->svga; + svga_t *svga = &ht216->svga; - if (mode) { - ht216->read_bank_reg[0] = ht216->ht_regs[0xe8]; - ht216->write_bank_reg[0] = ht216->ht_regs[0xe8]; - ht216->read_bank_reg[1] = ht216->ht_regs[0xe9]; - ht216->write_bank_reg[1] = ht216->ht_regs[0xe9]; + if (mode) { + ht216->read_bank_reg[0] = ht216->ht_regs[0xe8]; + ht216->write_bank_reg[0] = ht216->ht_regs[0xe8]; + ht216->read_bank_reg[1] = ht216->ht_regs[0xe9]; + ht216->write_bank_reg[1] = ht216->ht_regs[0xe9]; } else { - ht216->read_bank_reg[0] = ((ht216->ht_regs[0xf6] & 0xc) << 4); - ht216->read_bank_reg[1] = ((ht216->ht_regs[0xf6] & 0xc) << 4); - ht216->write_bank_reg[0] = ((ht216->ht_regs[0xf6] & 0x3) << 6); - ht216->write_bank_reg[1] = ((ht216->ht_regs[0xf6] & 0x3) << 6); + ht216->read_bank_reg[0] = ((ht216->ht_regs[0xf6] & 0xc) << 4); + ht216->read_bank_reg[1] = ((ht216->ht_regs[0xf6] & 0xc) << 4); + ht216->write_bank_reg[0] = ((ht216->ht_regs[0xf6] & 0x3) << 6); + ht216->write_bank_reg[1] = ((ht216->ht_regs[0xf6] & 0x3) << 6); - if (svga->packed_chain4 || (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) { - ht216->read_bank_reg[0] |= (ht216->misc & 0x20); - ht216->read_bank_reg[1] |= (ht216->misc & 0x20); - ht216->write_bank_reg[0] |= (ht216->misc & 0x20); - ht216->write_bank_reg[1] |= (ht216->misc & 0x20); - } + if (svga->packed_chain4 || (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE)) { + ht216->read_bank_reg[0] |= (ht216->misc & 0x20); + ht216->read_bank_reg[1] |= (ht216->misc & 0x20); + ht216->write_bank_reg[0] |= (ht216->misc & 0x20); + ht216->write_bank_reg[1] |= (ht216->misc & 0x20); + } - if (svga->packed_chain4 || ((ht216->ht_regs[0xfc] & 0x06) == 0x04)) { - ht216->read_bank_reg[0] |= ((ht216->ht_regs[0xf9] & 1) << 4); - ht216->read_bank_reg[1] |= ((ht216->ht_regs[0xf9] & 1) << 4); - ht216->write_bank_reg[0] |= ((ht216->ht_regs[0xf9] & 1) << 4); - ht216->write_bank_reg[1] |= ((ht216->ht_regs[0xf9] & 1) << 4); - } + if (svga->packed_chain4 || ((ht216->ht_regs[0xfc] & 0x06) == 0x04)) { + ht216->read_bank_reg[0] |= ((ht216->ht_regs[0xf9] & 1) << 4); + ht216->read_bank_reg[1] |= ((ht216->ht_regs[0xf9] & 1) << 4); + ht216->write_bank_reg[0] |= ((ht216->ht_regs[0xf9] & 1) << 4); + ht216->write_bank_reg[1] |= ((ht216->ht_regs[0xf9] & 1) << 4); + } } } - void ht216_out(uint16_t addr, uint8_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; - uint8_t old; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; + uint8_t old; ht216_log("ht216 %i out %04X %02X %04X:%04X\n", svga->miscout & 1, addr, val, CS, cpu_state.pc); if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { - case 0x3c2: - /*Bit 17 of the display memory address, only active on odd/even modes, has no effect on graphics modes.*/ - ht216->misc = val; - svga->miscout = val; - ht216_log("HT216 misc val = %02x, mode = 0, chain4 = %x\n", val, svga->chain4); - ht216_recalc_bank_regs(ht216, 0); - ht216_remap(ht216); - svga_recalctimings(svga); - break; + case 0x3c2: + /*Bit 17 of the display memory address, only active on odd/even modes, has no effect on graphics modes.*/ + ht216->misc = val; + svga->miscout = val; + ht216_log("HT216 misc val = %02x, mode = 0, chain4 = %x\n", val, svga->chain4); + ht216_recalc_bank_regs(ht216, 0); + ht216_remap(ht216); + svga_recalctimings(svga); + break; - case 0x3c4: - svga->seqaddr = val; - break; + case 0x3c4: + svga->seqaddr = val; + break; - case 0x3c5: - if (svga->seqaddr == 4) { - svga->chain2_write = !(val & 4); - svga->chain4 = val & 8; - ht216_remap(ht216); - } else if (svga->seqaddr == 6) { - if (val == 0xea) - ht216->ext_reg_enable = 1; - else if (val == 0xae) - ht216->ext_reg_enable = 0; + case 0x3c5: + if (svga->seqaddr == 4) { + svga->chain2_write = !(val & 4); + svga->chain4 = val & 8; + ht216_remap(ht216); + } else if (svga->seqaddr == 6) { + if (val == 0xea) + ht216->ext_reg_enable = 1; + else if (val == 0xae) + ht216->ext_reg_enable = 0; #ifdef ENABLE_HT216_LOG - /* Functionality to output to the console a dump of all registers for debugging purposes. */ - } else if (svga->seqaddr == 0x7f) { - ht216_log(" 8 | 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); - ht216_log("----+-------------------------------------------------\n"); - ht216_log(" 8 | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0x80], ht216->ht_regs[0x81], ht216->ht_regs[0x82], ht216->ht_regs[0x83], - ht216->ht_regs[0x84], ht216->ht_regs[0x85], ht216->ht_regs[0x86], ht216->ht_regs[0x87], - ht216->ht_regs[0x88], ht216->ht_regs[0x89], ht216->ht_regs[0x8a], ht216->ht_regs[0x8b], - ht216->ht_regs[0x8c], ht216->ht_regs[0x8d], ht216->ht_regs[0x8e], ht216->ht_regs[0x8f]); - ht216_log(" 9 | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0x90], ht216->ht_regs[0x91], ht216->ht_regs[0x92], ht216->ht_regs[0x93], - ht216->ht_regs[0x94], ht216->ht_regs[0x95], ht216->ht_regs[0x96], ht216->ht_regs[0x97], - ht216->ht_regs[0x98], ht216->ht_regs[0x99], ht216->ht_regs[0x9a], ht216->ht_regs[0x9b], - ht216->ht_regs[0x9c], ht216->ht_regs[0x9d], ht216->ht_regs[0x9e], ht216->ht_regs[0x9f]); - ht216_log(" A | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0xa0], ht216->ht_regs[0xa1], ht216->ht_regs[0xa2], ht216->ht_regs[0xa3], - ht216->ht_regs[0xa4], ht216->ht_regs[0xa5], ht216->ht_regs[0xa6], ht216->ht_regs[0xa7], - ht216->ht_regs[0xa8], ht216->ht_regs[0xa9], ht216->ht_regs[0xaa], ht216->ht_regs[0xab], - ht216->ht_regs[0xac], ht216->ht_regs[0xad], ht216->ht_regs[0xae], ht216->ht_regs[0xaf]); - ht216_log(" B | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0xb0], ht216->ht_regs[0xb1], ht216->ht_regs[0xb2], ht216->ht_regs[0xb3], - ht216->ht_regs[0xb4], ht216->ht_regs[0xb5], ht216->ht_regs[0xb6], ht216->ht_regs[0xb7], - ht216->ht_regs[0xb8], ht216->ht_regs[0xb9], ht216->ht_regs[0xba], ht216->ht_regs[0xbb], - ht216->ht_regs[0xbc], ht216->ht_regs[0xbd], ht216->ht_regs[0xbe], ht216->ht_regs[0xbf]); - ht216_log(" C | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0xc0], ht216->ht_regs[0xc1], ht216->ht_regs[0xc2], ht216->ht_regs[0xc3], - ht216->ht_regs[0xc4], ht216->ht_regs[0xc5], ht216->ht_regs[0xc6], ht216->ht_regs[0xc7], - ht216->ht_regs[0xc8], ht216->ht_regs[0xc9], ht216->ht_regs[0xca], ht216->ht_regs[0xcb], - ht216->ht_regs[0xcc], ht216->ht_regs[0xcd], ht216->ht_regs[0xce], ht216->ht_regs[0xcf]); - ht216_log(" D | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0xd0], ht216->ht_regs[0xd1], ht216->ht_regs[0xd2], ht216->ht_regs[0xd3], - ht216->ht_regs[0xd4], ht216->ht_regs[0xd5], ht216->ht_regs[0xd6], ht216->ht_regs[0xd7], - ht216->ht_regs[0xd8], ht216->ht_regs[0xd9], ht216->ht_regs[0xda], ht216->ht_regs[0xdb], - ht216->ht_regs[0xdc], ht216->ht_regs[0xdd], ht216->ht_regs[0xde], ht216->ht_regs[0xdf]); - ht216_log(" E | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0xe0], ht216->ht_regs[0xe1], ht216->ht_regs[0xe2], ht216->ht_regs[0xe3], - ht216->ht_regs[0xe4], ht216->ht_regs[0xe5], ht216->ht_regs[0xe6], ht216->ht_regs[0xe7], - ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], ht216->ht_regs[0xea], ht216->ht_regs[0xeb], - ht216->ht_regs[0xec], ht216->ht_regs[0xed], ht216->ht_regs[0xee], ht216->ht_regs[0xef]); - ht216_log(" F | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", - ht216->ht_regs[0xf0], ht216->ht_regs[0xf1], ht216->ht_regs[0xf2], ht216->ht_regs[0xf3], - ht216->ht_regs[0xf4], ht216->ht_regs[0xf5], ht216->ht_regs[0xf6], ht216->ht_regs[0xf7], - ht216->ht_regs[0xf8], ht216->ht_regs[0xf9], ht216->ht_regs[0xfa], ht216->ht_regs[0xfb], - ht216->ht_regs[0xfc], ht216->ht_regs[0xfd], ht216->ht_regs[0xfe], ht216->ht_regs[0xff]); - return; + /* Functionality to output to the console a dump of all registers for debugging purposes. */ + } else if (svga->seqaddr == 0x7f) { + ht216_log(" 8 | 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); + ht216_log("----+-------------------------------------------------\n"); + ht216_log(" 8 | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0x80], ht216->ht_regs[0x81], ht216->ht_regs[0x82], ht216->ht_regs[0x83], + ht216->ht_regs[0x84], ht216->ht_regs[0x85], ht216->ht_regs[0x86], ht216->ht_regs[0x87], + ht216->ht_regs[0x88], ht216->ht_regs[0x89], ht216->ht_regs[0x8a], ht216->ht_regs[0x8b], + ht216->ht_regs[0x8c], ht216->ht_regs[0x8d], ht216->ht_regs[0x8e], ht216->ht_regs[0x8f]); + ht216_log(" 9 | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0x90], ht216->ht_regs[0x91], ht216->ht_regs[0x92], ht216->ht_regs[0x93], + ht216->ht_regs[0x94], ht216->ht_regs[0x95], ht216->ht_regs[0x96], ht216->ht_regs[0x97], + ht216->ht_regs[0x98], ht216->ht_regs[0x99], ht216->ht_regs[0x9a], ht216->ht_regs[0x9b], + ht216->ht_regs[0x9c], ht216->ht_regs[0x9d], ht216->ht_regs[0x9e], ht216->ht_regs[0x9f]); + ht216_log(" A | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0xa0], ht216->ht_regs[0xa1], ht216->ht_regs[0xa2], ht216->ht_regs[0xa3], + ht216->ht_regs[0xa4], ht216->ht_regs[0xa5], ht216->ht_regs[0xa6], ht216->ht_regs[0xa7], + ht216->ht_regs[0xa8], ht216->ht_regs[0xa9], ht216->ht_regs[0xaa], ht216->ht_regs[0xab], + ht216->ht_regs[0xac], ht216->ht_regs[0xad], ht216->ht_regs[0xae], ht216->ht_regs[0xaf]); + ht216_log(" B | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0xb0], ht216->ht_regs[0xb1], ht216->ht_regs[0xb2], ht216->ht_regs[0xb3], + ht216->ht_regs[0xb4], ht216->ht_regs[0xb5], ht216->ht_regs[0xb6], ht216->ht_regs[0xb7], + ht216->ht_regs[0xb8], ht216->ht_regs[0xb9], ht216->ht_regs[0xba], ht216->ht_regs[0xbb], + ht216->ht_regs[0xbc], ht216->ht_regs[0xbd], ht216->ht_regs[0xbe], ht216->ht_regs[0xbf]); + ht216_log(" C | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0xc0], ht216->ht_regs[0xc1], ht216->ht_regs[0xc2], ht216->ht_regs[0xc3], + ht216->ht_regs[0xc4], ht216->ht_regs[0xc5], ht216->ht_regs[0xc6], ht216->ht_regs[0xc7], + ht216->ht_regs[0xc8], ht216->ht_regs[0xc9], ht216->ht_regs[0xca], ht216->ht_regs[0xcb], + ht216->ht_regs[0xcc], ht216->ht_regs[0xcd], ht216->ht_regs[0xce], ht216->ht_regs[0xcf]); + ht216_log(" D | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0xd0], ht216->ht_regs[0xd1], ht216->ht_regs[0xd2], ht216->ht_regs[0xd3], + ht216->ht_regs[0xd4], ht216->ht_regs[0xd5], ht216->ht_regs[0xd6], ht216->ht_regs[0xd7], + ht216->ht_regs[0xd8], ht216->ht_regs[0xd9], ht216->ht_regs[0xda], ht216->ht_regs[0xdb], + ht216->ht_regs[0xdc], ht216->ht_regs[0xdd], ht216->ht_regs[0xde], ht216->ht_regs[0xdf]); + ht216_log(" E | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0xe0], ht216->ht_regs[0xe1], ht216->ht_regs[0xe2], ht216->ht_regs[0xe3], + ht216->ht_regs[0xe4], ht216->ht_regs[0xe5], ht216->ht_regs[0xe6], ht216->ht_regs[0xe7], + ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], ht216->ht_regs[0xea], ht216->ht_regs[0xeb], + ht216->ht_regs[0xec], ht216->ht_regs[0xed], ht216->ht_regs[0xee], ht216->ht_regs[0xef]); + ht216_log(" F | %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", + ht216->ht_regs[0xf0], ht216->ht_regs[0xf1], ht216->ht_regs[0xf2], ht216->ht_regs[0xf3], + ht216->ht_regs[0xf4], ht216->ht_regs[0xf5], ht216->ht_regs[0xf6], ht216->ht_regs[0xf7], + ht216->ht_regs[0xf8], ht216->ht_regs[0xf9], ht216->ht_regs[0xfa], ht216->ht_regs[0xfb], + ht216->ht_regs[0xfc], ht216->ht_regs[0xfd], ht216->ht_regs[0xfe], ht216->ht_regs[0xff]); + return; #endif - } else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable) { - old = ht216->ht_regs[svga->seqaddr & 0xff]; - ht216->ht_regs[svga->seqaddr & 0xff] = val; + } else if (svga->seqaddr >= 0x80 && ht216->ext_reg_enable) { + old = ht216->ht_regs[svga->seqaddr & 0xff]; + ht216->ht_regs[svga->seqaddr & 0xff] = val; - switch (svga->seqaddr & 0xff) { - case 0x83: - svga->attraddr = val & 0x1f; - svga->attrff = !!(val & 0x80); - break; + switch (svga->seqaddr & 0xff) { + case 0x83: + svga->attraddr = val & 0x1f; + svga->attrff = !!(val & 0x80); + break; - case 0x94: - case 0xff: - svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | 0xc000 | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2; - svga->hwcursor.addr &= svga->vram_mask; - if (svga->crtc[0x17] == 0xeb) /*Looks like that 1024x768 mono mode expects 512K of video memory*/ - svga->hwcursor.addr += 0x40000; - break; - case 0x9c: case 0x9d: - svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8); - break; - case 0x9e: case 0x9f: - svga->hwcursor.y = ht216->ht_regs[0x9f] | ((ht216->ht_regs[0x9e] & 3) << 8); - break; + case 0x94: + case 0xff: + svga->hwcursor.addr = ((ht216->ht_regs[0x94] << 6) | 0xc000 | ((ht216->ht_regs[0xff] & 0x60) << 11)) << 2; + svga->hwcursor.addr &= svga->vram_mask; + if (svga->crtc[0x17] == 0xeb) /*Looks like that 1024x768 mono mode expects 512K of video memory*/ + svga->hwcursor.addr += 0x40000; + break; + case 0x9c: + case 0x9d: + svga->hwcursor.x = ht216->ht_regs[0x9d] | ((ht216->ht_regs[0x9c] & 7) << 8); + break; + case 0x9e: + case 0x9f: + svga->hwcursor.y = ht216->ht_regs[0x9f] | ((ht216->ht_regs[0x9e] & 3) << 8); + break; - case 0xa0: - svga->latch.b[0] = val; - break; - case 0xa1: - svga->latch.b[1] = val; - break; - case 0xa2: - svga->latch.b[2] = val; - break; - case 0xa3: - svga->latch.b[3] = val; - break; + case 0xa0: + svga->latch.b[0] = val; + break; + case 0xa1: + svga->latch.b[1] = val; + break; + case 0xa2: + svga->latch.b[2] = val; + break; + case 0xa3: + svga->latch.b[3] = val; + break; - case 0xa4: - case 0xf8: - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; + case 0xa4: + case 0xf8: + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; - case 0xa5: - svga->hwcursor.ena = !!(val & 0x80); - break; + case 0xa5: + svga->hwcursor.ena = !!(val & 0x80); + break; - case 0xc0: - break; + case 0xc0: + break; - case 0xc1: - break; + case 0xc1: + break; - case 0xc8: - if ((old ^ val) & HT_REG_C8_E256) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - ht216_remap(ht216); - break; + case 0xc8: + if ((old ^ val) & HT_REG_C8_E256) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + ht216_remap(ht216); + break; - case 0xc9: case 0xcf: - ht216_remap(ht216); - break; + case 0xc9: + case 0xcf: + ht216_remap(ht216); + break; - case 0xe0: - svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; - if (val & 0x04) - svga->adv_flags |= FLAG_RAMDAC_SHIFT; - /* FALLTHROUGH */ - /*Bank registers*/ - case 0xe8: case 0xe9: - ht216_log("HT216 reg 0x%02x write = %02x, mode = 1, chain4 = %x\n", svga->seqaddr & 0xff, val, svga->chain4); - ht216_recalc_bank_regs(ht216, 1); - ht216_remap(ht216); - break; + case 0xe0: + svga->adv_flags &= ~FLAG_RAMDAC_SHIFT; + if (val & 0x04) + svga->adv_flags |= FLAG_RAMDAC_SHIFT; + /* FALLTHROUGH */ + /*Bank registers*/ + case 0xe8: + case 0xe9: + ht216_log("HT216 reg 0x%02x write = %02x, mode = 1, chain4 = %x\n", svga->seqaddr & 0xff, val, svga->chain4); + ht216_recalc_bank_regs(ht216, 1); + ht216_remap(ht216); + break; - case 0xec: - ht216->fg_latch[0] = val; - break; - case 0xed: - ht216->fg_latch[1] = val; - break; - case 0xee: - ht216->fg_latch[2] = val; - break; - case 0xef: - ht216->fg_latch[3] = val; - break; + case 0xec: + ht216->fg_latch[0] = val; + break; + case 0xed: + ht216->fg_latch[1] = val; + break; + case 0xee: + ht216->fg_latch[2] = val; + break; + case 0xef: + ht216->fg_latch[3] = val; + break; - case 0xf0: - ht216->fg_latch[ht216->fg_plane_sel] = val; - ht216->fg_plane_sel = (ht216->fg_plane_sel + 1) & 3; - break; + case 0xf0: + ht216->fg_latch[ht216->fg_plane_sel] = val; + ht216->fg_plane_sel = (ht216->fg_plane_sel + 1) & 3; + break; - case 0xf1: - ht216->bg_plane_sel = val & 3; - ht216->fg_plane_sel = (val & 0x30) >> 4; - break; + case 0xf1: + ht216->bg_plane_sel = val & 3; + ht216->fg_plane_sel = (val & 0x30) >> 4; + break; - case 0xf2: - svga->latch.b[ht216->bg_plane_sel] = val; - ht216->bg_plane_sel = (ht216->bg_plane_sel + 1) & 3; - break; + case 0xf2: + svga->latch.b[ht216->bg_plane_sel] = val; + ht216->bg_plane_sel = (ht216->bg_plane_sel + 1) & 3; + break; - case 0xf6: - /*Bits 18 and 19 of the display memory address*/ - ht216_log("HT216 reg 0xf6 write = %02x, mode = 0, chain4 = %x, vram mask = %08x, cr17 = %02x\n", val, svga->chain4, svga->vram_display_mask, svga->crtc[0x17]); - ht216_recalc_bank_regs(ht216, 0); - ht216_remap(ht216); - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; + case 0xf6: + /*Bits 18 and 19 of the display memory address*/ + ht216_log("HT216 reg 0xf6 write = %02x, mode = 0, chain4 = %x, vram mask = %08x, cr17 = %02x\n", val, svga->chain4, svga->vram_display_mask, svga->crtc[0x17]); + ht216_recalc_bank_regs(ht216, 0); + ht216_remap(ht216); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; - case 0xf9: - /*Bit 16 of the display memory address, only active when in chain4 mode and 256 color mode.*/ - ht216_log("HT216 reg 0xf9 write = %02x, mode = 0, chain4 = %x\n", val & HT_REG_F9_XPSEL, svga->chain4); - ht216_recalc_bank_regs(ht216, 0); - ht216_remap(ht216); - break; + case 0xf9: + /*Bit 16 of the display memory address, only active when in chain4 mode and 256 color mode.*/ + ht216_log("HT216 reg 0xf9 write = %02x, mode = 0, chain4 = %x\n", val & HT_REG_F9_XPSEL, svga->chain4); + ht216_recalc_bank_regs(ht216, 0); + ht216_remap(ht216); + break; - case 0xfc: - ht216_log("HT216 reg 0xfc write = %02x, mode = 0, chain4 = %x, bit 7 = %02x, packedchain = %02x\n", val, svga->chain4, val & 0x80, val & 0x20); - svga->packed_chain4 = !!(val & 0x20); - ht216_recalc_bank_regs(ht216, 0); - ht216_remap(ht216); - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; - } - return; - } - break; + case 0xfc: + ht216_log("HT216 reg 0xfc write = %02x, mode = 0, chain4 = %x, bit 7 = %02x, packedchain = %02x\n", val, svga->chain4, val & 0x80, val & 0x20); + svga->packed_chain4 = !!(val & 0x20); + ht216_recalc_bank_regs(ht216, 0); + ht216_remap(ht216); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + } + return; + } + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (ht216->id == 0x7152) - sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); - else - svga_out(addr, val, svga); - return; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (ht216->id == 0x7152) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + return; - case 0x3cb: - if (ht216->id == 0x7152) { - ht216->reg_3cb = val; - svga_set_ramdac_type(svga, (val & 0x20) ? RAMDAC_6BIT : RAMDAC_8BIT); - } - break; + case 0x3cb: + if (ht216->id == 0x7152) { + ht216->reg_3cb = val; + svga_set_ramdac_type(svga, (val & 0x20) ? RAMDAC_6BIT : RAMDAC_8BIT); + } + break; - case 0x3cf: - if (svga->gdcaddr == 5) { - svga->chain2_read = val & 0x10; - ht216_remap(ht216); - } else if (svga->gdcaddr == 6) { - if (val & 8) - svga->banked_mask = 0x7fff; - else - svga->banked_mask = 0xffff; - } + case 0x3cf: + if (svga->gdcaddr == 5) { + svga->chain2_read = val & 0x10; + ht216_remap(ht216); + } else if (svga->gdcaddr == 6) { + if (val & 8) + svga->banked_mask = 0x7fff; + else + svga->banked_mask = 0xffff; + } - if (svga->gdcaddr <= 8) { - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4; - } - break; + 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: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - break; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; - case 0x46e8: - if ((ht216->id == 0x7152) && ht216->isabus) - io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&ht216->linear_mapping); - if (val & 8) { - if ((ht216->id == 0x7152) && ht216->isabus) - io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - mem_mapping_enable(&svga->mapping); - ht216_remap(ht216); - } - break; + case 0x46e8: + if ((ht216->id == 0x7152) && ht216->isabus) + io_removehandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_removehandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&ht216->linear_mapping); + if (val & 8) { + if ((ht216->id == 0x7152) && ht216->isabus) + io_sethandler(0x0105, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); + mem_mapping_enable(&svga->mapping); + ht216_remap(ht216); + } + break; } svga_out(addr, val, svga); } - uint8_t ht216_in(uint16_t addr, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; - uint8_t ret = 0xff; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; + uint8_t ret = 0xff; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; if ((ht216->id == 0x7152) && ht216->isabus) { - if (addr == 0x105) - return ht216->extensions; + if (addr == 0x105) + return ht216->extensions; } switch (addr) { - case 0x3c4: - return svga->seqaddr; + case 0x3c4: + return svga->seqaddr; - case 0x3c5: - if (svga->seqaddr == 6) - return ht216->ext_reg_enable; - else if (svga->seqaddr >= 0x80) { - if (ht216->ext_reg_enable) { - ret = ht216->ht_regs[svga->seqaddr & 0xff]; + case 0x3c5: + if (svga->seqaddr == 6) + return ht216->ext_reg_enable; + else if (svga->seqaddr >= 0x80) { + if (ht216->ext_reg_enable) { + ret = ht216->ht_regs[svga->seqaddr & 0xff]; - switch (svga->seqaddr & 0xff) { - case 0x83: - if (svga->attrff) - ret = svga->attraddr | 0x80; - else - ret = svga->attraddr; - break; + switch (svga->seqaddr & 0xff) { + case 0x83: + if (svga->attrff) + ret = svga->attraddr | 0x80; + else + ret = svga->attraddr; + break; - case 0x8e: - ret = ht216->id & 0xff; - break; - case 0x8f: - ret = (ht216->id >> 8) & 0xff; - break; + case 0x8e: + ret = ht216->id & 0xff; + break; + case 0x8f: + ret = (ht216->id >> 8) & 0xff; + break; - case 0xa0: - ret = svga->latch.b[0]; - break; - case 0xa1: - ret = svga->latch.b[1]; - break; - case 0xa2: - ret = svga->latch.b[2]; - break; - case 0xa3: - ret = svga->latch.b[3]; - break; + case 0xa0: + ret = svga->latch.b[0]; + break; + case 0xa1: + ret = svga->latch.b[1]; + break; + case 0xa2: + ret = svga->latch.b[2]; + break; + case 0xa3: + ret = svga->latch.b[3]; + break; - case 0xf0: - ret = ht216->fg_latch[ht216->fg_plane_sel]; - ht216->fg_plane_sel = 0; - break; + case 0xf0: + ret = ht216->fg_latch[ht216->fg_plane_sel]; + ht216->fg_plane_sel = 0; + break; - case 0xf2: - ret = svga->latch.b[ht216->bg_plane_sel]; - ht216->bg_plane_sel = 0; - break; - } + case 0xf2: + ret = svga->latch.b[ht216->bg_plane_sel]; + ht216->bg_plane_sel = 0; + break; + } - return ret; - } else - return 0xff; - } - break; + return ret; + } else + return 0xff; + } + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (ht216->id == 0x7152) - return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); - return svga_in(addr, svga); + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (ht216->id == 0x7152) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); - case 0x3cb: - if (ht216->id == 0x7152) - return ht216->reg_3cb; - break; + case 0x3cb: + if (ht216->id == 0x7152) + return ht216->reg_3cb; + break; - case 0x3cc: - return svga->miscout; + case 0x3cc: + return svga->miscout; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg == 0x1f) - return svga->crtc[0xc] ^ 0xea; - return svga->crtc[svga->crtcreg]; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if (svga->crtcreg == 0x1f) + return svga->crtc[0xc] ^ 0xea; + return svga->crtc[svga->crtcreg]; } return svga_in(addr, svga); @@ -565,204 +565,226 @@ ht216_remap(ht216_t *ht216) mem_mapping_disable(&ht216->linear_mapping); if (ht216->ht_regs[0xc8] & HT_REG_C8_XLAM) { - /*Linear mapping enabled*/ - ht216_log("Linear mapping enabled\n"); - ht216->linear_base = ((ht216->ht_regs[0xc9] & 0xf) << 20) | (ht216->ht_regs[0xcf] << 24); - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&ht216->linear_mapping, ht216->linear_base, 0x100000); + /*Linear mapping enabled*/ + ht216_log("Linear mapping enabled\n"); + ht216->linear_base = ((ht216->ht_regs[0xc9] & 0xf) << 20) | (ht216->ht_regs[0xcf] << 24); + mem_mapping_disable(&svga->mapping); + mem_mapping_set_addr(&ht216->linear_mapping, ht216->linear_base, 0x100000); } - ht216->read_banks[0] = ht216->read_bank_reg[0] << 12; + ht216->read_banks[0] = ht216->read_bank_reg[0] << 12; ht216->write_banks[0] = ht216->write_bank_reg[0] << 12; /* Split bank: two banks used */ if (ht216->ht_regs[0xe0] & HT_REG_E0_SBAE) { - ht216->read_banks[1] = ht216->read_bank_reg[1] << 12; - ht216->write_banks[1] = ht216->write_bank_reg[1] << 12; + ht216->read_banks[1] = ht216->read_bank_reg[1] << 12; + ht216->write_banks[1] = ht216->write_bank_reg[1] << 12; } if (!svga->chain4) { - ht216->read_banks[0] = ((ht216->read_banks[0] & 0xc0000) >> 2) | (ht216->read_banks[0] & 0xffff); - ht216->read_banks[1] = ((ht216->read_banks[1] & 0xc0000) >> 2) | (ht216->read_banks[1] & 0xffff); - ht216->write_banks[0] = ((ht216->write_banks[0] & 0xc0000) >> 2) | (ht216->write_banks[0] & 0xffff); - ht216->write_banks[1] = ((ht216->write_banks[1] & 0xc0000) >> 2) | (ht216->write_banks[1] & 0xffff); + ht216->read_banks[0] = ((ht216->read_banks[0] & 0xc0000) >> 2) | (ht216->read_banks[0] & 0xffff); + ht216->read_banks[1] = ((ht216->read_banks[1] & 0xc0000) >> 2) | (ht216->read_banks[1] & 0xffff); + ht216->write_banks[0] = ((ht216->write_banks[0] & 0xc0000) >> 2) | (ht216->write_banks[0] & 0xffff); + ht216->write_banks[1] = ((ht216->write_banks[1] & 0xc0000) >> 2) | (ht216->write_banks[1] & 0xffff); } if (!(ht216->ht_regs[0xe0] & HT_REG_E0_SBAE)) { - ht216->read_banks[1] = ht216->read_banks[0] + 0x8000; - ht216->write_banks[1] = ht216->write_banks[0] + 0x8000; + ht216->read_banks[1] = ht216->read_banks[0] + 0x8000; + ht216->write_banks[1] = ht216->write_banks[0] + 0x8000; } #ifdef ENABLE_HT216_LOG ht216_log("Registers: %02X, %02X, %02X, %02X, %02X\n", ht216->misc, ht216->ht_regs[0xe8], ht216->ht_regs[0xe9], - ht216->ht_regs[0xf6], ht216->ht_regs[0xf9]); + ht216->ht_regs[0xf6], ht216->ht_regs[0xf9]); ht216_log("Banks: %08X, %08X, %08X, %08X\n", ht216->read_banks[0], ht216->read_banks[1], - ht216->write_banks[0], ht216->write_banks[1]); + ht216->write_banks[0], ht216->write_banks[1]); #endif } - void ht216_recalctimings(svga_t *svga) { - ht216_t *ht216 = (ht216_t *)svga->p; - int high_res_256 = 0; + ht216_t *ht216 = (ht216_t *) svga->p; + int high_res_256 = 0; - switch ((((((svga->miscout >> 2) & 3) || ((ht216->ht_regs[0xa4] >> 2) & 3)) | - ((ht216->ht_regs[0xa4] >> 2) & 4)) || ((ht216->ht_regs[0xf8] >> 5) & 0x0f)) | - ((ht216->ht_regs[0xf8] << 1) & 8)) { - case 0: - case 1: - break; - case 4: - svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; - break; - case 5: - svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; - break; - case 7: - svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; - break; - default: - svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - } + switch ((((((svga->miscout >> 2) & 3) || ((ht216->ht_regs[0xa4] >> 2) & 3)) | ((ht216->ht_regs[0xa4] >> 2) & 4)) || ((ht216->ht_regs[0xf8] >> 5) & 0x0f)) | ((ht216->ht_regs[0xf8] << 1) & 8)) { + case 0: + case 1: + break; + case 4: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0; + break; + case 5: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0; + break; + case 7: + svga->clock = (cpuclock * (double) (1ull << 32)) / 40000000.0; + break; + default: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + } svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 12); svga->interlace = ht216->ht_regs[0xe0] & 1; if (svga->interlace) - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); else - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); ht216->adjust_cursor = 0; 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*/ { - svga->render = svga_render_text_40; - } else { - svga->render = svga_render_text_80; - } - } else { - if (svga->crtc[0x17] == 0xeb) { - svga->rowoffset <<= 1; - svga->render = svga_render_2bpp_headland_highres; - } + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) /*40 column*/ { + svga->render = svga_render_text_40; + } else { + svga->render = svga_render_text_80; + } + } else { + if (svga->crtc[0x17] == 0xeb) { + svga->rowoffset <<= 1; + svga->render = svga_render_2bpp_headland_highres; + } - if (svga->bpp == 8) { - ht216_log("regC8 = %02x, gdcreg5 bit 6 = %02x, no lowres = %02x, regf8 bit 7 = %02x, regfc = %02x\n", ht216->ht_regs[0xc8] & HT_REG_C8_E256, svga->gdcreg[5] & 0x40, !svga->lowres, ht216->ht_regs[0xf6] & 0x80, ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE); - if (((ht216->ht_regs[0xc8] & HT_REG_C8_E256) || (svga->gdcreg[5] & 0x40)) && (!svga->lowres || (ht216->ht_regs[0xf6] & 0x80))) { - if (high_res_256) { - svga->hdisp >>= 1; - ht216->adjust_cursor = 1; - } - svga->render = svga_render_8bpp_highres; - } else if (svga->lowres) { - if (high_res_256) { - svga->hdisp >>= 1; - ht216->adjust_cursor = 1; - svga->render = svga_render_8bpp_highres; - } else { - ht216_log("8bpp low, packed = %02x, chain4 = %02x\n", svga->packed_chain4, svga->chain4); - svga->render = svga_render_8bpp_lowres; - } - } else if (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE) { - if (ht216->id == 0x7152) { - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - if (!(svga->crtc[1] & 1)) - svga->hdisp--; - svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->rowoffset <<= 1; - if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ - svga->crtc[0x17] |= 0x40; - } - svga->render = svga_render_8bpp_highres; - } - } else if (svga->bpp == 15) { - svga->rowoffset <<= 1; - svga->hdisp >>= 1; - if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ - svga->crtc[0x17] |= 0x40; - svga->render = svga_render_15bpp_highres; - } - } - } + if (svga->bpp == 8) { + ht216_log("regC8 = %02x, gdcreg5 bit 6 = %02x, no lowres = %02x, regf8 bit 7 = %02x, regfc = %02x\n", ht216->ht_regs[0xc8] & HT_REG_C8_E256, svga->gdcreg[5] & 0x40, !svga->lowres, ht216->ht_regs[0xf6] & 0x80, ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE); + if (((ht216->ht_regs[0xc8] & HT_REG_C8_E256) || (svga->gdcreg[5] & 0x40)) && (!svga->lowres || (ht216->ht_regs[0xf6] & 0x80))) { + if (high_res_256) { + svga->hdisp >>= 1; + ht216->adjust_cursor = 1; + } + svga->render = svga_render_8bpp_highres; + } else if (svga->lowres) { + if (high_res_256) { + svga->hdisp >>= 1; + ht216->adjust_cursor = 1; + svga->render = svga_render_8bpp_highres; + } else { + ht216_log("8bpp low, packed = %02x, chain4 = %02x\n", svga->packed_chain4, svga->chain4); + svga->render = svga_render_8bpp_lowres; + } + } else if (ht216->ht_regs[0xfc] & HT_REG_FC_ECOLRE) { + if (ht216->id == 0x7152) { + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + if (!(svga->crtc[1] & 1)) + svga->hdisp--; + svga->hdisp++; + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->rowoffset <<= 1; + if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ + svga->crtc[0x17] |= 0x40; + } + svga->render = svga_render_8bpp_highres; + } + } else if (svga->bpp == 15) { + svga->rowoffset <<= 1; + svga->hdisp >>= 1; + if ((svga->crtc[0x17] & 0x60) == 0x20) /*Would result in a garbled screen with trailing cursor glitches*/ + svga->crtc[0x17] |= 0x40; + svga->render = svga_render_15bpp_highres; + } + } + } - svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 14); + svga->ma_latch |= ((ht216->ht_regs[0xf6] & 0x30) << 14); if (svga->crtc[0x17] == 0xeb) /*Looks like 1024x768 mono mode expects 512K of video memory*/ - svga->vram_display_mask = 0x7ffff; + svga->vram_display_mask = 0x7ffff; else - svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; + svga->vram_display_mask = (ht216->ht_regs[0xf6] & 0x40) ? ht216->vram_mask : 0x3ffff; } - static void ht216_hwcursor_draw(svga_t *svga, int displine) { - ht216_t *ht216 = (ht216_t *)svga->p; - int x, shift = (ht216->adjust_cursor ? 2 : 1); + ht216_t *ht216 = (ht216_t *) svga->p; + int x, shift = (ht216->adjust_cursor ? 2 : 1); uint32_t dat[2]; - int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; - int width = (ht216->adjust_cursor ? 16 : 32); + int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; + int width = (ht216->adjust_cursor ? 16 : 32); if (ht216->adjust_cursor) - offset >>= 1; + offset >>= 1; if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; + svga->hwcursor_latch.addr += 4; - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | - (svga->vram[svga->hwcursor_latch.addr+1] << 16) | - (svga->vram[svga->hwcursor_latch.addr+2] << 8) | - svga->vram[svga->hwcursor_latch.addr+3]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr+128] << 24) | - (svga->vram[svga->hwcursor_latch.addr+128+1] << 16) | - (svga->vram[svga->hwcursor_latch.addr+128+2] << 8) | - svga->vram[svga->hwcursor_latch.addr+128+3]; + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr + 128] << 24) | (svga->vram[svga->hwcursor_latch.addr + 128 + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 128 + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 128 + 3]; for (x = 0; x < width; x++) { - if (!(dat[0] & 0x80000000)) - ((uint32_t *)buffer32->line[displine])[svga->x_add + offset + x] = 0; - if (dat[1] & 0x80000000) - ((uint32_t *)buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff; + if (!(dat[0] & 0x80000000)) + ((uint32_t *) buffer32->line[displine])[svga->x_add + offset + x] = 0; + if (dat[1] & 0x80000000) + ((uint32_t *) buffer32->line[displine])[svga->x_add + offset + x] ^= 0xffffff; - dat[0] <<= shift; - dat[1] <<= shift; + dat[0] <<= shift; + dat[1] <<= shift; } svga->hwcursor_latch.addr += 4; if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 4; + svga->hwcursor_latch.addr += 4; } - static __inline uint8_t extalu(int op, uint8_t input_a, uint8_t input_b) { uint8_t val; switch (op) { - case 0x0: val = 0; break; - case 0x1: val = ~(input_a | input_b); break; - case 0x2: val = input_a & ~input_b; break; - case 0x3: val = ~input_b; break; - case 0x4: val = ~input_a & input_b; break; - case 0x5: val = ~input_a; break; - case 0x6: val = input_a ^ input_b; break; - case 0x7: val = ~(input_a & input_b); break; - case 0x8: val = input_a & input_b; break; - case 0x9: val = ~(input_a ^ input_b); break; - case 0xa: val = input_a; break; - case 0xb: val = input_a | ~input_b; break; - case 0xc: val = input_b; break; - case 0xd: val = ~input_a | input_b; break; - case 0xe: val = input_a | input_b; break; - case 0xf: default: val = 0xff; break; + case 0x0: + val = 0; + break; + case 0x1: + val = ~(input_a | input_b); + break; + case 0x2: + val = input_a & ~input_b; + break; + case 0x3: + val = ~input_b; + break; + case 0x4: + val = ~input_a & input_b; + break; + case 0x5: + val = ~input_a; + break; + case 0x6: + val = input_a ^ input_b; + break; + case 0x7: + val = ~(input_a & input_b); + break; + case 0x8: + val = input_a & input_b; + break; + case 0x9: + val = ~(input_a ^ input_b); + break; + case 0xa: + val = input_a; + break; + case 0xb: + val = input_a | ~input_b; + break; + case 0xc: + val = input_b; + break; + case 0xd: + val = ~input_a | input_b; + break; + case 0xe: + val = input_a | input_b; + break; + case 0xf: + default: + val = 0xff; + break; } return val; @@ -771,180 +793,179 @@ extalu(int op, uint8_t input_a, uint8_t input_b) static void ht216_dm_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t cpu_dat_unexpanded) { - svga_t *svga = &ht216->svga; - int writemask2 = svga->writemask, reset_wm = 0; + svga_t *svga = &ht216->svga; + int writemask2 = svga->writemask, reset_wm = 0; latch_t vall; uint8_t i, wm = svga->writemask; - uint8_t count = 4, fg_data[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + uint8_t count = 4, fg_data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) - writemask2 = svga->seqregs[2]; + writemask2 = svga->seqregs[2]; if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; + svga->fullchange = 2; - if (svga->chain4) { - writemask2 = 1 << (addr & 3); - addr = dword_remap(svga, addr) & ~3; - } else if (svga->chain2_write && (svga->crtc[0x17] != 0xeb)) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; + if (svga->chain4) { + writemask2 = 1 << (addr & 3); + addr = dword_remap(svga, addr) & ~3; + } else if (svga->chain2_write && (svga->crtc[0x17] != 0xeb)) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; } else - addr <<= 2; + addr <<= 2; if (addr >= svga->vram_max) - return; + return; svga->changedvram[addr >> 12] = changeframecount; if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) - count = 8; + count = 8; switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) { - case 0x00: - for (i = 0; i < count; i++) - fg_data[i] = cpu_dat; - break; - case 0x04: - if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) { - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xfa] & (1 << i)) - fg_data[i] = cpu_dat_unexpanded; - else if (ht216->ht_regs[0xfb] & (1 << i)) - fg_data[i] = 0xff - cpu_dat_unexpanded; - } - } else { - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xfa] & (1 << i)) - fg_data[i] = ht216->ht_regs[0xf5]; - else if (ht216->ht_regs[0xfb] & (1 << i)) - fg_data[i] = 0xff - ht216->ht_regs[0xf5]; - } - } - break; - case 0x08: - case 0x0c: - for (i = 0; i < count; i++) - fg_data[i] = ht216->fg_latch[i]; - break; + case 0x00: + for (i = 0; i < count; i++) + fg_data[i] = cpu_dat; + break; + case 0x04: + if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) { + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xfa] & (1 << i)) + fg_data[i] = cpu_dat_unexpanded; + else if (ht216->ht_regs[0xfb] & (1 << i)) + fg_data[i] = 0xff - cpu_dat_unexpanded; + } + } else { + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xfa] & (1 << i)) + fg_data[i] = ht216->ht_regs[0xf5]; + else if (ht216->ht_regs[0xfb] & (1 << i)) + fg_data[i] = 0xff - ht216->ht_regs[0xf5]; + } + } + break; + case 0x08: + case 0x0c: + for (i = 0; i < count; i++) + fg_data[i] = ht216->fg_latch[i]; + break; } switch (svga->writemode) { - case 0: - if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = fg_data[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = fg_data[i]; - } - } - return; - } else { - for (i = 0; i < count; i++) { - if (svga->gdcreg[1] & (1 << i)) - vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; - else - vall.b[i] = fg_data[i]; - } - } - break; - case 1: - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = svga->latch.b[i]; - } - } - return; - case 2: - for (i = 0; i < count; i++) - vall.b[i] = !!(cpu_dat & (1 << i)) * 0xff; + case 0: + if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = fg_data[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = fg_data[i]; + } + } + return; + } else { + for (i = 0; i < count; i++) { + if (svga->gdcreg[1] & (1 << i)) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + else + vall.b[i] = fg_data[i]; + } + } + break; + case 1: + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = svga->latch.b[i]; + } + } + return; + case 2: + for (i = 0; i < count; i++) + vall.b[i] = !!(cpu_dat & (1 << i)) * 0xff; - if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } - } - return; - } - break; - case 3: - wm = svga->gdcreg[8]; - svga->gdcreg[8] &= cpu_dat; + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + } + return; + } + break; + case 3: + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= cpu_dat; - for (i = 0; i < count; i++) - vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + for (i = 0; i < count; i++) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; - reset_wm = 1; - break; + reset_wm = 1; + break; } switch (svga->gdcreg[3] & 0x18) { - case 0x00: /* Set */ - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } - } - break; - case 0x08: /* AND */ - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; - } - } - break; - case 0x10: /* OR */ - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; - } - } - break; - case 0x18: /* XOR */ - for (i = 0; i < count; i++) { - if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; - } - } - break; + case 0x00: /* Set */ + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + } + break; + case 0x08: /* AND */ + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; + } + } + break; + case 0x10: /* OR */ + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; + } + } + break; + case 0x18: /* XOR */ + for (i = 0; i < count; i++) { + if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; + } + } + break; } if (reset_wm) - svga->gdcreg[8] = wm; + svga->gdcreg[8] = wm; } - static void ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bit_mask, uint8_t cpu_dat_unexpanded, uint8_t rop_select) { @@ -960,122 +981,121 @@ ht216_dm_extalu_write(ht216_t *ht216, uint32_t addr, uint8_t cpu_dat, uint8_t bi 00 = CPU byte 01 = Bit mask (3CF:8) 1x = (3C4:F5)*/ - svga_t *svga = &ht216->svga; - uint8_t input_a = 0, input_b = 0; - uint8_t fg, bg; - uint8_t output; - uint32_t remapped_addr = dword_remap(svga, addr); + svga_t *svga = &ht216->svga; + uint8_t input_a = 0, input_b = 0; + uint8_t fg, bg; + uint8_t output; + uint32_t remapped_addr = dword_remap(svga, addr); if (ht216->ht_regs[0xcd] & HT_REG_CD_RMWMDE) /*RMW*/ - input_b = svga->vram[remapped_addr]; + input_b = svga->vram[remapped_addr]; else - input_b = ht216->bg_latch[addr & 7]; + input_b = ht216->bg_latch[addr & 7]; switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBMC) { - case 0x00: - input_a = cpu_dat; - break; - case 0x04: - if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) - input_a = (cpu_dat_unexpanded & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - else - input_a = (ht216->ht_regs[0xf5] & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; - break; - case 0x08: - input_a = ht216->fg_latch[addr & 3]; - break; - case 0x0c: - input_a = ht216->bg_latch[addr & 7]; - break; + case 0x00: + input_a = cpu_dat; + break; + case 0x04: + if (ht216->ht_regs[0xfe] & HT_REG_FE_FBRC) + input_a = (cpu_dat_unexpanded & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + else + input_a = (ht216->ht_regs[0xf5] & (1 << ((addr & 7) ^ 7))) ? ht216->ht_regs[0xfa] : ht216->ht_regs[0xfb]; + break; + case 0x08: + input_a = ht216->fg_latch[addr & 3]; + break; + case 0x0c: + input_a = ht216->bg_latch[addr & 7]; + break; } - fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b); - bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b); - output = (fg & rop_select) | (bg & ~rop_select); - svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask); + fg = extalu(ht216->ht_regs[0xce] >> 4, input_a, input_b); + bg = extalu(ht216->ht_regs[0xce] & 0xf, input_a, input_b); + output = (fg & rop_select) | (bg & ~rop_select); + svga->vram[addr] = (svga->vram[remapped_addr] & ~bit_mask) | (output & bit_mask); svga->changedvram[remapped_addr >> 12] = changeframecount; } static void ht216_dm_masked_write(ht216_t *ht216, uint32_t addr, uint8_t val, uint8_t bit_mask) { - svga_t *svga = &ht216->svga; - int writemask2 = svga->writemask; - uint8_t count = 4, i; - uint8_t full_mask = 0x0f; + svga_t *svga = &ht216->svga; + int writemask2 = svga->writemask; + uint8_t count = 4, i; + uint8_t full_mask = 0x0f; if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) - writemask2 = svga->seqregs[2]; + writemask2 = svga->seqregs[2]; if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; + svga->fullchange = 2; - if (svga->chain4) { - writemask2 = 1 << (addr & 3); - addr = dword_remap(svga, addr) & ~3; - } else if (svga->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; + if (svga->chain4) { + writemask2 = 1 << (addr & 3); + addr = dword_remap(svga, addr) & ~3; + } else if (svga->chain2_write) { + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; } else - addr <<= 2; + addr <<= 2; if (addr >= svga->vram_max) - return; + return; addr &= svga->decode_mask; if (addr >= svga->vram_max) - return; + return; addr &= svga->vram_mask; svga->changedvram[addr >> 12] = changeframecount; if (ht216->ht_regs[0xcd] & HT_REG_CD_P8PCEXP) { - count = 8; - full_mask = 0xff; + count = 8; + full_mask = 0xff; } if (bit_mask == 0xff) { - for (i = 0; i < count; i++) { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = val; - } + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = val; + } } else { - if (writemask2 == full_mask) { - for (i = 0; i < count; i++) - svga->vram[addr | i] = (svga->latch.b[i] & bit_mask) | (svga->vram[addr | i] & ~bit_mask); - } else { - for (i = 0; i < count; i++) { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (val & bit_mask) | (svga->vram[addr | i] & ~bit_mask); - } - } + if (writemask2 == full_mask) { + for (i = 0; i < count; i++) + svga->vram[addr | i] = (svga->latch.b[i] & bit_mask) | (svga->vram[addr | i] & ~bit_mask); + } else { + for (i = 0; i < count; i++) { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (val & bit_mask) | (svga->vram[addr | i] & ~bit_mask); + } + } } } - static void ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) { /*Input B = CD.5 Input A = FE[3:2] - 00 = Set/Reset output mode - output = CPU-side ALU input - 01 = Solid fg/bg mode (3C4:FA/FB) - Bit mask = 3CF.F5 or CPU byte - 10 = Dithered fg (3CF:EC-EF) - 11 = RMW (dest data) (set if CD.5 = 1) + 00 = Set/Reset output mode + output = CPU-side ALU input + 01 = Solid fg/bg mode (3C4:FA/FB) + Bit mask = 3CF.F5 or CPU byte + 10 = Dithered fg (3CF:EC-EF) + 11 = RMW (dest data) (set if CD.5 = 1) F/B ROP select = FE[5:4] - 00 = CPU byte - 01 = Bit mask (3CF:8) - 1x = (3C4:F5) + 00 = CPU byte + 01 = Bit mask (3CF:8) + 1x = (3C4:F5) */ svga_t *svga = &ht216->svga; - int i; + int i; uint8_t bit_mask = 0, rop_select = 0; cycles -= video_timing_write_b; @@ -1085,199 +1105,194 @@ ht216_write_common(ht216_t *ht216, uint32_t addr, uint8_t val) val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); if (ht216->ht_regs[0xcd] & HT_REG_CD_EXALU) { - /*Extended ALU*/ - switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL) { - case 0x00: - rop_select = val; - break; - case 0x10: - rop_select = svga->gdcreg[8]; - break; - case 0x20: case 0x30: - rop_select = ht216->ht_regs[0xf5]; - break; - } - switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) { - case 0x00: - bit_mask = svga->gdcreg[8]; - break; - case 0x04: - bit_mask = val; - break; - case 0x08: case 0x0c: - bit_mask = ht216->ht_regs[0xf5]; - break; - } + /*Extended ALU*/ + switch (ht216->ht_regs[0xfe] & HT_REG_FE_FBRSL) { + case 0x00: + rop_select = val; + break; + case 0x10: + rop_select = svga->gdcreg[8]; + break; + case 0x20: + case 0x30: + rop_select = ht216->ht_regs[0xf5]; + break; + } + switch (ht216->ht_regs[0xcd] & HT_REG_CD_BMSKSL) { + case 0x00: + bit_mask = svga->gdcreg[8]; + break; + case 0x04: + bit_mask = val; + break; + case 0x08: + case 0x0c: + bit_mask = ht216->ht_regs[0xf5]; + break; + } - if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) { /*1->8 bit expansion*/ - addr = (addr << 3) & 0xfffff; - for (i = 0; i < 8; i++) - ht216_dm_extalu_write(ht216, addr + i, (val & (0x80 >> i)) ? 0xff : 0, (bit_mask & (0x80 >> i)) ? 0xff : 0, val, (rop_select & (0x80 >> i)) ? 0xff : 0); - } else { - ht216_dm_extalu_write(ht216, addr, val, bit_mask, val, rop_select); - } + if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) { /*1->8 bit expansion*/ + addr = (addr << 3) & 0xfffff; + for (i = 0; i < 8; i++) + ht216_dm_extalu_write(ht216, addr + i, (val & (0x80 >> i)) ? 0xff : 0, (bit_mask & (0x80 >> i)) ? 0xff : 0, val, (rop_select & (0x80 >> i)) ? 0xff : 0); + } else { + ht216_dm_extalu_write(ht216, addr, val, bit_mask, val, rop_select); + } } else if (ht216->ht_regs[0xf3]) { - if (ht216->ht_regs[0xf3] & 2) { - ht216_dm_masked_write(ht216, addr, val, val); - } else - ht216_dm_masked_write(ht216, addr, val, ht216->ht_regs[0xf4]); + if (ht216->ht_regs[0xf3] & 2) { + ht216_dm_masked_write(ht216, addr, val, val); + } else + ht216_dm_masked_write(ht216, addr, val, ht216->ht_regs[0xf4]); } else { - if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) { /*1->8 bit expansion*/ - addr = (addr << 3) & 0xfffff; - for (i = 0; i < 8; i++) - ht216_dm_write(ht216, addr + i, (val & (0x80 >> i)) ? 0xff : 0, val); - } else { - ht216_dm_write(ht216, addr, val, val); - } + if (ht216->ht_regs[0xcd] & HT_REG_CD_FP8PCEXP) { /*1->8 bit expansion*/ + addr = (addr << 3) & 0xfffff; + for (i = 0; i < 8; i++) + ht216_dm_write(ht216, addr + i, (val & (0x80 >> i)) ? 0xff : 0, val); + } else { + ht216_dm_write(ht216, addr, val, val); + } } } - static void ht216_write(uint32_t addr, uint8_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000) - addr += 0x10000; + addr += 0x10000; else if (svga->chain4 && ((ht216->ht_regs[0xfc] & 0x06) == 0x06)) - addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); + addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3] && svga->crtc[0x17] != 0xeb) { - svga_write_linear(addr, val, svga); + svga_write_linear(addr, val, svga); } else - ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr, val); } - static void ht216_writew(uint32_t addr, uint16_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000) - addr += 0x10000; + addr += 0x10000; else if (svga->chain4 && ((ht216->ht_regs[0xfc] & 0x06) == 0x06)) - addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); + addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3] && svga->crtc[0x17] != 0xeb) - svga_writew_linear(addr, val, svga); + svga_writew_linear(addr, val, svga); else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr+1, val >> 8); + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); } } - static void ht216_writel(uint32_t addr, uint32_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->write_banks[(addr >> 15) & 1]; if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000) - addr += 0x10000; + addr += 0x10000; else if (svga->chain4 && ((ht216->ht_regs[0xfc] & 0x06) == 0x06)) - addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); + addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe] && !ht216->ht_regs[0xf3] && svga->crtc[0x17] != 0xeb) - svga_writel_linear(addr, val, svga); + svga_writel_linear(addr, val, svga); else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr+1, val >> 8); - ht216_write_common(ht216, addr+2, val >> 16); - ht216_write_common(ht216, addr+3, val >> 24); + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); + ht216_write_common(ht216, addr + 2, val >> 16); + ht216_write_common(ht216, addr + 3, val >> 24); } } - static void ht216_write_linear(uint32_t addr, uint8_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; addr -= ht216->linear_base; - if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ - addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); addr += ht216->write_banks[0]; if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_write_linear(addr, val, svga); + svga_write_linear(addr, val, svga); else - ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr, val); } - static void ht216_writew_linear(uint32_t addr, uint16_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; addr -= ht216->linear_base; - if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ - addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); addr += ht216->write_banks[0]; if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_writew_linear(addr, val, svga); + svga_writew_linear(addr, val, svga); else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr+1, val >> 8); + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); } } - static void ht216_writel_linear(uint32_t addr, uint32_t val, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; addr -= ht216->linear_base; - if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ - addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); addr += ht216->write_banks[0]; if (!ht216->ht_regs[0xcd] && !ht216->ht_regs[0xfe]) - svga_writel_linear(addr, val, svga); + svga_writel_linear(addr, val, svga); else { - ht216_write_common(ht216, addr, val); - ht216_write_common(ht216, addr+1, val >> 8); - ht216_write_common(ht216, addr+2, val >> 16); - ht216_write_common(ht216, addr+3, val >> 24); + ht216_write_common(ht216, addr, val); + ht216_write_common(ht216, addr + 1, val >> 8); + ht216_write_common(ht216, addr + 2, val >> 16); + ht216_write_common(ht216, addr + 3, val >> 24); } } - static uint8_t ht216_read_common(ht216_t *ht216, uint32_t addr) { - svga_t *svga = &ht216->svga; + svga_t *svga = &ht216->svga; uint32_t latch_addr = 0; - int offset, readplane = svga->readplane; + int offset, readplane = svga->readplane; uint8_t or, i; uint8_t count = 2; uint8_t plane, pixel; uint8_t temp, ret; if (ht216->ht_regs[0xc8] & HT_REG_C8_MOVSB) - addr <<= 3; + addr <<= 3; addr &= svga->vram_mask; @@ -1286,95 +1301,93 @@ ht216_read_common(ht216_t *ht216, uint32_t addr) count = (1 << count); if (svga->chain4 && svga->packed_chain4) { - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; - latch_addr = (addr & svga->vram_mask) & ~7; - if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) - latch_addr += (svga->gdcreg[3] & 7); - for (i = 0; i < 8; i++) - ht216->bg_latch[i] = svga->vram[dword_remap(svga, latch_addr + i)]; - return svga->vram[dword_remap(svga, addr) & svga->vram_mask]; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + latch_addr = (addr & svga->vram_mask) & ~7; + if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) + latch_addr += (svga->gdcreg[3] & 7); + for (i = 0; i < 8; i++) + ht216->bg_latch[i] = svga->vram[dword_remap(svga, latch_addr + i)]; + return svga->vram[dword_remap(svga, addr) & svga->vram_mask]; } else if (svga->chain4) { - readplane = addr & 3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); - } else if (svga->chain2_read && (svga->crtc[0x17] != 0xeb)) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - addr <<= 2; + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + } else if (svga->chain2_read && (svga->crtc[0x17] != 0xeb)) { + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; } else - addr <<= 2; + addr <<= 2; addr &= svga->decode_mask; if (addr >= svga->vram_max) - return 0xff; + return 0xff; addr &= svga->vram_mask; latch_addr = addr & ~7; if (ht216->ht_regs[0xcd] & HT_REG_CD_ASTODE) { - offset = addr & 7; - for (i = 0; i < 8; i++) - ht216->bg_latch[i] = svga->vram[latch_addr | ((offset + i) & 7)]; + offset = addr & 7; + for (i = 0; i < 8; i++) + ht216->bg_latch[i] = svga->vram[latch_addr | ((offset + i) & 7)]; } else { - for (i = 0; i < 8; i++) - ht216->bg_latch[i] = svga->vram[latch_addr | i]; + for (i = 0; i < 8; i++) + ht216->bg_latch[i] = svga->vram[latch_addr | i]; } or = addr & 4; for (i = 0; i < 4; i++) - svga->latch.b[i] = ht216->bg_latch[i | or]; + svga->latch.b[i] = ht216->bg_latch[i | or ]; if (svga->readmode) { - temp = 0xff; + temp = 0xff; - for (pixel = 0; pixel < 8; pixel++) { - for (plane = 0; plane < (1 << count); plane++) { - if (svga->colournocare & (1 << plane)) { - /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ - if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) - temp &= ~(1 << pixel); - } - } - } + for (pixel = 0; pixel < 8; pixel++) { + for (plane = 0; plane < (1 << count); plane++) { + if (svga->colournocare & (1 << plane)) { + /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ + if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) + temp &= ~(1 << pixel); + } + } + } - ret = temp; + ret = temp; } else - ret = svga->vram[addr | readplane]; + ret = svga->vram[addr | readplane]; return ret; } - static uint8_t ht216_read(uint32_t addr, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; uint32_t prev_addr = addr; addr &= svga->banked_mask; addr = (addr & 0x7fff) + ht216->read_banks[(addr >> 15) & 1]; if (svga->crtc[0x17] == 0xeb && !(svga->gdcreg[6] & 0xc) && prev_addr >= 0xb0000) - addr += 0x10000; + addr += 0x10000; else if (svga->chain4 && ((ht216->ht_regs[0xfc] & 0x06) == 0x06)) - addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); + addr = (addr & 0xfffeffff) | (prev_addr & 0x10000); return ht216_read_common(ht216, addr); } - static uint8_t ht216_read_linear(uint32_t addr, void *p) { - ht216_t *ht216 = (ht216_t *)p; - svga_t *svga = &ht216->svga; + ht216_t *ht216 = (ht216_t *) p; + svga_t *svga = &ht216->svga; addr -= ht216->linear_base; - if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ - addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); + if (!svga->chain4) /*Bits 16 and 17 of linear address are unused in planar modes*/ + addr = (addr & 0xffff) | ((addr & 0xc0000) >> 2); addr += ht216->read_banks[0]; return ht216_read_common(ht216, addr); @@ -1383,20 +1396,21 @@ ht216_read_linear(uint32_t addr, void *p) static uint8_t radius_mca_read(int port, void *priv) { - ht216_t *ht216 = (ht216_t *)priv; - ht216_log("Port %03x MCA read = %02x\n", port, ht216->pos_regs[port & 7]); + ht216_t *ht216 = (ht216_t *) priv; + ht216_log("Port %03x MCA read = %02x\n", port, ht216->pos_regs[port & 7]); return (ht216->pos_regs[port & 7]); } static void radius_mca_write(int port, uint8_t val, void *priv) { - ht216_t *ht216 = (ht216_t *)priv; + ht216_t *ht216 = (ht216_t *) priv; /* MCA does not write registers below 0x0100. */ - if (port < 0x0102) return; + if (port < 0x0102) + return; - ht216_log("Port %03x MCA write = %02x, setup mode = %02x\n", port, val, ht216->ht_regs[0xfc] & 0x80); + ht216_log("Port %03x MCA write = %02x, setup mode = %02x\n", port, val, ht216->ht_regs[0xfc] & 0x80); /* Save the MCA register value. */ ht216->pos_regs[port & 7] = val; @@ -1405,112 +1419,113 @@ radius_mca_write(int port, uint8_t val, void *priv) static uint8_t radius_mca_feedb(void *priv) { - return 1; + return 1; } void -*ht216_init(const device_t *info, uint32_t mem_size, int has_rom) + * + ht216_init(const device_t *info, uint32_t mem_size, int has_rom) { ht216_t *ht216 = malloc(sizeof(ht216_t)); - svga_t *svga; + svga_t *svga; memset(ht216, 0, sizeof(ht216_t)); svga = &ht216->svga; if (info->flags & DEVICE_VLB) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_vlb); else if (info->flags & DEVICE_MCA) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_mca); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_mca); else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_isa); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_v7vga_isa); svga_init(info, svga, ht216, mem_size, - ht216_recalctimings, - ht216_in, ht216_out, - ht216_hwcursor_draw, - NULL); + ht216_recalctimings, + ht216_in, ht216_out, + ht216_hwcursor_draw, + NULL); switch (has_rom) { - case 1: - rom_init(&ht216->bios_rom, BIOS_G2_GC205_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case 2: - rom_init(&ht216->bios_rom, BIOS_VIDEO7_VGA_1024I_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; - case 3: - ht216->monitor_type = device_get_config_int("monitor_type"); - rom_init(&ht216->bios_rom, BIOS_HT216_32_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - /* Patch the BIOS for monitor type. */ - if (ht216->monitor_type & 0x10) { - /* Color */ - ht216->bios_rom.rom[0x0526] = 0x0c; - ht216->bios_rom.rom[0x0528] = 0xeb; - ht216->bios_rom.rom[0x7fff] += 0x26; - } else { - /* Mono */ - ht216->bios_rom.rom[0x0526] = 0x24; - ht216->bios_rom.rom[0x0527] = 0xef; - ht216->bios_rom.rom[0x0528] = ht216->bios_rom.rom[0x0529] = 0x90; - ht216->bios_rom.rom[0x7fff] += 0xfe; - } - /* Patch bios for interlaced/non-interlaced. */ - if (ht216->monitor_type & 0x08) { - /* Non-Interlaced */ - ht216->bios_rom.rom[0x170b] = 0x0c; - ht216->bios_rom.rom[0x170d] = ht216->bios_rom.rom[0x170e] = 0x90; - ht216->bios_rom.rom[0x7fff] += 0xf4; - } else { - /* Interlaced */ - ht216->bios_rom.rom[0x170b] = 0x24; - ht216->bios_rom.rom[0x170c] = 0xf7; - ht216->bios_rom.rom[0x170d] = 0xeb; - ht216->bios_rom.rom[0x7fff] += 0x1e; - } - break; - case 4: - if ((info->local == 0x7152) && (info->flags & DEVICE_ISA)) - ht216->extensions = device_get_config_int("extensions"); - else if ((info->local == 0x7152) && (info->flags & DEVICE_MCA)) { - ht216->pos_regs[0] = 0xb7; - ht216->pos_regs[1] = 0x80; - mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); - } - rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - break; + case 1: + rom_init(&ht216->bios_rom, BIOS_G2_GC205_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case 2: + rom_init(&ht216->bios_rom, BIOS_VIDEO7_VGA_1024I_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; + case 3: + ht216->monitor_type = device_get_config_int("monitor_type"); + rom_init(&ht216->bios_rom, BIOS_HT216_32_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + /* Patch the BIOS for monitor type. */ + if (ht216->monitor_type & 0x10) { + /* Color */ + ht216->bios_rom.rom[0x0526] = 0x0c; + ht216->bios_rom.rom[0x0528] = 0xeb; + ht216->bios_rom.rom[0x7fff] += 0x26; + } else { + /* Mono */ + ht216->bios_rom.rom[0x0526] = 0x24; + ht216->bios_rom.rom[0x0527] = 0xef; + ht216->bios_rom.rom[0x0528] = ht216->bios_rom.rom[0x0529] = 0x90; + ht216->bios_rom.rom[0x7fff] += 0xfe; + } + /* Patch bios for interlaced/non-interlaced. */ + if (ht216->monitor_type & 0x08) { + /* Non-Interlaced */ + ht216->bios_rom.rom[0x170b] = 0x0c; + ht216->bios_rom.rom[0x170d] = ht216->bios_rom.rom[0x170e] = 0x90; + ht216->bios_rom.rom[0x7fff] += 0xf4; + } else { + /* Interlaced */ + ht216->bios_rom.rom[0x170b] = 0x24; + ht216->bios_rom.rom[0x170c] = 0xf7; + ht216->bios_rom.rom[0x170d] = 0xeb; + ht216->bios_rom.rom[0x7fff] += 0x1e; + } + break; + case 4: + if ((info->local == 0x7152) && (info->flags & DEVICE_ISA)) + ht216->extensions = device_get_config_int("extensions"); + else if ((info->local == 0x7152) && (info->flags & DEVICE_MCA)) { + ht216->pos_regs[0] = 0xb7; + ht216->pos_regs[1] = 0x80; + mca_add(radius_mca_read, radius_mca_write, radius_mca_feedb, NULL, ht216); + } + rom_init(&ht216->bios_rom, BIOS_RADIUS_SVGA_MULTIVIEW_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + break; } svga->hwcursor.cur_ysize = 32; - ht216->vram_mask = mem_size - 1; - svga->decode_mask = mem_size - 1; + ht216->vram_mask = mem_size - 1; + svga->decode_mask = mem_size - 1; if (has_rom == 4) - svga->ramdac = device_add(&sc11484_nors2_ramdac_device); + svga->ramdac = device_add(&sc11484_nors2_ramdac_device); if ((info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) { - 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); + 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 { - 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); + 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); } mem_mapping_set_p(&svga->mapping, ht216); mem_mapping_disable(&ht216->linear_mapping); - ht216->id = info->local; + ht216->id = info->local; ht216->isabus = (info->flags & DEVICE_ISA); - ht216->mca = (info->flags & DEVICE_MCA); + ht216->mca = (info->flags & DEVICE_MCA); io_sethandler(0x03c0, 0x0020, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); io_sethandler(0x46e8, 0x0001, ht216_in, NULL, NULL, ht216_out, NULL, NULL, ht216); - svga->bpp = 8; + svga->bpp = 8; svga->miscout = 1; if (ht216->id == 0x7861) - ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ + ht216->ht_regs[0xb4] = 0x08; /*32-bit DRAM bus*/ if (ht216->id == 0x7152) - ht216->reg_3cb = 0x20; + ht216->reg_3cb = 0x20; /* Initialize the cursor pointer towards the end of its segment, needed for ht256sf.drv to work correctly when Windows 3.1 is started after boot. */ @@ -1521,7 +1536,6 @@ void return ht216; } - static void * g2_gc205_init(const device_t *info) { @@ -1530,7 +1544,6 @@ g2_gc205_init(const device_t *info) return ht216; } - static void * v7_vga_1024i_init(const device_t *info) { @@ -1539,7 +1552,6 @@ v7_vga_1024i_init(const device_t *info) return ht216; } - static void * ht216_pb410a_init(const device_t *info) { @@ -1548,7 +1560,6 @@ ht216_pb410a_init(const device_t *info) return ht216; } - static void * ht216_standalone_init(const device_t *info) { @@ -1565,21 +1576,18 @@ radius_svga_multiview_init(const device_t *info) return ht216; } - static int g2_gc205_available(void) { return rom_present(BIOS_G2_GC205_PATH); } - static int v7_vga_1024i_available(void) { return rom_present(BIOS_VIDEO7_VGA_1024I_PATH); } - static int ht216_standalone_available(void) { @@ -1592,58 +1600,44 @@ radius_svga_multiview_available(void) return rom_present(BIOS_RADIUS_SVGA_MULTIVIEW_PATH); } - void ht216_close(void *p) { - ht216_t *ht216 = (ht216_t *)p; + ht216_t *ht216 = (ht216_t *) p; svga_close(&ht216->svga); free(ht216); } - void ht216_speed_changed(void *p) { - ht216_t *ht216 = (ht216_t *)p; + ht216_t *ht216 = (ht216_t *) p; svga_recalctimings(&ht216->svga); } - void ht216_force_redraw(void *p) { - ht216_t *ht216 = (ht216_t *)p; + ht216_t *ht216 = (ht216_t *) p; ht216->svga.fullchange = changeframecount; } static const device_config_t v7_vga_1024i_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 512, - .selection = { - { - .description = "256 kB", - .value = 256 - }, - { - .description = "512 kB", - .value = 512 - }, - { - .description = "" - } - } - }, - { - .type = CONFIG_END - } + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 512, + .selection = { + { .description = "256 kB", + .value = 256 }, + { .description = "512 kB", + .value = 512 }, + { .description = "" } } }, + { .type = CONFIG_END} }; // clang-format off @@ -1707,85 +1701,85 @@ static const device_config_t radius_svga_multiview_config[] = { // clang-format on const device_t g2_gc205_device = { - .name = "G2 GC205", + .name = "G2 GC205", .internal_name = "g2_gc205", - .flags = DEVICE_ISA, - .local = 0x7070, - .init = g2_gc205_init, - .close = ht216_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0x7070, + .init = g2_gc205_init, + .close = ht216_close, + .reset = NULL, { .available = g2_gc205_available }, .speed_changed = ht216_speed_changed, - .force_redraw = ht216_force_redraw, - .config = NULL + .force_redraw = ht216_force_redraw, + .config = NULL }; const device_t v7_vga_1024i_device = { - .name = "Video 7 VGA 1024i (HT208)", + .name = "Video 7 VGA 1024i (HT208)", .internal_name = "v7_vga_1024i", - .flags = DEVICE_ISA, - .local = 0x7140, - .init = v7_vga_1024i_init, - .close = ht216_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0x7140, + .init = v7_vga_1024i_init, + .close = ht216_close, + .reset = NULL, { .available = v7_vga_1024i_available }, .speed_changed = ht216_speed_changed, - .force_redraw = ht216_force_redraw, - .config = v7_vga_1024i_config + .force_redraw = ht216_force_redraw, + .config = v7_vga_1024i_config }; const device_t ht216_32_pb410a_device = { - .name = "Headland HT216-32 (Packard Bell PB410A)", + .name = "Headland HT216-32 (Packard Bell PB410A)", .internal_name = "ht216_32_pb410a", - .flags = DEVICE_VLB, - .local = 0x7861, /*HT216-32*/ - .init = ht216_pb410a_init, - .close = ht216_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = 0x7861, /*HT216-32*/ + .init = ht216_pb410a_init, + .close = ht216_close, + .reset = NULL, { .available = NULL }, .speed_changed = ht216_speed_changed, - .force_redraw = ht216_force_redraw, - .config = NULL + .force_redraw = ht216_force_redraw, + .config = NULL }; const device_t ht216_32_standalone_device = { - .name = "Headland HT216-32", + .name = "Headland HT216-32", .internal_name = "ht216_32", - .flags = DEVICE_VLB, - .local = 0x7861, /*HT216-32*/ - .init = ht216_standalone_init, - .close = ht216_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = 0x7861, /*HT216-32*/ + .init = ht216_standalone_init, + .close = ht216_close, + .reset = NULL, { .available = ht216_standalone_available }, .speed_changed = ht216_speed_changed, - .force_redraw = ht216_force_redraw, - .config = ht216_32_standalone_config + .force_redraw = ht216_force_redraw, + .config = ht216_32_standalone_config }; const device_t radius_svga_multiview_isa_device = { - .name = "Radius SVGA Multiview ISA (HT209)", + .name = "Radius SVGA Multiview ISA (HT209)", .internal_name = "radius_isa", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0x7152, /*HT209*/ - .init = radius_svga_multiview_init, - .close = ht216_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0x7152, /*HT209*/ + .init = radius_svga_multiview_init, + .close = ht216_close, + .reset = NULL, { .available = radius_svga_multiview_available }, .speed_changed = ht216_speed_changed, - .force_redraw = ht216_force_redraw, - .config = radius_svga_multiview_config + .force_redraw = ht216_force_redraw, + .config = radius_svga_multiview_config }; const device_t radius_svga_multiview_mca_device = { - .name = "Radius SVGA Multiview MCA (HT209)", + .name = "Radius SVGA Multiview MCA (HT209)", .internal_name = "radius_mc", - .flags = DEVICE_MCA, - .local = 0x7152, /*HT209*/ - .init = radius_svga_multiview_init, - .close = ht216_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = 0x7152, /*HT209*/ + .init = radius_svga_multiview_init, + .close = ht216_close, + .reset = NULL, { .available = radius_svga_multiview_available }, .speed_changed = ht216_speed_changed, - .force_redraw = ht216_force_redraw, - .config = NULL + .force_redraw = ht216_force_redraw, + .config = NULL }; diff --git a/src/video/vid_ibm_rgb528_ramdac.c b/src/video/vid_ibm_rgb528_ramdac.c index f119e722e..2f050e7c7 100644 --- a/src/video/vid_ibm_rgb528_ramdac.c +++ b/src/video/vid_ibm_rgb528_ramdac.c @@ -26,504 +26,497 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef union { - uint8_t pixel; - struct { - uint8_t b :2, g :3, r :2; - }; + uint8_t pixel; + struct { + uint8_t b : 2, g : 3, r : 2; + }; } ibm_rgb528_pixel8_t; typedef union { - uint16_t pixel; - struct { - uint16_t b_ :5, g_ :6, r_ :5; - }; - struct { - uint16_t b :5, g :5, r :5, c :1; - }; + uint16_t pixel; + struct { + uint16_t b_ : 5, g_ : 6, r_ : 5; + }; + struct { + uint16_t b : 5, g : 5, r : 5, c : 1; + }; } ibm_rgb528_pixel16_t; typedef union { - uint32_t pixel; - struct { - uint8_t b, g, r, a; - }; + uint32_t pixel; + struct { + uint8_t b, g, r, a; + }; } ibm_rgb528_pixel32_t; typedef struct { - PALETTE extpal; - uint32_t extpallook[256]; - uint8_t indexed_data[2048]; - uint8_t cursor32_data[256]; - uint8_t cursor64_data[1024]; - uint8_t palettes[3][256]; - ibm_rgb528_pixel32_t extra_pal[4]; - int16_t hwc_y, hwc_x; - uint16_t index, smlc_part; - uint8_t cmd_r0; - uint8_t cmd_r1; - uint8_t cmd_r2; - uint8_t cmd_r3; - uint8_t cmd_r4; - uint8_t status, indx_cntl; - uint8_t cursor_array, - cursor_hotspot_x, cursor_hotspot_y; + PALETTE extpal; + uint32_t extpallook[256]; + uint8_t indexed_data[2048]; + uint8_t cursor32_data[256]; + uint8_t cursor64_data[1024]; + uint8_t palettes[3][256]; + ibm_rgb528_pixel32_t extra_pal[4]; + int16_t hwc_y, hwc_x; + uint16_t index, smlc_part; + uint8_t cmd_r0; + uint8_t cmd_r1; + uint8_t cmd_r2; + uint8_t cmd_r3; + uint8_t cmd_r4; + uint8_t status, indx_cntl; + uint8_t cursor_array, + cursor_hotspot_x, cursor_hotspot_y; } ibm_rgb528_ramdac_t; - void ibm_rgb528_render_4bpp(svga_t *svga) { - int x; - uint32_t *p; + int x; + uint32_t *p; ibm_rgb528_pixel32_t dat_out; - uint8_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; + uint8_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t partition = (ramdac->indexed_data[0x07] & 0x0f) << 4; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t swap_nib = ramdac->indexed_data[0x72] & 0x21; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (vram_size == 3) { - if (!(x & 31)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - dat642 = *(uint64_t *)(&svga->vram[svga->ma + 8]); - if (swap_word) { - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); - } - } - if (swap_nib) - dat = (((x & 16) ? dat642 : dat64) >> ((x & 15) << 2)) & 0xf; - else - dat = (((x & 16) ? dat642 : dat64) >> (((x & 15) << 2) ^ 4)) & 0xf; - } else if (vram_size == 1) { - if (!(x & 15)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - if (swap_word) - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - } - if (swap_nib) - dat = (dat64 >> ((x & 15) << 2)) & 0xf; - else - dat = (dat64 >> (((x & 15) << 2) ^ 4)) & 0xf; - } else { - if (!(x & 7)) - dat32 = *(uint32_t *)(&svga->vram[svga->ma]); - if (swap_nib) - dat = (dat32 >> ((x & 7) << 2)) & 0xf; - else - dat = (dat32 >> (((x & 7) << 2) ^ 4)) & 0xf; - } - if (b8_dcol == 0x00) { - dat_out.a = 0x00; - dat_out.r = ramdac->palettes[0][partition | dat]; - dat_out.g = ramdac->palettes[1][partition | dat]; - dat_out.b = ramdac->palettes[2][partition | dat]; - } else - dat_out.pixel = video_8togs[dat]; - if (svga->lowres) { - p[x << 1] = p[(x << 1) + 1] = dat_out.pixel & 0xffffff; - } else - p[x] = dat_out.pixel & 0xffffff; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (vram_size == 3) { + if (!(x & 31)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + if (swap_word) { + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); + } + } + if (swap_nib) + dat = (((x & 16) ? dat642 : dat64) >> ((x & 15) << 2)) & 0xf; + else + dat = (((x & 16) ? dat642 : dat64) >> (((x & 15) << 2) ^ 4)) & 0xf; + } else if (vram_size == 1) { + if (!(x & 15)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + if (swap_word) + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + } + if (swap_nib) + dat = (dat64 >> ((x & 15) << 2)) & 0xf; + else + dat = (dat64 >> (((x & 15) << 2) ^ 4)) & 0xf; + } else { + if (!(x & 7)) + dat32 = *(uint32_t *) (&svga->vram[svga->ma]); + if (swap_nib) + dat = (dat32 >> ((x & 7) << 2)) & 0xf; + else + dat = (dat32 >> (((x & 7) << 2) ^ 4)) & 0xf; + } + if (b8_dcol == 0x00) { + dat_out.a = 0x00; + dat_out.r = ramdac->palettes[0][partition | dat]; + dat_out.g = ramdac->palettes[1][partition | dat]; + dat_out.b = ramdac->palettes[2][partition | dat]; + } else + dat_out.pixel = video_8togs[dat]; + if (svga->lowres) { + p[x << 1] = p[(x << 1) + 1] = dat_out.pixel & 0xffffff; + } else + p[x] = dat_out.pixel & 0xffffff; - if ((vram_size == 3) && ((x & 31) == 31)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; - if ((vram_size == 1) && ((x & 15) == 15)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; - else if ((!vram_size) && ((x & 7) == 7)) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; - } + if ((vram_size == 3) && ((x & 31) == 31)) + svga->ma = (svga->ma + 16) & svga->vram_display_mask; + if ((vram_size == 1) && ((x & 15) == 15)) + svga->ma = (svga->ma + 8) & svga->vram_display_mask; + else if ((!vram_size) && ((x & 7) == 7)) + svga->ma = (svga->ma + 4) & svga->vram_display_mask; + } } } - void ibm_rgb528_render_8bpp(svga_t *svga) { - int x; - uint32_t *p; + int x; + uint32_t *p; ibm_rgb528_pixel32_t dat_out; - uint8_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; + uint8_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b8_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x03; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (vram_size == 3) { - if (!(x & 15)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - dat642 = *(uint64_t *)(&svga->vram[svga->ma + 8]); - if (swap_word) { - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); - } - } - dat = (((x & 8) ? dat642 : dat64) >> ((x & 7) << 3)) & 0xff; - } else if (vram_size == 1) { - if (!(x & 7)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - if (swap_word) - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - } - dat = (dat64 >> ((x & 7) << 3)) & 0xff; - } else { - if (!(x & 3)) - dat32 = *(uint32_t *)(&svga->vram[svga->ma]); - dat = (dat32 >> ((x & 3) << 3)) & 0xff; - } - if (b8_dcol == 0x00) { - dat_out.a = 0x00; - dat_out.r = ramdac->palettes[0][dat]; - dat_out.g = ramdac->palettes[1][dat]; - dat_out.b = ramdac->palettes[2][dat]; - } else - dat_out.pixel = video_8togs[dat]; - if (svga->lowres) { - p[x << 1] = p[(x << 1) + 1] = dat_out.pixel & 0xffffff; - } else - p[x] = dat_out.pixel & 0xffffff; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (vram_size == 3) { + if (!(x & 15)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + if (swap_word) { + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); + } + } + dat = (((x & 8) ? dat642 : dat64) >> ((x & 7) << 3)) & 0xff; + } else if (vram_size == 1) { + if (!(x & 7)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + if (swap_word) + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + } + dat = (dat64 >> ((x & 7) << 3)) & 0xff; + } else { + if (!(x & 3)) + dat32 = *(uint32_t *) (&svga->vram[svga->ma]); + dat = (dat32 >> ((x & 3) << 3)) & 0xff; + } + if (b8_dcol == 0x00) { + dat_out.a = 0x00; + dat_out.r = ramdac->palettes[0][dat]; + dat_out.g = ramdac->palettes[1][dat]; + dat_out.b = ramdac->palettes[2][dat]; + } else + dat_out.pixel = video_8togs[dat]; + if (svga->lowres) { + p[x << 1] = p[(x << 1) + 1] = dat_out.pixel & 0xffffff; + } else + p[x] = dat_out.pixel & 0xffffff; - if ((vram_size == 3) && ((x & 15) == 15)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; - else if ((vram_size == 1) && ((x & 7) == 7)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; - else if ((!vram_size) && ((x & 3) == 3)) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; - } + if ((vram_size == 3) && ((x & 15) == 15)) + svga->ma = (svga->ma + 16) & svga->vram_display_mask; + else if ((vram_size == 1) && ((x & 7) == 7)) + svga->ma = (svga->ma + 8) & svga->vram_display_mask; + else if ((!vram_size) && ((x & 3) == 3)) + svga->ma = (svga->ma + 4) & svga->vram_display_mask; + } } } - void ibm_rgb528_render_15_16bpp(svga_t *svga) { - int x; - uint32_t *p; + int x; + uint32_t *p; ibm_rgb528_pixel16_t *dat_ex; - ibm_rgb528_pixel32_t dat_out; - uint16_t dat; - uint32_t dat32 = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; - uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20; - uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02; - uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01; - uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01, temp; + ibm_rgb528_pixel32_t dat_out; + uint16_t dat; + uint32_t dat32 = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b16_dcol = (ramdac->indexed_data[0x0c] & 0xc0) >> 6; + uint8_t by16_pol = ramdac->indexed_data[0x0c] & 0x20; + uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02; + uint8_t bspr_cnt = ramdac->indexed_data[0x0c] & 0x01; + uint8_t partition = (ramdac->indexed_data[0x07] & 0x0e) << 4; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01, temp; if ((svga->displine + svga->y_add) < 0) - return; + return; if (b555_565 && (b16_dcol != 0x01)) - partition &= 0xc0; + partition &= 0xc0; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (vram_size == 2) { - if (!(x & 7)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - dat642 = *(uint64_t *)(&svga->vram[svga->ma + 8]); - if (swap_word) { - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - dat642 = (dat64 << 32ULL) | (dat642 >> 32ULL); - } - } - dat = (((x & 4) ? dat642 : dat64) >> ((x & 3) << 4)) & 0xffff; - } else if (vram_size == 1) { - if (!(x & 3)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - if (swap_word) - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - } - dat = (dat64 >> ((x & 3) << 4)) & 0xffff; - } else { - if (!(x & 1)) - dat32 = *(uint32_t *)(&svga->vram[svga->ma]); - dat = (dat32 >> ((x & 1) << 4)) & 0xffff; - } - dat_ex = (ibm_rgb528_pixel16_t *) &dat; - if (b555_565 && (b16_dcol != 0x01)) { - if (swaprb) { - temp = dat_ex->r_; - dat_ex->r_ = dat_ex->b_; - dat_ex->b_ = temp; - } - if (b16_dcol == 0x00) { - dat_out.a = 0x00; - if (bspr_cnt) { - dat_out.r = ramdac->palettes[0][partition | dat_ex->r_]; - dat_out.g = ramdac->palettes[1][partition | dat_ex->g_]; - dat_out.b = ramdac->palettes[2][partition | dat_ex->b_]; - } else { - dat_out.r = ramdac->palettes[0][dat_ex->r_ << 3]; - dat_out.g = ramdac->palettes[1][dat_ex->g_ << 2]; - dat_out.b = ramdac->palettes[2][dat_ex->b_ << 3]; - } - if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { - dat_out.r |= ((dat_out.r & 0xc0) >> 6); - dat_out.g |= ((dat_out.g & 0xc0) >> 6); - dat_out.b |= ((dat_out.b & 0xc0) >> 6); - } - } else - dat_out.pixel = video_16to32[dat_ex->pixel]; - } else { - if (swaprb) { - temp = dat_ex->r; - dat_ex->r = dat_ex->b; - dat_ex->b = temp; - } - if (by16_pol) - dat ^= 0x8000; - if ((b16_dcol == 0x00) || ((b16_dcol == 0x01) && !(dat & 0x8000))) { - dat_out.a = 0x00; - if (bspr_cnt) { - dat_out.r = ramdac->palettes[0][partition | dat_ex->r]; - dat_out.g = ramdac->palettes[1][partition | dat_ex->g]; - dat_out.b = ramdac->palettes[2][partition | dat_ex->b]; - } else { - dat_out.r = ramdac->palettes[0][dat_ex->r << 3]; - dat_out.g = ramdac->palettes[1][dat_ex->g << 3]; - dat_out.b = ramdac->palettes[2][dat_ex->b << 3]; - } - if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { - dat_out.r |= ((dat_out.r & 0xc0) >> 6); - dat_out.g |= ((dat_out.g & 0xc0) >> 6); - dat_out.b |= ((dat_out.b & 0xc0) >> 6); - } - } else - dat_out.pixel = video_15to32[dat_ex->pixel & 0x7fff]; - } - if (svga->lowres) { - p[x << 1] = p[(x << 1) + 1] = dat_out.pixel & 0xffffff; - } else - p[x] = dat_out.pixel & 0xffffff; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (vram_size == 2) { + if (!(x & 7)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + if (swap_word) { + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + dat642 = (dat64 << 32ULL) | (dat642 >> 32ULL); + } + } + dat = (((x & 4) ? dat642 : dat64) >> ((x & 3) << 4)) & 0xffff; + } else if (vram_size == 1) { + if (!(x & 3)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + if (swap_word) + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + } + dat = (dat64 >> ((x & 3) << 4)) & 0xffff; + } else { + if (!(x & 1)) + dat32 = *(uint32_t *) (&svga->vram[svga->ma]); + dat = (dat32 >> ((x & 1) << 4)) & 0xffff; + } + dat_ex = (ibm_rgb528_pixel16_t *) &dat; + if (b555_565 && (b16_dcol != 0x01)) { + if (swaprb) { + temp = dat_ex->r_; + dat_ex->r_ = dat_ex->b_; + dat_ex->b_ = temp; + } + if (b16_dcol == 0x00) { + dat_out.a = 0x00; + if (bspr_cnt) { + dat_out.r = ramdac->palettes[0][partition | dat_ex->r_]; + dat_out.g = ramdac->palettes[1][partition | dat_ex->g_]; + dat_out.b = ramdac->palettes[2][partition | dat_ex->b_]; + } else { + dat_out.r = ramdac->palettes[0][dat_ex->r_ << 3]; + dat_out.g = ramdac->palettes[1][dat_ex->g_ << 2]; + dat_out.b = ramdac->palettes[2][dat_ex->b_ << 3]; + } + if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { + dat_out.r |= ((dat_out.r & 0xc0) >> 6); + dat_out.g |= ((dat_out.g & 0xc0) >> 6); + dat_out.b |= ((dat_out.b & 0xc0) >> 6); + } + } else + dat_out.pixel = video_16to32[dat_ex->pixel]; + } else { + if (swaprb) { + temp = dat_ex->r; + dat_ex->r = dat_ex->b; + dat_ex->b = temp; + } + if (by16_pol) + dat ^= 0x8000; + if ((b16_dcol == 0x00) || ((b16_dcol == 0x01) && !(dat & 0x8000))) { + dat_out.a = 0x00; + if (bspr_cnt) { + dat_out.r = ramdac->palettes[0][partition | dat_ex->r]; + dat_out.g = ramdac->palettes[1][partition | dat_ex->g]; + dat_out.b = ramdac->palettes[2][partition | dat_ex->b]; + } else { + dat_out.r = ramdac->palettes[0][dat_ex->r << 3]; + dat_out.g = ramdac->palettes[1][dat_ex->g << 3]; + dat_out.b = ramdac->palettes[2][dat_ex->b << 3]; + } + if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { + dat_out.r |= ((dat_out.r & 0xc0) >> 6); + dat_out.g |= ((dat_out.g & 0xc0) >> 6); + dat_out.b |= ((dat_out.b & 0xc0) >> 6); + } + } else + dat_out.pixel = video_15to32[dat_ex->pixel & 0x7fff]; + } + if (svga->lowres) { + p[x << 1] = p[(x << 1) + 1] = dat_out.pixel & 0xffffff; + } else + p[x] = dat_out.pixel & 0xffffff; - if ((vram_size == 3) && ((x & 7) == 7)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; - else if ((vram_size == 1) && ((x & 3) == 3)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; - else if (!vram_size && ((x & 1) == 1)) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; - } + if ((vram_size == 3) && ((x & 7) == 7)) + svga->ma = (svga->ma + 16) & svga->vram_display_mask; + else if ((vram_size == 1) && ((x & 3) == 3)) + svga->ma = (svga->ma + 8) & svga->vram_display_mask; + else if (!vram_size && ((x & 1) == 1)) + svga->ma = (svga->ma + 4) & svga->vram_display_mask; + } } } - void ibm_rgb528_render_24bpp(svga_t *svga) { - int x; - uint32_t *p; + int x; + uint32_t *p; ibm_rgb528_pixel32_t *dat_ex; - uint32_t dat; - uint64_t dat64[6]; - uint8_t *dat8 = (uint8_t *) dat64; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80, temp; + uint32_t dat; + uint64_t dat64[6]; + uint8_t *dat8 = (uint8_t *) dat64; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b24_dcol = ramdac->indexed_data[0x0d] & 0x01; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80, temp; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat_ex = (ibm_rgb528_pixel32_t *) &dat; - if (vram_size == 3) { - if ((x & 15) == 0) { - dat64[0] = *(uint64_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat64[1] = *(uint64_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - dat64[2] = *(uint64_t *)(&svga->vram[(svga->ma + 16) & svga->vram_display_mask]); - dat64[3] = *(uint64_t *)(&svga->vram[(svga->ma + 24) & svga->vram_display_mask]); - dat64[4] = *(uint64_t *)(&svga->vram[(svga->ma + 32) & svga->vram_display_mask]); - dat64[5] = *(uint64_t *)(&svga->vram[(svga->ma + 40) & svga->vram_display_mask]); - if (swap_word) { - dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL); - dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL); - dat64[2] = (dat64[2] << 32ULL) | (dat64[2] >> 32ULL); - dat64[3] = (dat64[3] << 32ULL) | (dat64[3] >> 32ULL); - dat64[4] = (dat64[4] << 32ULL) | (dat64[4] >> 32ULL); - dat64[5] = (dat64[5] << 32ULL) | (dat64[5] >> 32ULL); - } - } - dat_ex = (ibm_rgb528_pixel32_t *) &(dat8[((x & 15) * 3)]); - } else if (vram_size == 1) { - if ((x & 7) == 0) { - dat64[0] = *(uint64_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat64[1] = *(uint64_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - dat64[2] = *(uint64_t *)(&svga->vram[(svga->ma + 16) & svga->vram_display_mask]); - if (swap_word) { - dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL); - dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL); - dat64[2] = (dat64[2] << 32ULL) | (dat64[2] >> 32ULL); - } - } - dat_ex = (ibm_rgb528_pixel32_t *) &(dat8[((x & 7) * 3)]); - } else - dat = 0x00000000; - if (swaprb) { - temp = dat_ex->r; - dat_ex->r = dat_ex->b; - dat_ex->b = temp; - } - if (b24_dcol == 0x00) { - dat_ex->a = 0x00; - dat_ex->r = ramdac->palettes[0][dat_ex->r]; - dat_ex->g = ramdac->palettes[1][dat_ex->g]; - dat_ex->g = ramdac->palettes[2][dat_ex->b]; - if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { - dat_ex->r |= ((dat_ex->r & 0xc0) >> 6); - dat_ex->g |= ((dat_ex->g & 0xc0) >> 6); - dat_ex->b |= ((dat_ex->b & 0xc0) >> 6); - } - } - if (svga->lowres) { - p[x << 1] = p[(x << 1) + 1] = dat_ex->pixel & 0xffffff; - } else - p[x] = dat_ex->pixel & 0xffffff; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat_ex = (ibm_rgb528_pixel32_t *) &dat; + if (vram_size == 3) { + if ((x & 15) == 0) { + dat64[0] = *(uint64_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat64[1] = *(uint64_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + dat64[2] = *(uint64_t *) (&svga->vram[(svga->ma + 16) & svga->vram_display_mask]); + dat64[3] = *(uint64_t *) (&svga->vram[(svga->ma + 24) & svga->vram_display_mask]); + dat64[4] = *(uint64_t *) (&svga->vram[(svga->ma + 32) & svga->vram_display_mask]); + dat64[5] = *(uint64_t *) (&svga->vram[(svga->ma + 40) & svga->vram_display_mask]); + if (swap_word) { + dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL); + dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL); + dat64[2] = (dat64[2] << 32ULL) | (dat64[2] >> 32ULL); + dat64[3] = (dat64[3] << 32ULL) | (dat64[3] >> 32ULL); + dat64[4] = (dat64[4] << 32ULL) | (dat64[4] >> 32ULL); + dat64[5] = (dat64[5] << 32ULL) | (dat64[5] >> 32ULL); + } + } + dat_ex = (ibm_rgb528_pixel32_t *) &(dat8[((x & 15) * 3)]); + } else if (vram_size == 1) { + if ((x & 7) == 0) { + dat64[0] = *(uint64_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat64[1] = *(uint64_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + dat64[2] = *(uint64_t *) (&svga->vram[(svga->ma + 16) & svga->vram_display_mask]); + if (swap_word) { + dat64[0] = (dat64[0] << 32ULL) | (dat64[0] >> 32ULL); + dat64[1] = (dat64[1] << 32ULL) | (dat64[1] >> 32ULL); + dat64[2] = (dat64[2] << 32ULL) | (dat64[2] >> 32ULL); + } + } + dat_ex = (ibm_rgb528_pixel32_t *) &(dat8[((x & 7) * 3)]); + } else + dat = 0x00000000; + if (swaprb) { + temp = dat_ex->r; + dat_ex->r = dat_ex->b; + dat_ex->b = temp; + } + if (b24_dcol == 0x00) { + dat_ex->a = 0x00; + dat_ex->r = ramdac->palettes[0][dat_ex->r]; + dat_ex->g = ramdac->palettes[1][dat_ex->g]; + dat_ex->g = ramdac->palettes[2][dat_ex->b]; + if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { + dat_ex->r |= ((dat_ex->r & 0xc0) >> 6); + dat_ex->g |= ((dat_ex->g & 0xc0) >> 6); + dat_ex->b |= ((dat_ex->b & 0xc0) >> 6); + } + } + if (svga->lowres) { + p[x << 1] = p[(x << 1) + 1] = dat_ex->pixel & 0xffffff; + } else + p[x] = dat_ex->pixel & 0xffffff; - if ((vram_size == 3) && ((x & 15) == 15)) - svga->ma = (svga->ma + 48) & svga->vram_display_mask; - else if ((vram_size == 1) && ((x & 7) == 7)) - svga->ma = (svga->ma + 24) & svga->vram_display_mask; - } + if ((vram_size == 3) && ((x & 15) == 15)) + svga->ma = (svga->ma + 48) & svga->vram_display_mask; + else if ((vram_size == 1) && ((x & 7) == 7)) + svga->ma = (svga->ma + 24) & svga->vram_display_mask; + } } } - void ibm_rgb528_render_32bpp(svga_t *svga) { - int x; - uint32_t *p; + int x; + uint32_t *p; ibm_rgb528_pixel32_t *dat_ex; - uint32_t dat = 0x00000000; - uint64_t dat64 = 0x0000000000000000ULL; - uint64_t dat642 = 0x0000000000000000ULL; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03; - uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04; - uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; - uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; - uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; - uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80, temp; + uint32_t dat = 0x00000000; + uint64_t dat64 = 0x0000000000000000ULL; + uint64_t dat642 = 0x0000000000000000ULL; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t b32_dcol = ramdac->indexed_data[0x0e] & 0x03; + uint8_t by32_pol = ramdac->indexed_data[0x0e] & 0x04; + uint8_t swaprb = ramdac->indexed_data[0x72] & 0x80; + uint8_t swap_word = ramdac->indexed_data[0x72] & 0x10; + uint8_t vram_size = ramdac->indexed_data[0x70] & 0x01; + uint8_t b6bit_lin = ramdac->indexed_data[0x07] & 0x80, temp; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - if (vram_size == 3) { - if (!(x & 3)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - dat642 = *(uint64_t *)(&svga->vram[svga->ma + 8]); - if (swap_word) { - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); - } - } - dat = (((x & 2) ? dat642 : dat64) >> ((x & 1ULL) << 5ULL)) & 0xffffffff; - } else if (vram_size == 1) { - if (!(x & 1)) { - dat64 = *(uint64_t *)(&svga->vram[svga->ma]); - if (swap_word) - dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); - } - dat = (dat64 >> ((x & 1ULL) << 5ULL)) & 0xffffffff; - } else - dat = *(uint32_t *)(&svga->vram[svga->ma]); - dat_ex = (ibm_rgb528_pixel32_t *) &dat; - if (swaprb) { - temp = dat_ex->r; - dat_ex->r = dat_ex->b; - dat_ex->b = temp; - } - if ((b32_dcol < 0x03) && (by32_pol)) - dat ^= 0x01000000; - if ((b32_dcol == 0x00) || ((b32_dcol == 0x01) && !(dat & 0x01000000))) { - dat_ex->a = 0x00; - dat_ex->r = ramdac->palettes[0][dat_ex->r]; - dat_ex->g = ramdac->palettes[1][dat_ex->g]; - dat_ex->g = ramdac->palettes[2][dat_ex->b]; - if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { - dat_ex->r |= ((dat_ex->r & 0xc0) >> 6); - dat_ex->g |= ((dat_ex->g & 0xc0) >> 6); - dat_ex->b |= ((dat_ex->b & 0xc0) >> 6); - } - } - if (svga->lowres) { - p[x << 1] = p[(x << 1) + 1] = dat_ex->pixel & 0xffffff; - } else - p[x] = dat_ex->pixel & 0xffffff; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + if (vram_size == 3) { + if (!(x & 3)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + dat642 = *(uint64_t *) (&svga->vram[svga->ma + 8]); + if (swap_word) { + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + dat642 = (dat642 << 32ULL) | (dat642 >> 32ULL); + } + } + dat = (((x & 2) ? dat642 : dat64) >> ((x & 1ULL) << 5ULL)) & 0xffffffff; + } else if (vram_size == 1) { + if (!(x & 1)) { + dat64 = *(uint64_t *) (&svga->vram[svga->ma]); + if (swap_word) + dat64 = (dat64 << 32ULL) | (dat64 >> 32ULL); + } + dat = (dat64 >> ((x & 1ULL) << 5ULL)) & 0xffffffff; + } else + dat = *(uint32_t *) (&svga->vram[svga->ma]); + dat_ex = (ibm_rgb528_pixel32_t *) &dat; + if (swaprb) { + temp = dat_ex->r; + dat_ex->r = dat_ex->b; + dat_ex->b = temp; + } + if ((b32_dcol < 0x03) && (by32_pol)) + dat ^= 0x01000000; + if ((b32_dcol == 0x00) || ((b32_dcol == 0x01) && !(dat & 0x01000000))) { + dat_ex->a = 0x00; + dat_ex->r = ramdac->palettes[0][dat_ex->r]; + dat_ex->g = ramdac->palettes[1][dat_ex->g]; + dat_ex->g = ramdac->palettes[2][dat_ex->b]; + if ((svga->ramdac_type != RAMDAC_8BIT) && !b6bit_lin) { + dat_ex->r |= ((dat_ex->r & 0xc0) >> 6); + dat_ex->g |= ((dat_ex->g & 0xc0) >> 6); + dat_ex->b |= ((dat_ex->b & 0xc0) >> 6); + } + } + if (svga->lowres) { + p[x << 1] = p[(x << 1) + 1] = dat_ex->pixel & 0xffffff; + } else + p[x] = dat_ex->pixel & 0xffffff; - if ((vram_size == 3) && ((x & 3) == 3)) - svga->ma = (svga->ma + 16) & svga->vram_display_mask; - else if ((vram_size == 1) && ((x & 1) == 1)) - svga->ma = (svga->ma + 8) & svga->vram_display_mask; - else if (!vram_size) - svga->ma = (svga->ma + 4) & svga->vram_display_mask; - } + if ((vram_size == 3) && ((x & 3) == 3)) + svga->ma = (svga->ma + 16) & svga->vram_display_mask; + else if ((vram_size == 1) && ((x & 1) == 1)) + svga->ma = (svga->ma + 8) & svga->vram_display_mask; + else if (!vram_size) + svga->ma = (svga->ma + 4) & svga->vram_display_mask; + } } } - static void ibm_rgb528_set_bpp(ibm_rgb528_ramdac_t *ramdac, svga_t *svga) { @@ -531,264 +524,269 @@ ibm_rgb528_set_bpp(ibm_rgb528_ramdac_t *ramdac, svga_t *svga) uint8_t b555_565 = ramdac->indexed_data[0x0c] & 0x02; if (ramdac->indexed_data[0x071] & 0x01) - switch (ramdac->indexed_data[0x00a] & 0x07) { - case 0x02: - svga->bpp = 4; - break; - case 0x03: - default: - svga->bpp = 8; - break; - case 0x04: - if (b555_565 && (b16_dcol != 0x01)) - svga->bpp = 16; - else - svga->bpp = 15; - break; - case 0x05: - svga->bpp = 24; - break; - case 0x06: - svga->bpp = 32; - break; - } else - svga->bpp = 8; + switch (ramdac->indexed_data[0x00a] & 0x07) { + case 0x02: + svga->bpp = 4; + break; + case 0x03: + default: + svga->bpp = 8; + break; + case 0x04: + if (b555_565 && (b16_dcol != 0x01)) + svga->bpp = 16; + else + svga->bpp = 15; + break; + case 0x05: + svga->bpp = 24; + break; + case 0x06: + svga->bpp = 32; + break; + } + else + svga->bpp = 8; svga_recalctimings(svga); } - void ibm_rgb528_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; - uint16_t index; - uint8_t rs = (addr & 0x03); - uint16_t da_mask = 0x03ff; - uint8_t updt_cntl = (ramdac->indexed_data[0x30] & 0x08); + uint16_t index; + uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; + uint8_t updt_cntl = (ramdac->indexed_data[0x30] & 0x08); rs |= (!!rs2 << 2); switch (rs) { - case 0x00: /* Palette Write Index Register (RS value = 0000) */ - case 0x03: - svga->dac_pos = 0; - svga->dac_status = addr & 0x03; - svga->dac_addr = val; - if (svga->dac_status) - svga->dac_addr = (svga->dac_addr + 1) & da_mask; - break; - case 0x01: /* Palette Data Register (RS value = 0001) */ - index = svga->dac_addr & 255; - if (svga->ramdac_type == RAMDAC_8BIT) - ramdac->palettes[svga->dac_pos][index] = val; - else - ramdac->palettes[svga->dac_pos][index] = (val & 0x3f) << 2; - svga_out(addr, val, svga); - break; - case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - svga_out(addr, val, svga); - break; - case 0x04: - ramdac->index = (ramdac->index & 0x0700) | val; - if ((ramdac->index >= 0x0100) && (ramdac->index <= 0x04ff)) - ramdac->cursor_array = 1; - break; - case 0x05: - ramdac->index = (ramdac->index & 0x00ff) | ((val & 0x07) << 0x08); - if ((ramdac->index >= 0x0100) && (ramdac->index <= 0x04ff)) - ramdac->cursor_array = 1; - break; - case 0x06: - if ((ramdac->index < 0x0100) || (ramdac->index > 0x04ff) || ramdac->cursor_array) - ramdac->indexed_data[ramdac->index] = val; - switch (ramdac->index) { - case 0x00a: case 0x00c: - ibm_rgb528_set_bpp(ramdac, svga); - break; - case 0x030: - switch (val & 0xc0) { - case 0x00: - ramdac->smlc_part = 0x0100; - break; - case 0x40: - ramdac->smlc_part = 0x0200; - break; - case 0x80: - ramdac->smlc_part = 0x0300; - break; - case 0xc0: - ramdac->smlc_part = 0x0400; - break; - } - svga->dac_hwcursor.addr = ramdac->smlc_part; - svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 0x04) ? 64 : 32; - svga->dac_hwcursor.ena = ((val & 0x03) != 0x00); - break; - case 0x031: - if (!updt_cntl) - break; - ramdac->hwc_x = (ramdac->hwc_x & 0xff00) | val; - svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; - break; - case 0x032: - /* Sign-extend the sign bit (7) to the remaining bits (6-4). */ - val &= 0x8f; - if (val & 0x80) - val |= 0x70; - ramdac->indexed_data[ramdac->index] = val; - if (!updt_cntl) - break; - ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | (val << 8); - svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; - break; - case 0x033: - if (!updt_cntl) - break; - ramdac->hwc_y = (ramdac->hwc_y & 0xff00) | val; - svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; - break; - case 0x034: - /* Sign-extend the sign bit (7) to the remaining bits (6-4). */ - val &= 0x8f; - if (val & 0x80) - val |= 0x70; - ramdac->indexed_data[ramdac->index] = val; - if (updt_cntl) { - ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | (val << 8); - svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; - } else { - ramdac->hwc_x = ramdac->indexed_data[0x031]; - ramdac->hwc_x |= (ramdac->indexed_data[0x032] << 8); - ramdac->hwc_y = ramdac->indexed_data[0x033]; - ramdac->hwc_y |= (val << 8); - svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; - svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; - } - break; - case 0x035: - if (svga->dac_hwcursor.cur_xsize == 64) - ramdac->cursor_hotspot_x = (val & 0x3f); - else - ramdac->cursor_hotspot_x = (val & 0x1f); - svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; - break; - case 0x036: - if (svga->dac_hwcursor.cur_xsize == 64) - ramdac->cursor_hotspot_y = (val & 0x3f); - else - ramdac->cursor_hotspot_y = (val & 0x1f); - svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; - break; - case 0x040: case 0x043: case 0x046: - ramdac->extra_pal[(ramdac->index - 0x40) / 3].r = val; - break; - case 0x041: case 0x044: case 0x047: - ramdac->extra_pal[(ramdac->index - 0x41) / 3].g = val; - break; - case 0x042: case 0x045: case 0x048: - ramdac->extra_pal[(ramdac->index - 0x42) / 3].b = val; - break; - case 0x060: - ramdac->extra_pal[3].r = val; - break; - case 0x061: - ramdac->extra_pal[3].g = val; - break; - case 0x062: - ramdac->extra_pal[3].b = val; - break; - case 0x071: - svga->ramdac_type = (val & 0x04) ? RAMDAC_8BIT : RAMDAC_6BIT; - ibm_rgb528_set_bpp(ramdac, svga); - break; - default: - break; - } - if (ramdac->indx_cntl) { - if (ramdac->index == 0x00ff) - ramdac->cursor_array = 0; - ramdac->index = (ramdac->index + 1) & 0x07ff; - } - break; - case 0x07: - ramdac->indx_cntl = val & 0x01; - break; + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x03: + svga->dac_pos = 0; + svga->dac_status = addr & 0x03; + svga->dac_addr = val; + if (svga->dac_status) + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x01: /* Palette Data Register (RS value = 0001) */ + index = svga->dac_addr & 255; + if (svga->ramdac_type == RAMDAC_8BIT) + ramdac->palettes[svga->dac_pos][index] = val; + else + ramdac->palettes[svga->dac_pos][index] = (val & 0x3f) << 2; + svga_out(addr, val, svga); + break; + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + svga_out(addr, val, svga); + break; + case 0x04: + ramdac->index = (ramdac->index & 0x0700) | val; + if ((ramdac->index >= 0x0100) && (ramdac->index <= 0x04ff)) + ramdac->cursor_array = 1; + break; + case 0x05: + ramdac->index = (ramdac->index & 0x00ff) | ((val & 0x07) << 0x08); + if ((ramdac->index >= 0x0100) && (ramdac->index <= 0x04ff)) + ramdac->cursor_array = 1; + break; + case 0x06: + if ((ramdac->index < 0x0100) || (ramdac->index > 0x04ff) || ramdac->cursor_array) + ramdac->indexed_data[ramdac->index] = val; + switch (ramdac->index) { + case 0x00a: + case 0x00c: + ibm_rgb528_set_bpp(ramdac, svga); + break; + case 0x030: + switch (val & 0xc0) { + case 0x00: + ramdac->smlc_part = 0x0100; + break; + case 0x40: + ramdac->smlc_part = 0x0200; + break; + case 0x80: + ramdac->smlc_part = 0x0300; + break; + case 0xc0: + ramdac->smlc_part = 0x0400; + break; + } + svga->dac_hwcursor.addr = ramdac->smlc_part; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 0x04) ? 64 : 32; + svga->dac_hwcursor.ena = ((val & 0x03) != 0x00); + break; + case 0x031: + if (!updt_cntl) + break; + ramdac->hwc_x = (ramdac->hwc_x & 0xff00) | val; + svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; + break; + case 0x032: + /* Sign-extend the sign bit (7) to the remaining bits (6-4). */ + val &= 0x8f; + if (val & 0x80) + val |= 0x70; + ramdac->indexed_data[ramdac->index] = val; + if (!updt_cntl) + break; + ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | (val << 8); + svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; + break; + case 0x033: + if (!updt_cntl) + break; + ramdac->hwc_y = (ramdac->hwc_y & 0xff00) | val; + svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; + break; + case 0x034: + /* Sign-extend the sign bit (7) to the remaining bits (6-4). */ + val &= 0x8f; + if (val & 0x80) + val |= 0x70; + ramdac->indexed_data[ramdac->index] = val; + if (updt_cntl) { + ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | (val << 8); + svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; + } else { + ramdac->hwc_x = ramdac->indexed_data[0x031]; + ramdac->hwc_x |= (ramdac->indexed_data[0x032] << 8); + ramdac->hwc_y = ramdac->indexed_data[0x033]; + ramdac->hwc_y |= (val << 8); + svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; + svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; + } + break; + case 0x035: + if (svga->dac_hwcursor.cur_xsize == 64) + ramdac->cursor_hotspot_x = (val & 0x3f); + else + ramdac->cursor_hotspot_x = (val & 0x1f); + svga->dac_hwcursor.x = ((int) ramdac->hwc_x) - ramdac->cursor_hotspot_x; + break; + case 0x036: + if (svga->dac_hwcursor.cur_xsize == 64) + ramdac->cursor_hotspot_y = (val & 0x3f); + else + ramdac->cursor_hotspot_y = (val & 0x1f); + svga->dac_hwcursor.y = ((int) ramdac->hwc_y) - ramdac->cursor_hotspot_y; + break; + case 0x040: + case 0x043: + case 0x046: + ramdac->extra_pal[(ramdac->index - 0x40) / 3].r = val; + break; + case 0x041: + case 0x044: + case 0x047: + ramdac->extra_pal[(ramdac->index - 0x41) / 3].g = val; + break; + case 0x042: + case 0x045: + case 0x048: + ramdac->extra_pal[(ramdac->index - 0x42) / 3].b = val; + break; + case 0x060: + ramdac->extra_pal[3].r = val; + break; + case 0x061: + ramdac->extra_pal[3].g = val; + break; + case 0x062: + ramdac->extra_pal[3].b = val; + break; + case 0x071: + svga->ramdac_type = (val & 0x04) ? RAMDAC_8BIT : RAMDAC_6BIT; + ibm_rgb528_set_bpp(ramdac, svga); + break; + default: + break; + } + if (ramdac->indx_cntl) { + if (ramdac->index == 0x00ff) + ramdac->cursor_array = 0; + ramdac->index = (ramdac->index + 1) & 0x07ff; + } + break; + case 0x07: + ramdac->indx_cntl = val & 0x01; + break; } return; } - uint8_t ibm_rgb528_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; - uint8_t temp = 0xff; - uint8_t rs = (addr & 0x03); - uint8_t loc_read = (ramdac->indexed_data[0x30] & 0x10); + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) p; + uint8_t temp = 0xff; + uint8_t rs = (addr & 0x03); + uint8_t loc_read = (ramdac->indexed_data[0x30] & 0x10); rs |= (!!rs2 << 2); switch (rs) { - case 0x00: /* Palette Write Index Register (RS value = 0000) */ - case 0x01: /* Palette Data Register (RS value = 0001) */ - case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - temp = svga_in(addr, svga); - break; - case 0x03: /* Palette Read Index Register (RS value = 0011) */ - temp = svga->dac_addr & 0xff; - if (ramdac->indexed_data[0x070] & 0x20) - temp = (temp & 0xfc) | svga->dac_status; - break; - case 0x04: - temp = ramdac->index & 0xff; - break; - case 0x05: - temp = ramdac->index >> 8; - break; - case 0x06: - temp = ramdac->indexed_data[ramdac->index]; - switch (ramdac->index) { - case 0x0000: /* Revision */ - temp = 0xe0; - break; - case 0x0001: /* ID */ - temp = 0x02; - break; - case 0x0031: - if (loc_read) - temp = ramdac->hwc_x & 0xff; - break; - case 0x0032: - if (loc_read) - temp = ramdac->hwc_x >> 8; - break; - case 0x0033: - if (loc_read) - temp = ramdac->hwc_y & 0xff; - break; - case 0x0034: - if (loc_read) - temp = ramdac->hwc_y >> 8; - break; - default: - temp = ramdac->indexed_data[ramdac->index]; - break; - } - if (ramdac->indx_cntl) { - if (ramdac->index == 0x00ff) - ramdac->cursor_array = 0; - ramdac->index = (ramdac->index + 1) & 0x07ff; - } - break; - case 0x07: - temp = ramdac->indx_cntl; - break; + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + temp = svga_in(addr, svga); + break; + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + temp = svga->dac_addr & 0xff; + if (ramdac->indexed_data[0x070] & 0x20) + temp = (temp & 0xfc) | svga->dac_status; + break; + case 0x04: + temp = ramdac->index & 0xff; + break; + case 0x05: + temp = ramdac->index >> 8; + break; + case 0x06: + temp = ramdac->indexed_data[ramdac->index]; + switch (ramdac->index) { + case 0x0000: /* Revision */ + temp = 0xe0; + break; + case 0x0001: /* ID */ + temp = 0x02; + break; + case 0x0031: + if (loc_read) + temp = ramdac->hwc_x & 0xff; + break; + case 0x0032: + if (loc_read) + temp = ramdac->hwc_x >> 8; + break; + case 0x0033: + if (loc_read) + temp = ramdac->hwc_y & 0xff; + break; + case 0x0034: + if (loc_read) + temp = ramdac->hwc_y >> 8; + break; + default: + temp = ramdac->indexed_data[ramdac->index]; + break; + } + if (ramdac->indx_cntl) { + if (ramdac->index == 0x00ff) + ramdac->cursor_array = 0; + ramdac->index = (ramdac->index + 1) & 0x07ff; + } + break; + case 0x07: + temp = ramdac->indx_cntl; + break; } return temp; } - void ibm_rgb528_recalctimings(void *p, svga_t *svga) { @@ -797,122 +795,121 @@ ibm_rgb528_recalctimings(void *p, svga_t *svga) svga->interlace = ramdac->indexed_data[0x071] & 0x20; if (svga->scrblank || !svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (((svga->gdcreg[5] & 0x60) == 0x40) || ((svga->gdcreg[5] & 0x60) == 0x60)) { - if (ramdac->indexed_data[0x071] & 0x01) { - switch (svga->bpp) { - case 4: - svga->render = ibm_rgb528_render_4bpp; - break; - case 8: - svga->render = ibm_rgb528_render_8bpp; - break; - case 15: case 16: - svga->render = ibm_rgb528_render_15_16bpp; - break; - case 24: - svga->render = ibm_rgb528_render_24bpp; - break; - case 32: - svga->render = ibm_rgb528_render_32bpp; - break; - } - } - } - } + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (((svga->gdcreg[5] & 0x60) == 0x40) || ((svga->gdcreg[5] & 0x60) == 0x60)) { + if (ramdac->indexed_data[0x071] & 0x01) { + switch (svga->bpp) { + case 4: + svga->render = ibm_rgb528_render_4bpp; + break; + case 8: + svga->render = ibm_rgb528_render_8bpp; + break; + case 15: + case 16: + svga->render = ibm_rgb528_render_15_16bpp; + break; + case 24: + svga->render = ibm_rgb528_render_24bpp; + break; + case 32: + svga->render = ibm_rgb528_render_32bpp; + break; + } + } + } + } } } - void ibm_rgb528_hwcursor_draw(svga_t *svga, int displine) { - uint8_t dat, four_pixels = 0x00; - int x, pitch, x_pos, y_pos, offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; - uint32_t *p; - ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; - uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20; - uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03; + uint8_t dat, four_pixels = 0x00; + int x, pitch, x_pos, y_pos, offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff; + uint32_t *p; + ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) svga->ramdac; + uint8_t pix_ordr = ramdac->indexed_data[0x30] & 0x20; + uint8_t cursor_mode = ramdac->indexed_data[0x30] & 0x03; /* The planes come in one part, and each plane is 2bpp, so a 32x32 cursor has 8 bytes per line, and a 64x64 cursor has 16 bytes per line. */ - pitch = (svga->dac_hwcursor_latch.cur_xsize >> 2); /* Bytes per line. */ + pitch = (svga->dac_hwcursor_latch.cur_xsize >> 2); /* Bytes per line. */ if ((ramdac->indexed_data[0x071] & 0x20) && svga->dac_hwcursor_oddeven) - svga->dac_hwcursor_latch.addr += pitch; + svga->dac_hwcursor_latch.addr += pitch; y_pos = displine; x_pos = offset + svga->x_add; - p = buffer32->line[y_pos]; + p = buffer32->line[y_pos]; for (x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x++) { - if (!(x & 3)) - four_pixels = ramdac->indexed_data[svga->dac_hwcursor_latch.addr]; + if (!(x & 3)) + four_pixels = ramdac->indexed_data[svga->dac_hwcursor_latch.addr]; - if (pix_ordr) - dat = (four_pixels >> (((3 - x) & 3) << 1)) & 0x03; - else - dat = (four_pixels >> ((x & 3) << 1)) & 0x03; + if (pix_ordr) + dat = (four_pixels >> (((3 - x) & 3) << 1)) & 0x03; + else + dat = (four_pixels >> ((x & 3) << 1)) & 0x03; - x_pos = offset + svga->x_add + x; + x_pos = offset + svga->x_add + x; - switch (cursor_mode) { - case 0x01: - switch (dat) { - case 0x01: - /* Cursor Color 1 */ - p[x_pos] = ramdac->extra_pal[0].pixel; - break; - case 0x02: - /* Cursor Color 2 */ - p[x_pos] = ramdac->extra_pal[1].pixel; - break; - case 0x03: - /* Cursor Color 3 */ - p[x_pos] = ramdac->extra_pal[2].pixel; - break; - } - break; - case 0x02: - switch (dat) { - case 0x00: - /* Cursor Color 1 */ - p[x_pos] = ramdac->extra_pal[0].pixel; - break; - case 0x01: - /* Cursor Color 2 */ - p[x_pos] = ramdac->extra_pal[1].pixel; - break; - case 0x03: - /* Complement */ - p[x_pos] ^= 0xffffff; - break; - } - break; - case 0x03: - switch (dat) { - case 0x02: - /* Cursor Color 1 */ - p[x_pos] = ramdac->extra_pal[0].pixel; - break; - case 0x03: - /* Cursor Color 2 */ - p[x_pos] = ramdac->extra_pal[1].pixel; - break; - } - break; - } + switch (cursor_mode) { + case 0x01: + switch (dat) { + case 0x01: + /* Cursor Color 1 */ + p[x_pos] = ramdac->extra_pal[0].pixel; + break; + case 0x02: + /* Cursor Color 2 */ + p[x_pos] = ramdac->extra_pal[1].pixel; + break; + case 0x03: + /* Cursor Color 3 */ + p[x_pos] = ramdac->extra_pal[2].pixel; + break; + } + break; + case 0x02: + switch (dat) { + case 0x00: + /* Cursor Color 1 */ + p[x_pos] = ramdac->extra_pal[0].pixel; + break; + case 0x01: + /* Cursor Color 2 */ + p[x_pos] = ramdac->extra_pal[1].pixel; + break; + case 0x03: + /* Complement */ + p[x_pos] ^= 0xffffff; + break; + } + break; + case 0x03: + switch (dat) { + case 0x02: + /* Cursor Color 1 */ + p[x_pos] = ramdac->extra_pal[0].pixel; + break; + case 0x03: + /* Cursor Color 2 */ + p[x_pos] = ramdac->extra_pal[1].pixel; + break; + } + break; + } - if ((x & 3) == 3) - svga->dac_hwcursor_latch.addr++; + if ((x & 3) == 3) + svga->dac_hwcursor_latch.addr++; } if ((ramdac->indexed_data[0x071] & 0x20) && !svga->dac_hwcursor_oddeven) - svga->dac_hwcursor_latch.addr += pitch; + svga->dac_hwcursor_latch.addr += pitch; } - void * ibm_rgb528_ramdac_init(const device_t *info) { @@ -928,26 +925,25 @@ ibm_rgb528_ramdac_init(const device_t *info) return ramdac; } - static void ibm_rgb528_ramdac_close(void *priv) { ibm_rgb528_ramdac_t *ramdac = (ibm_rgb528_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t ibm_rgb528_ramdac_device = { - .name = "IBM RGB528 RAMDAC", + .name = "IBM RGB528 RAMDAC", .internal_name = "ibm_rgb528_ramdac", - .flags = 0, - .local = 0, - .init = ibm_rgb528_ramdac_init, - .close = ibm_rgb528_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = ibm_rgb528_ramdac_init, + .close = ibm_rgb528_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_icd2061.c b/src/video/vid_icd2061.c index cb7ffecbe..3eca22fc1 100644 --- a/src/video/vid_icd2061.c +++ b/src/video/vid_icd2061.c @@ -28,37 +28,32 @@ #include <86box/86box.h> #include <86box/device.h> - -typedef struct icd2061_t -{ +typedef struct icd2061_t { float freq[3]; int count, bit_count, - unlocked, state; + unlocked, state; uint32_t data, ctrl; } icd2061_t; - #ifdef ENABLE_ICD2061_LOG int icd2061_do_log = ENABLE_ICD2061_LOG; - static void icd2061_log(const char *fmt, ...) { va_list ap; if (icd2061_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define icd2061_log(fmt, ...) +# define icd2061_log(fmt, ...) #endif - void icd2061_write(void *p, int val) { @@ -67,81 +62,79 @@ icd2061_write(void *p, int val) int nd, oc, nc; int a, qa, q, pa, p_, m, ps; - nd = (val & 2) >> 1; /* Old data. */ - oc = icd2061->state & 1; /* Old clock. */ - nc = val & 1; /* New clock. */ + nd = (val & 2) >> 1; /* Old data. */ + oc = icd2061->state & 1; /* Old clock. */ + nc = val & 1; /* New clock. */ icd2061->state = val; - if (nc && !oc) { /* Low-to-high transition of CLK. */ - if (!icd2061->unlocked) { - if (nd) { /* DATA high. */ - icd2061->count++; - icd2061_log("Low-to-high transition of CLK with DATA high, %i total\n", icd2061->count); - } else { /* DATA low. */ - if (icd2061->count >= 5) { - icd2061->unlocked = 1; - icd2061->bit_count = icd2061->data = 0; + if (nc && !oc) { /* Low-to-high transition of CLK. */ + if (!icd2061->unlocked) { + if (nd) { /* DATA high. */ + icd2061->count++; + icd2061_log("Low-to-high transition of CLK with DATA high, %i total\n", icd2061->count); + } else { /* DATA low. */ + if (icd2061->count >= 5) { + icd2061->unlocked = 1; + icd2061->bit_count = icd2061->data = 0; #ifdef ENABLE_ICD2061_LOG - icd2061_log("ICD2061 unlocked\n"); + icd2061_log("ICD2061 unlocked\n"); #endif - } else { - icd2061->count = 0; + } else { + icd2061->count = 0; #ifdef ENABLE_ICD2061_LOG - icd2061_log("ICD2061 locked\n"); + icd2061_log("ICD2061 locked\n"); #endif - } - } - } else if (nc) { - icd2061->data |= (nd << icd2061->bit_count); - icd2061->bit_count++; + } + } + } else if (nc) { + icd2061->data |= (nd << icd2061->bit_count); + icd2061->bit_count++; - if (icd2061->bit_count == 26) { - icd2061_log("26 bits received, data = %08X\n", icd2061->data); + if (icd2061->bit_count == 26) { + icd2061_log("26 bits received, data = %08X\n", icd2061->data); - a = ((icd2061->data >> 22) & 0x07); /* A */ - icd2061_log("A = %01X\n", a); + a = ((icd2061->data >> 22) & 0x07); /* A */ + icd2061_log("A = %01X\n", a); - if (a < 3) { - pa = ((icd2061->data >> 11) & 0x7f); /* P' (ICD2061) / N' (ICS9161) */ - m = ((icd2061->data >> 8) & 0x07); /* M (ICD2061) / R (ICS9161) */ - qa = ((icd2061->data >> 1) & 0x7f); /* Q' (ICD2061) / M' (ICS9161) */ + if (a < 3) { + pa = ((icd2061->data >> 11) & 0x7f); /* P' (ICD2061) / N' (ICS9161) */ + m = ((icd2061->data >> 8) & 0x07); /* M (ICD2061) / R (ICS9161) */ + qa = ((icd2061->data >> 1) & 0x7f); /* Q' (ICD2061) / M' (ICS9161) */ - p_ = pa + 3; /* P (ICD2061) / N (ICS9161) */ - m = 1 << m; - q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ - ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ + p_ = pa + 3; /* P (ICD2061) / N (ICS9161) */ + m = 1 << m; + q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ + ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - icd2061->freq[a] = ((float)(p_ * ps) / (float)(q * m)) * 14318184.0f; + icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * 14318184.0f; - icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); - } else if (a == 6) { - icd2061->ctrl = ((icd2061->data >> 13) & 0xff); - icd2061_log("ctrl = %02X\n", icd2061->ctrl); - } - icd2061->count = icd2061->bit_count = icd2061->data = 0; - icd2061->unlocked = 0; + icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); + } else if (a == 6) { + icd2061->ctrl = ((icd2061->data >> 13) & 0xff); + icd2061_log("ctrl = %02X\n", icd2061->ctrl); + } + icd2061->count = icd2061->bit_count = icd2061->data = 0; + icd2061->unlocked = 0; #ifdef ENABLE_ICD2061_LOG - icd2061_log("ICD2061 locked\n"); + icd2061_log("ICD2061 locked\n"); #endif - } - } + } + } } } - float icd2061_getclock(int clock, void *p) { icd2061_t *icd2061 = (icd2061_t *) p; if (clock > 2) - clock = 2; + clock = 2; return icd2061->freq[clock]; } - static void * icd2061_init(const device_t *info) { @@ -155,40 +148,39 @@ icd2061_init(const device_t *info) return icd2061; } - static void icd2061_close(void *priv) { icd2061_t *icd2061 = (icd2061_t *) priv; if (icd2061) - free(icd2061); + free(icd2061); } const device_t icd2061_device = { - .name = "ICD2061 Clock Generator", + .name = "ICD2061 Clock Generator", .internal_name = "icd2061", - .flags = 0, - .local = 0, - .init = icd2061_init, - .close = icd2061_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = icd2061_init, + .close = icd2061_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t ics9161_device = { - .name = "ICS9161 Clock Generator", + .name = "ICS9161 Clock Generator", .internal_name = "ics9161", - .flags = 0, - .local = 0, - .init = icd2061_init, - .close = icd2061_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = icd2061_init, + .close = icd2061_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_ics2494.c b/src/video/vid_ics2494.c index f06726e02..9ab686ae9 100644 --- a/src/video/vid_ics2494.c +++ b/src/video/vid_ics2494.c @@ -24,45 +24,39 @@ #include <86box/86box.h> #include <86box/device.h> - -typedef struct ics2494_t -{ +typedef struct ics2494_t { float freq[16]; } ics2494_t; - #ifdef ENABLE_ics2494_LOG int ics2494_do_log = ENABLE_ics2494_LOG; - static void ics2494_log(const char *fmt, ...) { va_list ap; if (ics2494_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define ics2494_log(fmt, ...) +# define ics2494_log(fmt, ...) #endif - float ics2494_getclock(int clock, void *p) { ics2494_t *ics2494 = (ics2494_t *) p; if (clock > 16) - clock = 16; + clock = 16; return ics2494->freq[clock]; } - static void * ics2494_init(const device_t *info) { @@ -70,50 +64,49 @@ ics2494_init(const device_t *info) memset(ics2494, 0, sizeof(ics2494_t)); switch (info->local) { - case 305: - /* ICS2494A(N)-205 for S3 86C924 */ - ics2494->freq[0x0] = 25175000.0; - ics2494->freq[0x1] = 28322000.0; - ics2494->freq[0x2] = 40000000.0; - ics2494->freq[0x3] = 0.0; - ics2494->freq[0x4] = 50000000.0; - ics2494->freq[0x5] = 77000000.0; - ics2494->freq[0x6] = 36000000.0; - ics2494->freq[0x7] = 44889000.0; - ics2494->freq[0x8] = 130000000.0; - ics2494->freq[0x9] = 120000000.0; - ics2494->freq[0xa] = 80000000.0; - ics2494->freq[0xb] = 31500000.0; - ics2494->freq[0xc] = 110000000.0; - ics2494->freq[0xd] = 65000000.0; - ics2494->freq[0xe] = 75000000.0; - ics2494->freq[0xf] = 94500000.0; - break; + case 305: + /* ICS2494A(N)-205 for S3 86C924 */ + ics2494->freq[0x0] = 25175000.0; + ics2494->freq[0x1] = 28322000.0; + ics2494->freq[0x2] = 40000000.0; + ics2494->freq[0x3] = 0.0; + ics2494->freq[0x4] = 50000000.0; + ics2494->freq[0x5] = 77000000.0; + ics2494->freq[0x6] = 36000000.0; + ics2494->freq[0x7] = 44889000.0; + ics2494->freq[0x8] = 130000000.0; + ics2494->freq[0x9] = 120000000.0; + ics2494->freq[0xa] = 80000000.0; + ics2494->freq[0xb] = 31500000.0; + ics2494->freq[0xc] = 110000000.0; + ics2494->freq[0xd] = 65000000.0; + ics2494->freq[0xe] = 75000000.0; + ics2494->freq[0xf] = 94500000.0; + break; } return ics2494; } - static void ics2494_close(void *priv) { ics2494_t *ics2494 = (ics2494_t *) priv; if (ics2494) - free(ics2494); + free(ics2494); } const device_t ics2494an_305_device = { - .name = "ICS2494AN-305 Clock Generator", + .name = "ICS2494AN-305 Clock Generator", .internal_name = "ics2494an_305", - .flags = 0, - .local = 305, - .init = ics2494_init, - .close = ics2494_close, - .reset = NULL, + .flags = 0, + .local = 305, + .init = ics2494_init, + .close = ics2494_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_ics2595.c b/src/video/vid_ics2595.c index e36c4048e..77c46b6c3 100644 --- a/src/video/vid_ics2595.c +++ b/src/video/vid_ics2595.c @@ -24,9 +24,7 @@ #include <86box/86box.h> #include <86box/device.h> - -typedef struct ics2595_t -{ +typedef struct ics2595_t { int oldfs3, oldfs2; int dat; int pos, state; @@ -35,57 +33,52 @@ typedef struct ics2595_t double output_clock; } ics2595_t; - -enum -{ - ICS2595_IDLE = 0, - ICS2595_WRITE, - ICS2595_READ +enum { + ICS2595_IDLE = 0, + ICS2595_WRITE, + ICS2595_READ }; - -static int ics2595_div[4] = {8, 4, 2, 1}; - +static int ics2595_div[4] = { 8, 4, 2, 1 }; void ics2595_write(void *p, int strobe, int dat) { ics2595_t *ics2595 = (ics2595_t *) p; - int d, n; - int l; + int d, n; + int l; if (strobe) { - if ((dat & 8) && !ics2595->oldfs3) { /*Data clock*/ - switch (ics2595->state) { - case ICS2595_IDLE: - ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; - ics2595->pos = 0; - break; - case ICS2595_WRITE: - ics2595->dat = (ics2595->dat >> 1); - if (dat & 4) - ics2595->dat |= (1 << 19); - ics2595->pos++; - if (ics2595->pos == 20) { - l = (ics2595->dat >> 2) & 0xf; - n = ((ics2595->dat >> 7) & 255) + 257; - d = ics2595_div[(ics2595->dat >> 16) & 3]; + if ((dat & 8) && !ics2595->oldfs3) { /*Data clock*/ + switch (ics2595->state) { + case ICS2595_IDLE: + ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE; + ics2595->pos = 0; + break; + case ICS2595_WRITE: + ics2595->dat = (ics2595->dat >> 1); + if (dat & 4) + ics2595->dat |= (1 << 19); + ics2595->pos++; + if (ics2595->pos == 20) { + l = (ics2595->dat >> 2) & 0xf; + n = ((ics2595->dat >> 7) & 255) + 257; + d = ics2595_div[(ics2595->dat >> 16) & 3]; - ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; - ics2595->state = ICS2595_IDLE; - } - break; - } - } + ics2595->clocks[l] = (14318181.8 * ((double) n / 46.0)) / (double) d; + ics2595->state = ICS2595_IDLE; + } + break; + } + } - ics2595->oldfs2 = dat & 4; - ics2595->oldfs3 = dat & 8; + ics2595->oldfs2 = dat & 4; + ics2595->oldfs3 = dat & 8; } ics2595->output_clock = ics2595->clocks[dat]; } - static void * ics2595_init(const device_t *info) { @@ -95,17 +88,15 @@ ics2595_init(const device_t *info) return ics2595; } - static void ics2595_close(void *priv) { ics2595_t *ics2595 = (ics2595_t *) priv; if (ics2595) - free(ics2595); + free(ics2595); } - double ics2595_getclock(void *p) { @@ -114,7 +105,6 @@ ics2595_getclock(void *p) return ics2595->output_clock; } - void ics2595_setclock(void *p, double clock) { @@ -124,15 +114,15 @@ ics2595_setclock(void *p, double clock) } const device_t ics2595_device = { - .name = "ICS2595 clock chip", + .name = "ICS2595 clock chip", .internal_name = "ics2595", - .flags = 0, - .local = 0, - .init = ics2595_init, - .close = ics2595_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = ics2595_init, + .close = ics2595_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index 932faecb7..15aab0cb8 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -66,68 +66,63 @@ #include <86box/video.h> #include <86box/vid_pgc.h> - -#define BIOS_ROM_PATH "roms/video/im1024/im1024font.bin" - +#define BIOS_ROM_PATH "roms/video/im1024/im1024font.bin" typedef struct { - pgc_t pgc; + pgc_t pgc; - uint8_t fontx[256]; - uint8_t fonty[256]; - uint8_t font[256][128]; + uint8_t fontx[256]; + uint8_t fonty[256]; + uint8_t font[256][128]; - uint8_t *fifo; - unsigned fifo_len, - fifo_wrptr, - fifo_rdptr; + uint8_t *fifo; + unsigned fifo_len, + fifo_wrptr, + fifo_rdptr; } im1024_t; - -static video_timings_t timing_im1024 = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; - +static video_timings_t timing_im1024 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; #ifdef ENABLE_IM1024_LOG int im1024_do_log = ENABLE_IM1024_LOG; - static void im1024_log(const char *fmt, ...) { va_list ap; if (im1024_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define im1024_log(fmt, ...) +# define im1024_log(fmt, ...) #endif - static void fifo_write(im1024_t *dev, uint8_t val) { im1024_log("IM1024: fifo_write: %02x [rd=%04x wr=%04x]\n", - val, dev->fifo_rdptr, dev->fifo_wrptr); + val, dev->fifo_rdptr, dev->fifo_wrptr); if (((dev->fifo_wrptr + 1) % dev->fifo_len) == dev->fifo_rdptr) { - /* FIFO is full. Double its size. */ - uint8_t *buf; + /* FIFO is full. Double its size. */ + uint8_t *buf; - im1024_log("IM1024: fifo_resize: %i to %i\n", - dev->fifo_len, 2 * dev->fifo_len); + im1024_log("IM1024: fifo_resize: %i to %i\n", + dev->fifo_len, 2 * dev->fifo_len); - buf = realloc(dev->fifo, 2 * dev->fifo_len); - if (buf == NULL) return; + buf = realloc(dev->fifo, 2 * dev->fifo_len); + if (buf == NULL) + return; - /* Move the [0..wrptr] range to the newly-allocated area [len..len+wrptr] */ - memmove(buf + dev->fifo_len, buf, dev->fifo_wrptr); - dev->fifo = buf; - dev->fifo_wrptr += dev->fifo_len; - dev->fifo_len *= 2; + /* Move the [0..wrptr] range to the newly-allocated area [len..len+wrptr] */ + memmove(buf + dev->fifo_len, buf, dev->fifo_wrptr); + dev->fifo = buf; + dev->fifo_wrptr += dev->fifo_len; + dev->fifo_len *= 2; } /* Append to the queue. */ @@ -135,28 +130,26 @@ fifo_write(im1024_t *dev, uint8_t val) /* Wrap if end of buffer reached. */ if (dev->fifo_wrptr >= dev->fifo_len) - dev->fifo_wrptr = 0; + dev->fifo_wrptr = 0; } - static int fifo_read(im1024_t *dev) { uint8_t ret; if (dev->fifo_wrptr == dev->fifo_rdptr) - return -1; /* FIFO empty */ + return -1; /* FIFO empty */ ret = dev->fifo[dev->fifo_rdptr++]; if (dev->fifo_rdptr >= dev->fifo_len) - dev->fifo_rdptr = 0; + dev->fifo_rdptr = 0; im1024_log("IM1024: fifo_read: %02x\n", ret); - return(ret); + return (ret); } - /* * Where a normal PGC would just read from the ring buffer at 0xC6300, * the IM-1024 can read from either this or from its internal FIFO. @@ -166,96 +159,92 @@ fifo_read(im1024_t *dev) static int input_byte(pgc_t *pgc, uint8_t *result) { - im1024_t *dev = (im1024_t *)pgc; + im1024_t *dev = (im1024_t *) pgc; /* If input buffer empty, wait for it to fill. */ - while (!pgc->stopped && (dev->fifo_wrptr == dev->fifo_rdptr) && - (pgc->mapram[0x300] == pgc->mapram[0x301])) { - pgc->waiting_input_fifo = 1; - pgc_sleep(pgc); + while (!pgc->stopped && (dev->fifo_wrptr == dev->fifo_rdptr) && (pgc->mapram[0x300] == pgc->mapram[0x301])) { + pgc->waiting_input_fifo = 1; + pgc_sleep(pgc); } if (pgc->stopped) - return(0); + return (0); if (pgc->mapram[0x3ff]) { - /* Reset triggered. */ - pgc_reset(pgc); - return(0); + /* Reset triggered. */ + pgc_reset(pgc); + return (0); } if (dev->fifo_wrptr == dev->fifo_rdptr) { - *result = pgc->mapram[pgc->mapram[0x301]]; - pgc->mapram[0x301]++; + *result = pgc->mapram[pgc->mapram[0x301]]; + pgc->mapram[0x301]++; } else - *result = fifo_read(dev); + *result = fifo_read(dev); - return(1); + return (1); } - /* Macros to disable clipping and save clip state. */ -#define PUSHCLIP { \ - uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \ - vp_x1 = pgc->vp_x1; \ - vp_y1 = pgc->vp_y1; \ - vp_x2 = pgc->vp_x2; \ - vp_y2 = pgc->vp_y2; \ - pgc->vp_x1 = 0; \ - pgc->vp_y1 = 0; \ - pgc->vp_x2 = pgc->maxw - 1; \ - pgc->vp_y2 = pgc->maxh - 1; \ +#define PUSHCLIP \ + { \ + uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \ + vp_x1 = pgc->vp_x1; \ + vp_y1 = pgc->vp_y1; \ + vp_x2 = pgc->vp_x2; \ + vp_y2 = pgc->vp_y2; \ + pgc->vp_x1 = 0; \ + pgc->vp_y1 = 0; \ + pgc->vp_x2 = pgc->maxw - 1; \ + pgc->vp_y2 = pgc->maxh - 1; /* And to restore clip state */ -#define POPCLIP \ - pgc->vp_x1 = vp_x1; \ - pgc->vp_y1 = vp_y1; \ - pgc->vp_x2 = vp_x2; \ - pgc->vp_y2 = vp_y2; \ - } - +#define POPCLIP \ + pgc->vp_x1 = vp_x1; \ + pgc->vp_y1 = vp_y1; \ + pgc->vp_x2 = vp_x2; \ + pgc->vp_y2 = vp_y2; \ + } /* Override memory read to return FIFO space. */ static uint8_t im1024_read(uint32_t addr, void *priv) { - im1024_t *dev = (im1024_t *)priv; + im1024_t *dev = (im1024_t *) priv; if (addr == 0xc6331 && dev->pgc.mapram[0x330] == 1) { - /* Hardcode that there are 128 bytes free. */ - return(0x80); + /* Hardcode that there are 128 bytes free. */ + return (0x80); } - return(pgc_read(addr, &dev->pgc)); + return (pgc_read(addr, &dev->pgc)); } - /* Override memory write to handle writes to the FIFO. */ static void im1024_write(uint32_t addr, uint8_t val, void *priv) { - im1024_t *dev = (im1024_t *)priv; + im1024_t *dev = (im1024_t *) priv; /* * If we are in 'fast' input mode, send all * writes to the internal FIFO. */ if (addr >= 0xc6000 && addr < 0xc6100 && dev->pgc.mapram[0x330] == 1) { - fifo_write(dev, val); + fifo_write(dev, val); - im1024_log("IM1024: write(%02x)\n", val); + im1024_log("IM1024: write(%02x)\n", val); - if (dev->pgc.waiting_input_fifo) { - dev->pgc.waiting_input_fifo = 0; - pgc_wake(&dev->pgc); - } - return; + if (dev->pgc.waiting_input_fifo) { + dev->pgc.waiting_input_fifo = 0; + pgc_wake(&dev->pgc); + } + return; } pgc_write(addr, val, &dev->pgc); } - /* * I don't know what the IMGSIZ command does, only that the * Windows driver issues it. So just parse and ignore it. @@ -269,15 +258,18 @@ hndl_imgsiz(pgc_t *pgc) int16_t w, h; uint8_t a, b; - if (! pgc_param_word(pgc, &w)) return; - if (! pgc_param_word(pgc, &h)) return; - if (! pgc_param_byte(pgc, &a)) return; - if (! pgc_param_byte(pgc, &b)) return; + if (!pgc_param_word(pgc, &w)) + return; + if (!pgc_param_word(pgc, &h)) + return; + if (!pgc_param_byte(pgc, &a)) + return; + if (!pgc_param_byte(pgc, &b)) + return; im1024_log("IM1024: IMGSIZ %i,%i,%i,%i\n", w, h, a, b); } - /* * I don't know what the IPREC command does, only that the * Windows driver issues it. So just parse and ignore it. @@ -290,12 +282,12 @@ hndl_iprec(pgc_t *pgc) #endif uint8_t param; - if (! pgc_param_byte(pgc, ¶m)) return; + if (!pgc_param_byte(pgc, ¶m)) + return; im1024_log("IM1024: IPREC %i\n", param); } - /* * Set drawing mode. * @@ -309,16 +301,16 @@ hndl_linfun(pgc_t *pgc) { uint8_t param; - if (! pgc_param_byte(pgc, ¶m)) return; + if (!pgc_param_byte(pgc, ¶m)) + return; if (param < 4) { - pgc->draw_mode = param; - im1024_log("IM1024: LINFUN(%i)\n", param); + pgc->draw_mode = param; + im1024_log("IM1024: LINFUN(%i)\n", param); } else - pgc_error(pgc, PGC_ERROR_RANGE); + pgc_error(pgc, PGC_ERROR_RANGE); } - /* * I think PAN controls which part of the 1024x1024 framebuffer * is displayed in the 1024x800 visible screen. @@ -328,8 +320,10 @@ hndl_pan(pgc_t *pgc) { int16_t x, y; - if (! pgc_param_word(pgc, &x)) return; - if (! pgc_param_word(pgc, &y)) return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; im1024_log("IM1024: PAN %i,%i\n", x, y); @@ -337,32 +331,33 @@ hndl_pan(pgc_t *pgc) pgc->pan_y = y; } - /* PLINE draws a non-filled polyline at a fixed position. */ static void hndl_pline(pgc_t *pgc) { - int16_t x[257], y[257]; + int16_t x[257], y[257]; uint16_t linemask = pgc->line_pattern; - uint8_t count; + uint8_t count; unsigned n; - if (! pgc_param_byte(pgc, &count)) return; + if (!pgc_param_byte(pgc, &count)) + return; im1024_log("IM1024: PLINE (%i) ", count); for (n = 0; n < count; n++) { - if (! pgc_param_word(pgc, &x[n])) return; - if (! pgc_param_word(pgc, &y[n])) return; - im1024_log(" (%i,%i)\n", x[n], y[n]); + if (!pgc_param_word(pgc, &x[n])) + return; + if (!pgc_param_word(pgc, &y[n])) + return; + im1024_log(" (%i,%i)\n", x[n], y[n]); } for (n = 1; n < count; n++) { - linemask = pgc_draw_line(pgc, x[n - 1] << 16, y[n - 1] << 16, - x[n] << 16, y[n] << 16, linemask); + linemask = pgc_draw_line(pgc, x[n - 1] << 16, y[n - 1] << 16, + x[n] << 16, y[n] << 16, linemask); } } - /* * Blit a single row of pixels from one location to another. * @@ -377,31 +372,31 @@ blkmov_row(pgc_t *pgc, int16_t x0, int16_t x1, int16_t x2, int16_t sy, int16_t t int16_t x; for (x = x0; x <= x1; x++) { - src[x - x0] = pgc_read_pixel(pgc, x, sy); - dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty); + src[x - x0] = pgc_read_pixel(pgc, x, sy); + dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty); } - for (x = x0; x <= x1; x++) switch (pgc->draw_mode) { - default: - case 0: - pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]); - break; + for (x = x0; x <= x1; x++) + switch (pgc->draw_mode) { + default: + case 0: + pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]); + break; - case 1: - pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xff); - break; + case 1: + pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xff); + break; - case 2: - pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]); - break; + case 2: + pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]); + break; - case 3: - pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]); - break; - } + case 3: + pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]); + break; + } } - /* * BLKMOV blits a rectangular area from one location to another. * @@ -415,14 +410,20 @@ hndl_blkmov(pgc_t *pgc) int16_t x2, y2; int16_t y; - if (! pgc_param_word(pgc, &x0)) return; - if (! pgc_param_word(pgc, &y0)) return; - if (! pgc_param_word(pgc, &x1)) return; - if (! pgc_param_word(pgc, &y1)) return; - if (! pgc_param_word(pgc, &x2)) return; - if (! pgc_param_word(pgc, &y2)) return; + if (!pgc_param_word(pgc, &x0)) + return; + if (!pgc_param_word(pgc, &y0)) + return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &y1)) + return; + if (!pgc_param_word(pgc, &x2)) + return; + if (!pgc_param_word(pgc, &y2)) + return; - im1024_log("IM1024: BLKMOV %i,%i,%i,%i,%i,%i\n", x0,y0,x1,y1,x2,y2); + im1024_log("IM1024: BLKMOV %i,%i,%i,%i,%i,%i\n", x0, y0, x1, y1, x2, y2); /* Disable clipping. */ PUSHCLIP @@ -432,37 +433,37 @@ hndl_blkmov(pgc_t *pgc) * depending whether areas might overlap. */ if (y2 <= y0) { - for (y = y0; y <= y1; y++) - blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); + for (y = y0; y <= y1; y++) + blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); } else { - for (y = y1; y >= y0; y--) - blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); + for (y = y1; y >= y0; y--) + blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); } /* Restore clipping. */ POPCLIP } - /* * Override the PGC ELIPSE command to parse its * parameters as words rather than coordinates. - */ + */ static void hndl_ellipse(pgc_t *pgc) { int16_t x, y; - if (! pgc_param_word(pgc, &x)) return; - if (! pgc_param_word(pgc, &y)) return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; im1024_log("IM1024: ELLIPSE %i,%i @ %i,%i\n", - x, y, pgc->x >> 16, pgc->y >> 16); + x, y, pgc->x >> 16, pgc->y >> 16); pgc_draw_ellipse(pgc, x << 16, y << 16); } - /* * Override the PGC MOVE command to parse its * parameters as words rather than coordinates. @@ -472,8 +473,10 @@ hndl_move(pgc_t *pgc) { int16_t x, y; - if (! pgc_param_word(pgc, &x)) return; - if (! pgc_param_word(pgc, &y)) return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; im1024_log("IM1024: MOVE %i,%i\n", x, y); @@ -481,7 +484,6 @@ hndl_move(pgc_t *pgc) pgc->y = y << 16; } - /* * Override the PGC DRAW command to parse its * parameters as words rather than coordinates. @@ -491,8 +493,10 @@ hndl_draw(pgc_t *pgc) { int16_t x, y; - if (! pgc_param_word(pgc, &x)) return; - if (! pgc_param_word(pgc, &y)) return; + if (!pgc_param_word(pgc, &x)) + return; + if (!pgc_param_word(pgc, &y)) + return; im1024_log("IM1024: DRAW %i,%i to %i,%i\n", pgc->x >> 16, pgc->y >> 16, x, y); @@ -502,7 +506,6 @@ hndl_draw(pgc_t *pgc) pgc->y = y << 16; } - /* * Override the PGC POLY command to parse its * parameters as words rather than coordinates. @@ -511,113 +514,110 @@ static void hndl_poly(pgc_t *pgc) { int32_t *x, *y, *nx, *ny; - int16_t xw, yw, mask; + int16_t xw, yw, mask; unsigned realcount = 0; unsigned n, as = 256; - int parsing = 1; - uint8_t count; + int parsing = 1; + uint8_t count; - x = (int32_t *)malloc(as * sizeof(int32_t)); - y = (int32_t *)malloc(as * sizeof(int32_t)); + x = (int32_t *) malloc(as * sizeof(int32_t)); + y = (int32_t *) malloc(as * sizeof(int32_t)); if (!x || !y) { #ifdef ENABLE_IM1024_LOG - im1024_log("IM1024: POLY: out of memory\n"); + im1024_log("IM1024: POLY: out of memory\n"); #endif - if (x) - free(x); - if (y) - free(y); - return; + if (x) + free(x); + if (y) + free(y); + return; } while (parsing) { - if (! pgc_param_byte(pgc, &count)) { - if (x) - free(x); - if (y) - free(y); - return; - } + if (!pgc_param_byte(pgc, &count)) { + if (x) + free(x); + if (y) + free(y); + return; + } - if (count + realcount >= as) { - nx = (int32_t *)realloc(x, 2 * as * sizeof(int32_t)); - ny = (int32_t *)realloc(y, 2 * as * sizeof(int32_t)); - if (!x || !y) { + if (count + realcount >= as) { + nx = (int32_t *) realloc(x, 2 * as * sizeof(int32_t)); + ny = (int32_t *) realloc(y, 2 * as * sizeof(int32_t)); + if (!x || !y) { #ifdef ENABLE_IM1024_LOG - im1024_log("IM1024: poly: realloc failed\n"); + im1024_log("IM1024: poly: realloc failed\n"); #endif - break; - } - x = nx; - y = ny; - as *= 2; - } + break; + } + x = nx; + y = ny; + as *= 2; + } - for (n = 0; n < count; n++) { - if (! pgc_param_word(pgc, &xw)) { - if (x) - free(x); - if (y) - free(y); - return; - } - if (! pgc_param_word(pgc, &yw)) { - if (x) - free(x); - if (y) - free(y); - return; - } + for (n = 0; n < count; n++) { + if (!pgc_param_word(pgc, &xw)) { + if (x) + free(x); + if (y) + free(y); + return; + } + if (!pgc_param_word(pgc, &yw)) { + if (x) + free(x); + if (y) + free(y); + return; + } - /* Skip degenerate line segments. */ - if (realcount > 0 && - (xw << 16) == x[realcount - 1] && - (yw << 16) == y[realcount - 1]) continue; + /* Skip degenerate line segments. */ + if (realcount > 0 && (xw << 16) == x[realcount - 1] && (yw << 16) == y[realcount - 1]) + continue; - x[realcount] = xw << 16; - y[realcount] = yw << 16; - realcount++; - } + x[realcount] = xw << 16; + y[realcount] = yw << 16; + realcount++; + } - /* - * If we are in a command list, peek ahead to see if the next - * command is also POLY. If so, that's a continuation of this - * polygon! - */ - parsing = 0; - if (pgc->clcur && (pgc->clcur->rdptr+1) < pgc->clcur->wrptr && - pgc->clcur->list[pgc->clcur->rdptr] == 0x30) { + /* + * If we are in a command list, peek ahead to see if the next + * command is also POLY. If so, that's a continuation of this + * polygon! + */ + parsing = 0; + if (pgc->clcur && (pgc->clcur->rdptr + 1) < pgc->clcur->wrptr && pgc->clcur->list[pgc->clcur->rdptr] == 0x30) { #ifdef ENABLE_IM1024_LOG - im1024_log("IM1024: POLY continues!\n"); + im1024_log("IM1024: POLY continues!\n"); #endif - parsing = 1; + parsing = 1; - /* Swallow the POLY. */ - pgc->clcur->rdptr++; - } + /* Swallow the POLY. */ + pgc->clcur->rdptr++; + } }; im1024_log("IM1024: POLY (%i) fill_mode=%i\n", realcount, pgc->fill_mode); #ifdef ENABLE_IM1024_LOG for (n = 0; n < realcount; n++) { - im1024_log(" (%i,%i)\n", x[n] >> 16, y[n] >> 16); + im1024_log(" (%i,%i)\n", x[n] >> 16, y[n] >> 16); } #endif if (pgc->fill_mode) - pgc_fill_polygon(pgc, realcount, x, y); + pgc_fill_polygon(pgc, realcount, x, y); /* Now draw borders. */ mask = pgc->line_pattern; for (n = 1; n < realcount; n++) - mask = pgc_draw_line(pgc, x[n - 1], y[n - 1], x[n], y[n], mask); + mask = pgc_draw_line(pgc, x[n - 1], y[n - 1], x[n], y[n], mask); pgc_draw_line(pgc, x[realcount - 1], y[realcount - 1], x[0], y[0], mask); free(y); free(x); } - static int parse_poly(pgc_t *pgc, pgc_cl_t *cl, int c) { @@ -627,12 +627,13 @@ parse_poly(pgc_t *pgc, pgc_cl_t *cl, int c) im1024_log("IM1024: parse_poly\n"); #endif - if (! pgc_param_byte(pgc, &count)) return 0; + if (!pgc_param_byte(pgc, &count)) + return 0; im1024_log("IM1024: parse_poly: count=%02x\n", count); - if (! pgc_cl_append(cl, count)) { - pgc_error(pgc, PGC_ERROR_OVERFLOW); - return 0; + if (!pgc_cl_append(cl, count)) { + pgc_error(pgc, PGC_ERROR_OVERFLOW); + return 0; } im1024_log("IM1024: parse_poly: parse %i words\n", 2 * count); @@ -640,7 +641,6 @@ parse_poly(pgc_t *pgc, pgc_cl_t *cl, int c) return pgc_parse_words(pgc, cl, count * 2); } - /* * Override the PGC RECT command to parse its * parameters as words rather than coordinates. @@ -653,31 +653,40 @@ hndl_rect(pgc_t *pgc) x0 = pgc->x >> 16; y0 = pgc->y >> 16; - if (! pgc_param_word(pgc, &x1)) return; - if (! pgc_param_word(pgc, &y1)) return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &y1)) + return; /* Convert to raster coords. */ pgc_sto_raster(pgc, &x0, &y0); pgc_sto_raster(pgc, &x1, &y1); - if (x0 > x1) { p = x0; x0 = x1; x1 = p; } - if (y0 > y1) { q = y0; y0 = y1; y1 = q; } + if (x0 > x1) { + p = x0; + x0 = x1; + x1 = p; + } + if (y0 > y1) { + q = y0; + y0 = y1; + y1 = q; + } im1024_log("IM1024: RECT (%i,%i) -> (%i,%i)\n", x0, y0, x1, y1); if (pgc->fill_mode) { - for (p = y0; p <= y1; p++) - pgc_fill_line_r(pgc, x0, x1, p); + for (p = y0; p <= y1; p++) + pgc_fill_line_r(pgc, x0, x1, p); } else { - /* Outline: 4 lines. */ - p = pgc->line_pattern; - p = pgc_draw_line_r(pgc, x0, y0, x1, y0, p); - p = pgc_draw_line_r(pgc, x1, y0, x1, y1, p); - p = pgc_draw_line_r(pgc, x1, y1, x0, y1, p); - p = pgc_draw_line_r(pgc, x0, y1, x0, y0, p); + /* Outline: 4 lines. */ + p = pgc->line_pattern; + p = pgc_draw_line_r(pgc, x0, y0, x1, y0, p); + p = pgc_draw_line_r(pgc, x1, y0, x1, y1, p); + p = pgc_draw_line_r(pgc, x1, y1, x0, y1, p); + p = pgc_draw_line_r(pgc, x0, y1, x0, y0, p); } } - /* * FIXME: * Define a font character. @@ -688,57 +697,62 @@ hndl_rect(pgc_t *pgc) static void hndl_tdefin(pgc_t *pgc) { - im1024_t *dev = (im1024_t *)pgc; - uint8_t ch, bt; - uint8_t rows, cols; - unsigned len, n; + im1024_t *dev = (im1024_t *) pgc; + uint8_t ch, bt; + uint8_t rows, cols; + unsigned len, n; - if (! pgc_param_byte(pgc, &ch)) return; - if (! pgc_param_byte(pgc, &cols)) return; - if (! pgc_param_byte(pgc, &rows)) return; + if (!pgc_param_byte(pgc, &ch)) + return; + if (!pgc_param_byte(pgc, &cols)) + return; + if (!pgc_param_byte(pgc, &rows)) + return; im1024_log("IM1024: TDEFIN (%i,%i,%i) 0x%02x 0x%02x\n", - ch, rows, cols, pgc->mapram[0x300], pgc->mapram[0x301]); + ch, rows, cols, pgc->mapram[0x300], pgc->mapram[0x301]); len = ((cols + 7) / 8) * rows; for (n = 0; n < len; n++) { - if (! pgc_param_byte(pgc, &bt)) return; + if (!pgc_param_byte(pgc, &bt)) + return; - if (n < sizeof(dev->font[ch])) - dev->font[ch][n] = bt; + if (n < sizeof(dev->font[ch])) + dev->font[ch][n] = bt; } dev->fontx[ch] = cols; dev->fonty[ch] = rows; } - static void hndl_tsize(pgc_t *pgc) { int16_t size; - if (!pgc_param_word(pgc, &size)) return; + if (!pgc_param_word(pgc, &size)) + return; im1024_log("IM1024: TSIZE(%i)\n", size); pgc->tsize = size << 16; } - static void hndl_twrite(pgc_t *pgc) { - uint8_t buf[256]; - im1024_t *dev = (im1024_t *)pgc; - uint8_t count, mask, *row; - int x, y, wb, n; - int16_t x0 = pgc->x >> 16; - int16_t y0 = pgc->y >> 16; + uint8_t buf[256]; + im1024_t *dev = (im1024_t *) pgc; + uint8_t count, mask, *row; + int x, y, wb, n; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; - if (! pgc_param_byte(pgc, &count)) return; + if (!pgc_param_byte(pgc, &count)) + return; for (n = 0; n < count; n++) - if (! pgc_param_byte(pgc, &buf[n])) return; + if (!pgc_param_byte(pgc, &buf[n])) + return; buf[count] = 0; pgc_sto_raster(pgc, &x0, &y0); @@ -746,43 +760,44 @@ hndl_twrite(pgc_t *pgc) im1024_log("IM1024: TWRITE (%i) x0=%i y0=%i\n", count, x0, y0); for (n = 0; n < count; n++) { - wb = (dev->fontx[buf[n]] + 7) / 8; - im1024_log("IM1024: ch=0x%02x w=%i h=%i wb=%i\n", - buf[n], dev->fontx[buf[n]], dev->fonty[buf[n]], wb); + wb = (dev->fontx[buf[n]] + 7) / 8; + im1024_log("IM1024: ch=0x%02x w=%i h=%i wb=%i\n", + buf[n], dev->fontx[buf[n]], dev->fonty[buf[n]], wb); - for (y = 0; y < dev->fonty[buf[n]]; y++) { - mask = 0x80; - row = &dev->font[buf[n]][y * wb]; - for (x = 0; x < dev->fontx[buf[n]]; x++) { - if (row[0] & mask) - pgc_plot(pgc, x + x0, y0 - y); - mask = mask >> 1; - if (mask == 0) { - mask = 0x80; - row++; - } - } - } + for (y = 0; y < dev->fonty[buf[n]]; y++) { + mask = 0x80; + row = &dev->font[buf[n]][y * wb]; + for (x = 0; x < dev->fontx[buf[n]]; x++) { + if (row[0] & mask) + pgc_plot(pgc, x + x0, y0 - y); + mask = mask >> 1; + if (mask == 0) { + mask = 0x80; + row++; + } + } + } - x0 += dev->fontx[buf[n]]; + x0 += dev->fontx[buf[n]]; } } - static void hndl_txt88(pgc_t *pgc) { - uint8_t buf[256]; - uint8_t count, mask, *row; - int16_t x0 = pgc->x >> 16; - int16_t y0 = pgc->y >> 16; + uint8_t buf[256]; + uint8_t count, mask, *row; + int16_t x0 = pgc->x >> 16; + int16_t y0 = pgc->y >> 16; unsigned n; - int x, y; + int x, y; - if (! pgc_param_byte(pgc, &count)) return; + if (!pgc_param_byte(pgc, &count)) + return; for (n = 0; n < count; n++) - if (! pgc_param_byte(pgc, &buf[n])) return; + if (!pgc_param_byte(pgc, &buf[n])) + return; buf[count] = 0; pgc_sto_raster(pgc, &x0, &y0); @@ -790,26 +805,26 @@ hndl_txt88(pgc_t *pgc) im1024_log("IM204: TXT88 (%i) x0=%i y0=%i\n", count, x0, y0); for (n = 0; n < count; n++) { - im1024_log("ch=0x%02x w=12 h=18\n", buf[n]); + im1024_log("ch=0x%02x w=12 h=18\n", buf[n]); - for (y = 0; y < 18; y++) { - mask = 0x80; - row = &fontdat12x18[buf[n]][y * 2]; - for (x = 0; x < 12; x++) { - if (row[0] & mask) pgc_plot(pgc, x + x0, y0 - y); - mask = mask >> 1; - if (mask == 0) { - mask = 0x80; - row++; - } - } - } + for (y = 0; y < 18; y++) { + mask = 0x80; + row = &fontdat12x18[buf[n]][y * 2]; + for (x = 0; x < 12; x++) { + if (row[0] & mask) + pgc_plot(pgc, x + x0, y0 - y); + mask = mask >> 1; + if (mask == 0) { + mask = 0x80; + row++; + } + } + } - x0 += 12; + x0 += 12; } } - static void hndl_imagew(pgc_t *pgc) { @@ -817,9 +832,12 @@ hndl_imagew(pgc_t *pgc) int16_t row1, col1, col2; uint8_t v1, v2; - if (! pgc_param_word(pgc, &row1)) return; - if (! pgc_param_word(pgc, &col1)) return; - if (! pgc_param_word(pgc, &col2)) return; + if (!pgc_param_word(pgc, &row1)) + return; + if (!pgc_param_word(pgc, &col1)) + return; + if (!pgc_param_word(pgc, &col2)) + return; /* Already using raster coordinates, no need to convert. */ im1024_log("IM1024: IMAGEW (row=%i,col1=%i,col2=%i)\n", row1, col1, col2); @@ -837,39 +855,42 @@ hndl_imagew(pgc_t *pgc) /* In ASCII mode, what is written is a stream of bytes. */ if (pgc->ascii_mode) { - while (col1 <= col2) { - if (! pgc_param_byte(pgc, &v1)) - return; + while (col1 <= col2) { + if (!pgc_param_byte(pgc, &v1)) + return; - pgc_write_pixel(pgc, col1, row1, v1); - col1++; - } + pgc_write_pixel(pgc, col1, row1, v1); + col1++; + } } else { - /* In hex mode, it's RLE compressed. */ - while (col1 <= col2) { - if (! pgc_param_byte(pgc, &v1)) return; + /* In hex mode, it's RLE compressed. */ + while (col1 <= col2) { + if (!pgc_param_byte(pgc, &v1)) + return; - if (v1 & 0x80) { - /* Literal run. */ - v1 -= 0x7f; - while (col1 <= col2 && v1 != 0) { - if (! pgc_param_byte(pgc, &v2)) return; - pgc_write_pixel(pgc, col1, row1, v2); - col1++; - v1--; - } - } else { - /* Repeated run. */ - if (! pgc_param_byte(pgc, &v2)) return; + if (v1 & 0x80) { + /* Literal run. */ + v1 -= 0x7f; + while (col1 <= col2 && v1 != 0) { + if (!pgc_param_byte(pgc, &v2)) + return; + pgc_write_pixel(pgc, col1, row1, v2); + col1++; + v1--; + } + } else { + /* Repeated run. */ + if (!pgc_param_byte(pgc, &v2)) + return; - v1++; - while (col1 <= col2 && v1 != 0) { - pgc_write_pixel(pgc, col1, row1, v2); - col1++; - v1--; - } - } - } + v1++; + while (col1 <= col2 && v1 != 0) { + pgc_write_pixel(pgc, col1, row1, v2); + col1++; + v1--; + } + } + } } /* Restore clipping. */ @@ -879,7 +900,6 @@ hndl_imagew(pgc_t *pgc) pgc->vp_y2 = vp_y2; } - /* * I have called this command DOT - I don't know its proper name. * @@ -889,17 +909,16 @@ static void hndl_dot(pgc_t *pgc) { int16_t x = pgc->x >> 16, - y = pgc->y >> 16; + y = pgc->y >> 16; pgc_sto_raster(pgc, &x, &y); im1024_log("IM1024: DOT @ %i,%i ink=%i mode=%i\n", - x, y, pgc->color, pgc->draw_mode); + x, y, pgc->color, pgc->draw_mode); pgc_plot(pgc, x, y); } - /* * This command (which I have called IMAGEX, since I don't know its real * name) is a screen-to-memory blit. It reads a rectangle of bytes, rather @@ -910,25 +929,28 @@ static void hndl_imagex(pgc_t *pgc) { int16_t x0, x1, y0, y1; - int16_t p,q; + int16_t p, q; - if (! pgc_param_word(pgc, &x0)) return; - if (! pgc_param_word(pgc, &y0)) return; - if (! pgc_param_word(pgc, &x1)) return; - if (! pgc_param_word(pgc, &y1)) return; + if (!pgc_param_word(pgc, &x0)) + return; + if (!pgc_param_word(pgc, &y0)) + return; + if (!pgc_param_word(pgc, &x1)) + return; + if (!pgc_param_word(pgc, &y1)) + return; /* Already using raster coordinates, no need to convert. */ - im1024_log("IM1024: IMAGEX (%i,%i,%i,%i)\n", x0,y0,x1,y1); + im1024_log("IM1024: IMAGEX (%i,%i,%i,%i)\n", x0, y0, x1, y1); for (p = y0; p <= y1; p++) { - for (q = x0; q <= x1; q++) { - if (! pgc_result_byte(pgc, pgc_read_pixel(pgc, q, p))) - return; - } + for (q = x0; q <= x1; q++) { + if (!pgc_result_byte(pgc, pgc_read_pixel(pgc, q, p))) + return; + } } } - /* * Commands implemented by the IM-1024. * @@ -938,108 +960,103 @@ hndl_imagex(pgc_t *pgc) * does not use them. */ static const pgc_cmd_t im1024_commands[] = { - { "BLKMOV", 0xdf, hndl_blkmov, pgc_parse_words, 6 }, - { "DRAW", 0x28, hndl_draw, pgc_parse_words, 2 }, - { "D", 0x28, hndl_draw, pgc_parse_words, 2 }, - { "DOT", 0x08, hndl_dot, NULL, 0 }, - { "ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2 }, - { "EL", 0x39, hndl_ellipse, pgc_parse_words, 2 }, - { "IMAGEW", 0xd9, hndl_imagew, NULL, 0 }, - { "IMAGEX", 0xda, hndl_imagex, NULL, 0 }, - { "IMGSIZ", 0x4e, hndl_imgsiz, NULL, 0 }, - { "IPREC", 0xe4, hndl_iprec, NULL, 0 }, - { "IW", 0xd9, hndl_imagew, NULL, 0 }, - { "L8", 0xe6, pgc_hndl_lut8, NULL, 0 }, - { "LF", 0xeb, hndl_linfun, pgc_parse_bytes, 1 }, - { "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 }, - { "LUT8", 0xe6, pgc_hndl_lut8, NULL, 0 }, - { "LUT8RD", 0x53, pgc_hndl_lut8rd,NULL, 0 }, - { "L8RD", 0x53, pgc_hndl_lut8rd,NULL, 0 }, - { "TDEFIN", 0x84, hndl_tdefin, NULL, 0 }, - { "TD", 0x84, hndl_tdefin, NULL, 0 }, - { "TSIZE", 0x81, hndl_tsize, NULL, 0 }, - { "TS", 0x81, hndl_tsize, NULL, 0 }, - { "TWRITE", 0x8b, hndl_twrite, NULL, 0 }, - { "TXT88", 0x88, hndl_txt88, NULL, 0 }, - { "PAN", 0xb7, hndl_pan, NULL, 0 }, - { "POLY", 0x30, hndl_poly, parse_poly, 0 }, - { "P", 0x30, hndl_poly, parse_poly, 0 }, - { "PLINE", 0x36, hndl_pline, NULL, 0 }, - { "PL", 0x37, hndl_pline, NULL, 0 }, - { "MOVE", 0x10, hndl_move, pgc_parse_words, 2 }, - { "M", 0x10, hndl_move, pgc_parse_words, 2 }, - { "RECT", 0x34, hndl_rect, NULL, 0 }, - { "R", 0x34, hndl_rect, NULL, 0 }, - { "******", 0x00, NULL, NULL, 0 } + {"BLKMOV", 0xdf, hndl_blkmov, pgc_parse_words, 6}, + { "DRAW", 0x28, hndl_draw, pgc_parse_words, 2}, + { "D", 0x28, hndl_draw, pgc_parse_words, 2}, + { "DOT", 0x08, hndl_dot, NULL, 0}, + { "ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2}, + { "EL", 0x39, hndl_ellipse, pgc_parse_words, 2}, + { "IMAGEW", 0xd9, hndl_imagew, NULL, 0}, + { "IMAGEX", 0xda, hndl_imagex, NULL, 0}, + { "IMGSIZ", 0x4e, hndl_imgsiz, NULL, 0}, + { "IPREC", 0xe4, hndl_iprec, NULL, 0}, + { "IW", 0xd9, hndl_imagew, NULL, 0}, + { "L8", 0xe6, pgc_hndl_lut8, NULL, 0}, + { "LF", 0xeb, hndl_linfun, pgc_parse_bytes, 1}, + { "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1}, + { "LUT8", 0xe6, pgc_hndl_lut8, NULL, 0}, + { "LUT8RD", 0x53, pgc_hndl_lut8rd, NULL, 0}, + { "L8RD", 0x53, pgc_hndl_lut8rd, NULL, 0}, + { "TDEFIN", 0x84, hndl_tdefin, NULL, 0}, + { "TD", 0x84, hndl_tdefin, NULL, 0}, + { "TSIZE", 0x81, hndl_tsize, NULL, 0}, + { "TS", 0x81, hndl_tsize, NULL, 0}, + { "TWRITE", 0x8b, hndl_twrite, NULL, 0}, + { "TXT88", 0x88, hndl_txt88, NULL, 0}, + { "PAN", 0xb7, hndl_pan, NULL, 0}, + { "POLY", 0x30, hndl_poly, parse_poly, 0}, + { "P", 0x30, hndl_poly, parse_poly, 0}, + { "PLINE", 0x36, hndl_pline, NULL, 0}, + { "PL", 0x37, hndl_pline, NULL, 0}, + { "MOVE", 0x10, hndl_move, pgc_parse_words, 2}, + { "M", 0x10, hndl_move, pgc_parse_words, 2}, + { "RECT", 0x34, hndl_rect, NULL, 0}, + { "R", 0x34, hndl_rect, NULL, 0}, + { "******", 0x00, NULL, NULL, 0} }; - static void * im1024_init(const device_t *info) { im1024_t *dev; - dev = (im1024_t *)malloc(sizeof(im1024_t)); + dev = (im1024_t *) malloc(sizeof(im1024_t)); memset(dev, 0x00, sizeof(im1024_t)); loadfont(BIOS_ROM_PATH, 9); - dev->fifo_len = 4096; - dev->fifo = (uint8_t *)malloc(dev->fifo_len); + dev->fifo_len = 4096; + dev->fifo = (uint8_t *) malloc(dev->fifo_len); dev->fifo_wrptr = 0; dev->fifo_rdptr = 0; /* Create a 1024x1024 framebuffer with 1024x800 visible. */ - pgc_init(&dev->pgc, 1024, 1024, 1024, 800, input_byte, 65000000.0); + pgc_init(&dev->pgc, 1024, 1024, 1024, 800, input_byte, 65000000.0); dev->pgc.commands = im1024_commands; mem_mapping_set_handler(&dev->pgc.mapping, - im1024_read,NULL,NULL, im1024_write,NULL,NULL); + im1024_read, NULL, NULL, im1024_write, NULL, NULL); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_im1024); - return(dev); + return (dev); } - static void im1024_close(void *priv) { - im1024_t *dev = (im1024_t *)priv; + im1024_t *dev = (im1024_t *) priv; pgc_close_common(&dev->pgc); free(dev); } - static int im1024_available() { return rom_present(BIOS_ROM_PATH); } - static void im1024_speed_changed(void *priv) { - im1024_t *dev = (im1024_t *)priv; + im1024_t *dev = (im1024_t *) priv; pgc_speed_changed(&dev->pgc); } - const device_t im1024_device = { - .name = "ImageManager 1024", + .name = "ImageManager 1024", .internal_name = "im1024", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = im1024_init, - .close = im1024_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = im1024_init, + .close = im1024_close, + .reset = NULL, { .available = im1024_available }, .speed_changed = im1024_speed_changed, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_incolor.c b/src/video/vid_incolor.c index d44321863..6bf98ab86 100644 --- a/src/video/vid_incolor.c +++ b/src/video/vid_incolor.c @@ -31,10 +31,9 @@ #include <86box/device.h> #include <86box/video.h> - /* extended CRTC registers */ #define INCOLOR_CRTC_XMODE 20 /* xMode register */ -#define INCOLOR_CRTC_UNDER 21 /* Underline */ +#define INCOLOR_CRTC_UNDER 21 /* Underline */ #define INCOLOR_CRTC_OVER 22 /* Overstrike */ #define INCOLOR_CRTC_EXCEPT 23 /* Exception */ #define INCOLOR_CRTC_MASK 24 /* Plane display mask & write mask */ @@ -44,20 +43,20 @@ #define INCOLOR_CRTC_PALETTE 28 /* Palette */ /* character width */ -#define INCOLOR_CW ((dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) ? 8 : 9) +#define INCOLOR_CW ((dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) ? 8 : 9) /* mode control register */ -#define INCOLOR_CTRL_GRAPH 0x02 -#define INCOLOR_CTRL_ENABLE 0x08 -#define INCOLOR_CTRL_BLINK 0x20 -#define INCOLOR_CTRL_PAGE1 0x80 +#define INCOLOR_CTRL_GRAPH 0x02 +#define INCOLOR_CTRL_ENABLE 0x08 +#define INCOLOR_CTRL_BLINK 0x20 +#define INCOLOR_CTRL_PAGE1 0x80 /* CRTC status register */ -#define INCOLOR_STATUS_HSYNC 0x01 /* horizontal sync */ +#define INCOLOR_STATUS_HSYNC 0x01 /* horizontal sync */ #define INCOLOR_STATUS_LIGHT 0x02 #define INCOLOR_STATUS_VIDEO 0x08 -#define INCOLOR_STATUS_ID 0x50 /* Card identification */ -#define INCOLOR_STATUS_VSYNC 0x80 /* -vertical sync */ +#define INCOLOR_STATUS_ID 0x50 /* Card identification */ +#define INCOLOR_STATUS_VSYNC 0x80 /* -vertical sync */ /* configuration switch register */ #define INCOLOR_CTRL2_GRAPH 0x01 @@ -67,17 +66,14 @@ #define INCOLOR_XMODE_RAMFONT 0x01 #define INCOLOR_XMODE_90COL 0x02 - /* Read/write control */ #define INCOLOR_RWCTRL_WRMODE 0x30 #define INCOLOR_RWCTRL_POLARITY 0x40 /* exception register */ -#define INCOLOR_EXCEPT_CURSOR 0x0F /* Cursor colour */ -#define INCOLOR_EXCEPT_PALETTE 0x10 /* Enable palette register */ -#define INCOLOR_EXCEPT_ALTATTR 0x20 /* Use alternate attributes */ - - +#define INCOLOR_EXCEPT_CURSOR 0x0F /* Cursor colour */ +#define INCOLOR_EXCEPT_PALETTE 0x10 /* Enable palette register */ +#define INCOLOR_EXCEPT_ALTATTR 0x20 /* Use alternate attributes */ /* Default palette */ static const uint8_t defpal[16] = { @@ -87,106 +83,104 @@ static const uint8_t defpal[16] = { /* Mapping of inks to RGB */ static const uint8_t init_rgb[64][3] = { - /* rgbRGB */ - { 0x00, 0x00, 0x00 }, /* 000000 */ - { 0x00, 0x00, 0xaa }, /* 000001 */ - { 0x00, 0xaa, 0x00 }, /* 000010 */ - { 0x00, 0xaa, 0xaa }, /* 000011 */ - { 0xaa, 0x00, 0x00 }, /* 000100 */ - { 0xaa, 0x00, 0xaa }, /* 000101 */ - { 0xaa, 0xaa, 0x00 }, /* 000110 */ - { 0xaa, 0xaa, 0xaa }, /* 000111 */ - { 0x00, 0x00, 0x55 }, /* 001000 */ - { 0x00, 0x00, 0xff }, /* 001001 */ - { 0x00, 0xaa, 0x55 }, /* 001010 */ - { 0x00, 0xaa, 0xff }, /* 001011 */ - { 0xaa, 0x00, 0x55 }, /* 001100 */ - { 0xaa, 0x00, 0xff }, /* 001101 */ - { 0xaa, 0xaa, 0x55 }, /* 001110 */ - { 0xaa, 0xaa, 0xff }, /* 001111 */ - { 0x00, 0x55, 0x00 }, /* 010000 */ - { 0x00, 0x55, 0xaa }, /* 010001 */ - { 0x00, 0xff, 0x00 }, /* 010010 */ - { 0x00, 0xff, 0xaa }, /* 010011 */ - { 0xaa, 0x55, 0x00 }, /* 010100 */ - { 0xaa, 0x55, 0xaa }, /* 010101 */ - { 0xaa, 0xff, 0x00 }, /* 010110 */ - { 0xaa, 0xff, 0xaa }, /* 010111 */ - { 0x00, 0x55, 0x55 }, /* 011000 */ - { 0x00, 0x55, 0xff }, /* 011001 */ - { 0x00, 0xff, 0x55 }, /* 011010 */ - { 0x00, 0xff, 0xff }, /* 011011 */ - { 0xaa, 0x55, 0x55 }, /* 011100 */ - { 0xaa, 0x55, 0xff }, /* 011101 */ - { 0xaa, 0xff, 0x55 }, /* 011110 */ - { 0xaa, 0xff, 0xff }, /* 011111 */ - { 0x55, 0x00, 0x00 }, /* 100000 */ - { 0x55, 0x00, 0xaa }, /* 100001 */ - { 0x55, 0xaa, 0x00 }, /* 100010 */ - { 0x55, 0xaa, 0xaa }, /* 100011 */ - { 0xff, 0x00, 0x00 }, /* 100100 */ - { 0xff, 0x00, 0xaa }, /* 100101 */ - { 0xff, 0xaa, 0x00 }, /* 100110 */ - { 0xff, 0xaa, 0xaa }, /* 100111 */ - { 0x55, 0x00, 0x55 }, /* 101000 */ - { 0x55, 0x00, 0xff }, /* 101001 */ - { 0x55, 0xaa, 0x55 }, /* 101010 */ - { 0x55, 0xaa, 0xff }, /* 101011 */ - { 0xff, 0x00, 0x55 }, /* 101100 */ - { 0xff, 0x00, 0xff }, /* 101101 */ - { 0xff, 0xaa, 0x55 }, /* 101110 */ - { 0xff, 0xaa, 0xff }, /* 101111 */ - { 0x55, 0x55, 0x00 }, /* 110000 */ - { 0x55, 0x55, 0xaa }, /* 110001 */ - { 0x55, 0xff, 0x00 }, /* 110010 */ - { 0x55, 0xff, 0xaa }, /* 110011 */ - { 0xff, 0x55, 0x00 }, /* 110100 */ - { 0xff, 0x55, 0xaa }, /* 110101 */ - { 0xff, 0xff, 0x00 }, /* 110110 */ - { 0xff, 0xff, 0xaa }, /* 110111 */ - { 0x55, 0x55, 0x55 }, /* 111000 */ - { 0x55, 0x55, 0xff }, /* 111001 */ - { 0x55, 0xff, 0x55 }, /* 111010 */ - { 0x55, 0xff, 0xff }, /* 111011 */ - { 0xff, 0x55, 0x55 }, /* 111100 */ - { 0xff, 0x55, 0xff }, /* 111101 */ - { 0xff, 0xff, 0x55 }, /* 111110 */ - { 0xff, 0xff, 0xff }, /* 111111 */ + /* rgbRGB */ + {0x00, 0x00, 0x00}, /* 000000 */ + { 0x00, 0x00, 0xaa}, /* 000001 */ + { 0x00, 0xaa, 0x00}, /* 000010 */ + { 0x00, 0xaa, 0xaa}, /* 000011 */ + { 0xaa, 0x00, 0x00}, /* 000100 */ + { 0xaa, 0x00, 0xaa}, /* 000101 */ + { 0xaa, 0xaa, 0x00}, /* 000110 */ + { 0xaa, 0xaa, 0xaa}, /* 000111 */ + { 0x00, 0x00, 0x55}, /* 001000 */ + { 0x00, 0x00, 0xff}, /* 001001 */ + { 0x00, 0xaa, 0x55}, /* 001010 */ + { 0x00, 0xaa, 0xff}, /* 001011 */ + { 0xaa, 0x00, 0x55}, /* 001100 */ + { 0xaa, 0x00, 0xff}, /* 001101 */ + { 0xaa, 0xaa, 0x55}, /* 001110 */ + { 0xaa, 0xaa, 0xff}, /* 001111 */ + { 0x00, 0x55, 0x00}, /* 010000 */ + { 0x00, 0x55, 0xaa}, /* 010001 */ + { 0x00, 0xff, 0x00}, /* 010010 */ + { 0x00, 0xff, 0xaa}, /* 010011 */ + { 0xaa, 0x55, 0x00}, /* 010100 */ + { 0xaa, 0x55, 0xaa}, /* 010101 */ + { 0xaa, 0xff, 0x00}, /* 010110 */ + { 0xaa, 0xff, 0xaa}, /* 010111 */ + { 0x00, 0x55, 0x55}, /* 011000 */ + { 0x00, 0x55, 0xff}, /* 011001 */ + { 0x00, 0xff, 0x55}, /* 011010 */ + { 0x00, 0xff, 0xff}, /* 011011 */ + { 0xaa, 0x55, 0x55}, /* 011100 */ + { 0xaa, 0x55, 0xff}, /* 011101 */ + { 0xaa, 0xff, 0x55}, /* 011110 */ + { 0xaa, 0xff, 0xff}, /* 011111 */ + { 0x55, 0x00, 0x00}, /* 100000 */ + { 0x55, 0x00, 0xaa}, /* 100001 */ + { 0x55, 0xaa, 0x00}, /* 100010 */ + { 0x55, 0xaa, 0xaa}, /* 100011 */ + { 0xff, 0x00, 0x00}, /* 100100 */ + { 0xff, 0x00, 0xaa}, /* 100101 */ + { 0xff, 0xaa, 0x00}, /* 100110 */ + { 0xff, 0xaa, 0xaa}, /* 100111 */ + { 0x55, 0x00, 0x55}, /* 101000 */ + { 0x55, 0x00, 0xff}, /* 101001 */ + { 0x55, 0xaa, 0x55}, /* 101010 */ + { 0x55, 0xaa, 0xff}, /* 101011 */ + { 0xff, 0x00, 0x55}, /* 101100 */ + { 0xff, 0x00, 0xff}, /* 101101 */ + { 0xff, 0xaa, 0x55}, /* 101110 */ + { 0xff, 0xaa, 0xff}, /* 101111 */ + { 0x55, 0x55, 0x00}, /* 110000 */ + { 0x55, 0x55, 0xaa}, /* 110001 */ + { 0x55, 0xff, 0x00}, /* 110010 */ + { 0x55, 0xff, 0xaa}, /* 110011 */ + { 0xff, 0x55, 0x00}, /* 110100 */ + { 0xff, 0x55, 0xaa}, /* 110101 */ + { 0xff, 0xff, 0x00}, /* 110110 */ + { 0xff, 0xff, 0xaa}, /* 110111 */ + { 0x55, 0x55, 0x55}, /* 111000 */ + { 0x55, 0x55, 0xff}, /* 111001 */ + { 0x55, 0xff, 0x55}, /* 111010 */ + { 0x55, 0xff, 0xff}, /* 111011 */ + { 0xff, 0x55, 0x55}, /* 111100 */ + { 0xff, 0x55, 0xff}, /* 111101 */ + { 0xff, 0xff, 0x55}, /* 111110 */ + { 0xff, 0xff, 0xff}, /* 111111 */ }; - typedef struct { - mem_mapping_t mapping; + mem_mapping_t mapping; - uint8_t crtc[32]; - int crtcreg; + uint8_t crtc[32]; + int crtcreg; - uint8_t ctrl, ctrl2, stat; + uint8_t ctrl, ctrl2, stat; - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int firstline, lastline; + int firstline, lastline; - int linepos, displine; - int vc, sc; - uint16_t ma, maback; - int con, coff, cursoron; - int dispon, blink; - int vsynctime; - int vadj; + int linepos, displine; + int vc, sc; + uint16_t ma, maback; + int con, coff, cursoron; + int dispon, blink; + int vsynctime; + int vadj; - uint8_t palette[16]; /* EGA-style 16 -> 64 palette registers */ - uint8_t palette_idx; /* Palette write index */ - uint8_t latch[4]; /* Memory read/write latches */ + uint8_t palette[16]; /* EGA-style 16 -> 64 palette registers */ + uint8_t palette_idx; /* Palette write index */ + uint8_t latch[4]; /* Memory read/write latches */ - uint32_t rgb[64]; + uint32_t rgb[64]; - uint8_t *vram; + uint8_t *vram; } incolor_t; -static video_timings_t timing_incolor = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; - +static video_timings_t timing_incolor = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static void recalc_timings(incolor_t *dev) @@ -194,126 +188,128 @@ recalc_timings(incolor_t *dev) double disptime; double _dispontime, _dispofftime; - disptime = dev->crtc[0] + 1; + disptime = dev->crtc[0] + 1; _dispontime = dev->crtc[1]; _dispofftime = disptime - _dispontime; - _dispontime *= HERCCONST; + _dispontime *= HERCCONST; _dispofftime *= HERCCONST; - dev->dispontime = (uint64_t)(_dispontime); - dev->dispofftime = (uint64_t)(_dispofftime); + dev->dispontime = (uint64_t) (_dispontime); + dev->dispofftime = (uint64_t) (_dispofftime); } - static void incolor_out(uint16_t port, uint8_t val, void *priv) { - incolor_t *dev = (incolor_t *)priv; - uint8_t old; + incolor_t *dev = (incolor_t *) priv; + uint8_t old; switch (port) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - dev->crtcreg = val & 31; - return; + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + dev->crtcreg = val & 31; + return; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - if (dev->crtcreg > 28) return; - /* Palette load register */ - if (dev->crtcreg == INCOLOR_CRTC_PALETTE) { - dev->palette[dev->palette_idx % 16] = val; - ++dev->palette_idx; - } - old = dev->crtc[dev->crtcreg]; - dev->crtc[dev->crtcreg] = val; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + if (dev->crtcreg > 28) + return; + /* Palette load register */ + if (dev->crtcreg == INCOLOR_CRTC_PALETTE) { + dev->palette[dev->palette_idx % 16] = val; + ++dev->palette_idx; + } + old = dev->crtc[dev->crtcreg]; + dev->crtc[dev->crtcreg] = val; - if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { - /*Fix for Generic Turbo XT BIOS, - * which sets up cursor registers wrong*/ - dev->crtc[10] = 0xb; - dev->crtc[11] = 0xc; - } - if (old ^ val) - recalc_timings(dev); - return; + if (dev->crtc[10] == 6 && dev->crtc[11] == 7) { + /*Fix for Generic Turbo XT BIOS, + * which sets up cursor registers wrong*/ + dev->crtc[10] = 0xb; + dev->crtc[11] = 0xc; + } + if (old ^ val) + recalc_timings(dev); + return; - case 0x3b8: - old = dev->ctrl; - dev->ctrl = val; - if (old ^ val) - recalc_timings(dev); - return; + case 0x3b8: + old = dev->ctrl; + dev->ctrl = val; + if (old ^ val) + recalc_timings(dev); + return; - case 0x3bf: - dev->ctrl2 = val; - if (val & 2) - mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); - return; + case 0x3bf: + dev->ctrl2 = val; + if (val & 2) + mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000); + else + mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000); + return; } } - static uint8_t incolor_in(uint16_t port, void *priv) { - incolor_t *dev = (incolor_t *)priv; - uint8_t ret = 0xff; + incolor_t *dev = (incolor_t *) priv; + uint8_t ret = 0xff; switch (port) { - case 0x3b0: - case 0x3b2: - case 0x3b4: - case 0x3b6: - ret = dev->crtcreg; - break; + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + ret = dev->crtcreg; + break; - case 0x3b1: - case 0x3b3: - case 0x3b5: - case 0x3b7: - if (dev->crtcreg > 28) break; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + if (dev->crtcreg > 28) + break; - dev->palette_idx = 0; /* Read resets the palette index */ - ret = dev->crtc[dev->crtcreg]; - break; + dev->palette_idx = 0; /* Read resets the palette index */ + ret = dev->crtc[dev->crtcreg]; + break; - case 0x3ba: - /* 0x50: InColor card identity */ - ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x50; - break; + case 0x3ba: + /* 0x50: InColor card identity */ + ret = (dev->stat & 0xf) | ((dev->stat & 8) << 4) | 0x50; + break; - default: - break; + default: + break; } return ret; } - static void incolor_write(uint32_t addr, uint8_t val, void *priv) { - incolor_t *dev = (incolor_t *)priv; + incolor_t *dev = (incolor_t *) priv; unsigned char wmask = dev->crtc[INCOLOR_CRTC_MASK]; unsigned char wmode = dev->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_WRMODE; - unsigned char fg = dev->crtc[INCOLOR_CRTC_RWCOL] & 0x0F; - unsigned char bg = (dev->crtc[INCOLOR_CRTC_RWCOL] >> 4)&0x0F; - unsigned char w = 0; - unsigned char vmask; /* Mask of bit within byte */ - unsigned char pmask; /* Mask of plane within colour value */ + unsigned char fg = dev->crtc[INCOLOR_CRTC_RWCOL] & 0x0F; + unsigned char bg = (dev->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; + unsigned char w = 0; + unsigned char vmask; /* Mask of bit within byte */ + unsigned char pmask; /* Mask of plane within colour value */ unsigned char latch; - int plane; + int plane; addr &= 0xffff; /* In text mode, writes to the bottom 16k always touch all 4 planes */ if (!(dev->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) { - dev->vram[addr] = val; - return; + dev->vram[addr] = val; + return; } /* There are four write modes: @@ -324,51 +320,60 @@ incolor_write(uint32_t addr, uint8_t val, void *priv) */ pmask = 1; for (plane = 0; plane < 4; pmask <<= 1, wmask >>= 1, addr += 0x10000, plane++) { - if (wmask & 0x10) /* Ignore writes to selected plane */ - { - continue; - } - latch = dev->latch[plane]; - for (vmask = 0x80; vmask != 0; vmask >>= 1) { - switch (wmode) { - case 0x00: - if (val & vmask) w = (fg & pmask); - else w = (bg & pmask); - break; + if (wmask & 0x10) /* Ignore writes to selected plane */ + { + continue; + } + latch = dev->latch[plane]; + for (vmask = 0x80; vmask != 0; vmask >>= 1) { + switch (wmode) { + case 0x00: + if (val & vmask) + w = (fg & pmask); + else + w = (bg & pmask); + break; - case 0x10: - if (val & vmask) w = (fg & pmask); - else w = (latch & vmask); - break; + case 0x10: + if (val & vmask) + w = (fg & pmask); + else + w = (latch & vmask); + break; - case 0x20: - if (val & vmask) w = (latch & vmask); - else w = (bg & pmask); - break; + case 0x20: + if (val & vmask) + w = (latch & vmask); + else + w = (bg & pmask); + break; - case 0x30: - if (val & vmask) w = (latch & vmask); - else w = ((~latch) & vmask); - break; - } + case 0x30: + if (val & vmask) + w = (latch & vmask); + else + w = ((~latch) & vmask); + break; + } - /* w is nonzero to write a 1, zero to write a 0 */ - if (w) dev->vram[addr] |= vmask; - else dev->vram[addr] &= ~vmask; - } + /* w is nonzero to write a 1, zero to write a 0 */ + if (w) + dev->vram[addr] |= vmask; + else + dev->vram[addr] &= ~vmask; + } } } - static uint8_t incolor_read(uint32_t addr, void *priv) { - incolor_t *dev = (incolor_t *)priv; - unsigned plane; - unsigned char lp = dev->crtc[INCOLOR_CRTC_PROTECT]; + incolor_t *dev = (incolor_t *) priv; + unsigned plane; + unsigned char lp = dev->crtc[INCOLOR_CRTC_PROTECT]; unsigned char value = 0; - unsigned char dc; /* "don't care" register */ - unsigned char bg; /* background colour */ + unsigned char dc; /* "don't care" register */ + unsigned char bg; /* background colour */ unsigned char fg; unsigned char mask, pmask; @@ -376,687 +381,613 @@ incolor_read(uint32_t addr, void *priv) /* Read the four planes into latches */ for (plane = 0; plane < 4; plane++, addr += 0x10000) { - dev->latch[plane] &= lp; - dev->latch[plane] |= (dev->vram[addr] & ~lp); + dev->latch[plane] &= lp; + dev->latch[plane] |= (dev->vram[addr] & ~lp); } addr &= 0xffff; /* In text mode, reads from the bottom 16k assume all planes have * the same contents */ if (!(dev->ctrl & INCOLOR_CTRL_GRAPH) && addr < 0x4000) { - return dev->latch[0]; + return dev->latch[0]; } /* For each pixel, work out if its colour matches the background */ for (mask = 0x80; mask != 0; mask >>= 1) { - fg = 0; - dc = dev->crtc[INCOLOR_CRTC_RWCTRL] & 0x0F; - bg = (dev->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; - for (plane = 0, pmask = 1; plane < 4; plane++, pmask <<= 1) { - if (dc & pmask) { - fg |= (bg & pmask); - } else if (dev->latch[plane] & mask) { - fg |= pmask; - } - } - if (bg == fg) value |= mask; + fg = 0; + dc = dev->crtc[INCOLOR_CRTC_RWCTRL] & 0x0F; + bg = (dev->crtc[INCOLOR_CRTC_RWCOL] >> 4) & 0x0F; + for (plane = 0, pmask = 1; plane < 4; plane++, pmask <<= 1) { + if (dc & pmask) { + fg |= (bg & pmask); + } else if (dev->latch[plane] & mask) { + fg |= pmask; + } + } + if (bg == fg) + value |= mask; } if (dev->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_POLARITY) - value = ~value; + value = ~value; return value; } - static void draw_char_rom(incolor_t *dev, int x, uint8_t chr, uint8_t attr) { - int i; - int elg, blk; - unsigned ull; - unsigned val; - unsigned ifg, ibg; - const unsigned char *fnt; - uint32_t fg, bg; - int cw = INCOLOR_CW; + int i; + int elg, blk; + unsigned ull; + unsigned val; + unsigned ifg, ibg; + const unsigned char *fnt; + uint32_t fg, bg; + int cw = INCOLOR_CW; - blk = 0; - if (dev->ctrl & INCOLOR_CTRL_BLINK) - { - if (attr & 0x80) - { - blk = (dev->blink & 16); - } - attr &= 0x7f; - } + blk = 0; + if (dev->ctrl & INCOLOR_CTRL_BLINK) { + if (attr & 0x80) { + blk = (dev->blink & 16); + } + attr &= 0x7f; + } - if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) - { - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) - { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) - { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - } - else - { - /* CGA-compatible attributes */ - ull = 0xffff; - ifg = attr & 0x0F; - ibg = (attr >> 4) & 0x0F; - } - if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) - { - fg = dev->rgb[dev->palette[ifg]]; - bg = dev->rgb[dev->palette[ibg]]; - } - else - { - fg = dev->rgb[defpal[ifg]]; - bg = dev->rgb[defpal[ibg]]; - } + if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) { + /* MDA-compatible attributes */ + ibg = 0; + ifg = 7; + if ((attr & 0x77) == 0x70) /* Invert */ + { + ifg = 0; + ibg = 7; + } + if (attr & 8) { + ifg |= 8; /* High intensity FG */ + } + if (attr & 0x80) { + ibg |= 8; /* High intensity BG */ + } + if ((attr & 0x77) == 0) /* Blank */ + { + ifg = ibg; + } + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + } else { + /* CGA-compatible attributes */ + ull = 0xffff; + ifg = attr & 0x0F; + ibg = (attr >> 4) & 0x0F; + } + if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) { + fg = dev->rgb[dev->palette[ifg]]; + bg = dev->rgb[dev->palette[ibg]]; + } else { + fg = dev->rgb[defpal[ifg]]; + bg = dev->rgb[defpal[ibg]]; + } - /* ELG set to stretch 8px character to 9px */ - if (dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } + /* ELG set to stretch 8px character to 9px */ + if (dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) { + elg = 0; + } else { + elg = ((chr >= 0xc0) && (chr <= 0xdf)); + } - fnt = &(fontdatm[chr][dev->sc]); + fnt = &(fontdatm[chr][dev->sc]); - if (blk) - { - val = 0x000; /* Blinking, draw all background */ - } - else if (dev->sc == ull) - { - val = 0x1ff; /* Underscore, draw all foreground */ - } - else - { - val = fnt[0] << 1; + if (blk) { + val = 0x000; /* Blinking, draw all background */ + } else if (dev->sc == ull) { + val = 0x1ff; /* Underscore, draw all foreground */ + } else { + val = fnt[0] << 1; - if (elg) - { - val |= (val >> 1) & 1; - } - } - for (i = 0; i < cw; i++) - { - buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? fg : bg; - val = val << 1; - } + if (elg) { + val |= (val >> 1) & 1; + } + } + for (i = 0; i < cw; i++) { + buffer32->line[dev->displine][x * cw + i] = (val & 0x100) ? fg : bg; + val = val << 1; + } } - static void draw_char_ram4(incolor_t *dev, int x, uint8_t chr, uint8_t attr) { - int i; - int elg, blk; - unsigned ull; - unsigned val[4]; - unsigned ifg, ibg, cfg, pmask, plane; - const unsigned char *fnt; - uint32_t fg; - int cw = INCOLOR_CW; - int blink = dev->ctrl & INCOLOR_CTRL_BLINK; - int altattr = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; - int palette = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; + int i; + int elg, blk; + unsigned ull; + unsigned val[4]; + unsigned ifg, ibg, cfg, pmask, plane; + const unsigned char *fnt; + uint32_t fg; + int cw = INCOLOR_CW; + int blink = dev->ctrl & INCOLOR_CTRL_BLINK; + int altattr = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; + int palette = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; - blk = 0; - if (blink) - { - if (attr & 0x80) - { - blk = (dev->blink & 16); - } - attr &= 0x7f; - } + blk = 0; + if (blink) { + if (attr & 0x80) { + blk = (dev->blink & 16); + } + attr &= 0x7f; + } - if (altattr) - { - /* MDA-compatible attributes */ - ibg = 0; - ifg = 7; - if ((attr & 0x77) == 0x70) /* Invert */ - { - ifg = 0; - ibg = 7; - } - if (attr & 8) - { - ifg |= 8; /* High intensity FG */ - } - if (attr & 0x80) - { - ibg |= 8; /* High intensity BG */ - } - if ((attr & 0x77) == 0) /* Blank */ - { - ifg = ibg; - } - ull = ((attr & 0x07) == 1) ? 13 : 0xffff; - } - else - { - /* CGA-compatible attributes */ - ull = 0xffff; - ifg = attr & 0x0F; - ibg = (attr >> 4) & 0x0F; - } - if (dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = dev->vram + 0x4000 + 16 * chr + dev->sc; + if (altattr) { + /* MDA-compatible attributes */ + ibg = 0; + ifg = 7; + if ((attr & 0x77) == 0x70) /* Invert */ + { + ifg = 0; + ibg = 7; + } + if (attr & 8) { + ifg |= 8; /* High intensity FG */ + } + if (attr & 0x80) { + ibg |= 8; /* High intensity BG */ + } + if ((attr & 0x77) == 0) /* Blank */ + { + ifg = ibg; + } + ull = ((attr & 0x07) == 1) ? 13 : 0xffff; + } else { + /* CGA-compatible attributes */ + ull = 0xffff; + ifg = attr & 0x0F; + ibg = (attr >> 4) & 0x0F; + } + if (dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) { + elg = 0; + } else { + elg = ((chr >= 0xc0) && (chr <= 0xdf)); + } + fnt = dev->vram + 0x4000 + 16 * chr + dev->sc; - if (blk) - { - /* Blinking, draw all background */ - val[0] = val[1] = val[2] = val[3] = 0x000; - } - else if (dev->sc == ull) - { - /* Underscore, draw all foreground */ - val[0] = val[1] = val[2] = val[3] = 0x1ff; - } - else - { - val[0] = fnt[0x00000] << 1; - val[1] = fnt[0x10000] << 1; - val[2] = fnt[0x20000] << 1; - val[3] = fnt[0x30000] << 1; + if (blk) { + /* Blinking, draw all background */ + val[0] = val[1] = val[2] = val[3] = 0x000; + } else if (dev->sc == ull) { + /* Underscore, draw all foreground */ + val[0] = val[1] = val[2] = val[3] = 0x1ff; + } else { + val[0] = fnt[0x00000] << 1; + val[1] = fnt[0x10000] << 1; + val[2] = fnt[0x20000] << 1; + val[3] = fnt[0x30000] << 1; - if (elg) - { - val[0] |= (val[0] >> 1) & 1; - val[1] |= (val[1] >> 1) & 1; - val[2] |= (val[2] >> 1) & 1; - val[3] |= (val[3] >> 1) & 1; - } - } - for (i = 0; i < cw; i++) - { - /* Generate pixel colour */ - cfg = 0; - pmask = 1; - for (plane = 0; plane < 4; plane++, pmask = pmask << 1) - { - if (val[plane] & 0x100) cfg |= (ifg & pmask); - else cfg |= (ibg & pmask); - } - /* cfg = colour of foreground pixels */ - if (altattr && (attr & 0x77) == 0) cfg = ibg; /* 'blank' attribute */ - if (palette) - { - fg = dev->rgb[dev->palette[cfg]]; - } - else - { - fg = dev->rgb[defpal[cfg]]; - } + if (elg) { + val[0] |= (val[0] >> 1) & 1; + val[1] |= (val[1] >> 1) & 1; + val[2] |= (val[2] >> 1) & 1; + val[3] |= (val[3] >> 1) & 1; + } + } + for (i = 0; i < cw; i++) { + /* Generate pixel colour */ + cfg = 0; + pmask = 1; + for (plane = 0; plane < 4; plane++, pmask = pmask << 1) { + if (val[plane] & 0x100) + cfg |= (ifg & pmask); + else + cfg |= (ibg & pmask); + } + /* cfg = colour of foreground pixels */ + if (altattr && (attr & 0x77) == 0) + cfg = ibg; /* 'blank' attribute */ + if (palette) { + fg = dev->rgb[dev->palette[cfg]]; + } else { + fg = dev->rgb[defpal[cfg]]; + } - buffer32->line[dev->displine][x * cw + i] = fg; - val[0] = val[0] << 1; - val[1] = val[1] << 1; - val[2] = val[2] << 1; - val[3] = val[3] << 1; - } + buffer32->line[dev->displine][x * cw + i] = fg; + val[0] = val[0] << 1; + val[1] = val[1] << 1; + val[2] = val[2] << 1; + val[3] = val[3] << 1; + } } - static void draw_char_ram48(incolor_t *dev, int x, uint8_t chr, uint8_t attr) { - int i; - int elg, blk, ul, ol, bld; - unsigned ull, oll, ulc = 0, olc = 0; - unsigned val[4]; - unsigned ifg = 0, ibg, cfg, pmask, plane; - const unsigned char *fnt; - uint32_t fg; - int cw = INCOLOR_CW; - int blink = dev->ctrl & INCOLOR_CTRL_BLINK; - int altattr = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; - int palette = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; - int font = (attr & 0x0F); + int i; + int elg, blk, ul, ol, bld; + unsigned ull, oll, ulc = 0, olc = 0; + unsigned val[4]; + unsigned ifg = 0, ibg, cfg, pmask, plane; + const unsigned char *fnt; + uint32_t fg; + int cw = INCOLOR_CW; + int blink = dev->ctrl & INCOLOR_CTRL_BLINK; + int altattr = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR; + int palette = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE; + int font = (attr & 0x0F); - if (font >= 12) font &= 7; + if (font >= 12) + font &= 7; - blk = 0; - if (blink && altattr) - { - if (attr & 0x40) - { - blk = (dev->blink & 16); - } - attr &= 0x7f; - } - if (altattr) - { - /* MDA-compatible attributes */ - if (blink) - { - ibg = (attr & 0x80) ? 8 : 0; - bld = 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - else - { - bld = (attr & 0x80) ? 1 : 0; - ibg = (attr & 0x40) ? 0x0F : 0; - ol = (attr & 0x20) ? 1 : 0; - ul = (attr & 0x10) ? 1 : 0; - } - } - else - { - /* CGA-compatible attributes */ - ibg = 0; - ifg = (attr >> 4) & 0x0F; - ol = 0; - ul = 0; - bld = 0; - } - if (ul) - { - ull = dev->crtc[INCOLOR_CRTC_UNDER] & 0x0F; - ulc = (dev->crtc[INCOLOR_CRTC_UNDER] >> 4) & 0x0F; - if (ulc == 0) ulc = 7; - } - else - { - ull = 0xFFFF; - } - if (ol) - { - oll = dev->crtc[INCOLOR_CRTC_OVER] & 0x0F; - olc = (dev->crtc[INCOLOR_CRTC_OVER] >> 4) & 0x0F; - if (olc == 0) olc = 7; - } - else - { - oll = 0xFFFF; - } + blk = 0; + if (blink && altattr) { + if (attr & 0x40) { + blk = (dev->blink & 16); + } + attr &= 0x7f; + } + if (altattr) { + /* MDA-compatible attributes */ + if (blink) { + ibg = (attr & 0x80) ? 8 : 0; + bld = 0; + ol = (attr & 0x20) ? 1 : 0; + ul = (attr & 0x10) ? 1 : 0; + } else { + bld = (attr & 0x80) ? 1 : 0; + ibg = (attr & 0x40) ? 0x0F : 0; + ol = (attr & 0x20) ? 1 : 0; + ul = (attr & 0x10) ? 1 : 0; + } + } else { + /* CGA-compatible attributes */ + ibg = 0; + ifg = (attr >> 4) & 0x0F; + ol = 0; + ul = 0; + bld = 0; + } + if (ul) { + ull = dev->crtc[INCOLOR_CRTC_UNDER] & 0x0F; + ulc = (dev->crtc[INCOLOR_CRTC_UNDER] >> 4) & 0x0F; + if (ulc == 0) + ulc = 7; + } else { + ull = 0xFFFF; + } + if (ol) { + oll = dev->crtc[INCOLOR_CRTC_OVER] & 0x0F; + olc = (dev->crtc[INCOLOR_CRTC_OVER] >> 4) & 0x0F; + if (olc == 0) + olc = 7; + } else { + oll = 0xFFFF; + } - if (dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) - { - elg = 0; - } - else - { - elg = ((chr >= 0xc0) && (chr <= 0xdf)); - } - fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc; + if (dev->crtc[INCOLOR_CRTC_XMODE] & INCOLOR_XMODE_90COL) { + elg = 0; + } else { + elg = ((chr >= 0xc0) && (chr <= 0xdf)); + } + fnt = dev->vram + 0x4000 + 16 * chr + 4096 * font + dev->sc; - if (blk) - { - /* Blinking, draw all background */ - val[0] = val[1] = val[2] = val[3] = 0x000; - } - else if (dev->sc == ull) - { - /* Underscore, draw all foreground */ - val[0] = val[1] = val[2] = val[3] = 0x1ff; - } - else - { - val[0] = fnt[0x00000] << 1; - val[1] = fnt[0x10000] << 1; - val[2] = fnt[0x20000] << 1; - val[3] = fnt[0x30000] << 1; + if (blk) { + /* Blinking, draw all background */ + val[0] = val[1] = val[2] = val[3] = 0x000; + } else if (dev->sc == ull) { + /* Underscore, draw all foreground */ + val[0] = val[1] = val[2] = val[3] = 0x1ff; + } else { + val[0] = fnt[0x00000] << 1; + val[1] = fnt[0x10000] << 1; + val[2] = fnt[0x20000] << 1; + val[3] = fnt[0x30000] << 1; - if (elg) - { - val[0] |= (val[0] >> 1) & 1; - val[1] |= (val[1] >> 1) & 1; - val[2] |= (val[2] >> 1) & 1; - val[3] |= (val[3] >> 1) & 1; - } - if (bld) - { - val[0] |= (val[0] >> 1); - val[1] |= (val[1] >> 1); - val[2] |= (val[2] >> 1); - val[3] |= (val[3] >> 1); - } - } - for (i = 0; i < cw; i++) - { - /* Generate pixel colour */ - cfg = 0; - pmask = 1; - if (dev->sc == oll) - { - cfg = olc ^ ibg; /* Strikethrough */ - } - else if (dev->sc == ull) - { - cfg = ulc ^ ibg; /* Underline */ - } - else - { - for (plane = 0; plane < 4; plane++, pmask = pmask << 1) - { - if (val[plane] & 0x100) - { - if (altattr) cfg |= ((~ibg) & pmask); - else cfg |= ((~ifg) & pmask); - } - else if (altattr) cfg |= (ibg & pmask); - } - } - if (palette) - { - fg = dev->rgb[dev->palette[cfg]]; - } - else - { - fg = dev->rgb[defpal[cfg]]; - } + if (elg) { + val[0] |= (val[0] >> 1) & 1; + val[1] |= (val[1] >> 1) & 1; + val[2] |= (val[2] >> 1) & 1; + val[3] |= (val[3] >> 1) & 1; + } + if (bld) { + val[0] |= (val[0] >> 1); + val[1] |= (val[1] >> 1); + val[2] |= (val[2] >> 1); + val[3] |= (val[3] >> 1); + } + } + for (i = 0; i < cw; i++) { + /* Generate pixel colour */ + cfg = 0; + pmask = 1; + if (dev->sc == oll) { + cfg = olc ^ ibg; /* Strikethrough */ + } else if (dev->sc == ull) { + cfg = ulc ^ ibg; /* Underline */ + } else { + for (plane = 0; plane < 4; plane++, pmask = pmask << 1) { + if (val[plane] & 0x100) { + if (altattr) + cfg |= ((~ibg) & pmask); + else + cfg |= ((~ifg) & pmask); + } else if (altattr) + cfg |= (ibg & pmask); + } + } + if (palette) { + fg = dev->rgb[dev->palette[cfg]]; + } else { + fg = dev->rgb[defpal[cfg]]; + } - buffer32->line[dev->displine][x * cw + i] = fg; - val[0] = val[0] << 1; - val[1] = val[1] << 1; - val[2] = val[2] << 1; - val[3] = val[3] << 1; - } + buffer32->line[dev->displine][x * cw + i] = fg; + val[0] = val[0] << 1; + val[1] = val[1] << 1; + val[2] = val[2] << 1; + val[3] = val[3] << 1; + } } - static void text_line(incolor_t *dev, uint16_t ca) { - int drawcursor; - int x, c; - uint8_t chr, attr; + int drawcursor; + int x, c; + uint8_t chr, attr; uint32_t col; for (x = 0; x < dev->crtc[1]; x++) { - if (dev->ctrl & 8) { - chr = dev->vram[(dev->ma << 1) & 0xfff]; - attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; - } else - chr = attr = 0; + if (dev->ctrl & 8) { + chr = dev->vram[(dev->ma << 1) & 0xfff]; + attr = dev->vram[((dev->ma << 1) + 1) & 0xfff]; + } else + chr = attr = 0; - drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); + drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron); - switch (dev->crtc[INCOLOR_CRTC_XMODE] & 5) { - case 0: - case 4: /* ROM font */ - draw_char_rom(dev, x, chr, attr); - break; + switch (dev->crtc[INCOLOR_CRTC_XMODE] & 5) { + case 0: + case 4: /* ROM font */ + draw_char_rom(dev, x, chr, attr); + break; - case 1: /* 4k RAMfont */ - draw_char_ram4(dev, x, chr, attr); - break; + case 1: /* 4k RAMfont */ + draw_char_ram4(dev, x, chr, attr); + break; - case 5: /* 48k RAMfont */ - draw_char_ram48(dev, x, chr, attr); - break; - } - ++dev->ma; + case 5: /* 48k RAMfont */ + draw_char_ram48(dev, x, chr, attr); + break; + } + ++dev->ma; - if (drawcursor) { - int cw = INCOLOR_CW; - uint8_t ink = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_CURSOR; - if (ink == 0) ink = (attr & 0x08) | 7; + if (drawcursor) { + int cw = INCOLOR_CW; + uint8_t ink = dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_CURSOR; + if (ink == 0) + ink = (attr & 0x08) | 7; - /* In MDA-compatible mode, cursor brightness comes from - * background */ - if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) - { - ink = (attr & 0x08) | (ink & 7); - } - if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) - { - col = dev->rgb[dev->palette[ink]]; - } - else - { - col = dev->rgb[defpal[ink]]; - } - for (c = 0; c < cw; c++) - { - buffer32->line[dev->displine][x * cw + c] = col; - } - } + /* In MDA-compatible mode, cursor brightness comes from + * background */ + if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_ALTATTR) { + ink = (attr & 0x08) | (ink & 7); + } + if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) { + col = dev->rgb[dev->palette[ink]]; + } else { + col = dev->rgb[defpal[ink]]; + } + for (c = 0; c < cw; c++) { + buffer32->line[dev->displine][x * cw + c] = col; + } + } } } - static void graphics_line(incolor_t *dev) { - uint8_t mask; + uint8_t mask; uint16_t ca; - int x, c, plane, col; - uint8_t ink; + int x, c, plane, col; + uint8_t ink; uint16_t val[4]; /* Graphics mode. */ ca = (dev->sc & 3) * 0x2000; if ((dev->ctrl & INCOLOR_CTRL_PAGE1) && (dev->ctrl2 & INCOLOR_CTRL2_PAGE1)) - ca += 0x8000; + ca += 0x8000; for (x = 0; x < dev->crtc[1]; x++) { - mask = dev->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */ - for (plane = 0; plane < 4; plane++, mask = mask >> 1) - { - if (dev->ctrl & 8) { - if (mask & 1) - val[plane] = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | - dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; - else val[plane] = 0; - } else - val[plane] = 0; - } - dev->ma++; + mask = dev->crtc[INCOLOR_CRTC_MASK]; /* Planes to display */ + for (plane = 0; plane < 4; plane++, mask = mask >> 1) { + if (dev->ctrl & 8) { + if (mask & 1) + val[plane] = (dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 0x10000 * plane + 1]; + else + val[plane] = 0; + } else + val[plane] = 0; + } + dev->ma++; - for (c = 0; c < 16; c++) - { - ink = 0; - for (plane = 0; plane < 4; plane++) - { - ink = ink >> 1; - if (val[plane] & 0x8000) ink |= 8; - val[plane] = val[plane] << 1; - } - /* Is palette in use? */ - if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) - col = dev->palette[ink]; - else col = defpal[ink]; + for (c = 0; c < 16; c++) { + ink = 0; + for (plane = 0; plane < 4; plane++) { + ink = ink >> 1; + if (val[plane] & 0x8000) + ink |= 8; + val[plane] = val[plane] << 1; + } + /* Is palette in use? */ + if (dev->crtc[INCOLOR_CRTC_EXCEPT] & INCOLOR_EXCEPT_PALETTE) + col = dev->palette[ink]; + else + col = defpal[ink]; - buffer32->line[dev->displine][(x << 4) + c] = dev->rgb[col]; - } + buffer32->line[dev->displine][(x << 4) + c] = dev->rgb[col]; + } } } - static void incolor_poll(void *priv) { - incolor_t *dev = (incolor_t *)priv; - uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; - int x; - int oldvc; - int oldsc; + incolor_t *dev = (incolor_t *) priv; + uint16_t ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff; + int x; + int oldvc; + int oldsc; - if (! dev->linepos) { - timer_advance_u64(&dev->timer, dev->dispofftime); - dev->stat |= 1; - dev->linepos = 1; - oldsc = dev->sc; - if ((dev->crtc[8] & 3) == 3) - dev->sc = (dev->sc << 1) & 7; + if (!dev->linepos) { + timer_advance_u64(&dev->timer, dev->dispofftime); + dev->stat |= 1; + dev->linepos = 1; + oldsc = dev->sc; + if ((dev->crtc[8] & 3) == 3) + dev->sc = (dev->sc << 1) & 7; - if (dev->dispon) { - if (dev->displine < dev->firstline) { - dev->firstline = dev->displine; - video_wait_for_buffer(); - } - dev->lastline = dev->displine; - if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) - graphics_line(dev); - else - text_line(dev, ca); - } - dev->sc = oldsc; - if (dev->vc == dev->crtc[7] && !dev->sc) - dev->stat |= 8; - dev->displine++; - if (dev->displine >= 500) - dev->displine = 0; + if (dev->dispon) { + if (dev->displine < dev->firstline) { + dev->firstline = dev->displine; + video_wait_for_buffer(); + } + dev->lastline = dev->displine; + if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) + graphics_line(dev); + else + text_line(dev, ca); + } + dev->sc = oldsc; + if (dev->vc == dev->crtc[7] && !dev->sc) + dev->stat |= 8; + dev->displine++; + if (dev->displine >= 500) + dev->displine = 0; } else { - timer_advance_u64(&dev->timer, dev->dispontime); - if (dev->dispon) - dev->stat &= ~1; - dev->linepos = 0; - if (dev->vsynctime) { - dev->vsynctime--; - if (! dev->vsynctime) - dev->stat &= ~8; - } + timer_advance_u64(&dev->timer, dev->dispontime); + if (dev->dispon) + dev->stat &= ~1; + dev->linepos = 0; + if (dev->vsynctime) { + dev->vsynctime--; + if (!dev->vsynctime) + dev->stat &= ~8; + } - if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { - dev->con = 0; - dev->coff = 1; - } + if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) { + dev->con = 0; + dev->coff = 1; + } - if (dev->vadj) { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; - dev->vadj--; - if (! dev->vadj) { - dev->dispon = 1; - dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - dev->sc = 0; - } - } else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { - dev->maback = dev->ma; - dev->sc = 0; - oldvc = dev->vc; - dev->vc++; - dev->vc &= 127; - if (dev->vc == dev->crtc[6]) - dev->dispon = 0; - if (oldvc == dev->crtc[4]) { - dev->vc = 0; - dev->vadj = dev->crtc[5]; - if (!dev->vadj) dev->dispon=1; - if (!dev->vadj) dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; - if ((dev->crtc[10] & 0x60) == 0x20) dev->cursoron = 0; - else dev->cursoron = dev->blink & 16; - } + if (dev->vadj) { + dev->sc++; + dev->sc &= 31; + dev->ma = dev->maback; + dev->vadj--; + if (!dev->vadj) { + dev->dispon = 1; + dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + dev->sc = 0; + } + } else if (dev->sc == dev->crtc[9] || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) { + dev->maback = dev->ma; + dev->sc = 0; + oldvc = dev->vc; + dev->vc++; + dev->vc &= 127; + if (dev->vc == dev->crtc[6]) + dev->dispon = 0; + if (oldvc == dev->crtc[4]) { + dev->vc = 0; + dev->vadj = dev->crtc[5]; + if (!dev->vadj) + dev->dispon = 1; + if (!dev->vadj) + dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff; + if ((dev->crtc[10] & 0x60) == 0x20) + dev->cursoron = 0; + else + dev->cursoron = dev->blink & 16; + } - if (dev->vc == dev->crtc[7]) { - dev->dispon = 0; - dev->displine = 0; - dev->vsynctime = 16; - if (dev->crtc[7]) { - if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) - x = dev->crtc[1] << 4; - else - x = dev->crtc[1] * 9; - dev->lastline++; - if ((dev->ctrl & 8) && - ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { - xsize = x; - ysize = dev->lastline - dev->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); + if (dev->vc == dev->crtc[7]) { + dev->dispon = 0; + dev->displine = 0; + dev->vsynctime = 16; + if (dev->crtc[7]) { + if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) + x = dev->crtc[1] << 4; + else + x = dev->crtc[1] * 9; + dev->lastline++; + if ((dev->ctrl & 8) && ((x != xsize) || ((dev->lastline - dev->firstline) != ysize) || video_force_resize_get())) { + xsize = x; + ysize = dev->lastline - dev->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + set_screen_size(xsize, ysize); - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen(0, dev->firstline, xsize, dev->lastline - dev->firstline); - frames++; - if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) { - video_res_x = dev->crtc[1] * 16; - video_res_y = dev->crtc[6] * 4; - video_bpp = 1; - } else { - video_res_x = dev->crtc[1]; - video_res_y = dev->crtc[6]; - video_bpp = 0; - } - } - dev->firstline = 1000; - dev->lastline = 0; - dev->blink++; - } - } else { - dev->sc++; - dev->sc &= 31; - dev->ma = dev->maback; - } + if (video_force_resize_get()) + video_force_resize_set(0); + } + video_blit_memtoscreen(0, dev->firstline, xsize, dev->lastline - dev->firstline); + frames++; + if ((dev->ctrl & INCOLOR_CTRL_GRAPH) && (dev->ctrl2 & INCOLOR_CTRL2_GRAPH)) { + video_res_x = dev->crtc[1] * 16; + video_res_y = dev->crtc[6] * 4; + video_bpp = 1; + } else { + video_res_x = dev->crtc[1]; + video_res_y = dev->crtc[6]; + video_bpp = 0; + } + } + dev->firstline = 1000; + dev->lastline = 0; + dev->blink++; + } + } else { + dev->sc++; + dev->sc &= 31; + dev->ma = dev->maback; + } - if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) - dev->con = 1; + if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1)))) + dev->con = 1; } } - static void * incolor_init(const device_t *info) { incolor_t *dev; - int c; + int c; - dev = (incolor_t *)malloc(sizeof(incolor_t)); + dev = (incolor_t *) malloc(sizeof(incolor_t)); memset(dev, 0x00, sizeof(incolor_t)); - dev->vram = (uint8_t *)malloc(0x40000); /* 4 planes of 64k */ + dev->vram = (uint8_t *) malloc(0x40000); /* 4 planes of 64k */ - timer_add(&dev->timer, incolor_poll, dev, 1); + timer_add(&dev->timer, incolor_poll, dev, 1); mem_mapping_add(&dev->mapping, 0xb0000, 0x08000, - incolor_read,NULL,NULL, incolor_write,NULL,NULL, - NULL, MEM_MAPPING_EXTERNAL, dev); + incolor_read, NULL, NULL, incolor_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, dev); io_sethandler(0x03b0, 16, - incolor_in,NULL,NULL, incolor_out,NULL,NULL, dev); + incolor_in, NULL, NULL, incolor_out, NULL, NULL, dev); for (c = 0; c < 64; c++) { - dev->rgb[c] = makecol32(init_rgb[c][0], init_rgb[c][1], init_rgb[c][2]); + dev->rgb[c] = makecol32(init_rgb[c][0], init_rgb[c][1], init_rgb[c][2]); } /* Initialise CRTC regs to safe values */ - dev->crtc[INCOLOR_CRTC_MASK ] = 0x0F; /* All planes displayed */ + dev->crtc[INCOLOR_CRTC_MASK] = 0x0F; /* All planes displayed */ dev->crtc[INCOLOR_CRTC_RWCTRL] = INCOLOR_RWCTRL_POLARITY; - dev->crtc[INCOLOR_CRTC_RWCOL ] = 0x0F; /* White on black */ + dev->crtc[INCOLOR_CRTC_RWCOL] = 0x0F; /* White on black */ dev->crtc[INCOLOR_CRTC_EXCEPT] = INCOLOR_EXCEPT_ALTATTR; for (c = 0; c < 16; c++) - dev->palette[c] = defpal[c]; + dev->palette[c] = defpal[c]; dev->palette_idx = 0; video_inform(VIDEO_FLAG_TYPE_MDA, &timing_incolor); @@ -1067,40 +998,38 @@ incolor_init(const device_t *info) return dev; } - static void incolor_close(void *priv) { - incolor_t *dev = (incolor_t *)priv; + incolor_t *dev = (incolor_t *) priv; if (!dev) - return; + return; if (dev->vram) - free(dev->vram); + free(dev->vram); free(dev); } - static void speed_changed(void *priv) { - incolor_t *dev = (incolor_t *)priv; + incolor_t *dev = (incolor_t *) priv; recalc_timings(dev); } const device_t incolor_device = { - .name = "Hercules InColor", + .name = "Hercules InColor", .internal_name = "incolor", - .flags = DEVICE_ISA, - .local = 0, - .init = incolor_init, - .close = incolor_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = incolor_init, + .close = incolor_close, + .reset = NULL, { .available = NULL }, .speed_changed = speed_changed, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 0a4ed3c47..d02670d6a 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -34,305 +34,310 @@ static int mdacols[256][2][2]; -static video_timings_t timing_mda = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +static video_timings_t timing_mda = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; void mda_recalctimings(mda_t *mda); -void mda_out(uint16_t addr, uint8_t val, void *p) +void +mda_out(uint16_t addr, uint8_t val, void *p) { - mda_t *mda = (mda_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - mda->crtcreg = val & 31; - return; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - mda->crtc[mda->crtcreg] = val; - if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ - { - mda->crtc[10] = 0xb; - mda->crtc[11] = 0xc; + mda_t *mda = (mda_t *) p; + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + mda->crtcreg = val & 31; + return; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + mda->crtc[mda->crtcreg] = val; + if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/ + { + mda->crtc[10] = 0xb; + mda->crtc[11] = 0xc; + } + mda_recalctimings(mda); + return; + case 0x3b8: + mda->ctrl = val; + return; + } +} + +uint8_t +mda_in(uint16_t addr, void *p) +{ + mda_t *mda = (mda_t *) p; + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + return mda->crtcreg; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + return mda->crtc[mda->crtcreg]; + case 0x3ba: + return mda->stat | 0xF0; + } + return 0xff; +} + +void +mda_write(uint32_t addr, uint8_t val, void *p) +{ + mda_t *mda = (mda_t *) p; + mda->vram[addr & 0xfff] = val; +} + +uint8_t +mda_read(uint32_t addr, void *p) +{ + mda_t *mda = (mda_t *) p; + return mda->vram[addr & 0xfff]; +} + +void +mda_recalctimings(mda_t *mda) +{ + double _dispontime, _dispofftime, disptime; + disptime = mda->crtc[0] + 1; + _dispontime = mda->crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + mda->dispontime = (uint64_t) (_dispontime); + mda->dispofftime = (uint64_t) (_dispofftime); +} + +void +mda_poll(void *p) +{ + mda_t *mda = (mda_t *) p; + uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c; + int oldvc; + uint8_t chr, attr; + int oldsc; + int blink; + + VIDEO_MONITOR_PROLOGUE() + if (!mda->linepos) { + timer_advance_u64(&mda->timer, mda->dispofftime); + mda->stat |= 1; + mda->linepos = 1; + oldsc = mda->sc; + if ((mda->crtc[8] & 3) == 3) + mda->sc = (mda->sc << 1) & 7; + if (mda->dispon) { + if (mda->displine < mda->firstline) { + mda->firstline = mda->displine; + video_wait_for_buffer(); + } + mda->lastline = mda->displine; + for (x = 0; x < mda->crtc[1]; x++) { + chr = mda->vram[(mda->ma << 1) & 0xfff]; + attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; + drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); + blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); + if (mda->sc == 12 && ((attr & 7) == 1)) { + for (c = 0; c < 9; c++) + buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1]; + } else { + for (c = 0; c < 8; c++) + buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; + if ((chr & ~0x1f) == 0xc0) + buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; + else + buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0]; } - mda_recalctimings(mda); - return; - case 0x3b8: - mda->ctrl = val; - return; + mda->ma++; + if (drawcursor) { + for (c = 0; c < 9; c++) + buffer32->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1]; + } + } } -} - -uint8_t mda_in(uint16_t addr, void *p) -{ - mda_t *mda = (mda_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - return mda->crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - return mda->crtc[mda->crtcreg]; - case 0x3ba: - return mda->stat | 0xF0; + mda->sc = oldsc; + if (mda->vc == mda->crtc[7] && !mda->sc) { + mda->stat |= 8; } - return 0xff; -} - -void mda_write(uint32_t addr, uint8_t val, void *p) -{ - mda_t *mda = (mda_t *)p; - mda->vram[addr & 0xfff] = val; -} - -uint8_t mda_read(uint32_t addr, void *p) -{ - mda_t *mda = (mda_t *)p; - return mda->vram[addr & 0xfff]; -} - -void mda_recalctimings(mda_t *mda) -{ - double _dispontime, _dispofftime, disptime; - disptime = mda->crtc[0] + 1; - _dispontime = mda->crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - mda->dispontime = (uint64_t)(_dispontime); - mda->dispofftime = (uint64_t)(_dispofftime); -} - -void mda_poll(void *p) -{ - mda_t *mda = (mda_t *)p; - uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c; - int oldvc; - uint8_t chr, attr; - int oldsc; - int blink; - - VIDEO_MONITOR_PROLOGUE() - if (!mda->linepos) - { - timer_advance_u64(&mda->timer, mda->dispofftime); - mda->stat |= 1; - mda->linepos = 1; - oldsc = mda->sc; - if ((mda->crtc[8] & 3) == 3) - mda->sc = (mda->sc << 1) & 7; - if (mda->dispon) - { - if (mda->displine < mda->firstline) - { - mda->firstline = mda->displine; - video_wait_for_buffer(); - } - mda->lastline = mda->displine; - for (x = 0; x < mda->crtc[1]; x++) - { - chr = mda->vram[(mda->ma << 1) & 0xfff]; - attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; - drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); - blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); - if (mda->sc == 12 && ((attr & 7) == 1)) - { - for (c = 0; c < 9; c++) - buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1]; - } - else - { - for (c = 0; c < 8; c++) - buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0]; - if ((chr & ~0x1f) == 0xc0) buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1]; - else buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0]; - } - mda->ma++; - if (drawcursor) - { - for (c = 0; c < 9; c++) - buffer32->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1]; - } - } - } - mda->sc = oldsc; - if (mda->vc == mda->crtc[7] && !mda->sc) - { - mda->stat |= 8; - } - mda->displine++; - if (mda->displine >= 500) - mda->displine=0; + mda->displine++; + if (mda->displine >= 500) + mda->displine = 0; + } else { + timer_advance_u64(&mda->timer, mda->dispontime); + if (mda->dispon) + mda->stat &= ~1; + mda->linepos = 0; + if (mda->vsynctime) { + mda->vsynctime--; + if (!mda->vsynctime) { + mda->stat &= ~8; + } } - else - { - timer_advance_u64(&mda->timer, mda->dispontime); - if (mda->dispon) mda->stat&=~1; - mda->linepos=0; - if (mda->vsynctime) - { - mda->vsynctime--; - if (!mda->vsynctime) - { - mda->stat&=~8; - } - } - if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) - { - mda->con = 0; - mda->coff = 1; - } - if (mda->vadj) - { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - mda->vadj--; - if (!mda->vadj) - { - mda->dispon = 1; - mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - mda->sc = 0; - } - } - else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) - { - mda->maback = mda->ma; - mda->sc = 0; - oldvc = mda->vc; - mda->vc++; - mda->vc &= 127; - if (mda->vc == mda->crtc[6]) - mda->dispon=0; - if (oldvc == mda->crtc[4]) - { - mda->vc = 0; - mda->vadj = mda->crtc[5]; - if (!mda->vadj) mda->dispon = 1; - if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; - if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0; - else mda->cursoron = mda->blink & 16; - } - if (mda->vc == mda->crtc[7]) - { - mda->dispon = 0; - mda->displine = 0; - mda->vsynctime = 16; - if (mda->crtc[7]) - { - x = mda->crtc[1] * 9; - mda->lastline++; - if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) - { - xsize = x; - ysize = mda->lastline - mda->firstline; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen_8(0, mda->firstline, xsize, ysize); - frames++; - video_res_x = mda->crtc[1]; - video_res_y = mda->crtc[6]; - video_bpp = 0; - } - mda->firstline = 1000; - mda->lastline = 0; - mda->blink++; - } - } + if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) { + mda->con = 0; + mda->coff = 1; + } + if (mda->vadj) { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; + mda->vadj--; + if (!mda->vadj) { + mda->dispon = 1; + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + mda->sc = 0; + } + } else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) { + mda->maback = mda->ma; + mda->sc = 0; + oldvc = mda->vc; + mda->vc++; + mda->vc &= 127; + if (mda->vc == mda->crtc[6]) + mda->dispon = 0; + if (oldvc == mda->crtc[4]) { + mda->vc = 0; + mda->vadj = mda->crtc[5]; + if (!mda->vadj) + mda->dispon = 1; + if (!mda->vadj) + mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff; + if ((mda->crtc[10] & 0x60) == 0x20) + mda->cursoron = 0; else - { - mda->sc++; - mda->sc &= 31; - mda->ma = mda->maback; - } - if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) - { - mda->con = 1; + mda->cursoron = mda->blink & 16; + } + if (mda->vc == mda->crtc[7]) { + mda->dispon = 0; + mda->displine = 0; + mda->vsynctime = 16; + if (mda->crtc[7]) { + x = mda->crtc[1] * 9; + mda->lastline++; + if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) { + xsize = x; + ysize = mda->lastline - mda->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + set_screen_size(xsize, ysize); + + if (video_force_resize_get()) + video_force_resize_set(0); + } + video_blit_memtoscreen_8(0, mda->firstline, xsize, ysize); + frames++; + video_res_x = mda->crtc[1]; + video_res_y = mda->crtc[6]; + video_bpp = 0; } + mda->firstline = 1000; + mda->lastline = 0; + mda->blink++; + } + } else { + mda->sc++; + mda->sc &= 31; + mda->ma = mda->maback; } - VIDEO_MONITOR_EPILOGUE(); -} - -void mda_init(mda_t *mda) -{ - int c; - - for (c = 0; c < 256; c++) - { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; + if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) { + mda->con = 1; } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - - overscan_x = overscan_y = 0; - mda->monitor_index = monitor_index_global; - - cga_palette = device_get_config_int("rgb_type") << 1; - if (cga_palette > 6) - { - cga_palette = 0; - } - cgapal_rebuild(); - - timer_add(&mda->timer, mda_poll, mda, 1); + } + VIDEO_MONITOR_EPILOGUE(); } -void *mda_standalone_init(const device_t *info) +void +mda_init(mda_t *mda) { - mda_t *mda = malloc(sizeof(mda_t)); - memset(mda, 0, sizeof(mda_t)); - video_inform(VIDEO_FLAG_TYPE_MDA, &timing_mda); + int c; - mda->vram = malloc(0x1000); + for (c = 0; c < 256; c++) { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; + if (c & 8) + mdacols[c][0][1] = 15 + 16; + else + mdacols[c][0][1] = 7 + 16; + } + mdacols[0x70][0][1] = 16; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; + mdacols[0xF0][0][1] = 16; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; + mdacols[0x78][0][1] = 16 + 7; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; + mdacols[0xF8][0][1] = 16 + 7; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); - io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); + overscan_x = overscan_y = 0; + mda->monitor_index = monitor_index_global; - mda_init(mda); + cga_palette = device_get_config_int("rgb_type") << 1; + if (cga_palette > 6) { + cga_palette = 0; + } + cgapal_rebuild(); - lpt3_init(0x3BC); - - return mda; + timer_add(&mda->timer, mda_poll, mda, 1); } -void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink) +void * +mda_standalone_init(const device_t *info) { - mdacols[chr][blink][fg] = 16 + cga_ink; + mda_t *mda = malloc(sizeof(mda_t)); + memset(mda, 0, sizeof(mda_t)); + video_inform(VIDEO_FLAG_TYPE_MDA, &timing_mda); + + mda->vram = malloc(0x1000); + + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); + io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); + + mda_init(mda); + + lpt3_init(0x3BC); + + return mda; } -void mda_close(void *p) +void +mda_setcol(int chr, int blink, int fg, uint8_t cga_ink) { - mda_t *mda = (mda_t *)p; - - free(mda->vram); - free(mda); + mdacols[chr][blink][fg] = 16 + cga_ink; } -void mda_speed_changed(void *p) +void +mda_close(void *p) { - mda_t *mda = (mda_t *)p; + mda_t *mda = (mda_t *) p; - mda_recalctimings(mda); + free(mda->vram); + free(mda); +} + +void +mda_speed_changed(void *p) +{ + mda_t *mda = (mda_t *) p; + + mda_recalctimings(mda); } static const device_config_t mda_config[] = { -// clang-format off + // clang-format off { .name = "rgb_type", .description = "Display type", @@ -367,15 +372,15 @@ static const device_config_t mda_config[] = { }; const device_t mda_device = { - .name = "MDA", + .name = "MDA", .internal_name = "mda", - .flags = DEVICE_ISA, - .local = 0, - .init = mda_standalone_init, - .close = mda_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = mda_standalone_init, + .close = mda_close, + .reset = NULL, { .available = NULL }, .speed_changed = mda_speed_changed, - .force_redraw = NULL, - .config = mda_config + .force_redraw = NULL, + .config = mda_config }; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 87ed16ba5..134b778b2 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -34,27 +34,26 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" +#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" +#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" -#define ROM_MILLENNIUM "roms/video/matrox/matrox2064wr2.BIN" -#define ROM_MYSTIQUE "roms/video/matrox/MYSTIQUE.VBI" -#define ROM_MYSTIQUE_220 "roms/video/matrox/Myst220_66-99mhz.vbi" +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) +#define FIFO_THRESHOLD 0xe000 -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) -#define FIFO_THRESHOLD 0xe000 +#define WAKE_DELAY (100 * TIMER_USEC) /* 100us */ -#define WAKE_DELAY (100 * TIMER_USEC) /* 100us */ +#define FIFO_ENTRIES (mystique->fifo_write_idx - mystique->fifo_read_idx) +#define FIFO_FULL ((mystique->fifo_write_idx - mystique->fifo_read_idx) >= (FIFO_SIZE - 1)) +#define FIFO_EMPTY (mystique->fifo_read_idx == mystique->fifo_write_idx) -#define FIFO_ENTRIES (mystique->fifo_write_idx - mystique->fifo_read_idx) -#define FIFO_FULL ((mystique->fifo_write_idx - mystique->fifo_read_idx) >= (FIFO_SIZE-1)) -#define FIFO_EMPTY (mystique->fifo_read_idx == mystique->fifo_write_idx) - -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff #define DMA_POLL_TIME_US 100 /*100us*/ -#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ +#define DMA_MAX_WORDS 256 /*256 quad words per 100us poll*/ /*These registers are also mirrored into 0x1dxx, with the mirrored versions starting the blitter*/ @@ -139,119 +138,119 @@ #define REG_CACHEFLUSH 0x1fff /*Mystique only*/ -#define REG_TMR0 0x2c00 -#define REG_TMR1 0x2c04 -#define REG_TMR2 0x2c08 -#define REG_TMR3 0x2c0c -#define REG_TMR4 0x2c10 -#define REG_TMR5 0x2c14 -#define REG_TMR6 0x2c18 -#define REG_TMR7 0x2c1c -#define REG_TMR8 0x2c20 -#define REG_TEXORG 0x2c24 -#define REG_TEXWIDTH 0x2c28 -#define REG_TEXHEIGHT 0x2c2c -#define REG_TEXCTL 0x2c30 -#define REG_TEXTRANS 0x2c34 -#define REG_SECADDRESS 0x2c40 -#define REG_SECEND 0x2c44 -#define REG_SOFTRAP 0x2c48 +#define REG_TMR0 0x2c00 +#define REG_TMR1 0x2c04 +#define REG_TMR2 0x2c08 +#define REG_TMR3 0x2c0c +#define REG_TMR4 0x2c10 +#define REG_TMR5 0x2c14 +#define REG_TMR6 0x2c18 +#define REG_TMR7 0x2c1c +#define REG_TMR8 0x2c20 +#define REG_TEXORG 0x2c24 +#define REG_TEXWIDTH 0x2c28 +#define REG_TEXHEIGHT 0x2c2c +#define REG_TEXCTL 0x2c30 +#define REG_TEXTRANS 0x2c34 +#define REG_SECADDRESS 0x2c40 +#define REG_SECEND 0x2c44 +#define REG_SOFTRAP 0x2c48 /*Mystique only*/ -#define REG_PALWTADD 0x3c00 -#define REG_PALDATA 0x3c01 -#define REG_PIXRDMSK 0x3c02 -#define REG_PALRDADD 0x3c03 -#define REG_X_DATAREG 0x3c0a -#define REG_CURPOSX 0x3c0c -#define REG_CURPOSY 0x3c0e +#define REG_PALWTADD 0x3c00 +#define REG_PALDATA 0x3c01 +#define REG_PIXRDMSK 0x3c02 +#define REG_PALRDADD 0x3c03 +#define REG_X_DATAREG 0x3c0a +#define REG_CURPOSX 0x3c0c +#define REG_CURPOSY 0x3c0e -#define REG_STATUS_VSYNCSTS (1 << 3) +#define REG_STATUS_VSYNCSTS (1 << 3) -#define CRTCX_R0_STARTADD_MASK (0xf << 0) -#define CRTCX_R0_OFFSET_MASK (3 << 4) +#define CRTCX_R0_STARTADD_MASK (0xf << 0) +#define CRTCX_R0_OFFSET_MASK (3 << 4) -#define CRTCX_R1_HTOTAL8 (1 << 0) +#define CRTCX_R1_HTOTAL8 (1 << 0) -#define CRTCX_R2_VTOTAL10 (1 << 0) -#define CRTCX_R2_VTOTAL11 (1 << 1) -#define CRTCX_R2_VDISPEND10 (1 << 2) -#define CRTCX_R2_VBLKSTR10 (1 << 3) -#define CRTCX_R2_VBLKSTR11 (1 << 4) -#define CRTCX_R2_VSYNCSTR10 (1 << 5) -#define CRTCX_R2_VSYNCSTR11 (1 << 6) -#define CRTCX_R2_LINECOMP10 (1 << 7) +#define CRTCX_R2_VTOTAL10 (1 << 0) +#define CRTCX_R2_VTOTAL11 (1 << 1) +#define CRTCX_R2_VDISPEND10 (1 << 2) +#define CRTCX_R2_VBLKSTR10 (1 << 3) +#define CRTCX_R2_VBLKSTR11 (1 << 4) +#define CRTCX_R2_VSYNCSTR10 (1 << 5) +#define CRTCX_R2_VSYNCSTR11 (1 << 6) +#define CRTCX_R2_LINECOMP10 (1 << 7) -#define CRTCX_R3_MGAMODE (1 << 7) +#define CRTCX_R3_MGAMODE (1 << 7) -#define XREG_XCURADDL 0x04 -#define XREG_XCURADDH 0x05 -#define XREG_XCURCTRL 0x06 +#define XREG_XCURADDL 0x04 +#define XREG_XCURADDH 0x05 +#define XREG_XCURCTRL 0x06 -#define XREG_XCURCOL0R 0x08 -#define XREG_XCURCOL0G 0x09 -#define XREG_XCURCOL0B 0x0a +#define XREG_XCURCOL0R 0x08 +#define XREG_XCURCOL0G 0x09 +#define XREG_XCURCOL0B 0x0a -#define XREG_XCURCOL1R 0x0c -#define XREG_XCURCOL1G 0x0d -#define XREG_XCURCOL1B 0x0e +#define XREG_XCURCOL1R 0x0c +#define XREG_XCURCOL1G 0x0d +#define XREG_XCURCOL1B 0x0e -#define XREG_XCURCOL2R 0x10 -#define XREG_XCURCOL2G 0x11 -#define XREG_XCURCOL2B 0x12 +#define XREG_XCURCOL2R 0x10 +#define XREG_XCURCOL2G 0x11 +#define XREG_XCURCOL2B 0x12 -#define XREG_XVREFCTRL 0x18 -#define XREG_XMULCTRL 0x19 -#define XREG_XPIXCLKCTRL 0x1a -#define XREG_XGENCTRL 0x1d -#define XREG_XMISCCTRL 0x1e +#define XREG_XVREFCTRL 0x18 +#define XREG_XMULCTRL 0x19 +#define XREG_XPIXCLKCTRL 0x1a +#define XREG_XGENCTRL 0x1d +#define XREG_XMISCCTRL 0x1e -#define XREG_XGENIOCTRL 0x2a -#define XREG_XGENIODATA 0x2b +#define XREG_XGENIOCTRL 0x2a +#define XREG_XGENIODATA 0x2b -#define XREG_XSYSPLLM 0x2c -#define XREG_XSYSPLLN 0x2d -#define XREG_XSYSPLLP 0x2e -#define XREG_XSYSPLLSTAT 0x2f +#define XREG_XSYSPLLM 0x2c +#define XREG_XSYSPLLN 0x2d +#define XREG_XSYSPLLP 0x2e +#define XREG_XSYSPLLSTAT 0x2f -#define XREG_XZOOMCTRL 0x38 +#define XREG_XZOOMCTRL 0x38 -#define XREG_XSENSETEST 0x3a +#define XREG_XSENSETEST 0x3a -#define XREG_XCRCREML 0x3c -#define XREG_XCRCREMH 0x3d -#define XREG_XCRCBITSEL 0x3e +#define XREG_XCRCREML 0x3c +#define XREG_XCRCREMH 0x3d +#define XREG_XCRCBITSEL 0x3e -#define XREG_XCOLKEYMSKL 0x40 -#define XREG_XCOLKEYMSKH 0x41 -#define XREG_XCOLKEYL 0x42 -#define XREG_XCOLKEYH 0x43 +#define XREG_XCOLKEYMSKL 0x40 +#define XREG_XCOLKEYMSKH 0x41 +#define XREG_XCOLKEYL 0x42 +#define XREG_XCOLKEYH 0x43 -#define XREG_XPIXPLLCM 0x4c -#define XREG_XPIXPLLCN 0x4d -#define XREG_XPIXPLLCP 0x4e -#define XREG_XPIXPLLSTAT 0x4f +#define XREG_XPIXPLLCM 0x4c +#define XREG_XPIXPLLCN 0x4d +#define XREG_XPIXPLLCP 0x4e +#define XREG_XPIXPLLSTAT 0x4f -#define XMISCCTRL_VGA8DAC (1 << 3) +#define XMISCCTRL_VGA8DAC (1 << 3) -#define XMULCTRL_DEPTH_MASK (7 << 0) -#define XMULCTRL_DEPTH_8 (0 << 0) -#define XMULCTRL_DEPTH_15 (1 << 0) -#define XMULCTRL_DEPTH_16 (2 << 0) -#define XMULCTRL_DEPTH_24 (3 << 0) -#define XMULCTRL_DEPTH_32_OVERLAYED (4 << 0) -#define XMULCTRL_DEPTH_2G8V16 (5 << 0) -#define XMULCTRL_DEPTH_G16V16 (6 << 0) -#define XMULCTRL_DEPTH_32 (7 << 0) +#define XMULCTRL_DEPTH_MASK (7 << 0) +#define XMULCTRL_DEPTH_8 (0 << 0) +#define XMULCTRL_DEPTH_15 (1 << 0) +#define XMULCTRL_DEPTH_16 (2 << 0) +#define XMULCTRL_DEPTH_24 (3 << 0) +#define XMULCTRL_DEPTH_32_OVERLAYED (4 << 0) +#define XMULCTRL_DEPTH_2G8V16 (5 << 0) +#define XMULCTRL_DEPTH_G16V16 (6 << 0) +#define XMULCTRL_DEPTH_32 (7 << 0) -#define XSYSPLLSTAT_SYSLOCK (1 << 6) +#define XSYSPLLSTAT_SYSLOCK (1 << 6) -#define XPIXPLLSTAT_SYSLOCK (1 << 6) +#define XPIXPLLSTAT_SYSLOCK (1 << 6) -#define XCURCTRL_CURMODE_MASK (3 << 0) -#define XCURCTRL_CURMODE_3COL (1 << 0) -#define XCURCTRL_CURMODE_XGA (2 << 0) -#define XCURCTRL_CURMODE_XWIN (3 << 0) +#define XCURCTRL_CURMODE_MASK (3 << 0) +#define XCURCTRL_CURMODE_3COL (1 << 0) +#define XCURCTRL_CURMODE_XGA (2 << 0) +#define XCURCTRL_CURMODE_XWIN (3 << 0) #define DWGCTRL_OPCODE_MASK (0xf << 0) #define DWGCTRL_OPCODE_LINE_OPEN (0x0 << 0) @@ -267,183 +266,178 @@ #define DWGCTRL_OPCODE_FBITBLT (0xc << 0) #define DWGCTRL_OPCODE_ILOAD_SCALE (0xd << 0) #define DWGCTRL_OPCODE_ILOAD_HIGHV (0xe << 0) -#define DWGCTRL_OPCODE_ILOAD_FILTER (0xf << 0) /* Not implemented. */ -#define DWGCTRL_ATYPE_MASK (7 << 4) -#define DWGCTRL_ATYPE_RPL (0 << 4) -#define DWGCTRL_ATYPE_RSTR (1 << 4) -#define DWGCTRL_ATYPE_ZI (3 << 4) -#define DWGCTRL_ATYPE_BLK (4 << 4) -#define DWGCTRL_ATYPE_I (7 << 4) -#define DWGCTRL_LINEAR (1 << 7) -#define DWGCTRL_ZMODE_MASK (7 << 8) -#define DWGCTRL_ZMODE_NOZCMP (0 << 8) -#define DWGCTRL_ZMODE_ZE (2 << 8) -#define DWGCTRL_ZMODE_ZNE (3 << 8) -#define DWGCTRL_ZMODE_ZLT (4 << 8) -#define DWGCTRL_ZMODE_ZLTE (5 << 8) -#define DWGCTRL_ZMODE_ZGT (6 << 8) -#define DWGCTRL_ZMODE_ZGTE (7 << 8) -#define DWGCTRL_SOLID (1 << 11) -#define DWGCTRL_ARZERO (1 << 12) -#define DWGCTRL_SGNZERO (1 << 13) -#define DWGCTRL_SHTZERO (1 << 14) -#define DWGCTRL_BOP_MASK (0xf << 16) -#define DWGCTRL_TRANS_SHIFT (20) -#define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) -#define DWGCTRL_BLTMOD_MASK (0xf << 25) -#define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) -#define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) -#define DWGCTRL_BLTMOD_BU32BGR (0x3 << 25) -#define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) -#define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) -#define DWGCTRL_BLTMOD_BUYUV (0xe << 25) -#define DWGCTRL_BLTMOD_BU24RGB (0xf << 25) -#define DWGCTRL_PATTERN (1 << 29) -#define DWGCTRL_TRANSC (1 << 30) -#define BOP(x) ((x) << 16) +#define DWGCTRL_OPCODE_ILOAD_FILTER (0xf << 0) /* Not implemented. */ +#define DWGCTRL_ATYPE_MASK (7 << 4) +#define DWGCTRL_ATYPE_RPL (0 << 4) +#define DWGCTRL_ATYPE_RSTR (1 << 4) +#define DWGCTRL_ATYPE_ZI (3 << 4) +#define DWGCTRL_ATYPE_BLK (4 << 4) +#define DWGCTRL_ATYPE_I (7 << 4) +#define DWGCTRL_LINEAR (1 << 7) +#define DWGCTRL_ZMODE_MASK (7 << 8) +#define DWGCTRL_ZMODE_NOZCMP (0 << 8) +#define DWGCTRL_ZMODE_ZE (2 << 8) +#define DWGCTRL_ZMODE_ZNE (3 << 8) +#define DWGCTRL_ZMODE_ZLT (4 << 8) +#define DWGCTRL_ZMODE_ZLTE (5 << 8) +#define DWGCTRL_ZMODE_ZGT (6 << 8) +#define DWGCTRL_ZMODE_ZGTE (7 << 8) +#define DWGCTRL_SOLID (1 << 11) +#define DWGCTRL_ARZERO (1 << 12) +#define DWGCTRL_SGNZERO (1 << 13) +#define DWGCTRL_SHTZERO (1 << 14) +#define DWGCTRL_BOP_MASK (0xf << 16) +#define DWGCTRL_TRANS_SHIFT (20) +#define DWGCTRL_TRANS_MASK (0xf << DWGCTRL_TRANS_SHIFT) +#define DWGCTRL_BLTMOD_MASK (0xf << 25) +#define DWGCTRL_BLTMOD_BMONOLEF (0x0 << 25) +#define DWGCTRL_BLTMOD_BFCOL (0x2 << 25) +#define DWGCTRL_BLTMOD_BU32BGR (0x3 << 25) +#define DWGCTRL_BLTMOD_BMONOWF (0x4 << 25) +#define DWGCTRL_BLTMOD_BU32RGB (0x7 << 25) +#define DWGCTRL_BLTMOD_BUYUV (0xe << 25) +#define DWGCTRL_BLTMOD_BU24RGB (0xf << 25) +#define DWGCTRL_PATTERN (1 << 29) +#define DWGCTRL_TRANSC (1 << 30) +#define BOP(x) ((x) << 16) -#define MACCESS_PWIDTH_MASK (3 << 0) -#define MACCESS_PWIDTH_8 (0 << 0) -#define MACCESS_PWIDTH_16 (1 << 0) -#define MACCESS_PWIDTH_32 (2 << 0) -#define MACCESS_PWIDTH_24 (3 << 0) -#define MACCESS_TLUTLOAD (1 << 29) -#define MACCESS_NODITHER (1 << 30) -#define MACCESS_DIT555 (1 << 31) +#define MACCESS_PWIDTH_MASK (3 << 0) +#define MACCESS_PWIDTH_8 (0 << 0) +#define MACCESS_PWIDTH_16 (1 << 0) +#define MACCESS_PWIDTH_32 (2 << 0) +#define MACCESS_PWIDTH_24 (3 << 0) +#define MACCESS_TLUTLOAD (1 << 29) +#define MACCESS_NODITHER (1 << 30) +#define MACCESS_DIT555 (1 << 31) -#define PITCH_MASK 0x7e0 -#define PITCH_YLIN (1 << 15) +#define PITCH_MASK 0x7e0 +#define PITCH_YLIN (1 << 15) -#define SGN_SDYDXL (1 << 0) -#define SGN_SCANLEFT (1 << 0) -#define SGN_SDXL (1 << 1) -#define SGN_SDY (1 << 2) -#define SGN_SDXR (1 << 5) +#define SGN_SDYDXL (1 << 0) +#define SGN_SCANLEFT (1 << 0) +#define SGN_SDXL (1 << 1) +#define SGN_SDY (1 << 2) +#define SGN_SDXR (1 << 5) -#define DMA_ADDR_MASK 0xfffffffc -#define DMA_MODE_MASK 3 +#define DMA_ADDR_MASK 0xfffffffc +#define DMA_MODE_MASK 3 -#define DMA_MODE_REG 0 -#define DMA_MODE_BLIT 1 -#define DMA_MODE_VECTOR 2 +#define DMA_MODE_REG 0 +#define DMA_MODE_BLIT 1 +#define DMA_MODE_VECTOR 2 -#define STATUS_SOFTRAPEN (1 << 0) -#define STATUS_VSYNCPEN (1 << 4) -#define STATUS_VLINEPEN (1 << 5) -#define STATUS_DWGENGSTS (1 << 16) -#define STATUS_ENDPRDMASTS (1 << 17) +#define STATUS_SOFTRAPEN (1 << 0) +#define STATUS_VSYNCPEN (1 << 4) +#define STATUS_VLINEPEN (1 << 5) +#define STATUS_DWGENGSTS (1 << 16) +#define STATUS_ENDPRDMASTS (1 << 17) -#define ICLEAR_SOFTRAPICLR (1 << 0) -#define ICLEAR_VLINEICLR (1 << 5) +#define ICLEAR_SOFTRAPICLR (1 << 0) +#define ICLEAR_VLINEICLR (1 << 5) -#define IEN_SOFTRAPEN (1 << 0) +#define IEN_SOFTRAPEN (1 << 0) -#define TEXCTL_TEXFORMAT_MASK (7 << 0) -#define TEXCTL_TEXFORMAT_TW4 (0 << 0) -#define TEXCTL_TEXFORMAT_TW8 (1 << 0) -#define TEXCTL_TEXFORMAT_TW15 (2 << 0) -#define TEXCTL_TEXFORMAT_TW16 (3 << 0) -#define TEXCTL_TEXFORMAT_TW12 (4 << 0) -#define TEXCTL_PALSEL_MASK (0xf << 4) -#define TEXCTL_TPITCH_SHIFT (16) -#define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) -#define TEXCTL_NPCEN (1 << 21) -#define TEXCTL_DECALCKEY (1 << 24) -#define TEXCTL_TAKEY (1 << 25) -#define TEXCTL_TAMASK (1 << 26) -#define TEXCTL_CLAMPV (1 << 27) -#define TEXCTL_CLAMPU (1 << 28) -#define TEXCTL_TMODULATE (1 << 29) -#define TEXCTL_STRANS (1 << 30) -#define TEXCTL_ITRANS (1 << 31) +#define TEXCTL_TEXFORMAT_MASK (7 << 0) +#define TEXCTL_TEXFORMAT_TW4 (0 << 0) +#define TEXCTL_TEXFORMAT_TW8 (1 << 0) +#define TEXCTL_TEXFORMAT_TW15 (2 << 0) +#define TEXCTL_TEXFORMAT_TW16 (3 << 0) +#define TEXCTL_TEXFORMAT_TW12 (4 << 0) +#define TEXCTL_PALSEL_MASK (0xf << 4) +#define TEXCTL_TPITCH_SHIFT (16) +#define TEXCTL_TPITCH_MASK (7 << TEXCTL_TPITCH_SHIFT) +#define TEXCTL_NPCEN (1 << 21) +#define TEXCTL_DECALCKEY (1 << 24) +#define TEXCTL_TAKEY (1 << 25) +#define TEXCTL_TAMASK (1 << 26) +#define TEXCTL_CLAMPV (1 << 27) +#define TEXCTL_CLAMPU (1 << 28) +#define TEXCTL_TMODULATE (1 << 29) +#define TEXCTL_STRANS (1 << 30) +#define TEXCTL_ITRANS (1 << 31) -#define TEXHEIGHT_TH_MASK (0x3f << 0) -#define TEXHEIGHT_THMASK_SHIFT (18) -#define TEXHEIGHT_THMASK_MASK (0x7ff << TEXHEIGHT_THMASK_SHIFT) +#define TEXHEIGHT_TH_MASK (0x3f << 0) +#define TEXHEIGHT_THMASK_SHIFT (18) +#define TEXHEIGHT_THMASK_MASK (0x7ff << TEXHEIGHT_THMASK_SHIFT) -#define TEXWIDTH_TW_MASK (0x3f << 0) -#define TEXWIDTH_TWMASK_SHIFT (18) -#define TEXWIDTH_TWMASK_MASK (0x7ff << TEXWIDTH_TWMASK_SHIFT) +#define TEXWIDTH_TW_MASK (0x3f << 0) +#define TEXWIDTH_TWMASK_SHIFT (18) +#define TEXWIDTH_TWMASK_MASK (0x7ff << TEXWIDTH_TWMASK_SHIFT) -#define TEXTRANS_TCKEY_MASK (0xffff) -#define TEXTRANS_TKMASK_SHIFT (16) -#define TEXTRANS_TKMASK_MASK (0xffff << TEXTRANS_TKMASK_SHIFT) +#define TEXTRANS_TCKEY_MASK (0xffff) +#define TEXTRANS_TKMASK_SHIFT (16) +#define TEXTRANS_TKMASK_MASK (0xffff << TEXTRANS_TKMASK_SHIFT) -#define DITHER_565 0 -#define DITHER_NONE_565 1 -#define DITHER_555 2 -#define DITHER_NONE_555 3 +#define DITHER_565 0 +#define DITHER_NONE_565 1 +#define DITHER_555 2 +#define DITHER_NONE_555 3 /*PCI configuration registers*/ #define OPTION_INTERLEAVE (1 << 12) -enum -{ - MGA_2064W, /*Millennium*/ - MGA_1064SG, /*Mystique*/ - MGA_1164SG, /*Mystique 220*/ +enum { + MGA_2064W, /*Millennium*/ + MGA_1064SG, /*Mystique*/ + MGA_1164SG, /*Mystique 220*/ }; -enum -{ +enum { FIFO_INVALID = (0x00 << 24), FIFO_WRITE_CTRL_BYTE = (0x01 << 24), FIFO_WRITE_CTRL_LONG = (0x02 << 24), FIFO_WRITE_ILOAD_LONG = (0x03 << 24) }; -enum -{ - DMA_STATE_IDLE = 0, - DMA_STATE_PRI, - DMA_STATE_SEC +enum { + DMA_STATE_IDLE = 0, + DMA_STATE_PRI, + DMA_STATE_SEC }; - typedef struct { uint32_t addr_type; uint32_t val; } fifo_entry_t; -typedef struct mystique_t -{ +typedef struct mystique_t { svga_t svga; rom_t bios_rom; - int type; + int type; mem_mapping_t lfb_mapping, ctrl_mapping, - iload_mapping; + iload_mapping; uint8_t int_line, xcurctrl, - xsyspllm, xsysplln, xsyspllp, - xgenioctrl, xgeniodata, - xmulctrl, xgenctrl, - xmiscctrl, xpixclkctrl, - xvrefctrl, ien, dmamod, - dmadatasiz, dirdatasiz, - xcolkeymskl, xcolkeymskh, - xcolkeyl, xcolkeyh, - xcrcbitsel; + xsyspllm, xsysplln, xsyspllp, + xgenioctrl, xgeniodata, + xmulctrl, xgenctrl, + xmiscctrl, xpixclkctrl, + xvrefctrl, ien, dmamod, + dmadatasiz, dirdatasiz, + xcolkeymskl, xcolkeymskh, + xcolkeyl, xcolkeyh, + xcrcbitsel; uint8_t pci_regs[256], crtcext_regs[6], - xreg_regs[256], dmamap[16]; + xreg_regs[256], dmamap[16]; int card, vram_size, crtcext_idx, xreg_idx, - xzoomctrl, - pixel_count, trap_count; + xzoomctrl, + pixel_count, trap_count; volatile int busy, blitter_submit_refcount, - blitter_submit_dma_refcount, blitter_complete_refcount, - endprdmasts_pending, softrap_pending, - fifo_read_idx, fifo_write_idx; + blitter_submit_dma_refcount, blitter_complete_refcount, + endprdmasts_pending, softrap_pending, + fifo_read_idx, fifo_write_idx; uint32_t vram_mask, vram_mask_w, vram_mask_l, - lfb_base, ctrl_base, iload_base, - ma_latch_old, maccess, mctlwtst, maccess_running, - status, softrap_pending_val; + lfb_base, ctrl_base, iload_base, + ma_latch_old, maccess, mctlwtst, maccess_running, + status, softrap_pending_val; uint64_t blitter_time, status_time; @@ -457,65 +451,65 @@ typedef struct mystique_t struct { - int m, n, p, s; + int m, n, p, s; } xpixpll[3]; struct { - uint8_t funcnt, stylelen, - dmamod; + uint8_t funcnt, stylelen, + dmamod; - int16_t fxleft, fxright, - xdst; + int16_t fxleft, fxright, + xdst; - uint16_t cxleft, cxright, - length; + uint16_t cxleft, cxright, + length; - int xoff, yoff, selline, ydst, - length_cur, iload_rem_count, idump_end_of_line, words, - ta_key, ta_mask, lastpix_r, lastpix_g, - lastpix_b, highv_line, beta, dither; + int xoff, yoff, selline, ydst, + length_cur, iload_rem_count, idump_end_of_line, words, + ta_key, ta_mask, lastpix_r, lastpix_g, + lastpix_b, highv_line, beta, dither; - int pattern[8][8]; + int pattern[8][8]; - uint32_t dwgctrl, dwgctrl_running, bcol, fcol, - pitch, plnwt, ybot, ydstorg, - ytop, texorg, texwidth, texheight, - texctl, textrans, zorg, ydst_lin, - src_addr, z_base, iload_rem_data, highv_data; + uint32_t dwgctrl, dwgctrl_running, bcol, fcol, + pitch, plnwt, ybot, ydstorg, + ytop, texorg, texwidth, texheight, + texctl, textrans, zorg, ydst_lin, + src_addr, z_base, iload_rem_data, highv_data; - uint32_t src[4], ar[7], - dr[16], tmr[9]; + uint32_t src[4], ar[7], + dr[16], tmr[9]; - struct - { - int sdydxl, scanleft, sdxl, sdy, - sdxr; - } sgn; + struct + { + int sdydxl, scanleft, sdxl, sdy, + sdxr; + } sgn; } dwgreg; struct { - uint8_t r, g, b; + uint8_t r, g, b; } lut[256]; struct { - uint16_t pos_x, pos_y, - addr; - uint32_t col[3]; + uint16_t pos_x, pos_y, + addr; + uint32_t col[3]; } cursor; struct { - int pri_pos, sec_pos, iload_pos, - pri_state, sec_state, iload_state, state; + int pri_pos, sec_pos, iload_pos, + pri_state, sec_state, iload_state, state; - uint32_t primaddress, primend, secaddress, secend, - pri_header, sec_header, - iload_header; + uint32_t primaddress, primend, secaddress, secend, + pri_header, sec_header, + iload_header; - mutex_t *lock; + mutex_t *lock; } dma; uint8_t thread_run; @@ -523,292 +517,291 @@ typedef struct mystique_t void *i2c, *i2c_ddc, *ddc; } mystique_t; - -static const uint8_t trans_masks[16][16] = -{ +static const uint8_t trans_masks[16][16] = { + // clang-format off { - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1, - 1, 1, 1, 1 + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1, + 1, 1, 1, 1 }, { - 1, 0, 1, 0, - 0, 1, 0, 1, - 1, 0, 1, 0, - 0, 1, 0, 1 + 1, 0, 1, 0, + 0, 1, 0, 1, + 1, 0, 1, 0, + 0, 1, 0, 1 }, { - 0, 1, 0, 1, - 1, 0, 1, 0, - 0, 1, 0, 1, - 1, 0, 1, 0 + 0, 1, 0, 1, + 1, 0, 1, 0, + 0, 1, 0, 1, + 1, 0, 1, 0 }, { - 1, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 1, 0, - 0, 0, 0, 0 + 1, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 1, 0, + 0, 0, 0, 0 }, { - 0, 1, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 0, 0, 0 + 0, 1, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 0, 0, 0 }, { - 0, 0, 0, 0, - 1, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 1, 0 + 0, 0, 0, 0, + 1, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 1, 0 }, { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 1 + 0, 0, 0, 0, + 0, 1, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 1 }, { - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 0 + 1, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0 }, { - 0, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 1 + 0, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1 }, { - 0, 0, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 0, 0 }, { - 0, 0, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 0, 0 + 0, 0, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 0, 0 }, { - 0, 0, 0, 0, - 1, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 1, 0 + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 1, 0 }, { - 0, 1, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 1, - 0, 0, 0, 0 + 0, 1, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 0, 0, 0 }, { - 0, 0, 0, 0, - 0, 0, 0, 1, - 0, 0, 0, 0, - 0, 1, 0, 0 + 0, 0, 0, 0, + 0, 0, 0, 1, + 0, 0, 0, 0, + 0, 1, 0, 0 }, { - 0, 0, 1, 0, - 0, 0, 0, 0, - 1, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 1, 0, + 0, 0, 0, 0, + 1, 0, 0, 0, + 0, 0, 0, 0 }, { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 } + // clang-format on }; +static int8_t dither5[256][2][2]; +static int8_t dither6[256][2][2]; -static int8_t dither5[256][2][2]; -static int8_t dither6[256][2][2]; +static video_timings_t timing_matrox_millennium = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 10, .read_w = 10, .read_l = 10 }; +static video_timings_t timing_matrox_mystique = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 }; -static video_timings_t timing_matrox_millennium = {VIDEO_PCI, 2, 2, 1, 10, 10, 10}; -static video_timings_t timing_matrox_mystique = {VIDEO_PCI, 4, 4, 4, 10, 10, 10}; +static void mystique_start_blit(mystique_t *mystique); +static void mystique_update_irqs(mystique_t *mystique); -static void mystique_start_blit(mystique_t *mystique); -static void mystique_update_irqs(mystique_t *mystique); +static void wake_fifo_thread(mystique_t *mystique); +static void wait_fifo_idle(mystique_t *mystique); +static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); -static void wake_fifo_thread(mystique_t *mystique); -static void wait_fifo_idle(mystique_t *mystique); -static void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type); - -static uint8_t mystique_readb_linear(uint32_t addr, void *p); +static uint8_t mystique_readb_linear(uint32_t addr, void *p); static uint16_t mystique_readw_linear(uint32_t addr, void *p); static uint32_t mystique_readl_linear(uint32_t addr, void *p); -static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p); -static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p); -static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p); +static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p); +static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p); +static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p); -static void mystique_recalc_mapping(mystique_t *mystique); -static int mystique_line_compare(svga_t *svga); +static void mystique_recalc_mapping(mystique_t *mystique); +static int mystique_line_compare(svga_t *svga); -static uint8_t mystique_iload_read_b(uint32_t addr, void *p); -static uint32_t mystique_iload_read_l(uint32_t addr, void *p); -static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p); -static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p); - -static uint32_t blit_idump_read(mystique_t *mystique); -static void blit_iload_write(mystique_t *mystique, uint32_t data, int size); +static uint8_t mystique_iload_read_b(uint32_t addr, void *p); +static uint32_t mystique_iload_read_l(uint32_t addr, void *p); +static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p); +static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p); +static uint32_t blit_idump_read(mystique_t *mystique); +static void blit_iload_write(mystique_t *mystique, uint32_t data, int size); void mystique_out(uint16_t addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; - uint8_t old; + mystique_t *mystique = (mystique_t *) p; + svga_t *svga = &mystique->svga; + uint8_t old; - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3c8: - mystique->xreg_idx = val; - case 0x3c6: case 0x3c7: case 0x3c9: - if (mystique->type == MGA_2064W) - { - tvp3026_ramdac_out(addr, 0, 0, val, svga->ramdac, svga); - return; - } - break; + case 0x3c8: + mystique->xreg_idx = val; + case 0x3c6: + case 0x3c7: + case 0x3c9: + if (mystique->type == MGA_2064W) { + tvp3026_ramdac_out(addr, 0, 0, val, svga->ramdac, svga); + return; + } + break; - case 0x3cf: - if ((svga->gdcaddr & 15) == 6 && svga->gdcreg[6] != val) { - svga->gdcreg[svga->gdcaddr & 15] = val; - mystique_recalc_mapping(mystique); - return; - } - break; + case 0x3cf: + if ((svga->gdcaddr & 15) == 6 && svga->gdcreg[6] != val) { + svga->gdcreg[svga->gdcaddr & 15] = val; + mystique_recalc_mapping(mystique); + return; + } + break; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if (((svga->crtcreg & 0x3f) < 7) && (svga->crtc[0x11] & 0x80)) - return; - if (((svga->crtcreg & 0x3f) == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg & 0x3f]; - svga->crtc[svga->crtcreg & 0x3f] = val; - if (old != val) { - if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) { - if (((svga->crtcreg & 0x3f) == 0xc) || ((svga->crtcreg & 0x3f) == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - if (svga->crtcreg == 0x11) { - if (!(val & 0x10)) - mystique->status &= ~STATUS_VSYNCPEN; - mystique_update_irqs(mystique); - } - } - break; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (((svga->crtcreg & 0x3f) < 7) && (svga->crtc[0x11] & 0x80)) + return; + if (((svga->crtcreg & 0x3f) == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg & 0x3f]; + svga->crtc[svga->crtcreg & 0x3f] = val; + if (old != val) { + if ((svga->crtcreg & 0x3f) < 0xE || (svga->crtcreg & 0x3f) > 0x10) { + if (((svga->crtcreg & 0x3f) == 0xc) || ((svga->crtcreg & 0x3f) == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + if (svga->crtcreg == 0x11) { + if (!(val & 0x10)) + mystique->status &= ~STATUS_VSYNCPEN; + mystique_update_irqs(mystique); + } + } + break; - case 0x3de: - mystique->crtcext_idx = val; - break; - case 0x3df: - if (mystique->crtcext_idx < 6) - mystique->crtcext_regs[mystique->crtcext_idx] = val; - if (mystique->crtcext_idx == 1) - svga->dpms = !!(val & 0x30); - if (mystique->crtcext_idx < 4) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 3) { - if (val & CRTCX_R3_MGAMODE) - svga->fb_only = 1; - else - svga->fb_only = 0; - svga_recalctimings(svga); - } - if (mystique->crtcext_idx == 4) { - if (svga->gdcreg[6] & 0xc) { - /*64k banks*/ - svga->read_bank = (val & 0x7f) << 16; - svga->write_bank = (val & 0x7f) << 16; - } else { - /*128k banks*/ - svga->read_bank = (val & 0x7e) << 16; - svga->write_bank = (val & 0x7e) << 16; - } - } - break; + case 0x3de: + mystique->crtcext_idx = val; + break; + case 0x3df: + if (mystique->crtcext_idx < 6) + mystique->crtcext_regs[mystique->crtcext_idx] = val; + if (mystique->crtcext_idx == 1) + svga->dpms = !!(val & 0x30); + if (mystique->crtcext_idx < 4) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 3) { + if (val & CRTCX_R3_MGAMODE) + svga->fb_only = 1; + else + svga->fb_only = 0; + svga_recalctimings(svga); + } + if (mystique->crtcext_idx == 4) { + if (svga->gdcreg[6] & 0xc) { + /*64k banks*/ + svga->read_bank = (val & 0x7f) << 16; + svga->write_bank = (val & 0x7f) << 16; + } else { + /*128k banks*/ + svga->read_bank = (val & 0x7e) << 16; + svga->write_bank = (val & 0x7e) << 16; + } + } + break; } svga_out(addr, val, svga); } - uint8_t mystique_in(uint16_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; - uint8_t temp = 0xff; + mystique_t *mystique = (mystique_t *) p; + svga_t *svga = &mystique->svga; + uint8_t temp = 0xff; - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) - addr ^= 0x60; + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3c1: - if (svga->attraddr >= 0x15) - temp = 0; - else - temp = svga->attrregs[svga->attraddr]; - break; + case 0x3c1: + if (svga->attraddr >= 0x15) + temp = 0; + else + temp = svga->attrregs[svga->attraddr]; + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (mystique->type == MGA_2064W) - temp = tvp3026_ramdac_in(addr, 0, 0, svga->ramdac, svga); - else - temp = svga_in(addr, svga); - break; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (mystique->type == MGA_2064W) + temp = tvp3026_ramdac_in(addr, 0, 0, svga->ramdac, svga); + else + temp = svga_in(addr, svga); + break; - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - if ((svga->crtcreg >= 0x19 && svga->crtcreg <= 0x21) || - svga->crtcreg == 0x23 || svga->crtcreg == 0x25 || svga->crtcreg >= 0x27) - temp = 0; - else - temp = svga->crtc[svga->crtcreg & 0x3f]; - break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if ((svga->crtcreg >= 0x19 && svga->crtcreg <= 0x21) || svga->crtcreg == 0x23 || svga->crtcreg == 0x25 || svga->crtcreg >= 0x27) + temp = 0; + else + temp = svga->crtc[svga->crtcreg & 0x3f]; + break; - case 0x3de: - temp = mystique->crtcext_idx; - break; + case 0x3de: + temp = mystique->crtcext_idx; + break; - case 0x3df: - if (mystique->crtcext_idx < 6) - temp = mystique->crtcext_regs[mystique->crtcext_idx]; - break; + case 0x3df: + if (mystique->crtcext_idx < 6) + temp = mystique->crtcext_regs[mystique->crtcext_idx]; + break; - default: - temp = svga_in(addr, svga); - break; + default: + temp = svga_in(addr, svga); + break; } return temp; } - static int mystique_line_compare(svga_t *svga) { - mystique_t *mystique = (mystique_t *)svga->p; + mystique_t *mystique = (mystique_t *) svga->p; mystique->status |= STATUS_VLINEPEN; mystique_update_irqs(mystique); @@ -819,241 +812,254 @@ mystique_line_compare(svga_t *svga) static void mystique_vsync_callback(svga_t *svga) { - mystique_t *mystique = (mystique_t *)svga->p; + mystique_t *mystique = (mystique_t *) svga->p; if (svga->crtc[0x11] & 0x10) { - mystique->status |= STATUS_VSYNCPEN; - mystique_update_irqs(mystique); + mystique->status |= STATUS_VSYNCPEN; + mystique_update_irqs(mystique); } } static float mystique_getclock(int clock, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; - int m = mystique->xpixpll[2].m; - int n = mystique->xpixpll[2].n; - int pl = mystique->xpixpll[2].p; + int m = mystique->xpixpll[2].m; + int n = mystique->xpixpll[2].n; + int pl = mystique->xpixpll[2].p; - float fvco = 14318181.0 * (n + 1) / (m + 1); - float fo = fvco / (pl + 1); + float fvco = 14318181.0 * (n + 1) / (m + 1); + float fo = fvco / (pl + 1); - return fo; + return fo; } void mystique_recalctimings(svga_t *svga) { - mystique_t *mystique = (mystique_t *)svga->p; - int clk_sel = (svga->miscout >> 2) & 3; + mystique_t *mystique = (mystique_t *) svga->p; + int clk_sel = (svga->miscout >> 2) & 3; - svga->clock = (cpuclock * (float)(1ull << 32)) / svga->getclock(clk_sel & 2, svga->clock_gen); + svga->clock = (cpuclock * (float) (1ull << 32)) / svga->getclock(clk_sel & 2, svga->clock_gen); if (mystique->crtcext_regs[1] & CRTCX_R1_HTOTAL8) - svga->htotal += 0x100; + svga->htotal += 0x100; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL10) - svga->vtotal += 0x400; + svga->vtotal += 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VTOTAL11) - svga->vtotal += 0x800; + svga->vtotal += 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VDISPEND10) - svga->dispend += 0x400; + svga->dispend += 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR10) - svga->vblankstart += 0x400; + svga->vblankstart += 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VBLKSTR11) - svga->vblankstart += 0x800; + svga->vblankstart += 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR10) - svga->vsyncstart += 0x400; + svga->vsyncstart += 0x400; if (mystique->crtcext_regs[2] & CRTCX_R2_VSYNCSTR11) - svga->vsyncstart += 0x800; + svga->vsyncstart += 0x800; if (mystique->crtcext_regs[2] & CRTCX_R2_LINECOMP10) - svga->split += 0x400; + svga->split += 0x400; if (mystique->type == MGA_2064W) - tvp3026_recalctimings(svga->ramdac, svga); - else - svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); + tvp3026_recalctimings(svga->ramdac, svga); + else + svga->interlace = !!(mystique->crtcext_regs[0] & 0x80); if (mystique->crtcext_regs[3] & CRTCX_R3_MGAMODE) { - svga->packed_chain4 = 1; - svga->lowres = 0; - svga->char_width = 8; - svga->hdisp = (svga->crtc[1] + 1) * 8; - svga->hdisp_time = svga->hdisp; - svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); - svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | - (svga->crtc[0xc] << 8) | svga->crtc[0xd]; - if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) - { - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } - if (mystique->type >= MGA_1064SG) { - /*Mystique, unlike most SVGA cards, allows display start to take - effect mid-screen*/ - if (svga->ma_latch != mystique->ma_latch_old) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); - else - svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); - mystique->ma_latch_old = svga->ma_latch; - } + svga->packed_chain4 = 1; + svga->lowres = 0; + svga->char_width = 8; + svga->hdisp = (svga->crtc[1] + 1) * 8; + svga->hdisp_time = svga->hdisp; + svga->rowoffset = svga->crtc[0x13] | ((mystique->crtcext_regs[0] & CRTCX_R0_OFFSET_MASK) << 4); + svga->ma_latch = ((mystique->crtcext_regs[0] & CRTCX_R0_STARTADD_MASK) << 16) | (svga->crtc[0xc] << 8) | svga->crtc[0xd]; + if (mystique->pci_regs[0x41] & (OPTION_INTERLEAVE >> 8)) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } + if (mystique->type >= MGA_1064SG) { + /*Mystique, unlike most SVGA cards, allows display start to take + effect mid-screen*/ + if (svga->ma_latch != mystique->ma_latch_old) { + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2) + (svga->rowoffset << 1); + else + svga->ma = svga->maback = (svga->maback - (mystique->ma_latch_old << 2)) + (svga->ma_latch << 2); + mystique->ma_latch_old = svga->ma_latch; + } - switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { - case XMULCTRL_DEPTH_8: - case XMULCTRL_DEPTH_2G8V16: - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - break; - case XMULCTRL_DEPTH_15: - case XMULCTRL_DEPTH_G16V16: - svga->render = svga_render_15bpp_highres; - svga->bpp = 15; - break; - case XMULCTRL_DEPTH_16: - svga->render = svga_render_16bpp_highres; - svga->bpp = 16; - break; - case XMULCTRL_DEPTH_24: - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - break; - case XMULCTRL_DEPTH_32: - case XMULCTRL_DEPTH_32_OVERLAYED: - svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - break; - } - } else { - switch (svga->bpp) - { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - break; - case 16: - svga->render = svga_render_16bpp_highres; - break; - case 24: - svga->render = svga_render_24bpp_highres; - break; - case 32: - svga->render = svga_render_32bpp_highres; - break; - } - } - svga->line_compare = mystique_line_compare; + switch (mystique->xmulctrl & XMULCTRL_DEPTH_MASK) { + case XMULCTRL_DEPTH_8: + case XMULCTRL_DEPTH_2G8V16: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case XMULCTRL_DEPTH_15: + case XMULCTRL_DEPTH_G16V16: + svga->render = svga_render_15bpp_highres; + svga->bpp = 15; + break; + case XMULCTRL_DEPTH_16: + svga->render = svga_render_16bpp_highres; + svga->bpp = 16; + break; + case XMULCTRL_DEPTH_24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case XMULCTRL_DEPTH_32: + case XMULCTRL_DEPTH_32_OVERLAYED: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; + } + } else { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } + svga->line_compare = mystique_line_compare; } else { - svga->packed_chain4 = 0; - svga->line_compare = NULL; - if (mystique->type >= MGA_1064SG) - svga->bpp = 8; + svga->packed_chain4 = 0; + svga->line_compare = NULL; + if (mystique->type >= MGA_1064SG) + svga->bpp = 8; } } - -static -void mystique_recalc_mapping(mystique_t *mystique) +static void +mystique_recalc_mapping(mystique_t *mystique) { svga_t *svga = &mystique->svga; io_removehandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); if ((mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && (mystique->pci_regs[0x41] & 1)) - io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); + io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); if (!(mystique->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&mystique->ctrl_mapping); - mem_mapping_disable(&mystique->lfb_mapping); - mem_mapping_disable(&mystique->iload_mapping); - return; + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mystique->ctrl_mapping); + mem_mapping_disable(&mystique->lfb_mapping); + mem_mapping_disable(&mystique->iload_mapping); + return; } if (mystique->ctrl_base) - mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); + mem_mapping_set_addr(&mystique->ctrl_mapping, mystique->ctrl_base, 0x4000); else - mem_mapping_disable(&mystique->ctrl_mapping); + mem_mapping_disable(&mystique->ctrl_mapping); if (mystique->lfb_base) - mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); + mem_mapping_set_addr(&mystique->lfb_mapping, mystique->lfb_base, 0x800000); else - mem_mapping_disable(&mystique->lfb_mapping); + mem_mapping_disable(&mystique->lfb_mapping); if (mystique->iload_base) - mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); + mem_mapping_set_addr(&mystique->iload_mapping, mystique->iload_base, 0x800000); else - mem_mapping_disable(&mystique->iload_mapping); + mem_mapping_disable(&mystique->iload_mapping); if (mystique->pci_regs[0x41] & 1) { - switch (svga->gdcreg[6] & 0x0C) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0x1ffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - if (svga->gdcreg[6] & 0xc) { - /*64k banks*/ - svga->read_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; - svga->write_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; - } else { - /*128k banks*/ - svga->read_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; - svga->write_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; - } + switch (svga->gdcreg[6] & 0x0C) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0x1ffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + if (svga->gdcreg[6] & 0xc) { + /*64k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7f) << 16; + } else { + /*128k banks*/ + svga->read_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + svga->write_bank = (mystique->crtcext_regs[4] & 0x7e) << 16; + } } else - mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&svga->mapping); } - static void mystique_update_irqs(mystique_t *mystique) { svga_t *svga = &mystique->svga; - int irq = 0; + int irq = 0; if ((mystique->status & mystique->ien) & STATUS_SOFTRAPEN) - irq = 1; + irq = 1; if ((mystique->status & STATUS_VSYNCPEN) && (svga->crtc[0x11] & 0x30) == 0x10) - irq = 1; + irq = 1; if (irq) - pci_set_irq(mystique->card, PCI_INTA); + pci_set_irq(mystique->card, PCI_INTA); else - pci_clear_irq(mystique->card, PCI_INTA); + pci_clear_irq(mystique->card, PCI_INTA); } +#define READ8(addr, var) \ + switch ((addr) &3) { \ + case 0: \ + ret = (var) &0xff; \ + break; \ + case 1: \ + ret = ((var) >> 8) & 0xff; \ + break; \ + case 2: \ + ret = ((var) >> 16) & 0xff; \ + break; \ + case 3: \ + ret = ((var) >> 24) & 0xff; \ + break; \ + } -#define READ8(addr, var) switch ((addr) & 3) { \ - case 0: ret = (var) & 0xff; break; \ - case 1: ret = ((var) >> 8) & 0xff; break; \ - case 2: ret = ((var) >> 16) & 0xff; break; \ - case 3: ret = ((var) >> 24) & 0xff; break; \ - } - -#define WRITE8(addr, var, val) switch ((addr) & 3) { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } - +#define WRITE8(addr, var, val) \ + switch ((addr) &3) { \ + case 0: \ + var = (var & 0xffffff00) | (val); \ + break; \ + case 1: \ + var = (var & 0xffff00ff) | ((val) << 8); \ + break; \ + case 2: \ + var = (var & 0xff00ffff) | ((val) << 16); \ + break; \ + case 3: \ + var = (var & 0x00ffffff) | ((val) << 24); \ + break; \ + } static uint8_t mystique_read_xreg(mystique_t *mystique, int reg) @@ -1061,1340 +1067,1527 @@ mystique_read_xreg(mystique_t *mystique, int reg) uint8_t ret = 0xff; switch (reg) { - case XREG_XCURADDL: - ret = mystique->cursor.addr & 0xff; - break; - case XREG_XCURADDH: - ret = mystique->cursor.addr >> 8; - break; - case XREG_XCURCTRL: - ret = mystique->xcurctrl; - break; + case XREG_XCURADDL: + ret = mystique->cursor.addr & 0xff; + break; + case XREG_XCURADDH: + ret = mystique->cursor.addr >> 8; + break; + case XREG_XCURCTRL: + ret = mystique->xcurctrl; + break; - case XREG_XCURCOL0R: case XREG_XCURCOL0G: case XREG_XCURCOL0B: - READ8(reg, mystique->cursor.col[0]); - break; - case XREG_XCURCOL1R: case XREG_XCURCOL1G: case XREG_XCURCOL1B: - READ8(reg, mystique->cursor.col[1]); - break; - case XREG_XCURCOL2R: case XREG_XCURCOL2G: case XREG_XCURCOL2B: - READ8(reg, mystique->cursor.col[2]); - break; + case XREG_XCURCOL0R: + case XREG_XCURCOL0G: + case XREG_XCURCOL0B: + READ8(reg, mystique->cursor.col[0]); + break; + case XREG_XCURCOL1R: + case XREG_XCURCOL1G: + case XREG_XCURCOL1B: + READ8(reg, mystique->cursor.col[1]); + break; + case XREG_XCURCOL2R: + case XREG_XCURCOL2G: + case XREG_XCURCOL2B: + READ8(reg, mystique->cursor.col[2]); + break; - case XREG_XMULCTRL: - ret = mystique->xmulctrl; - break; + case XREG_XMULCTRL: + ret = mystique->xmulctrl; + break; - case XREG_XMISCCTRL: - ret = mystique->xmiscctrl; - break; + case XREG_XMISCCTRL: + ret = mystique->xmiscctrl; + break; - case XREG_XGENCTRL: - ret = mystique->xgenctrl; - break; + case XREG_XGENCTRL: + ret = mystique->xgenctrl; + break; - case XREG_XVREFCTRL: - ret = mystique->xvrefctrl; - break; + case XREG_XVREFCTRL: + ret = mystique->xvrefctrl; + break; - case XREG_XGENIOCTRL: - ret = mystique->xgenioctrl; - break; - case XREG_XGENIODATA: - ret = mystique->xgeniodata & 0xf0; - if (i2c_gpio_get_scl(mystique->i2c_ddc)) - ret |= 0x08; - if (i2c_gpio_get_scl(mystique->i2c)) - ret |= 0x04; - if (i2c_gpio_get_sda(mystique->i2c_ddc)) - ret |= 0x02; - if (i2c_gpio_get_sda(mystique->i2c)) - ret |= 0x01; - break; + case XREG_XGENIOCTRL: + ret = mystique->xgenioctrl; + break; + case XREG_XGENIODATA: + ret = mystique->xgeniodata & 0xf0; + if (i2c_gpio_get_scl(mystique->i2c_ddc)) + ret |= 0x08; + if (i2c_gpio_get_scl(mystique->i2c)) + ret |= 0x04; + if (i2c_gpio_get_sda(mystique->i2c_ddc)) + ret |= 0x02; + if (i2c_gpio_get_sda(mystique->i2c)) + ret |= 0x01; + break; - case XREG_XSYSPLLM: - ret = mystique->xsyspllm; - break; - case XREG_XSYSPLLN: - ret = mystique->xsysplln; - break; - case XREG_XSYSPLLP: - ret = mystique->xsyspllp; - break; + case XREG_XSYSPLLM: + ret = mystique->xsyspllm; + break; + case XREG_XSYSPLLN: + ret = mystique->xsysplln; + break; + case XREG_XSYSPLLP: + ret = mystique->xsyspllp; + break; - case XREG_XZOOMCTRL: - ret = mystique->xzoomctrl; - break; + case XREG_XZOOMCTRL: + ret = mystique->xzoomctrl; + break; - case XREG_XSENSETEST: - ret = 0; - if (mystique->svga.vgapal[0].b < 0x80) - ret |= 1; - if (mystique->svga.vgapal[0].g < 0x80) - ret |= 2; - if (mystique->svga.vgapal[0].r < 0x80) - ret |= 4; - break; + case XREG_XSENSETEST: + ret = 0; + if (mystique->svga.vgapal[0].b < 0x80) + ret |= 1; + if (mystique->svga.vgapal[0].g < 0x80) + ret |= 2; + if (mystique->svga.vgapal[0].r < 0x80) + ret |= 4; + break; - case XREG_XCRCREML: /*CRC not implemented*/ - ret = 0; - break; - case XREG_XCRCREMH: - ret = 0; - break; - case XREG_XCRCBITSEL: - ret = mystique->xcrcbitsel; - break; + case XREG_XCRCREML: /*CRC not implemented*/ + ret = 0; + break; + case XREG_XCRCREMH: + ret = 0; + break; + case XREG_XCRCBITSEL: + ret = mystique->xcrcbitsel; + break; - case XREG_XCOLKEYMSKL: - ret = mystique->xcolkeymskl; - break; - case XREG_XCOLKEYMSKH: - ret = mystique->xcolkeymskh; - break; - case XREG_XCOLKEYL: - ret = mystique->xcolkeyl; - break; - case XREG_XCOLKEYH: - ret = mystique->xcolkeyh; - break; + case XREG_XCOLKEYMSKL: + ret = mystique->xcolkeymskl; + break; + case XREG_XCOLKEYMSKH: + ret = mystique->xcolkeymskh; + break; + case XREG_XCOLKEYL: + ret = mystique->xcolkeyl; + break; + case XREG_XCOLKEYH: + ret = mystique->xcolkeyh; + break; - case XREG_XPIXCLKCTRL: - ret = mystique->xpixclkctrl; - break; + case XREG_XPIXCLKCTRL: + ret = mystique->xpixclkctrl; + break; - case XREG_XSYSPLLSTAT: - ret = XSYSPLLSTAT_SYSLOCK; - break; + case XREG_XSYSPLLSTAT: + ret = XSYSPLLSTAT_SYSLOCK; + break; - case XREG_XPIXPLLSTAT: - ret = XPIXPLLSTAT_SYSLOCK; - break; + case XREG_XPIXPLLSTAT: + ret = XPIXPLLSTAT_SYSLOCK; + break; - case XREG_XPIXPLLCM: - ret = mystique->xpixpll[2].m; - break; - case XREG_XPIXPLLCN: - ret = mystique->xpixpll[2].n; - break; - case XREG_XPIXPLLCP: - ret = mystique->xpixpll[2].p | (mystique->xpixpll[2].s << 3); - break; + case XREG_XPIXPLLCM: + ret = mystique->xpixpll[2].m; + break; + case XREG_XPIXPLLCN: + ret = mystique->xpixpll[2].n; + break; + case XREG_XPIXPLLCP: + ret = mystique->xpixpll[2].p | (mystique->xpixpll[2].s << 3); + break; - case 0x00: case 0x20: case 0x3f: - ret = 0xff; - break; + case 0x00: + case 0x20: + case 0x3f: + ret = 0xff; + break; - default: - if (reg >= 0x50) - ret = 0xff; - break; + default: + if (reg >= 0x50) + ret = 0xff; + break; } return ret; } - static void mystique_write_xreg(mystique_t *mystique, int reg, uint8_t val) { svga_t *svga = &mystique->svga; switch (reg) { - case XREG_XCURADDL: - mystique->cursor.addr = (mystique->cursor.addr & 0x1f00) | val; - svga->hwcursor.addr = mystique->cursor.addr << 10; - break; - case XREG_XCURADDH: - mystique->cursor.addr = (mystique->cursor.addr & 0x00ff) | ((val & 0x1f) << 8); - svga->hwcursor.addr = mystique->cursor.addr << 10; - break; + case XREG_XCURADDL: + mystique->cursor.addr = (mystique->cursor.addr & 0x1f00) | val; + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; + case XREG_XCURADDH: + mystique->cursor.addr = (mystique->cursor.addr & 0x00ff) | ((val & 0x1f) << 8); + svga->hwcursor.addr = mystique->cursor.addr << 10; + break; - case XREG_XCURCTRL: - mystique->xcurctrl = val; - svga->hwcursor.ena = (val & 3) ? 1 : 0; - break; + case XREG_XCURCTRL: + mystique->xcurctrl = val; + svga->hwcursor.ena = (val & 3) ? 1 : 0; + break; - case XREG_XCURCOL0R: case XREG_XCURCOL0G: case XREG_XCURCOL0B: - WRITE8(reg, mystique->cursor.col[0], val); - break; - case XREG_XCURCOL1R: case XREG_XCURCOL1G: case XREG_XCURCOL1B: - WRITE8(reg, mystique->cursor.col[1], val); - break; - case XREG_XCURCOL2R: case XREG_XCURCOL2G: case XREG_XCURCOL2B: - WRITE8(reg, mystique->cursor.col[2], val); - break; + case XREG_XCURCOL0R: + case XREG_XCURCOL0G: + case XREG_XCURCOL0B: + WRITE8(reg, mystique->cursor.col[0], val); + break; + case XREG_XCURCOL1R: + case XREG_XCURCOL1G: + case XREG_XCURCOL1B: + WRITE8(reg, mystique->cursor.col[1], val); + break; + case XREG_XCURCOL2R: + case XREG_XCURCOL2G: + case XREG_XCURCOL2B: + WRITE8(reg, mystique->cursor.col[2], val); + break; - case XREG_XMULCTRL: - mystique->xmulctrl = val; - break; + case XREG_XMULCTRL: + mystique->xmulctrl = val; + break; - case XREG_XMISCCTRL: - mystique->xmiscctrl = val; - svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); - break; + case XREG_XMISCCTRL: + mystique->xmiscctrl = val; + svga_set_ramdac_type(svga, (val & XMISCCTRL_VGA8DAC) ? RAMDAC_8BIT : RAMDAC_6BIT); + break; - case XREG_XGENCTRL: - mystique->xgenctrl = val; - break; + case XREG_XGENCTRL: + mystique->xgenctrl = val; + break; - case XREG_XVREFCTRL: - mystique->xvrefctrl = val; - break; + case XREG_XVREFCTRL: + mystique->xvrefctrl = val; + break; - case XREG_XGENIOCTRL: - mystique->xgenioctrl = val; - i2c_gpio_set(mystique->i2c_ddc, !(mystique->xgenioctrl & 0x08) || (mystique->xgeniodata & 0x08), !(mystique->xgenioctrl & 0x02) || (mystique->xgeniodata & 0x02)); - i2c_gpio_set(mystique->i2c, !(mystique->xgenioctrl & 0x04) || (mystique->xgeniodata & 0x04), !(mystique->xgenioctrl & 0x01) || (mystique->xgeniodata & 0x01)); - break; - case XREG_XGENIODATA: - mystique->xgeniodata = val; - break; + case XREG_XGENIOCTRL: + mystique->xgenioctrl = val; + i2c_gpio_set(mystique->i2c_ddc, !(mystique->xgenioctrl & 0x08) || (mystique->xgeniodata & 0x08), !(mystique->xgenioctrl & 0x02) || (mystique->xgeniodata & 0x02)); + i2c_gpio_set(mystique->i2c, !(mystique->xgenioctrl & 0x04) || (mystique->xgeniodata & 0x04), !(mystique->xgenioctrl & 0x01) || (mystique->xgeniodata & 0x01)); + break; + case XREG_XGENIODATA: + mystique->xgeniodata = val; + break; - case XREG_XSYSPLLM: - mystique->xsyspllm = val; - break; - case XREG_XSYSPLLN: - mystique->xsysplln = val; - break; - case XREG_XSYSPLLP: - mystique->xsyspllp = val; - break; + case XREG_XSYSPLLM: + mystique->xsyspllm = val; + break; + case XREG_XSYSPLLN: + mystique->xsysplln = val; + break; + case XREG_XSYSPLLP: + mystique->xsyspllp = val; + break; - case XREG_XZOOMCTRL: - mystique->xzoomctrl = val & 3; - break; + case XREG_XZOOMCTRL: + mystique->xzoomctrl = val & 3; + break; - case XREG_XSENSETEST: - break; + case XREG_XSENSETEST: + break; - case XREG_XCRCREML: /*CRC not implemented*/ - break; - case XREG_XCRCREMH: - break; - case XREG_XCRCBITSEL: - mystique->xcrcbitsel = val & 0x1f; - break; + case XREG_XCRCREML: /*CRC not implemented*/ + break; + case XREG_XCRCREMH: + break; + case XREG_XCRCBITSEL: + mystique->xcrcbitsel = val & 0x1f; + break; - case XREG_XCOLKEYMSKL: - mystique->xcolkeymskl = val; - break; - case XREG_XCOLKEYMSKH: - mystique->xcolkeymskh = val; - break; - case XREG_XCOLKEYL: - mystique->xcolkeyl = val; - break; - case XREG_XCOLKEYH: - mystique->xcolkeyh = val; - break; + case XREG_XCOLKEYMSKL: + mystique->xcolkeymskl = val; + break; + case XREG_XCOLKEYMSKH: + mystique->xcolkeymskh = val; + break; + case XREG_XCOLKEYL: + mystique->xcolkeyl = val; + break; + case XREG_XCOLKEYH: + mystique->xcolkeyh = val; + break; - case XREG_XSYSPLLSTAT: - break; + case XREG_XSYSPLLSTAT: + break; - case XREG_XPIXPLLSTAT: - break; + case XREG_XPIXPLLSTAT: + break; - case XREG_XPIXCLKCTRL: - mystique->xpixclkctrl = val; - break; + case XREG_XPIXCLKCTRL: + mystique->xpixclkctrl = val; + break; - case XREG_XPIXPLLCM: - mystique->xpixpll[2].m = val; - break; - case XREG_XPIXPLLCN: - mystique->xpixpll[2].n = val; - break; - case XREG_XPIXPLLCP: - mystique->xpixpll[2].p = val & 7; - mystique->xpixpll[2].s = (val >> 3) & 3; - break; + case XREG_XPIXPLLCM: + mystique->xpixpll[2].m = val; + break; + case XREG_XPIXPLLCN: + mystique->xpixpll[2].n = val; + break; + case XREG_XPIXPLLCP: + mystique->xpixpll[2].p = val & 7; + mystique->xpixpll[2].s = (val >> 3) & 3; + break; - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x07: case 0x0b: case 0x0f: - case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1b: case 0x1c: case 0x20: case 0x39: case 0x3b: case 0x3f: - case 0x47: case 0x4b: - break; + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x07: + case 0x0b: + case 0x0f: + case 0x13: + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1b: + case 0x1c: + case 0x20: + case 0x39: + case 0x3b: + case 0x3f: + case 0x47: + case 0x4b: + break; - default: - break; + default: + break; } } - static uint8_t mystique_ctrl_read_b(uint32_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; - uint8_t ret = 0xff; - int fifocount; - uint16_t addr_0x0f = 0; - uint16_t addr_0x03 = 0; - int rs2 = 0, rs3 = 0; + mystique_t *mystique = (mystique_t *) p; + svga_t *svga = &mystique->svga; + uint8_t ret = 0xff; + int fifocount; + uint16_t addr_0x0f = 0; + uint16_t addr_0x03 = 0; + int rs2 = 0, rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) - { - /*RAMDAC*/ - addr_0x0f = addr & 0x0f; + if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + /*RAMDAC*/ + addr_0x0f = addr & 0x0f; - if ((addr_0x0f & 3) == 0) - addr_0x03 = 0x3c8; - else if ((addr_0x0f & 3) == 1) - addr_0x03 = 0x3c9; - else if ((addr_0x0f & 3) == 2) - addr_0x03 = 0x3c6; - else if ((addr_0x0f & 3) == 3) - addr_0x03 = 0x3c7; + if ((addr_0x0f & 3) == 0) + addr_0x03 = 0x3c8; + else if ((addr_0x0f & 3) == 1) + addr_0x03 = 0x3c9; + else if ((addr_0x0f & 3) == 2) + addr_0x03 = 0x3c6; + else if ((addr_0x0f & 3) == 3) + addr_0x03 = 0x3c7; - if ((addr_0x0f >= 0x04) && (addr_0x0f <= 0x07)) { - rs2 = 1; - rs3 = 0; - } else if ((addr_0x0f >= 0x08) && (addr_0x0f <= 0x0b)) { - rs2 = 0; - rs3 = 1; - } else if ((addr_0x0f >= 0x0c) && (addr_0x0f <= 0x0f)) { - rs2 = 1; - rs3 = 1; - } + if ((addr_0x0f >= 0x04) && (addr_0x0f <= 0x07)) { + rs2 = 1; + rs3 = 0; + } else if ((addr_0x0f >= 0x08) && (addr_0x0f <= 0x0b)) { + rs2 = 0; + rs3 = 1; + } else if ((addr_0x0f >= 0x0c) && (addr_0x0f <= 0x0f)) { + rs2 = 1; + rs3 = 1; + } - ret = tvp3026_ramdac_in(addr_0x03, rs2, rs3, svga->ramdac, svga); - } else switch (addr & 0x3fff) { - case REG_FIFOSTATUS: - fifocount = FIFO_SIZE - FIFO_ENTRIES; - if (fifocount > 64) - fifocount = 64; - ret = fifocount; - break; - case REG_FIFOSTATUS+1: - if (FIFO_EMPTY) - ret |= 2; - else if (FIFO_ENTRIES >= 64) - ret |= 1; - break; - case REG_FIFOSTATUS+2: case REG_FIFOSTATUS+3: - ret = 0; - break; - - case REG_STATUS: - ret = mystique->status & 0xff; - if (svga->cgastat & 8) - ret |= REG_STATUS_VSYNCSTS; - break; - case REG_STATUS+1: - ret = (mystique->status >> 8) & 0xff; - break; - case REG_STATUS+2: - ret = (mystique->status >> 16) & 0xff; - if (mystique->busy || - ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || - !FIFO_EMPTY) - ret |= (STATUS_DWGENGSTS >> 16); - break; - case REG_STATUS+3: - ret = (mystique->status >> 24) & 0xff; - break; - - case REG_IEN: - ret = mystique->ien & 0x64; - break; - case REG_IEN+1: case REG_IEN+2: case REG_IEN+3: - ret = 0; - break; - - case REG_OPMODE: - ret = mystique->dmamod << 2; - break; - case REG_OPMODE+1: - ret = mystique->dmadatasiz; - break; - case REG_OPMODE+2: - ret = mystique->dirdatasiz; - break; - case REG_OPMODE+3: - ret = 0; - break; - - case REG_PRIMADDRESS: case REG_PRIMADDRESS+1: case REG_PRIMADDRESS+2: case REG_PRIMADDRESS+3: - READ8(addr, mystique->dma.primaddress); - break; - case REG_PRIMEND: case REG_PRIMEND+1: case REG_PRIMEND+2: case REG_PRIMEND+3: - READ8(addr, mystique->dma.primend); - break; - - case REG_SECADDRESS: case REG_SECADDRESS+1: case REG_SECADDRESS+2: case REG_SECADDRESS+3: - READ8(addr, mystique->dma.secaddress); - break; - - case REG_VCOUNT: case REG_VCOUNT+1: case REG_VCOUNT+2: case REG_VCOUNT+3: - READ8(addr, svga->vc); - break; - - case REG_ATTR_IDX: - ret = svga_in(0x3c0, svga); - break; - case REG_ATTR_DATA: - ret = svga_in(0x3c1, svga); - break; - - case REG_INSTS0: - ret = svga_in(0x3c2, svga); - break; - - case REG_SEQ_IDX: - ret = svga_in(0x3c4, svga); - break; - case REG_SEQ_DATA: - ret = svga_in(0x3c5, svga); - break; - - case REG_MISCREAD: - ret = svga_in(0x3cc, svga); - break; - - case REG_GCTL_IDX: - ret = mystique_in(0x3ce, mystique); - break; - case REG_GCTL_DATA: - ret = mystique_in(0x3cf, mystique); - break; - - case REG_CRTC_IDX: - ret = mystique_in(0x3d4, mystique); - break; - case REG_CRTC_DATA: - ret = mystique_in(0x3d5, mystique); - break; - - case REG_INSTS1: - ret = mystique_in(0x3da, mystique); - break; - - case REG_CRTCEXT_IDX: - ret = mystique_in(0x3de, mystique); - break; - case REG_CRTCEXT_DATA: - ret = mystique_in(0x3df, mystique); - break; - - case REG_PALWTADD: - ret = svga_in(0x3c8, svga); - break; - case REG_PALDATA: - ret = svga_in(0x3c9, svga); - break; - case REG_PIXRDMSK: - ret = svga_in(0x3c6, svga); - break; - case REG_PALRDADD: - ret = svga_in(0x3c7, svga); - break; - - case REG_X_DATAREG: - ret = mystique_read_xreg(mystique, mystique->xreg_idx); - break; - - case 0x1c40: case 0x1c41: case 0x1c42: case 0x1c43: - case 0x1d44: case 0x1d45: case 0x1d46: case 0x1d47: - case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53: - case REG_ICLEAR: case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3: - case 0x2c30: case 0x2c31: case 0x2c32: case 0x2c33: - case 0x3e08: - break; - - case 0x3c08: case 0x3c09: case 0x3c0b: + ret = tvp3026_ramdac_in(addr_0x03, rs2, rs3, svga->ramdac, svga); + } else + switch (addr & 0x3fff) { + case REG_FIFOSTATUS: + fifocount = FIFO_SIZE - FIFO_ENTRIES; + if (fifocount > 64) + fifocount = 64; + ret = fifocount; + break; + case REG_FIFOSTATUS + 1: + if (FIFO_EMPTY) + ret |= 2; + else if (FIFO_ENTRIES >= 64) + ret |= 1; + break; + case REG_FIFOSTATUS + 2: + case REG_FIFOSTATUS + 3: + ret = 0; break; + case REG_STATUS: + ret = mystique->status & 0xff; + if (svga->cgastat & 8) + ret |= REG_STATUS_VSYNCSTS; + break; + case REG_STATUS + 1: + ret = (mystique->status >> 8) & 0xff; + break; + case REG_STATUS + 2: + ret = (mystique->status >> 16) & 0xff; + if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY) + ret |= (STATUS_DWGENGSTS >> 16); + break; + case REG_STATUS + 3: + ret = (mystique->status >> 24) & 0xff; + break; - default: - if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) - break; - if ((addr & 0x3fff) >= 0x3e00) - break; - break; - } + case REG_IEN: + ret = mystique->ien & 0x64; + break; + case REG_IEN + 1: + case REG_IEN + 2: + case REG_IEN + 3: + ret = 0; + break; + + case REG_OPMODE: + ret = mystique->dmamod << 2; + break; + case REG_OPMODE + 1: + ret = mystique->dmadatasiz; + break; + case REG_OPMODE + 2: + ret = mystique->dirdatasiz; + break; + case REG_OPMODE + 3: + ret = 0; + break; + + case REG_PRIMADDRESS: + case REG_PRIMADDRESS + 1: + case REG_PRIMADDRESS + 2: + case REG_PRIMADDRESS + 3: + READ8(addr, mystique->dma.primaddress); + break; + case REG_PRIMEND: + case REG_PRIMEND + 1: + case REG_PRIMEND + 2: + case REG_PRIMEND + 3: + READ8(addr, mystique->dma.primend); + break; + + case REG_SECADDRESS: + case REG_SECADDRESS + 1: + case REG_SECADDRESS + 2: + case REG_SECADDRESS + 3: + READ8(addr, mystique->dma.secaddress); + break; + + case REG_VCOUNT: + case REG_VCOUNT + 1: + case REG_VCOUNT + 2: + case REG_VCOUNT + 3: + READ8(addr, svga->vc); + break; + + case REG_ATTR_IDX: + ret = svga_in(0x3c0, svga); + break; + case REG_ATTR_DATA: + ret = svga_in(0x3c1, svga); + break; + + case REG_INSTS0: + ret = svga_in(0x3c2, svga); + break; + + case REG_SEQ_IDX: + ret = svga_in(0x3c4, svga); + break; + case REG_SEQ_DATA: + ret = svga_in(0x3c5, svga); + break; + + case REG_MISCREAD: + ret = svga_in(0x3cc, svga); + break; + + case REG_GCTL_IDX: + ret = mystique_in(0x3ce, mystique); + break; + case REG_GCTL_DATA: + ret = mystique_in(0x3cf, mystique); + break; + + case REG_CRTC_IDX: + ret = mystique_in(0x3d4, mystique); + break; + case REG_CRTC_DATA: + ret = mystique_in(0x3d5, mystique); + break; + + case REG_INSTS1: + ret = mystique_in(0x3da, mystique); + break; + + case REG_CRTCEXT_IDX: + ret = mystique_in(0x3de, mystique); + break; + case REG_CRTCEXT_DATA: + ret = mystique_in(0x3df, mystique); + break; + + case REG_PALWTADD: + ret = svga_in(0x3c8, svga); + break; + case REG_PALDATA: + ret = svga_in(0x3c9, svga); + break; + case REG_PIXRDMSK: + ret = svga_in(0x3c6, svga); + break; + case REG_PALRDADD: + ret = svga_in(0x3c7, svga); + break; + + case REG_X_DATAREG: + ret = mystique_read_xreg(mystique, mystique->xreg_idx); + break; + + case 0x1c40: + case 0x1c41: + case 0x1c42: + case 0x1c43: + case 0x1d44: + case 0x1d45: + case 0x1d46: + case 0x1d47: + case 0x1e50: + case 0x1e51: + case 0x1e52: + case 0x1e53: + case REG_ICLEAR: + case REG_ICLEAR + 1: + case REG_ICLEAR + 2: + case REG_ICLEAR + 3: + case 0x2c30: + case 0x2c31: + case 0x2c32: + case 0x2c33: + case 0x3e08: + break; + + case 0x3c08: + case 0x3c09: + case 0x3c0b: + break; + + default: + if ((addr & 0x3fff) >= 0x2c00 && (addr & 0x3fff) < 0x2c40) + break; + if ((addr & 0x3fff) >= 0x3e00) + break; + break; + } return ret; } - static void mystique_accel_ctrl_write_b(uint32_t addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - int start_blit = 0; - int x; + mystique_t *mystique = (mystique_t *) p; + int start_blit = 0; + int x; if ((addr & 0x300) == 0x100) { - addr &= ~0x100; - start_blit = 1; + addr &= ~0x100; + start_blit = 1; } switch (addr & 0x3fff) { - case REG_MACCESS: case REG_MACCESS+1: case REG_MACCESS+2: case REG_MACCESS+3: - WRITE8(addr, mystique->maccess, val); - mystique->dwgreg.dither = mystique->maccess >> 30; - break; + case REG_MACCESS: + case REG_MACCESS + 1: + case REG_MACCESS + 2: + case REG_MACCESS + 3: + WRITE8(addr, mystique->maccess, val); + mystique->dwgreg.dither = mystique->maccess >> 30; + break; - case REG_MCTLWTST: case REG_MCTLWTST+1: case REG_MCTLWTST+2: case REG_MCTLWTST+3: - WRITE8(addr, mystique->mctlwtst, val); - break; + case REG_MCTLWTST: + case REG_MCTLWTST + 1: + case REG_MCTLWTST + 2: + case REG_MCTLWTST + 3: + WRITE8(addr, mystique->mctlwtst, val); + break; - case REG_PAT0: case REG_PAT0+1: case REG_PAT0+2: case REG_PAT0+3: - case REG_PAT1: case REG_PAT1+1: case REG_PAT1+2: case REG_PAT1+3: - for (x = 0; x < 8; x++) - mystique->dwgreg.pattern[addr & 7][x] = val & (1 << (7-x)); - break; + case REG_PAT0: + case REG_PAT0 + 1: + case REG_PAT0 + 2: + case REG_PAT0 + 3: + case REG_PAT1: + case REG_PAT1 + 1: + case REG_PAT1 + 2: + case REG_PAT1 + 3: + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[addr & 7][x] = val & (1 << (7 - x)); + break; - case REG_XYSTRT: case REG_XYSTRT+1: - WRITE8(addr&1, mystique->dwgreg.ar[5], val); - if (mystique->dwgreg.ar[5] & 0x8000) - mystique->dwgreg.ar[5] |= 0xffff8000; - else - mystique->dwgreg.ar[5] &= ~0xffff8000; - WRITE8(addr&1, mystique->dwgreg.xdst, val); - break; - case REG_XYSTRT+2: case REG_XYSTRT+3: - WRITE8(addr & 1, mystique->dwgreg.ar[6], val); - if (mystique->dwgreg.ar[6] & 0x8000) - mystique->dwgreg.ar[6] |= 0xffff8000; - else - mystique->dwgreg.ar[6] &= ~0xffff8000; - WRITE8(addr & 1, mystique->dwgreg.ydst, val); - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - break; + case REG_XYSTRT: + case REG_XYSTRT + 1: + WRITE8(addr & 1, mystique->dwgreg.ar[5], val); + if (mystique->dwgreg.ar[5] & 0x8000) + mystique->dwgreg.ar[5] |= 0xffff8000; + else + mystique->dwgreg.ar[5] &= ~0xffff8000; + WRITE8(addr & 1, mystique->dwgreg.xdst, val); + break; + case REG_XYSTRT + 2: + case REG_XYSTRT + 3: + WRITE8(addr & 1, mystique->dwgreg.ar[6], val); + if (mystique->dwgreg.ar[6] & 0x8000) + mystique->dwgreg.ar[6] |= 0xffff8000; + else + mystique->dwgreg.ar[6] &= ~0xffff8000; + WRITE8(addr & 1, mystique->dwgreg.ydst, val); + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + break; - case REG_XYEND: case REG_XYEND+1: - WRITE8(addr&1, mystique->dwgreg.ar[0], val); - if (mystique->dwgreg.ar[0] & 0x8000) - mystique->dwgreg.ar[0] |= 0xffff8000; - else - mystique->dwgreg.ar[0] &= ~0xffff8000; - break; - case REG_XYEND+2: case REG_XYEND+3: - WRITE8(addr & 1, mystique->dwgreg.ar[2], val); - if (mystique->dwgreg.ar[2] & 0x8000) - mystique->dwgreg.ar[2] |= 0xffff8000; - else - mystique->dwgreg.ar[2] &= ~0xffff8000; - break; + case REG_XYEND: + case REG_XYEND + 1: + WRITE8(addr & 1, mystique->dwgreg.ar[0], val); + if (mystique->dwgreg.ar[0] & 0x8000) + mystique->dwgreg.ar[0] |= 0xffff8000; + else + mystique->dwgreg.ar[0] &= ~0xffff8000; + break; + case REG_XYEND + 2: + case REG_XYEND + 3: + WRITE8(addr & 1, mystique->dwgreg.ar[2], val); + if (mystique->dwgreg.ar[2] & 0x8000) + mystique->dwgreg.ar[2] |= 0xffff8000; + else + mystique->dwgreg.ar[2] &= ~0xffff8000; + break; - case REG_SGN: - mystique->dwgreg.sgn.sdydxl = val & SGN_SDYDXL; - mystique->dwgreg.sgn.scanleft = val & SGN_SCANLEFT; - mystique->dwgreg.sgn.sdxl = val & SGN_SDXL; - mystique->dwgreg.sgn.sdy = val & SGN_SDY; - mystique->dwgreg.sgn.sdxr = val & SGN_SDXR; - break; - case REG_SGN+1: case REG_SGN+2: case REG_SGN+3: - break; + case REG_SGN: + mystique->dwgreg.sgn.sdydxl = val & SGN_SDYDXL; + mystique->dwgreg.sgn.scanleft = val & SGN_SCANLEFT; + mystique->dwgreg.sgn.sdxl = val & SGN_SDXL; + mystique->dwgreg.sgn.sdy = val & SGN_SDY; + mystique->dwgreg.sgn.sdxr = val & SGN_SDXR; + break; + case REG_SGN + 1: + case REG_SGN + 2: + case REG_SGN + 3: + break; - case REG_LEN: case REG_LEN+1: - WRITE8(addr, mystique->dwgreg.length, val); - break; - case REG_LEN+2: - break; - case REG_LEN+3: - mystique->dwgreg.beta = val >> 4; - if (!mystique->dwgreg.beta) - mystique->dwgreg.beta = 16; - break; + case REG_LEN: + case REG_LEN + 1: + WRITE8(addr, mystique->dwgreg.length, val); + break; + case REG_LEN + 2: + break; + case REG_LEN + 3: + mystique->dwgreg.beta = val >> 4; + if (!mystique->dwgreg.beta) + mystique->dwgreg.beta = 16; + break; - case REG_CXBNDRY: case REG_CXBNDRY+1: - WRITE8(addr, mystique->dwgreg.cxleft, val); - break; - case REG_CXBNDRY+2: case REG_CXBNDRY+3: - WRITE8(addr & 1, mystique->dwgreg.cxright, val); - break; - case REG_FXBNDRY: case REG_FXBNDRY+1: - WRITE8(addr, mystique->dwgreg.fxleft, val); - break; - case REG_FXBNDRY+2: case REG_FXBNDRY+3: - WRITE8(addr & 1, mystique->dwgreg.fxright, val); - break; + case REG_CXBNDRY: + case REG_CXBNDRY + 1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXBNDRY + 2: + case REG_CXBNDRY + 3: + WRITE8(addr & 1, mystique->dwgreg.cxright, val); + break; + case REG_FXBNDRY: + case REG_FXBNDRY + 1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXBNDRY + 2: + case REG_FXBNDRY + 3: + WRITE8(addr & 1, mystique->dwgreg.fxright, val); + break; - case REG_YDSTLEN: case REG_YDSTLEN+1: - WRITE8(addr, mystique->dwgreg.length, val); - /* pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); */ - break; - case REG_YDSTLEN+2: - mystique->dwgreg.ydst = (mystique->dwgreg.ydst & ~0xff) | val; - if (mystique->dwgreg.pitch & PITCH_YLIN) - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - else { - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - mystique->dwgreg.selline = val & 7; - } - break; - case REG_YDSTLEN+3: - mystique->dwgreg.ydst = (mystique->dwgreg.ydst & 0xff) | (((int32_t)(int8_t)val) << 8); - if (mystique->dwgreg.pitch & PITCH_YLIN) - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - else - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - break; + case REG_YDSTLEN: + case REG_YDSTLEN + 1: + WRITE8(addr, mystique->dwgreg.length, val); + /* pclog("Write YDSTLEN+%i %i\n", addr&1, mystique->dwgreg.length); */ + break; + case REG_YDSTLEN + 2: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & ~0xff) | val; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else { + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } + break; + case REG_YDSTLEN + 3: + mystique->dwgreg.ydst = (mystique->dwgreg.ydst & 0xff) | (((int32_t) (int8_t) val) << 8); + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + break; - case REG_XDST: case REG_XDST+1: - WRITE8(addr & 1, mystique->dwgreg.xdst, val); - break; - case REG_XDST+2: case REG_XDST+3: - break; + case REG_XDST: + case REG_XDST + 1: + WRITE8(addr & 1, mystique->dwgreg.xdst, val); + break; + case REG_XDST + 2: + case REG_XDST + 3: + break; - case REG_YDSTORG: case REG_YDSTORG+1: case REG_YDSTORG+2: case REG_YDSTORG+3: - WRITE8(addr, mystique->dwgreg.ydstorg, val); - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg*2 + mystique->dwgreg.zorg; - break; - case REG_YTOP: case REG_YTOP+1: case REG_YTOP+2: case REG_YTOP+3: - WRITE8(addr, mystique->dwgreg.ytop, val); - break; - case REG_YBOT: case REG_YBOT+1: case REG_YBOT+2: case REG_YBOT+3: - WRITE8(addr, mystique->dwgreg.ybot, val); - break; + case REG_YDSTORG: + case REG_YDSTORG + 1: + case REG_YDSTORG + 2: + case REG_YDSTORG + 3: + WRITE8(addr, mystique->dwgreg.ydstorg, val); + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + break; + case REG_YTOP: + case REG_YTOP + 1: + case REG_YTOP + 2: + case REG_YTOP + 3: + WRITE8(addr, mystique->dwgreg.ytop, val); + break; + case REG_YBOT: + case REG_YBOT + 1: + case REG_YBOT + 2: + case REG_YBOT + 3: + WRITE8(addr, mystique->dwgreg.ybot, val); + break; - case REG_CXLEFT: case REG_CXLEFT+1: - WRITE8(addr, mystique->dwgreg.cxleft, val); - break; - case REG_CXLEFT+2: case REG_CXLEFT+3: - break; - case REG_CXRIGHT: case REG_CXRIGHT+1: - WRITE8(addr, mystique->dwgreg.cxright, val); - break; - case REG_CXRIGHT+2: case REG_CXRIGHT+3: - break; + case REG_CXLEFT: + case REG_CXLEFT + 1: + WRITE8(addr, mystique->dwgreg.cxleft, val); + break; + case REG_CXLEFT + 2: + case REG_CXLEFT + 3: + break; + case REG_CXRIGHT: + case REG_CXRIGHT + 1: + WRITE8(addr, mystique->dwgreg.cxright, val); + break; + case REG_CXRIGHT + 2: + case REG_CXRIGHT + 3: + break; - case REG_FXLEFT: case REG_FXLEFT+1: - WRITE8(addr, mystique->dwgreg.fxleft, val); - break; - case REG_FXLEFT+2: case REG_FXLEFT+3: - break; - case REG_FXRIGHT: case REG_FXRIGHT+1: - WRITE8(addr, mystique->dwgreg.fxright, val); - break; - case REG_FXRIGHT+2: case REG_FXRIGHT+3: - break; + case REG_FXLEFT: + case REG_FXLEFT + 1: + WRITE8(addr, mystique->dwgreg.fxleft, val); + break; + case REG_FXLEFT + 2: + case REG_FXLEFT + 3: + break; + case REG_FXRIGHT: + case REG_FXRIGHT + 1: + WRITE8(addr, mystique->dwgreg.fxright, val); + break; + case REG_FXRIGHT + 2: + case REG_FXRIGHT + 3: + break; - case REG_SECADDRESS: case REG_SECADDRESS+1: case REG_SECADDRESS+2: case REG_SECADDRESS+3: - WRITE8(addr, mystique->dma.secaddress, val); - mystique->dma.sec_state = 0; - break; + case REG_SECADDRESS: + case REG_SECADDRESS + 1: + case REG_SECADDRESS + 2: + case REG_SECADDRESS + 3: + WRITE8(addr, mystique->dma.secaddress, val); + mystique->dma.sec_state = 0; + break; - case REG_TMR0: case REG_TMR0+1: case REG_TMR0+2: case REG_TMR0+3: - WRITE8(addr, mystique->dwgreg.tmr[0], val); - break; - case REG_TMR1: case REG_TMR1+1: case REG_TMR1+2: case REG_TMR1+3: - WRITE8(addr, mystique->dwgreg.tmr[1], val); - break; - case REG_TMR2: case REG_TMR2+1: case REG_TMR2+2: case REG_TMR2+3: - WRITE8(addr, mystique->dwgreg.tmr[2], val); - break; - case REG_TMR3: case REG_TMR3+1: case REG_TMR3+2: case REG_TMR3+3: - WRITE8(addr, mystique->dwgreg.tmr[3], val); - break; - case REG_TMR4: case REG_TMR4+1: case REG_TMR4+2: case REG_TMR4+3: - WRITE8(addr, mystique->dwgreg.tmr[4], val); - break; - case REG_TMR5: case REG_TMR5+1: case REG_TMR5+2: case REG_TMR5+3: - WRITE8(addr, mystique->dwgreg.tmr[5], val); - break; - case REG_TMR6: case REG_TMR6+1: case REG_TMR6+2: case REG_TMR6+3: - WRITE8(addr, mystique->dwgreg.tmr[6], val); - break; - case REG_TMR7: case REG_TMR7+1: case REG_TMR7+2: case REG_TMR7+3: - WRITE8(addr, mystique->dwgreg.tmr[7], val); - break; - case REG_TMR8: case REG_TMR8+1: case REG_TMR8+2: case REG_TMR8+3: - WRITE8(addr, mystique->dwgreg.tmr[8], val); - break; + case REG_TMR0: + case REG_TMR0 + 1: + case REG_TMR0 + 2: + case REG_TMR0 + 3: + WRITE8(addr, mystique->dwgreg.tmr[0], val); + break; + case REG_TMR1: + case REG_TMR1 + 1: + case REG_TMR1 + 2: + case REG_TMR1 + 3: + WRITE8(addr, mystique->dwgreg.tmr[1], val); + break; + case REG_TMR2: + case REG_TMR2 + 1: + case REG_TMR2 + 2: + case REG_TMR2 + 3: + WRITE8(addr, mystique->dwgreg.tmr[2], val); + break; + case REG_TMR3: + case REG_TMR3 + 1: + case REG_TMR3 + 2: + case REG_TMR3 + 3: + WRITE8(addr, mystique->dwgreg.tmr[3], val); + break; + case REG_TMR4: + case REG_TMR4 + 1: + case REG_TMR4 + 2: + case REG_TMR4 + 3: + WRITE8(addr, mystique->dwgreg.tmr[4], val); + break; + case REG_TMR5: + case REG_TMR5 + 1: + case REG_TMR5 + 2: + case REG_TMR5 + 3: + WRITE8(addr, mystique->dwgreg.tmr[5], val); + break; + case REG_TMR6: + case REG_TMR6 + 1: + case REG_TMR6 + 2: + case REG_TMR6 + 3: + WRITE8(addr, mystique->dwgreg.tmr[6], val); + break; + case REG_TMR7: + case REG_TMR7 + 1: + case REG_TMR7 + 2: + case REG_TMR7 + 3: + WRITE8(addr, mystique->dwgreg.tmr[7], val); + break; + case REG_TMR8: + case REG_TMR8 + 1: + case REG_TMR8 + 2: + case REG_TMR8 + 3: + WRITE8(addr, mystique->dwgreg.tmr[8], val); + break; - case REG_TEXORG: case REG_TEXORG+1: case REG_TEXORG+2: case REG_TEXORG+3: - WRITE8(addr, mystique->dwgreg.texorg, val); - break; - case REG_TEXWIDTH: case REG_TEXWIDTH+1: case REG_TEXWIDTH+2: case REG_TEXWIDTH+3: - WRITE8(addr, mystique->dwgreg.texwidth, val); - break; - case REG_TEXHEIGHT: case REG_TEXHEIGHT+1: case REG_TEXHEIGHT+2: case REG_TEXHEIGHT+3: - WRITE8(addr, mystique->dwgreg.texheight, val); - break; - case REG_TEXCTL: case REG_TEXCTL+1: case REG_TEXCTL+2: case REG_TEXCTL+3: - WRITE8(addr, mystique->dwgreg.texctl, val); - mystique->dwgreg.ta_key = (mystique->dwgreg.texctl & TEXCTL_TAKEY) ? 1 : 0; - mystique->dwgreg.ta_mask = (mystique->dwgreg.texctl & TEXCTL_TAMASK) ? 1 : 0; - break; - case REG_TEXTRANS: case REG_TEXTRANS+1: case REG_TEXTRANS+2: case REG_TEXTRANS+3: - WRITE8(addr, mystique->dwgreg.textrans, val); - break; + case REG_TEXORG: + case REG_TEXORG + 1: + case REG_TEXORG + 2: + case REG_TEXORG + 3: + WRITE8(addr, mystique->dwgreg.texorg, val); + break; + case REG_TEXWIDTH: + case REG_TEXWIDTH + 1: + case REG_TEXWIDTH + 2: + case REG_TEXWIDTH + 3: + WRITE8(addr, mystique->dwgreg.texwidth, val); + break; + case REG_TEXHEIGHT: + case REG_TEXHEIGHT + 1: + case REG_TEXHEIGHT + 2: + case REG_TEXHEIGHT + 3: + WRITE8(addr, mystique->dwgreg.texheight, val); + break; + case REG_TEXCTL: + case REG_TEXCTL + 1: + case REG_TEXCTL + 2: + case REG_TEXCTL + 3: + WRITE8(addr, mystique->dwgreg.texctl, val); + mystique->dwgreg.ta_key = (mystique->dwgreg.texctl & TEXCTL_TAKEY) ? 1 : 0; + mystique->dwgreg.ta_mask = (mystique->dwgreg.texctl & TEXCTL_TAMASK) ? 1 : 0; + break; + case REG_TEXTRANS: + case REG_TEXTRANS + 1: + case REG_TEXTRANS + 2: + case REG_TEXTRANS + 3: + WRITE8(addr, mystique->dwgreg.textrans, val); + break; - case 0x1c18: case 0x1c19: case 0x1c1a: case 0x1c1b: - case 0x1c28: case 0x1c29: case 0x1c2a: case 0x1c2b: - case 0x1c2c: case 0x1c2d: case 0x1c2e: case 0x1c2f: - case 0x1cc4: case 0x1cc5: case 0x1cc6: case 0x1cc7: - case 0x1cd4: case 0x1cd5: case 0x1cd6: case 0x1cd7: - case 0x1ce4: case 0x1ce5: case 0x1ce6: case 0x1ce7: - case 0x1cf4: case 0x1cf5: case 0x1cf6: case 0x1cf7: - break; + case 0x1c18: + case 0x1c19: + case 0x1c1a: + case 0x1c1b: + case 0x1c28: + case 0x1c29: + case 0x1c2a: + case 0x1c2b: + case 0x1c2c: + case 0x1c2d: + case 0x1c2e: + case 0x1c2f: + case 0x1cc4: + case 0x1cc5: + case 0x1cc6: + case 0x1cc7: + case 0x1cd4: + case 0x1cd5: + case 0x1cd6: + case 0x1cd7: + case 0x1ce4: + case 0x1ce5: + case 0x1ce6: + case 0x1ce7: + case 0x1cf4: + case 0x1cf5: + case 0x1cf6: + case 0x1cf7: + break; - case REG_OPMODE: - mystique->dwgreg.dmamod = (val >> 2) & 3; - mystique->dma.iload_state = 0; - break; + case REG_OPMODE: + mystique->dwgreg.dmamod = (val >> 2) & 3; + mystique->dma.iload_state = 0; + break; - default: - if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) - break; - break; + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; + break; } if (start_blit) - mystique_start_blit(mystique); + mystique_start_blit(mystique); } - static void mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - svga_t *svga = &mystique->svga; - uint16_t addr_0x0f = 0; - uint16_t addr_0x03 = 0; - int rs2 = 0, rs3 = 0; + mystique_t *mystique = (mystique_t *) p; + svga_t *svga = &mystique->svga; + uint16_t addr_0x0f = 0; + uint16_t addr_0x03 = 0; + int rs2 = 0, rs3 = 0; - if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) - { - /*RAMDAC*/ - addr_0x0f = addr & 0x0f; + if ((mystique->type == MGA_2064W) && (addr & 0x3e00) == 0x3c00) { + /*RAMDAC*/ + addr_0x0f = addr & 0x0f; - if ((addr & 3) == 0) - addr_0x03 = 0x3c8; - else if ((addr & 3) == 1) - addr_0x03 = 0x3c9; - else if ((addr & 3) == 2) - addr_0x03 = 0x3c6; - else if ((addr & 3) == 3) - addr_0x03 = 0x3c7; + if ((addr & 3) == 0) + addr_0x03 = 0x3c8; + else if ((addr & 3) == 1) + addr_0x03 = 0x3c9; + else if ((addr & 3) == 2) + addr_0x03 = 0x3c6; + else if ((addr & 3) == 3) + addr_0x03 = 0x3c7; - if ((addr_0x0f >= 0x04) && (addr_0x0f <= 0x07)) { - rs2 = 1; - rs3 = 0; - } else if ((addr_0x0f >= 0x08) && (addr_0x0f <= 0x0b)) { - rs2 = 0; - rs3 = 1; - } else if ((addr_0x0f >= 0x0c) && (addr_0x0f <= 0x0f)) { - rs2 = 1; - rs3 = 1; - } + if ((addr_0x0f >= 0x04) && (addr_0x0f <= 0x07)) { + rs2 = 1; + rs3 = 0; + } else if ((addr_0x0f >= 0x08) && (addr_0x0f <= 0x0b)) { + rs2 = 0; + rs3 = 1; + } else if ((addr_0x0f >= 0x0c) && (addr_0x0f <= 0x0f)) { + rs2 = 1; + rs3 = 1; + } - tvp3026_ramdac_out(addr_0x03, rs2, rs3, val, svga->ramdac, svga); - return; - } + tvp3026_ramdac_out(addr_0x03, rs2, rs3, val, svga->ramdac, svga); + return; + } if ((addr & 0x3fff) < 0x1c00) { - mystique_iload_write_b(addr, val, p); - return; + mystique_iload_write_b(addr, val, p); + return; } if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { - if ((addr & 0x300) == 0x100) - mystique->blitter_submit_refcount++; - mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); - return; + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + return; } switch (addr & 0x3fff) { - case REG_ICLEAR: - if (val & ICLEAR_SOFTRAPICLR) { - mystique->status &= ~STATUS_SOFTRAPEN; - mystique_update_irqs(mystique); - } - if (val & ICLEAR_VLINEICLR) { - mystique->status &= ~STATUS_VLINEPEN; - mystique_update_irqs(mystique); - } - break; - case REG_ICLEAR+1: case REG_ICLEAR+2: case REG_ICLEAR+3: - break; - - case REG_IEN: - mystique->ien = val & 0x65; - break; - case REG_IEN+1: case REG_IEN+2: case REG_IEN+3: - break; - - case REG_OPMODE: - thread_wait_mutex(mystique->dma.lock); - mystique->dma.state = DMA_STATE_IDLE; /* Interrupt DMA. */ - thread_release_mutex(mystique->dma.lock); - mystique->dmamod = (val >> 2) & 3; - mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); - break; - case REG_OPMODE+1: - mystique->dmadatasiz = val & 3; - break; - case REG_OPMODE+2: - mystique->dirdatasiz = val & 3; - break; - case REG_OPMODE+3: - break; - - case REG_PRIMADDRESS: case REG_PRIMADDRESS+1: case REG_PRIMADDRESS+2: case REG_PRIMADDRESS+3: - thread_wait_mutex(mystique->dma.lock); - WRITE8(addr, mystique->dma.primaddress, val); - mystique->dma.pri_state = 0; - thread_release_mutex(mystique->dma.lock); - break; - - case REG_DMAMAP: case REG_DMAMAP+0x1: case REG_DMAMAP+0x2: case REG_DMAMAP+0x3: - case REG_DMAMAP+0x4: case REG_DMAMAP+0x5: case REG_DMAMAP+0x6: case REG_DMAMAP+0x7: - case REG_DMAMAP+0x8: case REG_DMAMAP+0x9: case REG_DMAMAP+0xa: case REG_DMAMAP+0xb: - case REG_DMAMAP+0xc: case REG_DMAMAP+0xd: case REG_DMAMAP+0xe: case REG_DMAMAP+0xf: - mystique->dmamap[addr & 0xf] = val; - break; - - case REG_RST: case REG_RST+1: case REG_RST+2: case REG_RST+3: - wait_fifo_idle(mystique); - mystique->busy = 0; - mystique->blitter_submit_refcount = 0; - mystique->blitter_submit_dma_refcount = 0; - mystique->blitter_complete_refcount = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->status = STATUS_ENDPRDMASTS; - break; - - case REG_ATTR_IDX: - svga_out(0x3c0, val, svga); - break; - case REG_ATTR_DATA: - svga_out(0x3c1, val, svga); - break; - - case REG_MISC: - svga_out(0x3c2, val, svga); - break; - - case REG_SEQ_IDX: - svga_out(0x3c4, val, svga); - break; - case REG_SEQ_DATA: - svga_out(0x3c5, val, svga); - break; - - case REG_GCTL_IDX: - mystique_out(0x3ce, val, mystique); - break; - case REG_GCTL_DATA: - mystique_out(0x3cf, val, mystique); - break; - - case REG_CRTC_IDX: - mystique_out(0x3d4, val, mystique); - break; - case REG_CRTC_DATA: - mystique_out(0x3d5, val, mystique); - break; - - case REG_CRTCEXT_IDX: - mystique_out(0x3de, val, mystique); - break; - case REG_CRTCEXT_DATA: - mystique_out(0x3df, val, mystique); - break; - - case REG_CACHEFLUSH: - break; - - case REG_PALWTADD: - svga_out(0x3c8, val, svga); - mystique->xreg_idx = val; - break; - case REG_PALDATA: - svga_out(0x3c9, val, svga); - break; - case REG_PIXRDMSK: - svga_out(0x3c6, val, svga); - break; - case REG_PALRDADD: - svga_out(0x3c7, val, svga); - break; - - case REG_X_DATAREG: - mystique_write_xreg(mystique, mystique->xreg_idx, val); - break; - - case REG_CURPOSX: case REG_CURPOSX+1: - WRITE8(addr, mystique->cursor.pos_x, val); - svga->hwcursor.x = mystique->cursor.pos_x - 64; - break; - case REG_CURPOSY: case REG_CURPOSY+1: - WRITE8(addr & 1, mystique->cursor.pos_y, val); - svga->hwcursor.y = mystique->cursor.pos_y - 64; - break; - - case 0x1e50: case 0x1e51: case 0x1e52: case 0x1e53: - case 0x3c0b: case 0x3e02: case 0x3e08: - break; - - default: - if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) - break; - if ((addr & 0x3fff) >= 0x3e00) + case REG_ICLEAR: + if (val & ICLEAR_SOFTRAPICLR) { + mystique->status &= ~STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); + } + if (val & ICLEAR_VLINEICLR) { + mystique->status &= ~STATUS_VLINEPEN; + mystique_update_irqs(mystique); + } + break; + case REG_ICLEAR + 1: + case REG_ICLEAR + 2: + case REG_ICLEAR + 3: + break; + + case REG_IEN: + mystique->ien = val & 0x65; + break; + case REG_IEN + 1: + case REG_IEN + 2: + case REG_IEN + 3: + break; + + case REG_OPMODE: + thread_wait_mutex(mystique->dma.lock); + mystique->dma.state = DMA_STATE_IDLE; /* Interrupt DMA. */ + thread_release_mutex(mystique->dma.lock); + mystique->dmamod = (val >> 2) & 3; + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); + break; + case REG_OPMODE + 1: + mystique->dmadatasiz = val & 3; + break; + case REG_OPMODE + 2: + mystique->dirdatasiz = val & 3; + break; + case REG_OPMODE + 3: + break; + + case REG_PRIMADDRESS: + case REG_PRIMADDRESS + 1: + case REG_PRIMADDRESS + 2: + case REG_PRIMADDRESS + 3: + thread_wait_mutex(mystique->dma.lock); + WRITE8(addr, mystique->dma.primaddress, val); + mystique->dma.pri_state = 0; + thread_release_mutex(mystique->dma.lock); + break; + + case REG_DMAMAP: + case REG_DMAMAP + 0x1: + case REG_DMAMAP + 0x2: + case REG_DMAMAP + 0x3: + case REG_DMAMAP + 0x4: + case REG_DMAMAP + 0x5: + case REG_DMAMAP + 0x6: + case REG_DMAMAP + 0x7: + case REG_DMAMAP + 0x8: + case REG_DMAMAP + 0x9: + case REG_DMAMAP + 0xa: + case REG_DMAMAP + 0xb: + case REG_DMAMAP + 0xc: + case REG_DMAMAP + 0xd: + case REG_DMAMAP + 0xe: + case REG_DMAMAP + 0xf: + mystique->dmamap[addr & 0xf] = val; + break; + + case REG_RST: + case REG_RST + 1: + case REG_RST + 2: + case REG_RST + 3: + wait_fifo_idle(mystique); + mystique->busy = 0; + mystique->blitter_submit_refcount = 0; + mystique->blitter_submit_dma_refcount = 0; + mystique->blitter_complete_refcount = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->status = STATUS_ENDPRDMASTS; + break; + + case REG_ATTR_IDX: + svga_out(0x3c0, val, svga); + break; + case REG_ATTR_DATA: + svga_out(0x3c1, val, svga); + break; + + case REG_MISC: + svga_out(0x3c2, val, svga); + break; + + case REG_SEQ_IDX: + svga_out(0x3c4, val, svga); + break; + case REG_SEQ_DATA: + svga_out(0x3c5, val, svga); + break; + + case REG_GCTL_IDX: + mystique_out(0x3ce, val, mystique); + break; + case REG_GCTL_DATA: + mystique_out(0x3cf, val, mystique); + break; + + case REG_CRTC_IDX: + mystique_out(0x3d4, val, mystique); + break; + case REG_CRTC_DATA: + mystique_out(0x3d5, val, mystique); + break; + + case REG_CRTCEXT_IDX: + mystique_out(0x3de, val, mystique); + break; + case REG_CRTCEXT_DATA: + mystique_out(0x3df, val, mystique); + break; + + case REG_CACHEFLUSH: + break; + + case REG_PALWTADD: + svga_out(0x3c8, val, svga); + mystique->xreg_idx = val; + break; + case REG_PALDATA: + svga_out(0x3c9, val, svga); + break; + case REG_PIXRDMSK: + svga_out(0x3c6, val, svga); + break; + case REG_PALRDADD: + svga_out(0x3c7, val, svga); + break; + + case REG_X_DATAREG: + mystique_write_xreg(mystique, mystique->xreg_idx, val); + break; + + case REG_CURPOSX: + case REG_CURPOSX + 1: + WRITE8(addr, mystique->cursor.pos_x, val); + svga->hwcursor.x = mystique->cursor.pos_x - 64; + break; + case REG_CURPOSY: + case REG_CURPOSY + 1: + WRITE8(addr & 1, mystique->cursor.pos_y, val); + svga->hwcursor.y = mystique->cursor.pos_y - 64; + break; + + case 0x1e50: + case 0x1e51: + case 0x1e52: + case 0x1e53: + case 0x3c0b: + case 0x3e02: + case 0x3e08: + break; + + default: + if ((addr & 0x3fff) >= 0x2c4c && (addr & 0x3fff) <= 0x2cff) + break; + if ((addr & 0x3fff) >= 0x3e00) + break; break; - break; } } - static uint32_t mystique_ctrl_read_l(uint32_t addr, void *p) { uint32_t ret; if ((addr & 0x3fff) < 0x1c00) - return mystique_iload_read_l(addr, p); + return mystique_iload_read_l(addr, p); ret = mystique_ctrl_read_b(addr, p); - ret |= mystique_ctrl_read_b(addr+1, p) << 8; - ret |= mystique_ctrl_read_b(addr+2, p) << 16; - ret |= mystique_ctrl_read_b(addr+3, p) << 24; + ret |= mystique_ctrl_read_b(addr + 1, p) << 8; + ret |= mystique_ctrl_read_b(addr + 2, p) << 16; + ret |= mystique_ctrl_read_b(addr + 3, p) << 24; return ret; } - static void mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - int start_blit = 0; + mystique_t *mystique = (mystique_t *) p; + int start_blit = 0; if ((addr & 0x300) == 0x100) { - addr &= ~0x100; - start_blit = 1; + addr &= ~0x100; + start_blit = 1; } switch (addr & 0x3ffc) { - case REG_DWGCTL: - mystique->dwgreg.dwgctrl = val; + case REG_DWGCTL: + mystique->dwgreg.dwgctrl = val; - if (val & DWGCTRL_SOLID) { - int x, y; + if (val & DWGCTRL_SOLID) { + int x, y; - for (y = 0; y < 8; y++) { - for (x = 0; x < 8; x++) - mystique->dwgreg.pattern[y][x] = 1; - } - mystique->dwgreg.src[0] = 0xffffffff; - mystique->dwgreg.src[1] = 0xffffffff; - mystique->dwgreg.src[2] = 0xffffffff; - mystique->dwgreg.src[3] = 0xffffffff; - } - if (val & DWGCTRL_ARZERO) { - mystique->dwgreg.ar[0] = 0; - mystique->dwgreg.ar[1] = 0; - mystique->dwgreg.ar[2] = 0; - mystique->dwgreg.ar[4] = 0; - mystique->dwgreg.ar[5] = 0; - mystique->dwgreg.ar[6] = 0; - } - if (val & DWGCTRL_SGNZERO) { - mystique->dwgreg.sgn.sdydxl = 0; - mystique->dwgreg.sgn.scanleft = 0; - mystique->dwgreg.sgn.sdxl = 0; - mystique->dwgreg.sgn.sdy = 0; - mystique->dwgreg.sgn.sdxr = 0; - } - if (val & DWGCTRL_SHTZERO) { - mystique->dwgreg.funcnt = 0; - mystique->dwgreg.stylelen = 0; - mystique->dwgreg.xoff = 0; - mystique->dwgreg.yoff = 0; - } - break; + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) + mystique->dwgreg.pattern[y][x] = 1; + } + mystique->dwgreg.src[0] = 0xffffffff; + mystique->dwgreg.src[1] = 0xffffffff; + mystique->dwgreg.src[2] = 0xffffffff; + mystique->dwgreg.src[3] = 0xffffffff; + } + if (val & DWGCTRL_ARZERO) { + mystique->dwgreg.ar[0] = 0; + mystique->dwgreg.ar[1] = 0; + mystique->dwgreg.ar[2] = 0; + mystique->dwgreg.ar[4] = 0; + mystique->dwgreg.ar[5] = 0; + mystique->dwgreg.ar[6] = 0; + } + if (val & DWGCTRL_SGNZERO) { + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.sgn.scanleft = 0; + mystique->dwgreg.sgn.sdxl = 0; + mystique->dwgreg.sgn.sdy = 0; + mystique->dwgreg.sgn.sdxr = 0; + } + if (val & DWGCTRL_SHTZERO) { + mystique->dwgreg.funcnt = 0; + mystique->dwgreg.stylelen = 0; + mystique->dwgreg.xoff = 0; + mystique->dwgreg.yoff = 0; + } + break; - case REG_ZORG: - mystique->dwgreg.zorg = val; - mystique->dwgreg.z_base = mystique->dwgreg.ydstorg*2 + mystique->dwgreg.zorg; - break; + case REG_ZORG: + mystique->dwgreg.zorg = val; + mystique->dwgreg.z_base = mystique->dwgreg.ydstorg * 2 + mystique->dwgreg.zorg; + break; - case REG_PLNWT: - mystique->dwgreg.plnwt = val; - break; + case REG_PLNWT: + mystique->dwgreg.plnwt = val; + break; - case REG_SHIFT: - mystique->dwgreg.funcnt = val & 0xff; - mystique->dwgreg.xoff = val & 7; - mystique->dwgreg.yoff = (val >> 4) & 7; - mystique->dwgreg.stylelen = (val >> 16) & 0xff; - break; + case REG_SHIFT: + mystique->dwgreg.funcnt = val & 0xff; + mystique->dwgreg.xoff = val & 7; + mystique->dwgreg.yoff = (val >> 4) & 7; + mystique->dwgreg.stylelen = (val >> 16) & 0xff; + break; - case REG_PITCH: - mystique->dwgreg.pitch = val & 0xffff; - if (mystique->dwgreg.pitch & PITCH_YLIN) - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - else - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - break; + case REG_PITCH: + mystique->dwgreg.pitch = val & 0xffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + else + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + break; - case REG_YDST: - mystique->dwgreg.ydst = val & 0x3fffff; - if (mystique->dwgreg.pitch & PITCH_YLIN) { - mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; - mystique->dwgreg.selline = val >> 29; - } else { - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; - mystique->dwgreg.selline = val & 7; - } - break; - case REG_BCOL: - mystique->dwgreg.bcol = val; - break; - case REG_FCOL: - mystique->dwgreg.fcol = val; - break; + case REG_YDST: + mystique->dwgreg.ydst = val & 0x3fffff; + if (mystique->dwgreg.pitch & PITCH_YLIN) { + mystique->dwgreg.ydst_lin = (mystique->dwgreg.ydst << 5) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val >> 29; + } else { + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.selline = val & 7; + } + break; + case REG_BCOL: + mystique->dwgreg.bcol = val; + break; + case REG_FCOL: + mystique->dwgreg.fcol = val; + break; - case REG_SRC0: - mystique->dwgreg.src[0] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[0], 32); - break; - case REG_SRC1: - mystique->dwgreg.src[1] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[1], 32); - break; - case REG_SRC2: - mystique->dwgreg.src[2] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[2], 32); - break; - case REG_SRC3: - mystique->dwgreg.src[3] = val; - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, mystique->dwgreg.src[3], 32); - break; + case REG_SRC0: + mystique->dwgreg.src[0] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[0], 32); + break; + case REG_SRC1: + mystique->dwgreg.src[1] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[1], 32); + break; + case REG_SRC2: + mystique->dwgreg.src[2] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[2], 32); + break; + case REG_SRC3: + mystique->dwgreg.src[3] = val; + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, mystique->dwgreg.src[3], 32); + break; - case REG_DMAPAD: - if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) - blit_iload_write(mystique, val, 32); - break; + case REG_DMAPAD: + if (mystique->busy && (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) == DWGCTRL_OPCODE_ILOAD) + blit_iload_write(mystique, val, 32); + break; - case REG_AR0: - mystique->dwgreg.ar[0] = val; - break; - case REG_AR1: - mystique->dwgreg.ar[1] = val; - break; - case REG_AR2: - mystique->dwgreg.ar[2] = val; - break; - case REG_AR3: - mystique->dwgreg.ar[3] = val; - break; - case REG_AR4: - mystique->dwgreg.ar[4] = val; - break; - case REG_AR5: - mystique->dwgreg.ar[5] = val; - break; - case REG_AR6: - mystique->dwgreg.ar[6] = val; - break; + case REG_AR0: + mystique->dwgreg.ar[0] = val; + break; + case REG_AR1: + mystique->dwgreg.ar[1] = val; + break; + case REG_AR2: + mystique->dwgreg.ar[2] = val; + break; + case REG_AR3: + mystique->dwgreg.ar[3] = val; + break; + case REG_AR4: + mystique->dwgreg.ar[4] = val; + break; + case REG_AR5: + mystique->dwgreg.ar[5] = val; + break; + case REG_AR6: + mystique->dwgreg.ar[6] = val; + break; - case REG_DR0: - mystique->dwgreg.dr[0] = val; - break; - case REG_DR2: - mystique->dwgreg.dr[2] = val; - break; - case REG_DR3: - mystique->dwgreg.dr[3] = val; - break; - case REG_DR4: - mystique->dwgreg.dr[4] = val; - break; - case REG_DR6: - mystique->dwgreg.dr[6] = val; - break; - case REG_DR7: - mystique->dwgreg.dr[7] = val; - break; - case REG_DR8: - mystique->dwgreg.dr[8] = val; - break; - case REG_DR10: - mystique->dwgreg.dr[10] = val; - break; - case REG_DR11: - mystique->dwgreg.dr[11] = val; - break; - case REG_DR12: - mystique->dwgreg.dr[12] = val; - break; - case REG_DR14: - mystique->dwgreg.dr[14] = val; - break; - case REG_DR15: - mystique->dwgreg.dr[15] = val; - break; + case REG_DR0: + mystique->dwgreg.dr[0] = val; + break; + case REG_DR2: + mystique->dwgreg.dr[2] = val; + break; + case REG_DR3: + mystique->dwgreg.dr[3] = val; + break; + case REG_DR4: + mystique->dwgreg.dr[4] = val; + break; + case REG_DR6: + mystique->dwgreg.dr[6] = val; + break; + case REG_DR7: + mystique->dwgreg.dr[7] = val; + break; + case REG_DR8: + mystique->dwgreg.dr[8] = val; + break; + case REG_DR10: + mystique->dwgreg.dr[10] = val; + break; + case REG_DR11: + mystique->dwgreg.dr[11] = val; + break; + case REG_DR12: + mystique->dwgreg.dr[12] = val; + break; + case REG_DR14: + mystique->dwgreg.dr[14] = val; + break; + case REG_DR15: + mystique->dwgreg.dr[15] = val; + break; - case REG_SECEND: - mystique->dma.secend = val; - if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) - mystique->dma.state = DMA_STATE_SEC; - break; + case REG_SECEND: + mystique->dma.secend = val; + if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) + mystique->dma.state = DMA_STATE_SEC; + break; - case REG_SOFTRAP: - mystique->dma.state = DMA_STATE_IDLE; - mystique->endprdmasts_pending = 1; - mystique->softrap_pending_val = val; - mystique->softrap_pending = 1; - break; + case REG_SOFTRAP: + mystique->dma.state = DMA_STATE_IDLE; + mystique->endprdmasts_pending = 1; + mystique->softrap_pending_val = val; + mystique->softrap_pending = 1; + break; - default: - mystique_accel_ctrl_write_b(addr, val & 0xff, p); - mystique_accel_ctrl_write_b(addr+1, (val >> 8) & 0xff, p); - mystique_accel_ctrl_write_b(addr+2, (val >> 16) & 0xff, p); - mystique_accel_ctrl_write_b(addr+3, (val >> 24) & 0xff, p); - break; + default: + mystique_accel_ctrl_write_b(addr, val & 0xff, p); + mystique_accel_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); + mystique_accel_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); + mystique_accel_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); + break; } if (start_blit) - mystique_start_blit(mystique); + mystique_start_blit(mystique); } - static void mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; - uint32_t reg_addr; + mystique_t *mystique = (mystique_t *) p; + uint32_t reg_addr; if ((addr & 0x3fff) < 0x1c00) { - mystique_iload_write_l(addr, val, p); - return; + mystique_iload_write_l(addr, val, p); + return; } if ((addr & 0x3e00) == 0x1c00 || (addr & 0x3e00) == 0x2c00) { - if ((addr & 0x300) == 0x100) - mystique->blitter_submit_refcount++; - mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_LONG); - return; + if ((addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; + mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_LONG); + return; } switch (addr & 0x3ffc) { - case REG_PRIMEND: - thread_wait_mutex(mystique->dma.lock); - mystique->dma.primend = val; - if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { - mystique->endprdmasts_pending = 0; - mystique->status &= ~STATUS_ENDPRDMASTS; + case REG_PRIMEND: + thread_wait_mutex(mystique->dma.lock); + mystique->dma.primend = val; + if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 0; + mystique->status &= ~STATUS_ENDPRDMASTS; - mystique->dma.state = DMA_STATE_PRI; - mystique->dma.pri_state = 0; - wake_fifo_thread(mystique); - } - thread_release_mutex(mystique->dma.lock); - break; + mystique->dma.state = DMA_STATE_PRI; + mystique->dma.pri_state = 0; + wake_fifo_thread(mystique); + } + thread_release_mutex(mystique->dma.lock); + break; - case REG_DWG_INDIR_WT: case REG_DWG_INDIR_WT+0x04: case REG_DWG_INDIR_WT+0x08: case REG_DWG_INDIR_WT+0x0c: - case REG_DWG_INDIR_WT+0x10: case REG_DWG_INDIR_WT+0x14: case REG_DWG_INDIR_WT+0x18: case REG_DWG_INDIR_WT+0x1c: - case REG_DWG_INDIR_WT+0x20: case REG_DWG_INDIR_WT+0x24: case REG_DWG_INDIR_WT+0x28: case REG_DWG_INDIR_WT+0x2c: - case REG_DWG_INDIR_WT+0x30: case REG_DWG_INDIR_WT+0x34: case REG_DWG_INDIR_WT+0x38: case REG_DWG_INDIR_WT+0x3c: - reg_addr = (mystique->dmamap[(addr >> 2) & 0xf] & 0x7f) << 2; - if (mystique->dmamap[(addr >> 2) & 0xf] & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + case REG_DWG_INDIR_WT: + case REG_DWG_INDIR_WT + 0x04: + case REG_DWG_INDIR_WT + 0x08: + case REG_DWG_INDIR_WT + 0x0c: + case REG_DWG_INDIR_WT + 0x10: + case REG_DWG_INDIR_WT + 0x14: + case REG_DWG_INDIR_WT + 0x18: + case REG_DWG_INDIR_WT + 0x1c: + case REG_DWG_INDIR_WT + 0x20: + case REG_DWG_INDIR_WT + 0x24: + case REG_DWG_INDIR_WT + 0x28: + case REG_DWG_INDIR_WT + 0x2c: + case REG_DWG_INDIR_WT + 0x30: + case REG_DWG_INDIR_WT + 0x34: + case REG_DWG_INDIR_WT + 0x38: + case REG_DWG_INDIR_WT + 0x3c: + reg_addr = (mystique->dmamap[(addr >> 2) & 0xf] & 0x7f) << 2; + if (mystique->dmamap[(addr >> 2) & 0xf] & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_refcount++; + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_refcount++; - mystique_queue(mystique, reg_addr, val, FIFO_WRITE_CTRL_LONG); - break; + mystique_queue(mystique, reg_addr, val, FIFO_WRITE_CTRL_LONG); + break; - default: - mystique_ctrl_write_b(addr, val & 0xff, p); - mystique_ctrl_write_b(addr+1, (val >> 8) & 0xff, p); - mystique_ctrl_write_b(addr+2, (val >> 16) & 0xff, p); - mystique_ctrl_write_b(addr+3, (val >> 24) & 0xff, p); - break; + default: + mystique_ctrl_write_b(addr, val & 0xff, p); + mystique_ctrl_write_b(addr + 1, (val >> 8) & 0xff, p); + mystique_ctrl_write_b(addr + 2, (val >> 16) & 0xff, p); + mystique_ctrl_write_b(addr + 3, (val >> 24) & 0xff, p); + break; } } - static uint8_t mystique_iload_read_b(uint32_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; wait_fifo_idle(mystique); if (!mystique->busy) - return 0xff; + return 0xff; return blit_idump_read(mystique); } - static uint32_t mystique_iload_read_l(uint32_t addr, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; wait_fifo_idle(mystique); if (!mystique->busy) - return 0xffffffff; + return 0xffffffff; mystique->dwgreg.words++; return blit_idump_read(mystique); } - static void mystique_iload_write_b(uint32_t addr, uint8_t val, void *p) { - } - static void mystique_iload_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; mystique_queue(mystique, 0, val, FIFO_WRITE_ILOAD_LONG); } - static void mystique_accel_iload_write_l(uint32_t addr, uint32_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; switch (mystique->dwgreg.dmamod) { - case DMA_MODE_REG: - if (mystique->dma.iload_state == 0) { - mystique->dma.iload_header = val; - mystique->dma.iload_state = 1; - } else { - uint32_t reg_addr = (mystique->dma.iload_header & 0x7f) << 2; - if (mystique->dma.iload_header & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + case DMA_MODE_REG: + if (mystique->dma.iload_state == 0) { + mystique->dma.iload_header = val; + mystique->dma.iload_state = 1; + } else { + uint32_t reg_addr = (mystique->dma.iload_header & 0x7f) << 2; + if (mystique->dma.iload_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; + mystique_accel_ctrl_write_l(reg_addr, val, mystique); - mystique->dma.iload_header >>= 8; - mystique->dma.iload_state = (mystique->dma.iload_state == 4) ? 0 : (mystique->dma.iload_state+1); - } - break; + mystique->dma.iload_header >>= 8; + mystique->dma.iload_state = (mystique->dma.iload_state == 4) ? 0 : (mystique->dma.iload_state + 1); + } + break; - case DMA_MODE_BLIT: - if (mystique->busy) - blit_iload_write(mystique, val, 32); - break; + case DMA_MODE_BLIT: + if (mystique->busy) + blit_iload_write(mystique, val, 32); + break; - /* default: - pclog("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); */ + /* default: + pclog("ILOAD write DMAMOD %i\n", mystique->dwgreg.dmamod); */ } } - static uint8_t mystique_readb_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - cycles -= video_timing_read_b; + cycles -= video_timing_read_b; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; - return svga->vram[addr & svga->vram_mask]; + return svga->vram[addr & svga->vram_mask]; } - static uint16_t mystique_readw_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - cycles -= video_timing_read_w; + cycles -= video_timing_read_w; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffff; - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint16_t *) &svga->vram[addr & svga->vram_mask]; } - static uint32_t mystique_readl_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - cycles -= video_timing_read_l; + cycles -= video_timing_read_l; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xffffffff; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xffffffff; - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint32_t *) &svga->vram[addr & svga->vram_mask]; } - static void mystique_writeb_linear(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - cycles -= video_timing_write_b; + cycles -= video_timing_write_b; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - svga->vram[addr] = val; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + svga->vram[addr] = val; } - static void mystique_writew_linear(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - cycles -= video_timing_write_w; + cycles -= video_timing_write_w; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr] = val; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *) &svga->vram[addr] = val; } - static void mystique_writel_linear(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - cycles -= video_timing_write_l; + cycles -= video_timing_write_l; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr] = val; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *) &svga->vram[addr] = val; } - static void run_dma(mystique_t *mystique) { @@ -2403,483 +2596,491 @@ run_dma(mystique_t *mystique) thread_wait_mutex(mystique->dma.lock); if (mystique->dma.state == DMA_STATE_IDLE) { - thread_release_mutex(mystique->dma.lock); - return; + thread_release_mutex(mystique->dma.lock); + return; } while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { - switch (mystique->dma.state) { - case DMA_STATE_PRI: - switch (mystique->dma.primaddress & DMA_MODE_MASK) { - case DMA_MODE_REG: - if (mystique->dma.pri_state == 0) { - dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); - mystique->dma.primaddress += 4; - } + switch (mystique->dma.state) { + case DMA_STATE_PRI: + switch (mystique->dma.primaddress & DMA_MODE_MASK) { + case DMA_MODE_REG: + if (mystique->dma.pri_state == 0) { + dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.pri_header, 4, 4); + mystique->dma.primaddress += 4; + } - if ((mystique->dma.pri_header & 0xff) != 0x15) { - uint32_t val, reg_addr; + if ((mystique->dma.pri_header & 0xff) != 0x15) { + uint32_t val, reg_addr; - dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); - mystique->dma.primaddress += 4; + dma_bm_read(mystique->dma.primaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); + mystique->dma.primaddress += 4; - reg_addr = (mystique->dma.pri_header & 0x7f) << 2; - if (mystique->dma.pri_header & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + reg_addr = (mystique->dma.pri_header & 0x7f) << 2; + if (mystique->dma.pri_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_dma_refcount++; + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); - } + mystique_accel_ctrl_write_l(reg_addr, val, mystique); + } - mystique->dma.pri_header >>= 8; - mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; + mystique->dma.pri_header >>= 8; + mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - words_transferred++; - if (mystique->dma.state == DMA_STATE_SEC) - mystique->dma.pri_state = 0; - else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { - mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; - } - break; + words_transferred++; + if (mystique->dma.state == DMA_STATE_SEC) + mystique->dma.pri_state = 0; + else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } + break; - default: - fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); - } - break; + default: + fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); + } + break; - case DMA_STATE_SEC: - switch (mystique->dma.secaddress & DMA_MODE_MASK) { - case DMA_MODE_REG: - if (mystique->dma.sec_state == 0) { - dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); - mystique->dma.secaddress += 4; - } + case DMA_STATE_SEC: + switch (mystique->dma.secaddress & DMA_MODE_MASK) { + case DMA_MODE_REG: + if (mystique->dma.sec_state == 0) { + dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &mystique->dma.sec_header, 4, 4); + mystique->dma.secaddress += 4; + } - uint32_t val, reg_addr; + uint32_t val, reg_addr; - dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); - mystique->dma.secaddress += 4; + dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); + mystique->dma.secaddress += 4; - reg_addr = (mystique->dma.sec_header & 0x7f) << 2; - if (mystique->dma.sec_header & 0x80) - reg_addr += 0x2c00; - else - reg_addr += 0x1c00; + reg_addr = (mystique->dma.sec_header & 0x7f) << 2; + if (mystique->dma.sec_header & 0x80) + reg_addr += 0x2c00; + else + reg_addr += 0x1c00; - if ((reg_addr & 0x300) == 0x100) - mystique->blitter_submit_dma_refcount++; + if ((reg_addr & 0x300) == 0x100) + mystique->blitter_submit_dma_refcount++; - mystique_accel_ctrl_write_l(reg_addr, val, mystique); + mystique_accel_ctrl_write_l(reg_addr, val, mystique); - mystique->dma.sec_header >>= 8; - mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; + mystique->dma.sec_header >>= 8; + mystique->dma.sec_state = (mystique->dma.sec_state + 1) & 3; - words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { - mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; - } else - mystique->dma.state = DMA_STATE_PRI; - } - break; + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } else + mystique->dma.state = DMA_STATE_PRI; + } + break; - case DMA_MODE_BLIT: { - uint32_t val; + case DMA_MODE_BLIT: + { + uint32_t val; - dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); - mystique->dma.secaddress += 4; + dma_bm_read(mystique->dma.secaddress & DMA_ADDR_MASK, (uint8_t *) &val, 4, 4); + mystique->dma.secaddress += 4; - if (mystique->busy) - blit_iload_write(mystique, val, 32); + if (mystique->busy) + blit_iload_write(mystique, val, 32); - words_transferred++; - if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { - if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { - mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; - } else - mystique->dma.state = DMA_STATE_PRI; - } - } break; + words_transferred++; + if ((mystique->dma.secaddress & DMA_ADDR_MASK) == (mystique->dma.secend & DMA_ADDR_MASK)) { + if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { + mystique->endprdmasts_pending = 1; + mystique->dma.state = DMA_STATE_IDLE; + } else + mystique->dma.state = DMA_STATE_PRI; + } + } + break; - default: - fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); - } - break; - } + default: + fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); + } + break; + } } thread_release_mutex(mystique->dma.lock); } - static void fifo_thread(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; while (mystique->thread_run) { - thread_set_event(mystique->fifo_not_full_event); - thread_wait_event(mystique->wake_fifo_thread, -1); - thread_reset_event(mystique->wake_fifo_thread); + thread_set_event(mystique->fifo_not_full_event); + thread_wait_event(mystique->wake_fifo_thread, -1); + thread_reset_event(mystique->wake_fifo_thread); - while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { - int words_transferred = 0; + while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { + int words_transferred = 0; - while (!FIFO_EMPTY && words_transferred < 100) { - fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; + while (!FIFO_EMPTY && words_transferred < 100) { + fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_CTRL_BYTE: - mystique_accel_ctrl_write_b(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); - break; - case FIFO_WRITE_CTRL_LONG: - mystique_accel_ctrl_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); - break; - case FIFO_WRITE_ILOAD_LONG: - mystique_accel_iload_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); - break; - } + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_CTRL_BYTE: + mystique_accel_ctrl_write_b(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_CTRL_LONG: + mystique_accel_ctrl_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + case FIFO_WRITE_ILOAD_LONG: + mystique_accel_iload_write_l(fifo->addr_type & FIFO_ADDR, fifo->val, mystique); + break; + } - fifo->addr_type = FIFO_INVALID; - mystique->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; + mystique->fifo_read_idx++; - if (FIFO_ENTRIES > FIFO_THRESHOLD) - thread_set_event(mystique->fifo_not_full_event); + if (FIFO_ENTRIES > FIFO_THRESHOLD) + thread_set_event(mystique->fifo_not_full_event); - words_transferred++; - } + words_transferred++; + } - /*Only run DMA once the FIFO is empty. Required by - Screamer 2 / Rally which will incorrectly clip an ILOAD - if DMA runs ahead*/ - if (!words_transferred) - run_dma(mystique); - } + /*Only run DMA once the FIFO is empty. Required by + Screamer 2 / Rally which will incorrectly clip an ILOAD + if DMA runs ahead*/ + if (!words_transferred) + run_dma(mystique); + } } } - static void wake_fifo_thread(mystique_t *mystique) { if (!timer_is_enabled(&mystique->wake_timer)) { - /* Don't wake FIFO thread immediately - if we do that it will probably - process one word and go back to sleep, requiring it to be woken on - almost every write. Instead, wait a short while so that the CPU - emulation writes more data so we have more batched-up work. */ - timer_set_delay_u64(&mystique->wake_timer, WAKE_DELAY); + /* Don't wake FIFO thread immediately - if we do that it will probably + process one word and go back to sleep, requiring it to be woken on + almost every write. Instead, wait a short while so that the CPU + emulation writes more data so we have more batched-up work. */ + timer_set_delay_u64(&mystique->wake_timer, WAKE_DELAY); } } - static void wake_fifo_thread_now(mystique_t *mystique) { thread_set_event(mystique->wake_fifo_thread); } - static void mystique_wake_timer(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; thread_set_event(mystique->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } - static void wait_fifo_idle(mystique_t *mystique) { while (!FIFO_EMPTY) { - wake_fifo_thread_now(mystique); - thread_wait_event(mystique->fifo_not_full_event, 1); + wake_fifo_thread_now(mystique); + thread_wait_event(mystique->fifo_not_full_event, 1); } } - /*IRQ code (PCI & PIC) is not currently thread safe. SOFTRAP IRQ requests must therefore be submitted from the main emulation thread, in this case via a timer callback. End-of-DMA status is also deferred here to prevent races between SOFTRAP IRQs and code reading the status register. Croc will get into an IRQ loop and triple fault if the ENDPRDMASTS flag is seen before the IRQ is taken*/ -static void mystique_softrap_pending_timer(void *p) +static void +mystique_softrap_pending_timer(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; timer_advance_u64(&mystique->softrap_pending_timer, TIMER_USEC * 100); if (mystique->endprdmasts_pending) { - mystique->endprdmasts_pending = 0; - mystique->status |= STATUS_ENDPRDMASTS; + mystique->endprdmasts_pending = 0; + mystique->status |= STATUS_ENDPRDMASTS; } if (mystique->softrap_pending) { - mystique->softrap_pending = 0; + mystique->softrap_pending = 0; - mystique->dma.secaddress = mystique->softrap_pending_val; - mystique->status |= STATUS_SOFTRAPEN; - mystique_update_irqs(mystique); + mystique->dma.secaddress = mystique->softrap_pending_val; + mystique->status |= STATUS_SOFTRAPEN; + mystique_update_irqs(mystique); } } - -static -void mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type) +static void +mystique_queue(mystique_t *mystique, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &mystique->fifo[mystique->fifo_write_idx & FIFO_MASK]; if (FIFO_FULL) { - thread_reset_event(mystique->fifo_not_full_event); - if (FIFO_FULL) - thread_wait_event(mystique->fifo_not_full_event, -1); /* Wait for room in ringbuffer */ + thread_reset_event(mystique->fifo_not_full_event); + if (FIFO_FULL) + thread_wait_event(mystique->fifo_not_full_event, -1); /* Wait for room in ringbuffer */ } - fifo->val = val; + fifo->val = val; fifo->addr_type = (addr & FIFO_ADDR) | type; mystique->fifo_write_idx++; if (FIFO_ENTRIES > FIFO_THRESHOLD || FIFO_ENTRIES < 8) - wake_fifo_thread(mystique); + wake_fifo_thread(mystique); } - static uint32_t bitop(uint32_t src, uint32_t dst, uint32_t dwgctrl) { switch (dwgctrl & DWGCTRL_BOP_MASK) { - case BOP(0x0): return 0; - case BOP(0x1): return ~(dst | src); - case BOP(0x2): return dst & ~src; - case BOP(0x3): return ~src; - case BOP(0x4): return ~dst & src; - case BOP(0x5): return ~dst; - case BOP(0x6): return dst ^ src; - case BOP(0x7): return ~(dst & src); - case BOP(0x8): return dst & src; - case BOP(0x9): return ~(dst ^ src); - case BOP(0xa): return dst; - case BOP(0xb): return dst | ~src; - case BOP(0xc): return src; - case BOP(0xd): return ~dst | src; - case BOP(0xe): return dst | src; - case BOP(0xf): return ~0; + case BOP(0x0): + return 0; + case BOP(0x1): + return ~(dst | src); + case BOP(0x2): + return dst & ~src; + case BOP(0x3): + return ~src; + case BOP(0x4): + return ~dst & src; + case BOP(0x5): + return ~dst; + case BOP(0x6): + return dst ^ src; + case BOP(0x7): + return ~(dst & src); + case BOP(0x8): + return dst & src; + case BOP(0x9): + return ~(dst ^ src); + case BOP(0xa): + return dst; + case BOP(0xb): + return dst | ~src; + case BOP(0xc): + return src; + case BOP(0xd): + return ~dst | src; + case BOP(0xe): + return dst | src; + case BOP(0xf): + return ~0; } return 0; } - static uint16_t dither(mystique_t *mystique, int r, int g, int b, int x, int y) { switch (mystique->dwgreg.dither) { - case DITHER_NONE_555: - return (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10); + case DITHER_NONE_555: + return (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10); - case DITHER_NONE_565: - return (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + case DITHER_NONE_565: + return (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); - case DITHER_555: - return dither5[b][y][x] | (dither5[g][y][x] << 5) | (dither5[r][y][x] << 10); + case DITHER_555: + return dither5[b][y][x] | (dither5[g][y][x] << 5) | (dither5[r][y][x] << 10); - case DITHER_565: - default: - return dither5[b][y][x] | (dither6[g][y][x] << 5) | (dither5[r][y][x] << 11); + case DITHER_565: + default: + return dither5[b][y][x] | (dither6[g][y][x] << 5) | (dither5[r][y][x] << 11); } } - static uint32_t blit_idump_idump(mystique_t *mystique) { - svga_t *svga = &mystique->svga; + svga_t *svga = &mystique->svga; uint64_t val64 = 0; - uint32_t val = 0; - int count = 0; + uint32_t val = 0; + int count = 0; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BU32RGB: - case DWGCTRL_BLTMOD_BFCOL: - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - while (count < 32) { - val |= (svga->vram[mystique->dwgreg.src_addr & mystique->vram_mask] << count); + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BU32RGB: + case DWGCTRL_BLTMOD_BFCOL: + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + while (count < 32) { + val |= (svga->vram[mystique->dwgreg.src_addr & mystique->vram_mask] << count); - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - count += 8; - } - break; + count += 8; + } + break; - case MACCESS_PWIDTH_16: - while (count < 32) { - val |= (((uint16_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_w] << count); + case MACCESS_PWIDTH_16: + while (count < 32) { + val |= (((uint16_t *) svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_w] << count); - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - count += 16; - } - break; + count += 16; + } + break; - case MACCESS_PWIDTH_24: - if (mystique->dwgreg.idump_end_of_line) { - mystique->dwgreg.idump_end_of_line = 0; - val = mystique->dwgreg.iload_rem_data; - mystique->dwgreg.iload_rem_count = 0; - mystique->dwgreg.iload_rem_data = 0; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - } - break; - } + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.idump_end_of_line) { + mystique->dwgreg.idump_end_of_line = 0; + val = mystique->dwgreg.iload_rem_data; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } - count += mystique->dwgreg.iload_rem_count; - val64 = mystique->dwgreg.iload_rem_data; + count += mystique->dwgreg.iload_rem_count; + val64 = mystique->dwgreg.iload_rem_data; - while ((count < 32) && !mystique->dwgreg.idump_end_of_line) { - val64 |= (uint64_t)((*(uint32_t *)&svga->vram[(mystique->dwgreg.src_addr * 3) & mystique->vram_mask]) & 0xffffff) << count; + while ((count < 32) && !mystique->dwgreg.idump_end_of_line) { + val64 |= (uint64_t) ((*(uint32_t *) &svga->vram[(mystique->dwgreg.src_addr * 3) & mystique->vram_mask]) & 0xffffff) << count; - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - if (count > 8) - mystique->dwgreg.idump_end_of_line = 1; - else { - count = 32; - mystique->busy = 0; - mystique->blitter_complete_refcount++; - } - break; - } - if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) { - if (count > 8) - mystique->dwgreg.idump_end_of_line = 1; - else { - count = 32; - break; - } - } - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else { + count = 32; + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) { + if (count > 8) + mystique->dwgreg.idump_end_of_line = 1; + else { + count = 32; + break; + } + } + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - count += 24; - } - if (count > 32) - mystique->dwgreg.iload_rem_count = count - 32; - else - mystique->dwgreg.iload_rem_count = 0; - mystique->dwgreg.iload_rem_data = (uint32_t)(val64 >> 32); - val = val64 & 0xffffffff; - break; + count += 24; + } + if (count > 32) + mystique->dwgreg.iload_rem_count = count - 32; + else + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = (uint32_t) (val64 >> 32); + val = val64 & 0xffffffff; + break; - case MACCESS_PWIDTH_32: - val = (((uint32_t *)svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_l] << count); + case MACCESS_PWIDTH_32: + val = (((uint32_t *) svga->vram)[mystique->dwgreg.src_addr & mystique->vram_mask_l] << count); - if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - } else - mystique->dwgreg.src_addr++; + if (mystique->dwgreg.src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + } else + mystique->dwgreg.src_addr++; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + break; - default: - fatal("IDUMP DWGCTRL_BLTMOD_BU32RGB %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->maccess_running); - } - break; + default: + fatal("IDUMP DWGCTRL_BLTMOD_BU32RGB %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->maccess_running); + } + break; - default: - fatal("IDUMP DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; - } - break; + default: + fatal("IDUMP DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; - default: - fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } return val; } - static uint32_t blit_idump_read(mystique_t *mystique) { uint32_t ret = 0xffffffff; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { - case DWGCTRL_OPCODE_IDUMP: - ret = blit_idump_idump(mystique); - break; + case DWGCTRL_OPCODE_IDUMP: + ret = blit_idump_idump(mystique); + break; - default: - /* pclog("blit_idump_read: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); */ - break; + default: + /* pclog("blit_idump_read: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); */ + break; } return ret; @@ -2888,1978 +3089,1910 @@ blit_idump_read(mystique_t *mystique) static void blit_fbitblt(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - uint32_t src_addr; - int y; - int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; - int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; - int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; + svga_t *svga = &mystique->svga; + uint32_t src_addr; + int y; + int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; + int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; + int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; - src_addr = mystique->dwgreg.ar[3]; + src_addr = mystique->dwgreg.ar[3]; - for (y = 0; y < mystique->dwgreg.length; y++) - { - int16_t x = x_start; - while (1) - { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) - { - uint32_t src, old_dst; + for (y = 0; y < mystique->dwgreg.length; y++) { + int16_t x = x_start; + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t src, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) - { - case MACCESS_PWIDTH_8: - src = svga->vram[src_addr & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = svga->vram[src_addr & mystique->vram_mask]; - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = src; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = src; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + src = ((uint16_t *) svga->vram)[src_addr & mystique->vram_mask_w]; - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = src; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = src; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + src = *(uint32_t *) &svga->vram[(src_addr * 3) & mystique->vram_mask]; + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (src & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (src & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + src = ((uint32_t *) svga->vram)[src_addr & mystique->vram_mask_l]; - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = src; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = src; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } - - if (src_addr == mystique->dwgreg.ar[0]) - { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - break; - } - else - src_addr += x_dir; - - if (x != x_end) - x += x_dir; - else - break; + default: + fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); } + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + break; + } else + src_addr += x_dir; + + if (x != x_end) + x += x_dir; + else + break; } - mystique->blitter_complete_refcount++; + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + + mystique->blitter_complete_refcount++; } static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { - svga_t *svga = &mystique->svga; - uint32_t src, dst; - uint32_t dst2; - uint64_t data64; - int min_size = 8; - uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; - const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC; - const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint32_t data_mask = 1; + svga_t *svga = &mystique->svga; + uint32_t src, dst; + uint32_t dst2; + uint64_t data64; + int min_size = 8; + uint32_t bltckey = mystique->dwgreg.fcol, bltcmsk = mystique->dwgreg.bcol; + const int transc = mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC; + const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint32_t data_mask = 1; switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - bltckey &= 0xff; - bltcmsk &= 0xff; - break; - case MACCESS_PWIDTH_16: - bltckey &= 0xffff; - bltcmsk &= 0xffff; - break; + case MACCESS_PWIDTH_8: + bltckey &= 0xff; + bltcmsk &= 0xff; + break; + case MACCESS_PWIDTH_16: + bltckey &= 0xffff; + bltcmsk &= 0xffff; + break; } mystique->dwgreg.words++; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - if (mystique->maccess_running & MACCESS_TLUTLOAD) { - while ((mystique->dwgreg.length_cur > 0) && (size >= 16)) { - uint16_t src = data & 0xffff; + case DWGCTRL_ATYPE_RPL: + if (mystique->maccess_running & MACCESS_TLUTLOAD) { + while ((mystique->dwgreg.length_cur > 0) && (size >= 16)) { + uint16_t src = data & 0xffff; - mystique->lut[mystique->dwgreg.ydst & 0xff].r = (src >> 11) << 3; - mystique->lut[mystique->dwgreg.ydst & 0xff].g = ((src >> 5) & 0x3f) << 2; - mystique->lut[mystique->dwgreg.ydst & 0xff].b = (src & 0x1f) << 3; - mystique->dwgreg.ydst++; - mystique->dwgreg.length_cur--; - data >>= 16; - size -= 16; - } + mystique->lut[mystique->dwgreg.ydst & 0xff].r = (src >> 11) << 3; + mystique->lut[mystique->dwgreg.ydst & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[mystique->dwgreg.ydst & 0xff].b = (src & 0x1f) << 3; + mystique->dwgreg.ydst++; + mystique->dwgreg.length_cur--; + data >>= 16; + size -= 16; + } - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - } - break; - } - case DWGCTRL_ATYPE_RSTR: - case DWGCTRL_ATYPE_BLK: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BFCOL: - size += mystique->dwgreg.iload_rem_count; - data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + } + break; + } + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BFCOL: + size += mystique->dwgreg.iload_rem_count; + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t) data << mystique->dwgreg.iload_rem_count); - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - min_size = 8; - break; - case MACCESS_PWIDTH_16: - min_size = 16; - break; - case MACCESS_PWIDTH_24: - min_size = 24; - break; - case MACCESS_PWIDTH_32: - min_size = 32; - break; - } + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + min_size = 8; + break; + case MACCESS_PWIDTH_16: + min_size = 16; + break; + case MACCESS_PWIDTH_24: + min_size = 24; + break; + case MACCESS_PWIDTH_32: + min_size = 32; + break; + } - while (size >= min_size) { - int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + while (size >= min_size) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; - dst = bitop(data & 0xff, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; - } + dst = bitop(data & 0xff, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + } - data >>= 8; - size -= 8; - break; + data >>= 8; + size -= 8; + break; - case MACCESS_PWIDTH_16: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; - dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - } + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + } - data >>= 16; - size -= 16; - break; + data >>= 16; + size -= 16; + break; - case MACCESS_PWIDTH_24: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t old_dst = *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]); + case MACCESS_PWIDTH_24: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t old_dst = *((uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]); - dst = bitop(data64, old_dst, mystique->dwgreg.dwgctrl_running); - *((uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]) = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; - } + dst = bitop(data64, old_dst, mystique->dwgreg.dwgctrl_running); + *((uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]) = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; + } - data64 >>= 24; - size -= 24; - break; + data64 >>= 24; + size -= 24; + break; - case MACCESS_PWIDTH_32: - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - } + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + } - size = 0; - break; + size = 0; + break; - default: - fatal("ILOAD RSTR/RPL BFCOL pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); - } + default: + fatal("ILOAD RSTR/RPL BFCOL pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - data64 = 0; - size = 0; - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } - mystique->dwgreg.iload_rem_count = size; - mystique->dwgreg.iload_rem_data = data64; - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; - case DWGCTRL_BLTMOD_BMONOWF: - data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24); - data_mask = (1 << 31); - case DWGCTRL_BLTMOD_BMONOLEF: - while (size) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - ((data & data_mask) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && - trans[mystique->dwgreg.xdst & 3]) { - uint32_t old_dst; + case DWGCTRL_BLTMOD_BMONOWF: + data = (data >> 24) | ((data & 0x00ff0000) >> 8) | ((data & 0x0000ff00) << 8) | (data << 24); + data_mask = (1 << 31); + case DWGCTRL_BLTMOD_BMONOLEF: + while (size) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((data & data_mask) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[mystique->dwgreg.xdst & 3]) { + uint32_t old_dst; - src = (data & data_mask) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + src = (data & data_mask) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask]; - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("ILOAD RSTR/RPL BMONOWF pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); - } - } + default: + fatal("ILOAD RSTR/RPL BMONOWF pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - if (data_mask == 1) - data >>= 1; - else - data <<= 1; - size--; - } - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + if (!(mystique->dwgreg.dwgctrl_running & DWGCTRL_LINEAR)) + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (data_mask == 1) + data >>= 1; + else + data <<= 1; + size--; + } + break; - case DWGCTRL_BLTMOD_BU24RGB: - size += mystique->dwgreg.iload_rem_count; - data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); + case DWGCTRL_BLTMOD_BU24RGB: + size += mystique->dwgreg.iload_rem_count; + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t) data << mystique->dwgreg.iload_rem_count); - while (size >= 24) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_32: - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + while (size >= 24) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(data64 & 0xffffff, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(data64 & 0xffffff, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("ILOAD RSTR/RPL BU24RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); - } - } + default: + fatal("ILOAD RSTR/RPL BU24RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } - data64 >>= 24; - size -= 24; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - data64 = 0; - size = 0; - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } + data64 >>= 24; + size -= 24; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } - mystique->dwgreg.iload_rem_count = size; - mystique->dwgreg.iload_rem_data = data64; - break; + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; - case DWGCTRL_BLTMOD_BU32RGB: - size += mystique->dwgreg.iload_rem_count; - data64 = mystique->dwgreg.iload_rem_data | ((uint64_t)data << mystique->dwgreg.iload_rem_count); - while (size >= 32) - { - int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + case DWGCTRL_BLTMOD_BU32RGB: + size += mystique->dwgreg.iload_rem_count; + data64 = mystique->dwgreg.iload_rem_data | ((uint64_t) data << mystique->dwgreg.iload_rem_count); + while (size >= 32) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) - { - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - } + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + } - size = 0; + size = 0; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) - { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) - { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - data64 = 0; - size = 0; - break; - } - else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } - mystique->dwgreg.iload_rem_count = size; - mystique->dwgreg.iload_rem_data = data64; - break; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; - case DWGCTRL_BLTMOD_BU32BGR: - size += mystique->dwgreg.iload_rem_count; - while (size >= 32) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_32: - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst2 = ((dst >> 16) & 0xff) | (dst & 0xff00) | ((dst & 0xff) << 16); /* BGR to RGB */ + case DWGCTRL_BLTMOD_BU32BGR: + size += mystique->dwgreg.iload_rem_count; + while (size >= 32) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst2 = ((dst >> 16) & 0xff) | (dst & 0xff00) | ((dst & 0xff) << 16); /* BGR to RGB */ - dst = bitop(data, dst2, mystique->dwgreg.dwgctrl_running); + dst = bitop(data, dst2, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("ILOAD RSTR/RPL BU32RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); - } - } + default: + fatal("ILOAD RSTR/RPL BU32RGB pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } - size = 0; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - } + size = 0; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } - mystique->dwgreg.iload_rem_count = size; - break; + mystique->dwgreg.iload_rem_count = size; + break; - default: - fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); - break; - } - break; + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL\n"); + break; + } + break; - default: - fatal("Unknown ILOAD iload atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD iload atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } } - -#define CLAMP(x) do { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } while (0) - +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) static void blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) { - svga_t *svga = &mystique->svga; + svga_t *svga = &mystique->svga; uint64_t data64 = 0; - int y0, y1; - int u, v; - int dR, dG, dB; - int r0, g0, b0; - int r1, g1, b1; + int y0, y1; + int u, v; + int dR, dG, dB; + int r0, g0, b0; + int r1, g1, b1; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: - y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; - u = ((data >> 8) & 0xff) - 0x80; - y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; - v = ((data >> 24) & 0xff) - 0x80; + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int) (data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int) ((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; - dR = (309*v) >> 8; - dG = (100*u + 208*v) >> 8; - dB = (516*u) >> 8; + dR = (309 * v) >> 8; + dG = (100 * u + 208 * v) >> 8; + dB = (516 * u) >> 8; - r0 = y0 + dR; - CLAMP(r0); - g0 = y0 - dG; - CLAMP(g0); - b0 = y0 + dB; - CLAMP(b0); - r1 = y1 + dR; - CLAMP(r1); - g1 = y1 - dG; - CLAMP(g1); - b1 = y1 + dB; - CLAMP(b1); + r0 = y0 + dR; + CLAMP(r0); + g0 = y0 - dG; + CLAMP(g0); + b0 = y0 + dB; + CLAMP(b0); + r1 = y1 + dR; + CLAMP(r1); + g1 = y1 - dG; + CLAMP(g1); + b1 = y1 + dB; + CLAMP(b1); - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16: - data = (b0 >> 3) | ((g0 >> 2) << 5) | ((r0 >> 3) << 11); - data |= (((b1 >> 3) | ((g1 >> 2) << 5) | ((r1 >> 3) << 11)) << 16); - size = 32; - break; - case MACCESS_PWIDTH_32: - data64 = b0 | (g0 << 8) | (r0 << 16); - data64 |= ((uint64_t)b0 << 32) | ((uint64_t)g0 << 40) | ((uint64_t)r0 << 48); - size = 64; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + data = (b0 >> 3) | ((g0 >> 2) << 5) | ((r0 >> 3) << 11); + data |= (((b1 >> 3) | ((g1 >> 2) << 5) | ((r1 >> 3) << 11)) << 16); + size = 32; + break; + case MACCESS_PWIDTH_32: + data64 = b0 | (g0 << 8) | (r0 << 16); + data64 |= ((uint64_t) b0 << 32) | ((uint64_t) g0 << 40) | ((uint64_t) r0 << 48); + size = 64; + break; - default: - fatal("blit_iload_iload_scale BUYUV pwidth %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); - } - break; + default: + fatal("blit_iload_iload_scale BUYUV pwidth %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + break; - default: - fatal("blit_iload_iload_scale bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; + default: + fatal("blit_iload_iload_scale bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; } switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16: - while (size >= 16) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint16_t dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; - dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - } + case MACCESS_PWIDTH_16: + while (size >= 16) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint16_t dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + dst = bitop(data & 0xffff, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + } - mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[6] >= 0) { - mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - data >>= 16; - size -= 16; - } + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t) mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data >>= 16; + size -= 16; + } - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) - { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } - } - break; + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + } + break; - case MACCESS_PWIDTH_32: - while (size >= 32) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(data64, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - } + case MACCESS_PWIDTH_32: + while (size >= 32) { + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst = bitop(data64, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + } - mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[6] >= 0) { - mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - data64 >>= 32; - size -= 32; - } + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t) mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + data64 >>= 32; + size -= 32; + } - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) - { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } - } - break; + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } + } + break; - default: - fatal("ILOAD_SCALE pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + default: + fatal("ILOAD_SCALE pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); } } - static void blit_iload_iload_high(mystique_t *mystique, uint32_t data, int size) { - svga_t *svga = &mystique->svga; + svga_t *svga = &mystique->svga; uint32_t out_data; - int y0, y1, u, v; - int dR, dG, dB; - int r = 0, g = 0, b = 0; - int next_r = 0, next_g = 0, next_b = 0; + int y0, y1, u, v; + int dR, dG, dB; + int r = 0, g = 0, b = 0; + int next_r = 0, next_g = 0, next_b = 0; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: - y0 = (298 * ((int)(data & 0xff) - 16)) >> 8; - u = ((data >> 8) & 0xff) - 0x80; - y1 = (298 * ((int)((data >> 16) & 0xff) - 16)) >> 8; - v = ((data >> 24) & 0xff) - 0x80; + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int) (data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int) ((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; - dR = (309*v) >> 8; - dG = (100*u + 208*v) >> 8; - dB = (516*u) >> 8; + dR = (309 * v) >> 8; + dG = (100 * u + 208 * v) >> 8; + dB = (516 * u) >> 8; - r = y0 + dR; - CLAMP(r); - g = y0 - dG; - CLAMP(g); - b = y0 + dB; - CLAMP(b); + r = y0 + dR; + CLAMP(r); + g = y0 - dG; + CLAMP(g); + b = y0 + dB; + CLAMP(b); - next_r = y1 + dR; - CLAMP(next_r); - next_g = y1 - dG; - CLAMP(next_g); - next_b = y1 + dB; - CLAMP(next_b); + next_r = y1 + dR; + CLAMP(next_r); + next_g = y1 - dG; + CLAMP(next_g); + next_b = y1 + dB; + CLAMP(next_b); - size = 32; - break; + size = 32; + break; - case DWGCTRL_BLTMOD_BU32BGR: - r = ((data >> 16) & 0xff); - CLAMP(r); - g = ((data >> 8) & 0xff); - CLAMP(g); - b = (data & 0xff); - CLAMP(b); + case DWGCTRL_BLTMOD_BU32BGR: + r = ((data >> 16) & 0xff); + CLAMP(r); + g = ((data >> 8) & 0xff); + CLAMP(g); + b = (data & 0xff); + CLAMP(b); - next_r = r; - next_g = g; - next_b = b; + next_r = r; + next_g = g; + next_b = b; - size = 32; - break; + size = 32; + break; - default: - fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; + default: + fatal("blit_iload_iload_high bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; } while (size >= 16) { - if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t dst; - int f1 = (mystique->dwgreg.ar[6] >> 12) & 0xf; - int f0 = 0x10 - f1; - int out_r = ((mystique->dwgreg.lastpix_r * f0) + (r * f1)) >> 4; - int out_g = ((mystique->dwgreg.lastpix_g * f0) + (g * f1)) >> 4; - int out_b = ((mystique->dwgreg.lastpix_b * f0) + (b * f1)) >> 4; + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t dst; + int f1 = (mystique->dwgreg.ar[6] >> 12) & 0xf; + int f0 = 0x10 - f1; + int out_r = ((mystique->dwgreg.lastpix_r * f0) + (r * f1)) >> 4; + int out_g = ((mystique->dwgreg.lastpix_g * f0) + (g * f1)) >> 4; + int out_b = ((mystique->dwgreg.lastpix_b * f0) + (b * f1)) >> 4; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16: - out_data = (out_b >> 3) | ((out_g >> 2) << 5) | ((out_r >> 3) << 11); - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; - dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; - break; - case MACCESS_PWIDTH_32: - out_data = out_b | (out_g << 8) | (out_r << 16); - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; - dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + out_data = (out_b >> 3) | ((out_g >> 2) << 5) | ((out_r >> 3) << 11); + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + case MACCESS_PWIDTH_32: + out_data = out_b | (out_g << 8) | (out_r << 16); + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + dst = bitop(out_data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("ILOAD_SCALE_HIGH RSTR/RPL BUYUV pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); - } - } + default: + fatal("ILOAD_SCALE_HIGH RSTR/RPL BUYUV pwidth %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } - mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[6] >= 0) { - mystique->dwgreg.ar[6] -= 65536; - size -= 16; + mystique->dwgreg.ar[6] += mystique->dwgreg.ar[2]; + if ((int32_t) mystique->dwgreg.ar[6] >= 0) { + mystique->dwgreg.ar[6] -= 65536; + size -= 16; - mystique->dwgreg.lastpix_r = r; - mystique->dwgreg.lastpix_g = g; - mystique->dwgreg.lastpix_b = b; - r = next_r; - g = next_g; - b = next_b; - } + mystique->dwgreg.lastpix_r = r; + mystique->dwgreg.lastpix_g = g; + mystique->dwgreg.lastpix_b = b; + r = next_r; + g = next_g; + b = next_b; + } - if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); - mystique->dwgreg.lastpix_r = 0; - mystique->dwgreg.lastpix_g = 0; - mystique->dwgreg.lastpix_b = 0; + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ar[6] = mystique->dwgreg.ar[2] - (mystique->dwgreg.fxright - mystique->dwgreg.fxleft); + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; - mystique->dwgreg.length_cur--; - if (!mystique->dwgreg.length_cur) { - mystique->busy = 0; - mystique->blitter_complete_refcount++; - break; - } - break; - } else - mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; } } - static void blit_iload_iload_highv(mystique_t *mystique, uint32_t data, int size) { uint8_t *src0, *src1; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: - if (!mystique->dwgreg.highv_line) { - mystique->dwgreg.highv_data = data; - mystique->dwgreg.highv_line = 1; - return; - } - mystique->dwgreg.highv_line = 0; + case DWGCTRL_BLTMOD_BUYUV: + if (!mystique->dwgreg.highv_line) { + mystique->dwgreg.highv_data = data; + mystique->dwgreg.highv_line = 1; + return; + } + mystique->dwgreg.highv_line = 0; - src0 = (uint8_t *)&mystique->dwgreg.highv_data; - src1 = (uint8_t *)&data; + src0 = (uint8_t *) &mystique->dwgreg.highv_data; + src1 = (uint8_t *) &data; - src1[0] = ((src0[0] * mystique->dwgreg.beta) + (src1[0] * (16 - mystique->dwgreg.beta))) >> 4; - src1[1] = ((src0[1] * mystique->dwgreg.beta) + (src1[1] * (16 - mystique->dwgreg.beta))) >> 4; - src1[2] = ((src0[2] * mystique->dwgreg.beta) + (src1[2] * (16 - mystique->dwgreg.beta))) >> 4; - src1[3] = ((src0[3] * mystique->dwgreg.beta) + (src1[3] * (16 - mystique->dwgreg.beta))) >> 4; - blit_iload_iload_high(mystique, data, 32); - break; + src1[0] = ((src0[0] * mystique->dwgreg.beta) + (src1[0] * (16 - mystique->dwgreg.beta))) >> 4; + src1[1] = ((src0[1] * mystique->dwgreg.beta) + (src1[1] * (16 - mystique->dwgreg.beta))) >> 4; + src1[2] = ((src0[2] * mystique->dwgreg.beta) + (src1[2] * (16 - mystique->dwgreg.beta))) >> 4; + src1[3] = ((src0[3] * mystique->dwgreg.beta) + (src1[3] * (16 - mystique->dwgreg.beta))) >> 4; + blit_iload_iload_high(mystique, data, 32); + break; - default: - fatal("blit_iload_iload_highv bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; + default: + fatal("blit_iload_iload_highv bltmod %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; } } - static void blit_iload_write(mystique_t *mystique, uint32_t data, int size) { switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { - case DWGCTRL_OPCODE_ILOAD: - blit_iload_iload(mystique, data, size); - break; + case DWGCTRL_OPCODE_ILOAD: + blit_iload_iload(mystique, data, size); + break; - case DWGCTRL_OPCODE_ILOAD_SCALE: - blit_iload_iload_scale(mystique, data, size); - break; + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_iload_scale(mystique, data, size); + break; - case DWGCTRL_OPCODE_ILOAD_HIGH: - blit_iload_iload_high(mystique, data, size); - break; + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_iload_high(mystique, data, size); + break; - case DWGCTRL_OPCODE_ILOAD_HIGHV: - blit_iload_iload_highv(mystique, data, size); - break; + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_iload_highv(mystique, data, size); + break; - default: - fatal("blit_iload_write: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); + default: + fatal("blit_iload_write: bad opcode %08x\n", mystique->dwgreg.dwgctrl_running); } } - static int -z_check(uint16_t z, uint16_t old_z, uint32_t z_mode)//mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) +z_check(uint16_t z, uint16_t old_z, uint32_t z_mode) // mystique->dwgreg.dwgctrl & DWGCTRL_ZMODE_MASK) { switch (z_mode) { - case DWGCTRL_ZMODE_ZE: - return (z == old_z); - case DWGCTRL_ZMODE_ZNE: - return (z != old_z); - case DWGCTRL_ZMODE_ZLT: - return (z < old_z); - case DWGCTRL_ZMODE_ZLTE: - return (z <= old_z); - case DWGCTRL_ZMODE_ZGT: - return (z > old_z); - case DWGCTRL_ZMODE_ZGTE: - return (z >= old_z); + case DWGCTRL_ZMODE_ZE: + return (z == old_z); + case DWGCTRL_ZMODE_ZNE: + return (z != old_z); + case DWGCTRL_ZMODE_ZLT: + return (z < old_z); + case DWGCTRL_ZMODE_ZLTE: + return (z <= old_z); + case DWGCTRL_ZMODE_ZGT: + return (z > old_z); + case DWGCTRL_ZMODE_ZGTE: + return (z >= old_z); - case DWGCTRL_ZMODE_NOZCMP: - default: - return 1; + case DWGCTRL_ZMODE_NOZCMP: + default: + return 1; } } - static void blit_line(mystique_t *mystique, int closed) { - svga_t *svga = &mystique->svga; + svga_t *svga = &mystique->svga; uint32_t src, dst, old_dst; - int x; - int z_write; + int x; + int z_write; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RSTR: - case DWGCTRL_ATYPE_RPL: - x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length > 0) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - src = mystique->dwgreg.fcol; - dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_RPL: + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = mystique->dwgreg.fcol; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - src = mystique->dwgreg.fcol; - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + src = mystique->dwgreg.fcol; + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - src = mystique->dwgreg.fcol; - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + src = mystique->dwgreg.fcol; + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - src = mystique->dwgreg.fcol; - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + src = mystique->dwgreg.fcol; + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("LINE RSTR/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } + default: + fatal("LINE RSTR/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } - if (mystique->dwgreg.sgn.sdydxl) - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - if ((int32_t)mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if (mystique->dwgreg.sgn.sdydxl) - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - else - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + if ((int32_t) mystique->dwgreg.ar[1] >= 0) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.length--; - } - break; + mystique->dwgreg.length--; + } + break; - case DWGCTRL_ATYPE_I: - case DWGCTRL_ATYPE_ZI: - z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); - x = mystique->dwgreg.xdst; - while (mystique->dwgreg.length > 0) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - uint16_t old_z = z_p[x]; + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + x = mystique->dwgreg.xdst; + while (mystique->dwgreg.length > 0) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + uint16_t old_z = z_p[x]; - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { - int r = 0, g = 0, b = 0; + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + int r = 0, g = 0, b = 0; - if (z_write) - z_p[x] = z; + if (z_write) + z_p[x] = z; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_16: - if (!(mystique->dwgreg.dr[4] & (1 << 23))) - r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; - if (!(mystique->dwgreg.dr[8] & (1 << 23))) - g = (mystique->dwgreg.dr[8] >> 17) & 0x3f; - if (!(mystique->dwgreg.dr[12] & (1 << 23))) - b = (mystique->dwgreg.dr[12] >> 18) & 0x1f; - dst = (r << 11) | (g << 5) | b; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 18) & 0x1f; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 17) & 0x3f; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 18) & 0x1f; + dst = (r << 11) | (g << 5) | b; - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - default: - fatal("LINE I/ZI PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } - } + default: + fatal("LINE I/ZI PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + } - if (mystique->dwgreg.sgn.sdydxl) - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + if (mystique->dwgreg.sgn.sdydxl) + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - if ((int32_t)mystique->dwgreg.ar[1] >= 0) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if ((int32_t) mystique->dwgreg.ar[1] >= 0) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if (mystique->dwgreg.sgn.sdydxl) - mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); - else - x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + if (mystique->dwgreg.sgn.sdydxl) + mystique->dwgreg.ydst_lin += (mystique->dwgreg.sgn.sdy ? -(mystique->dwgreg.pitch & PITCH_MASK) : (mystique->dwgreg.pitch & PITCH_MASK)); + else + x += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[15]; + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.length--; - } - break; + mystique->dwgreg.length--; + } + break; - default: - /* pclog("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ - break; + default: + /* pclog("Unknown atype %03x %08x LINE\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ + break; } mystique->blitter_complete_refcount++; } - static void blit_autoline(mystique_t *mystique, int closed) { - int start_x = (int32_t)mystique->dwgreg.ar[5]; - int start_y = (int32_t)mystique->dwgreg.ar[6]; - int end_x = (int32_t)mystique->dwgreg.ar[0]; - int end_y = (int32_t)mystique->dwgreg.ar[2]; - int dx = end_x - start_x; - int dy = end_y - start_y; + int start_x = (int32_t) mystique->dwgreg.ar[5]; + int start_y = (int32_t) mystique->dwgreg.ar[6]; + int end_x = (int32_t) mystique->dwgreg.ar[0]; + int end_y = (int32_t) mystique->dwgreg.ar[2]; + int dx = end_x - start_x; + int dy = end_y - start_y; if (ABS(dx) > ABS(dy)) { - mystique->dwgreg.sgn.sdydxl = 1; - mystique->dwgreg.ar[0] = 2*ABS(dy); - mystique->dwgreg.ar[1] = 2*ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2*ABS(dy) - 2*ABS(dx); - mystique->dwgreg.length = ABS(end_x - start_x); + mystique->dwgreg.sgn.sdydxl = 1; + mystique->dwgreg.ar[0] = 2 * ABS(dy); + mystique->dwgreg.ar[1] = 2 * ABS(dy) - ABS(dx) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2 * ABS(dy) - 2 * ABS(dx); + mystique->dwgreg.length = ABS(end_x - start_x); } else { - mystique->dwgreg.sgn.sdydxl = 0; - mystique->dwgreg.ar[0] = 2*ABS(dx); - mystique->dwgreg.ar[1] = 2*ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); - mystique->dwgreg.ar[2] = 2*ABS(dx) - 2*ABS(dy); - mystique->dwgreg.length = ABS(end_y - start_y); + mystique->dwgreg.sgn.sdydxl = 0; + mystique->dwgreg.ar[0] = 2 * ABS(dx); + mystique->dwgreg.ar[1] = 2 * ABS(dx) - ABS(dy) - ((start_y > end_y) ? 1 : 0); + mystique->dwgreg.ar[2] = 2 * ABS(dx) - 2 * ABS(dy); + mystique->dwgreg.length = ABS(end_y - start_y); } mystique->dwgreg.sgn.sdxl = (start_x > end_x) ? 1 : 0; - mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; + mystique->dwgreg.sgn.sdy = (start_y > end_y) ? 1 : 0; blit_line(mystique, closed); - mystique->dwgreg.ar[5] = end_x; - mystique->dwgreg.xdst = end_x; - mystique->dwgreg.ar[6] = end_y; - mystique->dwgreg.ydst = end_y; - mystique->dwgreg.ydst_lin = ((int32_t)(int16_t)mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; + mystique->dwgreg.ar[5] = end_x; + mystique->dwgreg.xdst = end_x; + mystique->dwgreg.ar[6] = end_y; + mystique->dwgreg.ydst = end_y; + mystique->dwgreg.ydst_lin = ((int32_t) (int16_t) mystique->dwgreg.ydst * (mystique->dwgreg.pitch & PITCH_MASK)) + mystique->dwgreg.ydstorg; } - static void blit_trap(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - uint32_t z_back, r_back, g_back, b_back; - int z_write; - int y; + svga_t *svga = &mystique->svga; + uint32_t z_back, r_back, g_back, b_back; + int z_write; + int y; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; mystique->trap_count++; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_BLK: - case DWGCTRL_ATYPE_RPL: - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + case DWGCTRL_ATYPE_BLK: + case DWGCTRL_ATYPE_RPL: + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - int xoff = (mystique->dwgreg.xoff + x_l) & 7; - int pattern = mystique->dwgreg.pattern[yoff][xoff]; - uint32_t dst; + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = - (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = - (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffff; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + case MACCESS_PWIDTH_16: + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = (pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffff; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; - *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = - ((pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff) | dst; - svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + case MACCESS_PWIDTH_24: + dst = *(uint32_t *) (&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; + *(uint32_t *) (&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = ((pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff) | dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = - pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + case MACCESS_PWIDTH_32: + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } - x_l++; - mystique->pixel_count++; - } + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + x_l++; + mystique->pixel_count++; + } - if ((int32_t)mystique->dwgreg.ar[1] < 0) { - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if ((int32_t) mystique->dwgreg.ar[1] < 0) { + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[4] < 0) { - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + if ((int32_t) mystique->dwgreg.ar[4] < 0) { + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; - case DWGCTRL_ATYPE_RSTR: - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; + case DWGCTRL_ATYPE_RSTR: + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int yoff = (mystique->dwgreg.yoff + mystique->dwgreg.ydst) & 7; - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - int xoff = (mystique->dwgreg.xoff + x_l) & 7; - int pattern = mystique->dwgreg.pattern[yoff][xoff]; - uint32_t src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - uint32_t dst, old_dst; + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + int xoff = (mystique->dwgreg.xoff + x_l) & 7; + int pattern = mystique->dwgreg.pattern[yoff][xoff]; + uint32_t src = pattern ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]; - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } - x_l++; - mystique->pixel_count++; - } + default: + fatal("TRAP RSTR PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + x_l++; + mystique->pixel_count++; + } - if ((int32_t)mystique->dwgreg.ar[1] < 0) { - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - } else - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + if ((int32_t) mystique->dwgreg.ar[1] < 0) { + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + } else + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - if ((int32_t)mystique->dwgreg.ar[4] < 0) { - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - } else - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + if ((int32_t) mystique->dwgreg.ar[4] < 0) { + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + } else + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; - case DWGCTRL_ATYPE_I: - case DWGCTRL_ATYPE_ZI: - z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int16_t old_x_l = x_l; - int dx; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; + int dx; - z_back = mystique->dwgreg.dr[0]; - r_back = mystique->dwgreg.dr[4]; - g_back = mystique->dwgreg.dr[8]; - b_back = mystique->dwgreg.dr[12]; + z_back = mystique->dwgreg.dr[0]; + r_back = mystique->dwgreg.dr[4]; + g_back = mystique->dwgreg.dr[8]; + b_back = mystique->dwgreg.dr[12]; - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { - uint32_t dst = 0, old_dst; - int r = 0, g = 0, b = 0; + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + uint32_t dst = 0, old_dst; + int r = 0, g = 0, b = 0; - if (!(mystique->dwgreg.dr[4] & (1 << 23))) - r = (mystique->dwgreg.dr[4] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[8] & (1 << 23))) - g = (mystique->dwgreg.dr[8] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[12] & (1 << 23))) - b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - if (z_write) - z_p[x_l] = z; + if (z_write) + z_p[x_l] = z; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + svga->vram[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - dst = dither(mystique, r, g, b, x_l & 1, mystique->dwgreg.selline & 1); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + case MACCESS_PWIDTH_16: + dst = dither(mystique, r, g, b, x_l & 1, mystique->dwgreg.selline & 1); + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - old_dst = *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; - *(uint32_t *)(&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = old_dst | dst; - svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) (&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) & 0xff000000; + *(uint32_t *) (&svga->vram[((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask]) = old_dst | dst; + svga->changedvram[(((mystique->dwgreg.ydst_lin + x_l) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = b | (g << 8) | (r << 16); - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + case MACCESS_PWIDTH_32: + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = b | (g << 8) | (r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } - } + default: + fatal("TRAP BLK/RPL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } + } - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - x_l++; - mystique->pixel_count++; - } + x_l++; + mystique->pixel_count++; + } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx*mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += dx*mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += dx*mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += dx*mystique->dwgreg.dr[14]; + dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; - default: - fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown atype %03x %08x TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } mystique->blitter_complete_refcount++; } - -static int texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) +static int +texture_read(mystique_t *mystique, int *tex_r, int *tex_g, int *tex_b, int *atransp) { svga_t *svga = &mystique->svga; - const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); - const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; - const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; - const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; - const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; - const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; - uint16_t src = 0; - int s, t; + const int tex_shift = 3 + ((mystique->dwgreg.texctl & TEXCTL_TPITCH_MASK) >> TEXCTL_TPITCH_SHIFT); + const unsigned int palsel = mystique->dwgreg.texctl & TEXCTL_PALSEL_MASK; + const uint16_t tckey = mystique->dwgreg.textrans & TEXTRANS_TCKEY_MASK; + const uint16_t tkmask = (mystique->dwgreg.textrans & TEXTRANS_TKMASK_MASK) >> TEXTRANS_TKMASK_SHIFT; + const unsigned int w_mask = (mystique->dwgreg.texwidth & TEXWIDTH_TWMASK_MASK) >> TEXWIDTH_TWMASK_SHIFT; + const unsigned int h_mask = (mystique->dwgreg.texheight & TEXHEIGHT_THMASK_MASK) >> TEXHEIGHT_THMASK_SHIFT; + uint16_t src = 0; + int s, t; if (mystique->dwgreg.texctl & TEXCTL_NPCEN) { - const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + const int s_shift = 20 - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = 20 - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - s = (int32_t)mystique->dwgreg.tmr[6] >> s_shift; - t = (int32_t)mystique->dwgreg.tmr[7] >> t_shift; + s = (int32_t) mystique->dwgreg.tmr[6] >> s_shift; + t = (int32_t) mystique->dwgreg.tmr[7] >> t_shift; } else { - const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); - const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); - int64_t q = mystique->dwgreg.tmr[8] ? ((0x100000000ll / (int64_t)(int32_t)mystique->dwgreg.tmr[8]) /*>> 16*/) : 0; + const int s_shift = (20 + 16) - (mystique->dwgreg.texwidth & TEXWIDTH_TW_MASK); + const int t_shift = (20 + 16) - (mystique->dwgreg.texheight & TEXHEIGHT_TH_MASK); + int64_t q = mystique->dwgreg.tmr[8] ? ((0x100000000ll / (int64_t) (int32_t) mystique->dwgreg.tmr[8]) /*>> 16*/) : 0; - s = (((int64_t)(int32_t)mystique->dwgreg.tmr[6] * q) /*<< 8*/) >> s_shift;/*((16+20)-12);*/ - t = (((int64_t)(int32_t)mystique->dwgreg.tmr[7] * q) /*<< 8*/) >> t_shift;/*((16+20)-9);*/ + s = (((int64_t) (int32_t) mystique->dwgreg.tmr[6] * q) /*<< 8*/) >> s_shift; /*((16+20)-12);*/ + t = (((int64_t) (int32_t) mystique->dwgreg.tmr[7] * q) /*<< 8*/) >> t_shift; /*((16+20)-9);*/ } if (mystique->dwgreg.texctl & TEXCTL_CLAMPU) { - if (s < 0) - s = 0; - else if (s > w_mask) - s = w_mask; + if (s < 0) + s = 0; + else if (s > w_mask) + s = w_mask; } else - s &= w_mask; + s &= w_mask; if (mystique->dwgreg.texctl & TEXCTL_CLAMPV) { - if (t < 0) - t = 0; - else if (t > h_mask) - t = h_mask; + if (t < 0) + t = 0; + else if (t > h_mask) + t = h_mask; } else - t &= h_mask; + t &= h_mask; switch (mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK) { - case TEXCTL_TEXFORMAT_TW4: - src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; - if (s & 1) - src >>= 4; - else - src &= 0xf; - *tex_r = mystique->lut[src | palsel].r; - *tex_g = mystique->lut[src | palsel].g; - *tex_b = mystique->lut[src | palsel].b; - *atransp = 0; - break; - case TEXCTL_TEXFORMAT_TW8: - src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; - *tex_r = mystique->lut[src].r; - *tex_g = mystique->lut[src].g; - *tex_b = mystique->lut[src].b; - *atransp = 0; - break; - case TEXCTL_TEXFORMAT_TW15: - src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; - *tex_r = ((src >> 10) & 0x1f) << 3; - *tex_g = ((src >> 5) & 0x1f) << 3; - *tex_b = (src & 0x1f) << 3; - if (((src >> 15) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key) - *atransp = 1; - else - *atransp = 0; - break; - case TEXCTL_TEXFORMAT_TW16: - src = ((uint16_t *)svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; - *tex_r = (src >> 11) << 3; - *tex_g = ((src >> 5) & 0x3f) << 2; - *tex_b = (src & 0x1f) << 3; - *atransp = 0; - break; - default: - fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); - break; + case TEXCTL_TEXFORMAT_TW4: + src = svga->vram[(mystique->dwgreg.texorg + (((t << tex_shift) + s) >> 1)) & mystique->vram_mask]; + if (s & 1) + src >>= 4; + else + src &= 0xf; + *tex_r = mystique->lut[src | palsel].r; + *tex_g = mystique->lut[src | palsel].g; + *tex_b = mystique->lut[src | palsel].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW8: + src = svga->vram[(mystique->dwgreg.texorg + (t << tex_shift) + s) & mystique->vram_mask]; + *tex_r = mystique->lut[src].r; + *tex_g = mystique->lut[src].g; + *tex_b = mystique->lut[src].b; + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW15: + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = ((src >> 10) & 0x1f) << 3; + *tex_g = ((src >> 5) & 0x1f) << 3; + *tex_b = (src & 0x1f) << 3; + if (((src >> 15) & mystique->dwgreg.ta_mask) == mystique->dwgreg.ta_key) + *atransp = 1; + else + *atransp = 0; + break; + case TEXCTL_TEXFORMAT_TW16: + src = ((uint16_t *) svga->vram)[((mystique->dwgreg.texorg >> 1) + (t << tex_shift) + s) & mystique->vram_mask_w]; + *tex_r = (src >> 11) << 3; + *tex_g = ((src >> 5) & 0x3f) << 2; + *tex_b = (src & 0x1f) << 3; + *atransp = 0; + break; + default: + fatal("Unknown texture format %i\n", mystique->dwgreg.texctl & TEXCTL_TEXFORMAT_MASK); + break; } return ((src & tkmask) == tckey); } - static void blit_texture_trap(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - int y; - int z_write; + svga_t *svga = &mystique->svga; + int y; + int z_write; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; - const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); + const int dest32 = ((mystique->maccess_running & MACCESS_PWIDTH_MASK) == MACCESS_PWIDTH_32); mystique->trap_count++; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_I: - case DWGCTRL_ATYPE_ZI: - z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); + case DWGCTRL_ATYPE_I: + case DWGCTRL_ATYPE_ZI: + z_write = ((mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) == DWGCTRL_ATYPE_ZI); - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint16_t *z_p = (uint16_t *)&svga->vram[(mystique->dwgreg.ydst_lin*2 + mystique->dwgreg.zorg) & mystique->vram_mask]; - int16_t x_l = mystique->dwgreg.fxleft & 0xffff; - int16_t x_r = mystique->dwgreg.fxright & 0xffff; - int16_t old_x_l = x_l; - int dx; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint16_t *z_p = (uint16_t *) &svga->vram[(mystique->dwgreg.ydst_lin * 2 + mystique->dwgreg.zorg) & mystique->vram_mask]; + int16_t x_l = mystique->dwgreg.fxleft & 0xffff; + int16_t x_r = mystique->dwgreg.fxright & 0xffff; + int16_t old_x_l = x_l; + int dx; - uint32_t z_back = mystique->dwgreg.dr[0]; - uint32_t r_back = mystique->dwgreg.dr[4]; - uint32_t g_back = mystique->dwgreg.dr[8]; - uint32_t b_back = mystique->dwgreg.dr[12]; - uint32_t s_back = mystique->dwgreg.tmr[6]; - uint32_t t_back = mystique->dwgreg.tmr[7]; - uint32_t q_back = mystique->dwgreg.tmr[8]; + uint32_t z_back = mystique->dwgreg.dr[0]; + uint32_t r_back = mystique->dwgreg.dr[4]; + uint32_t g_back = mystique->dwgreg.dr[8]; + uint32_t b_back = mystique->dwgreg.dr[12]; + uint32_t s_back = mystique->dwgreg.tmr[6]; + uint32_t t_back = mystique->dwgreg.tmr[7]; + uint32_t q_back = mystique->dwgreg.tmr[8]; - while (x_l != x_r) { - if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x_l & 3]) { - uint16_t z = ((int32_t)mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); - uint16_t old_z = z_p[x_l]; + while (x_l != x_r) { + if (x_l >= mystique->dwgreg.cxleft && x_l <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x_l & 3]) { + uint16_t z = ((int32_t) mystique->dwgreg.dr[0] < 0) ? 0 : (mystique->dwgreg.dr[0] >> 15); + uint16_t old_z = z_p[x_l]; - if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { - int tex_r = 0, tex_g = 0, tex_b = 0; - int ctransp, atransp = 0; - int i_r = 0, i_g = 0, i_b = 0; + if (z_check(z, old_z, mystique->dwgreg.dwgctrl_running & DWGCTRL_ZMODE_MASK)) { + int tex_r = 0, tex_g = 0, tex_b = 0; + int ctransp, atransp = 0; + int i_r = 0, i_g = 0, i_b = 0; - if (!(mystique->dwgreg.dr[4] & (1 << 23))) - i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[8] & (1 << 23))) - i_g = (mystique->dwgreg.dr[8] >> 15) & 0xff; - if (!(mystique->dwgreg.dr[12] & (1 << 23))) - i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[4] & (1 << 23))) + i_r = (mystique->dwgreg.dr[4] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[8] & (1 << 23))) + i_g = (mystique->dwgreg.dr[8] >> 15) & 0xff; + if (!(mystique->dwgreg.dr[12] & (1 << 23))) + i_b = (mystique->dwgreg.dr[12] >> 15) & 0xff; - ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); + ctransp = texture_read(mystique, &tex_r, &tex_g, &tex_b, &atransp); - switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { - case 0: - if (ctransp) - goto skip_pixel; - if (atransp) { - tex_r = i_r; - tex_g = i_g; - tex_b = i_b; - } - break; + switch (mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)) { + case 0: + if (ctransp) + goto skip_pixel; + if (atransp) { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; - case TEXCTL_DECALCKEY: - if (ctransp) { - tex_r = i_r; - tex_g = i_g; - tex_b = i_b; - } - break; + case TEXCTL_DECALCKEY: + if (ctransp) { + tex_r = i_r; + tex_g = i_g; + tex_b = i_b; + } + break; - case (TEXCTL_STRANS | TEXCTL_DECALCKEY): - if (ctransp) - goto skip_pixel; - break; + case (TEXCTL_STRANS | TEXCTL_DECALCKEY): + if (ctransp) + goto skip_pixel; + break; - case TEXCTL_TMODULATE: - if (ctransp) - goto skip_pixel; - if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { - tex_r = (tex_r * i_r) >> 8; - tex_g = (tex_g * i_g) >> 8; - tex_b = (tex_b * i_b) >> 8; - } - break; + case TEXCTL_TMODULATE: + if (ctransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; - case (TEXCTL_TMODULATE | TEXCTL_STRANS): - if (ctransp || atransp) - goto skip_pixel; - if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { - tex_r = (tex_r * i_r) >> 8; - tex_g = (tex_g * i_g) >> 8; - tex_b = (tex_b * i_b) >> 8; - } - break; + case (TEXCTL_TMODULATE | TEXCTL_STRANS): + if (ctransp || atransp) + goto skip_pixel; + if (mystique->dwgreg.texctl & TEXCTL_TMODULATE) { + tex_r = (tex_r * i_r) >> 8; + tex_g = (tex_g * i_g) >> 8; + tex_b = (tex_b * i_b) >> 8; + } + break; - default: - fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); - } + default: + fatal("Bad TEXCTL %08x %08x\n", mystique->dwgreg.texctl, mystique->dwgreg.texctl & (TEXCTL_TMODULATE | TEXCTL_STRANS | TEXCTL_ITRANS | TEXCTL_DECALCKEY)); + } - if (dest32) { - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; - } else { - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1); - svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; - } - if (z_write) - z_p[x_l] = z; - } - } + if (dest32) { + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l] = tex_b | (tex_g << 8) | (tex_r << 16); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_l) >> 10] = changeframecount; + } else { + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w] = dither(mystique, tex_r, tex_g, tex_b, x_l & 1, mystique->dwgreg.selline & 1); + svga->changedvram[((mystique->dwgreg.ydst_lin + x_l) & mystique->vram_mask_w) >> 11] = changeframecount; + } + if (z_write) + z_p[x_l] = z; + } + } skip_pixel: - x_l++; - mystique->pixel_count++; + x_l++; + mystique->pixel_count++; - mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; - mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; - mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; - mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; - } + mystique->dwgreg.dr[0] += mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += mystique->dwgreg.tmr[4]; + } - mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; - mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; - mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; - mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; - mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; - mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; - mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; + mystique->dwgreg.dr[0] = z_back + mystique->dwgreg.dr[3]; + mystique->dwgreg.dr[4] = r_back + mystique->dwgreg.dr[7]; + mystique->dwgreg.dr[8] = g_back + mystique->dwgreg.dr[11]; + mystique->dwgreg.dr[12] = b_back + mystique->dwgreg.dr[15]; + mystique->dwgreg.tmr[6] = s_back + mystique->dwgreg.tmr[1]; + mystique->dwgreg.tmr[7] = t_back + mystique->dwgreg.tmr[3]; + mystique->dwgreg.tmr[8] = q_back + mystique->dwgreg.tmr[5]; - while ((int32_t)mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; - mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); - } - mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; + while ((int32_t) mystique->dwgreg.ar[1] < 0 && mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[0]; + mystique->dwgreg.fxleft += (mystique->dwgreg.sgn.sdxl ? -1 : 1); + } + mystique->dwgreg.ar[1] += mystique->dwgreg.ar[2]; - while ((int32_t)mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; - mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); - } - mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; + while ((int32_t) mystique->dwgreg.ar[4] < 0 && mystique->dwgreg.ar[6]) { + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[6]; + mystique->dwgreg.fxright += (mystique->dwgreg.sgn.sdxr ? -1 : 1); + } + mystique->dwgreg.ar[4] += mystique->dwgreg.ar[5]; - dx = (int16_t)((mystique->dwgreg.fxleft - old_x_l) & 0xffff); - mystique->dwgreg.dr[0] += dx*mystique->dwgreg.dr[2]; - mystique->dwgreg.dr[4] += dx*mystique->dwgreg.dr[6]; - mystique->dwgreg.dr[8] += dx*mystique->dwgreg.dr[10]; - mystique->dwgreg.dr[12] += dx*mystique->dwgreg.dr[14]; - mystique->dwgreg.tmr[6] += dx*mystique->dwgreg.tmr[0]; - mystique->dwgreg.tmr[7] += dx*mystique->dwgreg.tmr[2]; - mystique->dwgreg.tmr[8] += dx*mystique->dwgreg.tmr[4]; + dx = (int16_t) ((mystique->dwgreg.fxleft - old_x_l) & 0xffff); + mystique->dwgreg.dr[0] += dx * mystique->dwgreg.dr[2]; + mystique->dwgreg.dr[4] += dx * mystique->dwgreg.dr[6]; + mystique->dwgreg.dr[8] += dx * mystique->dwgreg.dr[10]; + mystique->dwgreg.dr[12] += dx * mystique->dwgreg.dr[14]; + mystique->dwgreg.tmr[6] += dx * mystique->dwgreg.tmr[0]; + mystique->dwgreg.tmr[7] += dx * mystique->dwgreg.tmr[2]; + mystique->dwgreg.tmr[8] += dx * mystique->dwgreg.tmr[4]; - mystique->dwgreg.ydst++; - mystique->dwgreg.ydst &= 0x7fffff; - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.ydst++; + mystique->dwgreg.ydst &= 0x7fffff; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; - } - break; + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + } + break; - default: - fatal("Unknown atype %03x %08x TEXTURE_TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown atype %03x %08x TEXTURE_TRAP\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } mystique->blitter_complete_refcount++; } - static void blit_bitblt(mystique_t *mystique) { - svga_t *svga = &mystique->svga; - uint32_t src_addr; - int y; - int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; - int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; - int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; + svga_t *svga = &mystique->svga; + uint32_t src_addr; + int y; + int x_dir = mystique->dwgreg.sgn.scanleft ? -1 : 1; + int16_t x_start = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxright : mystique->dwgreg.fxleft; + int16_t x_end = mystique->dwgreg.sgn.scanleft ? mystique->dwgreg.fxleft : mystique->dwgreg.fxright; const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_BLK: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BMONOLEF: - src_addr = mystique->dwgreg.ar[3]; + case DWGCTRL_ATYPE_BLK: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BMONOLEF: + src_addr = mystique->dwgreg.ar[3]; - for (y = 0; y < mystique->dwgreg.length; y++) { - int16_t x = x_start; + for (y = 0; y < mystique->dwgreg.length; y++) { + int16_t x = x_start; - while (1) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { - uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; - uint32_t old_dst; + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot) { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; + uint32_t old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = mystique->dwgreg.fcol; - } else - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = - (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = mystique->dwgreg.fcol; + } else + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = mystique->dwgreg.fcol; - } else - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = - (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + case MACCESS_PWIDTH_16: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = mystique->dwgreg.fcol; + } else + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = - (old_dst & 0xff000000) | (mystique->dwgreg.fcol & 0xffffff); - } else - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = - (old_dst & 0xff000000) | (((svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (old_dst & 0xff000000) | (mystique->dwgreg.fcol & 0xffffff); + } else + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (old_dst & 0xff000000) | (((svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol) & 0xffffff); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { - if (svga->vram[byte_addr] & (1 << bit_offset)) - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = mystique->dwgreg.fcol; - } else - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = - (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 11] = changeframecount; - break; + case MACCESS_PWIDTH_32: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC) { + if (svga->vram[byte_addr] & (1 << bit_offset)) + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = mystique->dwgreg.fcol; + } else + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 11] = changeframecount; + break; - default: - fatal("BITBLT DWGCTRL_ATYPE_BLK unknown MACCESS %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); - } - } + default: + fatal("BITBLT DWGCTRL_ATYPE_BLK unknown MACCESS %i\n", mystique->maccess_running & MACCESS_PWIDTH_MASK); + } + } - if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; - if (x != x_end) - x += x_dir; - else - break; - } + if (x != x_end) + x += x_dir; + else + break; + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; - default: - fatal("BITBLT BLK %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); - break; - } - break; + default: + fatal("BITBLT BLK %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); + break; + } + break; - case DWGCTRL_ATYPE_RPL: - if (mystique->maccess_running & MACCESS_TLUTLOAD) { - src_addr = mystique->dwgreg.ar[3]; + case DWGCTRL_ATYPE_RPL: + if (mystique->maccess_running & MACCESS_TLUTLOAD) { + src_addr = mystique->dwgreg.ar[3]; - y = mystique->dwgreg.ydst; + y = mystique->dwgreg.ydst; - while (mystique->dwgreg.length) { - uint16_t src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; + while (mystique->dwgreg.length) { + uint16_t src = ((uint16_t *) svga->vram)[src_addr & mystique->vram_mask_w]; - mystique->lut[y & 0xff].r = (src >> 11) << 3; - mystique->lut[y & 0xff].g = ((src >> 5) & 0x3f) << 2; - mystique->lut[y & 0xff].b = (src & 0x1f) << 3; - src_addr++; - y++; - mystique->dwgreg.length--; - } - break; - } - case DWGCTRL_ATYPE_RSTR: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BMONOLEF: - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) - fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); + mystique->lut[y & 0xff].r = (src >> 11) << 3; + mystique->lut[y & 0xff].g = ((src >> 5) & 0x3f) << 2; + mystique->lut[y & 0xff].b = (src & 0x1f) << 3; + src_addr++; + y++; + mystique->dwgreg.length--; + } + break; + } + case DWGCTRL_ATYPE_RSTR: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BMONOLEF: + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + fatal("BITBLT RPL/RSTR BMONOLEF with pattern\n"); - src_addr = mystique->dwgreg.ar[3]; + src_addr = mystique->dwgreg.ar[3]; - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - int16_t x = x_start; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + int16_t x = x_start; - while (1) { - uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; - int bit_offset = src_addr & 7; + while (1) { + uint32_t byte_addr = (src_addr >> 3) & mystique->vram_mask; + int bit_offset = src_addr & 7; - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && - trans[x & 3]) { - uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; - uint32_t dst, old_dst; + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && ((svga->vram[byte_addr] & (1 << bit_offset)) || !(mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANSC)) && trans[x & 3]) { + uint32_t src = (svga->vram[byte_addr] & (1 << bit_offset)) ? mystique->dwgreg.fcol : mystique->dwgreg.bcol; + uint32_t dst, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running);// & DWGCTRL_BOP_MASK + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); // & DWGCTRL_BOP_MASK - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("BITBLT RPL BMONOLEF PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } + default: + fatal("BITBLT RPL BMONOLEF PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } - if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; + if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; - if (x != x_end) - x += x_dir; - else - break; - } + if (x != x_end) + x += x_dir; + else + break; + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; - case DWGCTRL_BLTMOD_BFCOL: - case DWGCTRL_BLTMOD_BU32RGB: - src_addr = mystique->dwgreg.ar[3]; + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BU32RGB: + src_addr = mystique->dwgreg.ar[3]; - for (y = 0; y < mystique->dwgreg.length; y++) { - uint8_t const * const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; - uint32_t old_src_addr = src_addr; - int16_t x = x_start; + for (y = 0; y < mystique->dwgreg.length; y++) { + uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; + uint32_t old_src_addr = src_addr; + int16_t x = x_start; - while (1) { - if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && - mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && - trans[x & 3]) { - uint32_t src, dst, old_dst; + while (1) { + if (x >= mystique->dwgreg.cxleft && x <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && trans[x & 3]) { + uint32_t src, dst, old_dst; - switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { - case MACCESS_PWIDTH_8: - src = svga->vram[src_addr & mystique->vram_mask]; - dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_8: + src = svga->vram[src_addr & mystique->vram_mask]; + dst = svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; - break; + svga->vram[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_16: - src = ((uint16_t *)svga->vram)[src_addr & mystique->vram_mask_w]; - dst = ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; + case MACCESS_PWIDTH_16: + src = ((uint16_t *) svga->vram)[src_addr & mystique->vram_mask_w]; + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint16_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; - break; + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_w) >> 11] = changeframecount; + break; - case MACCESS_PWIDTH_24: - src = *(uint32_t *)&svga->vram[(src_addr * 3) & mystique->vram_mask]; - old_dst = *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; + case MACCESS_PWIDTH_24: + src = *(uint32_t *) &svga->vram[(src_addr * 3) & mystique->vram_mask]; + old_dst = *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask]; - dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, old_dst, mystique->dwgreg.dwgctrl_running); - *(uint32_t *)&svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); - svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; - break; + *(uint32_t *) &svga->vram[((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask] = (dst & 0xffffff) | (old_dst & 0xff000000); + svga->changedvram[(((mystique->dwgreg.ydst_lin + x) * 3) & mystique->vram_mask) >> 12] = changeframecount; + break; - case MACCESS_PWIDTH_32: - src = ((uint32_t *)svga->vram)[src_addr & mystique->vram_mask_l]; - dst = ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; + case MACCESS_PWIDTH_32: + src = ((uint32_t *) svga->vram)[src_addr & mystique->vram_mask_l]; + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l]; - dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); + dst = bitop(src, dst, mystique->dwgreg.dwgctrl_running); - ((uint32_t *)svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; - svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; - break; + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + x) & mystique->vram_mask_l) >> 10] = changeframecount; + break; - default: - fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); - } - } + default: + fatal("BITBLT RPL BFCOL PWIDTH %x %08x\n", mystique->maccess_running & MACCESS_PWIDTH_MASK, mystique->dwgreg.dwgctrl_running); + } + } - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) - src_addr = ((src_addr + x_dir) & 7) | (src_addr & ~7); - else if (src_addr == mystique->dwgreg.ar[0]) { - mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; - mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; - src_addr = mystique->dwgreg.ar[3]; - } else - src_addr += x_dir; + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) + src_addr = ((src_addr + x_dir) & 7) | (src_addr & ~7); + else if (src_addr == mystique->dwgreg.ar[0]) { + mystique->dwgreg.ar[0] += mystique->dwgreg.ar[5]; + mystique->dwgreg.ar[3] += mystique->dwgreg.ar[5]; + src_addr = mystique->dwgreg.ar[3]; + } else + src_addr += x_dir; - if (x != x_end) - x += x_dir; - else - break; - } + if (x != x_end) + x += x_dir; + else + break; + } - if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) { - src_addr = old_src_addr; - if (mystique->dwgreg.sgn.sdy) - src_addr = ((src_addr - 32) & 0xe0) | (src_addr & ~0xe0); - else - src_addr = ((src_addr + 32) & 0xe0) | (src_addr & ~0xe0); - } + if (mystique->dwgreg.dwgctrl_running & DWGCTRL_PATTERN) { + src_addr = old_src_addr; + if (mystique->dwgreg.sgn.sdy) + src_addr = ((src_addr - 32) & 0xe0) | (src_addr & ~0xe0); + else + src_addr = ((src_addr + 32) & 0xe0) | (src_addr & ~0xe0); + } - if (mystique->dwgreg.sgn.sdy) - mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); - else - mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); - } - break; + if (mystique->dwgreg.sgn.sdy) + mystique->dwgreg.ydst_lin -= (mystique->dwgreg.pitch & PITCH_MASK); + else + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + } + break; - default: - fatal("BITBLT DWGCTRL_ATYPE_RPL unknown BLTMOD %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - } - break; + default: + fatal("BITBLT DWGCTRL_ATYPE_RPL unknown BLTMOD %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + } + break; - default: - /* pclog("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ - break; + default: + /* pclog("Unknown BITBLT atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); */ + break; } mystique->blitter_complete_refcount++; } - static void blit_iload(mystique_t *mystique) { switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - case DWGCTRL_ATYPE_RSTR: - case DWGCTRL_ATYPE_BLK: - /* pclog("ILOAD BLTMOD DWGCTRL = %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); */ - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BFCOL: - case DWGCTRL_BLTMOD_BMONOLEF: - case DWGCTRL_BLTMOD_BMONOWF: - case DWGCTRL_BLTMOD_BU24RGB: - case DWGCTRL_BLTMOD_BU32RGB: - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - /* pclog("ILOAD busy\n"); */ - mystique->dwgreg.words = 0; - break; + case DWGCTRL_ATYPE_RPL: + case DWGCTRL_ATYPE_RSTR: + case DWGCTRL_ATYPE_BLK: + /* pclog("ILOAD BLTMOD DWGCTRL = %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK); */ + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BFCOL: + case DWGCTRL_BLTMOD_BMONOLEF: + case DWGCTRL_BLTMOD_BMONOWF: + case DWGCTRL_BLTMOD_BU24RGB: + case DWGCTRL_BLTMOD_BU32RGB: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + /* pclog("ILOAD busy\n"); */ + mystique->dwgreg.words = 0; + break; - default: - fatal("ILOAD DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; - } - break; + default: + fatal("ILOAD DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; - default: - fatal("Unknown ILOAD atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } } - static void blit_idump(mystique_t *mystique) { switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; - mystique->dwgreg.words = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.idump_end_of_line = 0; - mystique->busy = 1; - /* pclog("IDUMP ATYPE RPL busy\n"); */ - break; + case DWGCTRL_ATYPE_RPL: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.src_addr = mystique->dwgreg.ar[3]; + mystique->dwgreg.words = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.idump_end_of_line = 0; + mystique->busy = 1; + /* pclog("IDUMP ATYPE RPL busy\n"); */ + break; - default: - fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown IDUMP atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } } - static void blit_iload_scale(mystique_t *mystique) { switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - mystique->dwgreg.words = 0; - /* pclog("ILOAD SCALE ATYPE RPL BLTMOD BUYUV busy\n"); */ - break; + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + /* pclog("ILOAD SCALE ATYPE RPL BLTMOD BUYUV busy\n"); */ + break; - default: - fatal("ILOAD_SCALE DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; - } - break; + default: + fatal("ILOAD_SCALE DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; - default: - fatal("Unknown ILOAD_SCALE atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD_SCALE atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } } - static void blit_iload_high(mystique_t *mystique) { switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: - case DWGCTRL_BLTMOD_BU32BGR: - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - mystique->dwgreg.words = 0; - /* pclog("ILOAD HIGH ATYPE RPL BLTMOD BUYUV busy\n"); */ - break; + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + case DWGCTRL_BLTMOD_BU32BGR: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + /* pclog("ILOAD HIGH ATYPE RPL BLTMOD BUYUV busy\n"); */ + break; - default: - fatal("ILOAD_HIGH DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; - } - break; + default: + fatal("ILOAD_HIGH DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; - default: - fatal("Unknown ILOAD_HIGH atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD_HIGH atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } } - -static -void blit_iload_highv(mystique_t *mystique) +static void +blit_iload_highv(mystique_t *mystique) { switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK) { - case DWGCTRL_ATYPE_RPL: - switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { - case DWGCTRL_BLTMOD_BUYUV: - mystique->dwgreg.length_cur = mystique->dwgreg.length; - mystique->dwgreg.xdst = mystique->dwgreg.fxleft; - mystique->dwgreg.iload_rem_data = 0; - mystique->dwgreg.iload_rem_count = 0; - mystique->busy = 1; - mystique->dwgreg.words = 0; - mystique->dwgreg.highv_line = 0; - mystique->dwgreg.lastpix_r = 0; - mystique->dwgreg.lastpix_g = 0; - mystique->dwgreg.lastpix_b = 0; - /* pclog("ILOAD HIGHV ATYPE RPL BLTMOD BUYUV busy\n"); */ - break; + case DWGCTRL_ATYPE_RPL: + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + mystique->dwgreg.length_cur = mystique->dwgreg.length; + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.iload_rem_data = 0; + mystique->dwgreg.iload_rem_count = 0; + mystique->busy = 1; + mystique->dwgreg.words = 0; + mystique->dwgreg.highv_line = 0; + mystique->dwgreg.lastpix_r = 0; + mystique->dwgreg.lastpix_g = 0; + mystique->dwgreg.lastpix_b = 0; + /* pclog("ILOAD HIGHV ATYPE RPL BLTMOD BUYUV busy\n"); */ + break; - default: - fatal("ILOAD_HIGHV DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); - break; - } - break; + default: + fatal("ILOAD_HIGHV DWGCTRL_ATYPE_RPL %08x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK, mystique->dwgreg.dwgctrl_running); + break; + } + break; - default: - fatal("Unknown ILOAD_HIGHV atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); + default: + fatal("Unknown ILOAD_HIGHV atype %03x %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_ATYPE_MASK, mystique->dwgreg.dwgctrl_running); } } - static void mystique_start_blit(mystique_t *mystique) { @@ -4867,177 +5000,253 @@ mystique_start_blit(mystique_t *mystique) uint64_t end_time; mystique->dwgreg.dwgctrl_running = mystique->dwgreg.dwgctrl; - mystique->maccess_running = mystique->maccess; + mystique->maccess_running = mystique->maccess; switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK) { - case DWGCTRL_OPCODE_LINE_OPEN: - blit_line(mystique, 0); - break; + case DWGCTRL_OPCODE_LINE_OPEN: + blit_line(mystique, 0); + break; - case DWGCTRL_OPCODE_AUTOLINE_OPEN: - blit_autoline(mystique, 0); - break; + case DWGCTRL_OPCODE_AUTOLINE_OPEN: + blit_autoline(mystique, 0); + break; - case DWGCTRL_OPCODE_LINE_CLOSE: - blit_line(mystique, 1); - break; + case DWGCTRL_OPCODE_LINE_CLOSE: + blit_line(mystique, 1); + break; - case DWGCTRL_OPCODE_AUTOLINE_CLOSE: - blit_autoline(mystique, 1); - break; + case DWGCTRL_OPCODE_AUTOLINE_CLOSE: + blit_autoline(mystique, 1); + break; - case DWGCTRL_OPCODE_TRAP: - blit_trap(mystique); - break; + case DWGCTRL_OPCODE_TRAP: + blit_trap(mystique); + break; - case DWGCTRL_OPCODE_TEXTURE_TRAP: - blit_texture_trap(mystique); - break; + case DWGCTRL_OPCODE_TEXTURE_TRAP: + blit_texture_trap(mystique); + break; - case DWGCTRL_OPCODE_ILOAD_HIGH: - blit_iload_high(mystique); - break; + case DWGCTRL_OPCODE_ILOAD_HIGH: + blit_iload_high(mystique); + break; - case DWGCTRL_OPCODE_BITBLT: - blit_bitblt(mystique); - break; + case DWGCTRL_OPCODE_BITBLT: + blit_bitblt(mystique); + break; - case DWGCTRL_OPCODE_FBITBLT: - blit_fbitblt(mystique); - break; + case DWGCTRL_OPCODE_FBITBLT: + blit_fbitblt(mystique); + break; - case DWGCTRL_OPCODE_ILOAD: - blit_iload(mystique); - break; + case DWGCTRL_OPCODE_ILOAD: + blit_iload(mystique); + break; - case DWGCTRL_OPCODE_IDUMP: - blit_idump(mystique); - break; + case DWGCTRL_OPCODE_IDUMP: + blit_idump(mystique); + break; - case DWGCTRL_OPCODE_ILOAD_SCALE: - blit_iload_scale(mystique); - break; + case DWGCTRL_OPCODE_ILOAD_SCALE: + blit_iload_scale(mystique); + break; - case DWGCTRL_OPCODE_ILOAD_HIGHV: - blit_iload_highv(mystique); - break; + case DWGCTRL_OPCODE_ILOAD_HIGHV: + blit_iload_highv(mystique); + break; - case DWGCTRL_OPCODE_ILOAD_FILTER: - /* TODO: Actually implement this. */ - break; + case DWGCTRL_OPCODE_ILOAD_FILTER: + /* TODO: Actually implement this. */ + break; - default: - fatal("mystique_start_blit: unknown blit %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK); - break; + default: + fatal("mystique_start_blit: unknown blit %08x\n", mystique->dwgreg.dwgctrl_running & DWGCTRL_OPCODE_MASK); + break; } end_time = plat_timer_read(); mystique->blitter_time += end_time - start_time; } - static void mystique_hwcursor_draw(svga_t *svga, int displine) { - mystique_t *mystique = (mystique_t *)svga->p; - int x; - uint64_t dat[2]; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + mystique_t *mystique = (mystique_t *) svga->p; + int x; + uint64_t dat[2]; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + svga->hwcursor_latch.addr += 16; - dat[0] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr]); - dat[1] = *(uint64_t *)(&svga->vram[svga->hwcursor_latch.addr + 8]); + dat[0] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr]); + dat[1] = *(uint64_t *) (&svga->vram[svga->hwcursor_latch.addr + 8]); svga->hwcursor_latch.addr += 16; switch (mystique->xcurctrl & XCURCTRL_CURMODE_MASK) { - case XCURCTRL_CURMODE_XGA: - for (x = 0; x < 64; x ++) { - if (!(dat[1] & (1ull << 63))) - buffer32->line[displine][offset + svga->x_add] = (dat[0] & (1ull << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; - else if (dat[0] & (1ull << 63)) - buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; + case XCURCTRL_CURMODE_XGA: + for (x = 0; x < 64; x++) { + if (!(dat[1] & (1ull << 63))) + buffer32->line[displine][offset + svga->x_add] = (dat[0] & (1ull << 63)) ? mystique->cursor.col[1] : mystique->cursor.col[0]; + else if (dat[0] & (1ull << 63)) + buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - break; + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + break; } if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + svga->hwcursor_latch.addr += 16; } - -static -uint8_t mystique_pci_read(int func, int addr, void *p) +static uint8_t +mystique_pci_read(int func, int addr, void *p) { - mystique_t *mystique = (mystique_t *)p; - uint8_t ret = 0x00; + mystique_t *mystique = (mystique_t *) p; + uint8_t ret = 0x00; if ((addr >= 0x30) && (addr <= 0x33) && !(mystique->pci_regs[0x43] & 0x40)) - ret = 0x00; - else switch (addr) { - case 0x00: ret = 0x2b; break; /*Matrox*/ - case 0x01: ret = 0x10; break; + ret = 0x00; + else + switch (addr) { + case 0x00: + ret = 0x2b; + break; /*Matrox*/ + case 0x01: + ret = 0x10; + break; - case 0x02: ret = (mystique->type == MGA_2064W) ? 0x19 : 0x1a; break; /*MGA*/ - case 0x03: ret = 0x05; break; + case 0x02: + ret = (mystique->type == MGA_2064W) ? 0x19 : 0x1a; + break; /*MGA*/ + case 0x03: + ret = 0x05; + break; - case PCI_REG_COMMAND: - ret = mystique->pci_regs[PCI_REG_COMMAND] | 0x80; break; /*Respond to IO and memory accesses*/ - case 0x05: - ret = 0x00; break; + case PCI_REG_COMMAND: + ret = mystique->pci_regs[PCI_REG_COMMAND] | 0x80; + break; /*Respond to IO and memory accesses*/ + case 0x05: + ret = 0x00; + break; - case 0x06: ret = 0x80; break; - case 0x07: ret = mystique->pci_regs[0x07]; break; /*Fast DEVSEL timing*/ + case 0x06: + ret = 0x80; + break; + case 0x07: + ret = mystique->pci_regs[0x07]; + break; /*Fast DEVSEL timing*/ - case 0x08: ret = 0; break; /*Revision ID*/ - case 0x09: ret = 0; break; /*Programming interface*/ + case 0x08: + ret = 0; + break; /*Revision ID*/ + case 0x09: + ret = 0; + break; /*Programming interface*/ - case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ - case 0x0b: ret = 0x03; break; + case 0x0a: + ret = 0x00; + break; /*Supports VGA interface*/ + case 0x0b: + ret = 0x03; + break; - case 0x10: ret = 0x00; break; /*Control aperture*/ - case 0x11: ret = (mystique->ctrl_base >> 8) & 0xc0; break; - case 0x12: ret = mystique->ctrl_base >> 16; break; - case 0x13: ret = mystique->ctrl_base >> 24; break; + case 0x10: + ret = 0x00; + break; /*Control aperture*/ + case 0x11: + ret = (mystique->ctrl_base >> 8) & 0xc0; + break; + case 0x12: + ret = mystique->ctrl_base >> 16; + break; + case 0x13: + ret = mystique->ctrl_base >> 24; + break; - case 0x14: ret = 0x00; break; /*Linear frame buffer*/ - case 0x16: ret = (mystique->lfb_base >> 16) & 0x80; break; - case 0x17: ret = mystique->lfb_base >> 24; break; + case 0x14: + ret = 0x00; + break; /*Linear frame buffer*/ + case 0x16: + ret = (mystique->lfb_base >> 16) & 0x80; + break; + case 0x17: + ret = mystique->lfb_base >> 24; + break; - case 0x18: ret = 0x00; break; /*Pseudo-DMA (ILOAD)*/ - case 0x1a: ret = (mystique->iload_base >> 16) & 0x80; break; - case 0x1b: ret = mystique->iload_base >> 24; break; + case 0x18: + ret = 0x00; + break; /*Pseudo-DMA (ILOAD)*/ + case 0x1a: + ret = (mystique->iload_base >> 16) & 0x80; + break; + case 0x1b: + ret = mystique->iload_base >> 24; + break; - case 0x2c: ret = mystique->pci_regs[0x2c]; break; - case 0x2d: ret = mystique->pci_regs[0x2d]; break; - case 0x2e: ret = mystique->pci_regs[0x2e]; break; - case 0x2f: ret = mystique->pci_regs[0x2f]; break; + case 0x2c: + ret = mystique->pci_regs[0x2c]; + break; + case 0x2d: + ret = mystique->pci_regs[0x2d]; + break; + case 0x2e: + ret = mystique->pci_regs[0x2e]; + break; + case 0x2f: + ret = mystique->pci_regs[0x2f]; + break; - case 0x30: ret = mystique->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ - case 0x31: ret = 0x00; break; - case 0x32: ret = mystique->pci_regs[0x32]; break; - case 0x33: ret = mystique->pci_regs[0x33]; break; + case 0x30: + ret = mystique->pci_regs[0x30] & 0x01; + break; /*BIOS ROM address*/ + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = mystique->pci_regs[0x32]; + break; + case 0x33: + ret = mystique->pci_regs[0x33]; + break; - case 0x3c: ret = mystique->int_line; break; - case 0x3d: ret = PCI_INTA; break; + case 0x3c: + ret = mystique->int_line; + break; + case 0x3d: + ret = PCI_INTA; + break; - case 0x40: ret = mystique->pci_regs[0x40]; break; - case 0x41: ret = mystique->pci_regs[0x41]; break; - case 0x42: ret = mystique->pci_regs[0x42]; break; - case 0x43: ret = mystique->pci_regs[0x43]; break; + case 0x40: + ret = mystique->pci_regs[0x40]; + break; + case 0x41: + ret = mystique->pci_regs[0x41]; + break; + case 0x42: + ret = mystique->pci_regs[0x42]; + break; + case 0x43: + ret = mystique->pci_regs[0x43]; + break; - case 0x44: ret = mystique->pci_regs[0x44]; break; - case 0x45: ret = mystique->pci_regs[0x45]; break; + case 0x44: + ret = mystique->pci_regs[0x44]; + break; + case 0x45: + ret = mystique->pci_regs[0x45]; + break; - case 0x48: case 0x49: case 0x4a: case 0x4b: - addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | - (addr & 3); - ret = mystique_ctrl_read_b(addr, mystique); break; - } + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); + ret = mystique_ctrl_read_b(addr, mystique); + break; + } return ret; } @@ -5045,183 +5254,188 @@ uint8_t mystique_pci_read(int func, int addr, void *p) static void mystique_pci_write(int func, int addr, uint8_t val, void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; switch (addr) { - case PCI_REG_COMMAND: - mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; - mystique_recalc_mapping(mystique); - break; + case PCI_REG_COMMAND: + mystique->pci_regs[PCI_REG_COMMAND] = (val & 0x27) | 0x80; + mystique_recalc_mapping(mystique); + break; - case 0x07: - mystique->pci_regs[0x07] &= ~(val & 0x38); - break; + case 0x07: + mystique->pci_regs[0x07] &= ~(val & 0x38); + break; - case 0x0d: - mystique->pci_regs[0x0d] = val; - break; + case 0x0d: + mystique->pci_regs[0x0d] = val; + break; - case 0x11: - mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); - mystique_recalc_mapping(mystique); - break; - case 0x12: - mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); - mystique_recalc_mapping(mystique); - break; - case 0x13: - mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); - mystique_recalc_mapping(mystique); - break; + case 0x11: + mystique->ctrl_base = (mystique->ctrl_base & 0xffff0000) | ((val & 0xc0) << 8); + mystique_recalc_mapping(mystique); + break; + case 0x12: + mystique->ctrl_base = (mystique->ctrl_base & 0xff00c000) | (val << 16); + mystique_recalc_mapping(mystique); + break; + case 0x13: + mystique->ctrl_base = (mystique->ctrl_base & 0x00ffc000) | (val << 24); + mystique_recalc_mapping(mystique); + break; - case 0x16: - mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); - mystique_recalc_mapping(mystique); - break; - case 0x17: - mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); - mystique_recalc_mapping(mystique); - break; + case 0x16: + mystique->lfb_base = (mystique->lfb_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x17: + mystique->lfb_base = (mystique->lfb_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; - case 0x1a: - mystique->iload_base = (mystique->iload_base & 0xff000000) | ((val & 0x80) << 16); - mystique_recalc_mapping(mystique); - break; - case 0x1b: - mystique->iload_base = (mystique->iload_base & 0x00800000) | (val << 24); - mystique_recalc_mapping(mystique); - break; + case 0x1a: + mystique->iload_base = (mystique->iload_base & 0xff000000) | ((val & 0x80) << 16); + mystique_recalc_mapping(mystique); + break; + case 0x1b: + mystique->iload_base = (mystique->iload_base & 0x00800000) | (val << 24); + mystique_recalc_mapping(mystique); + break; - case 0x30: case 0x32: case 0x33: - if (!(mystique->pci_regs[0x43] & 0x40)) - return; - mystique->pci_regs[addr] = val; - if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + case 0x30: + case 0x32: + case 0x33: + if (!(mystique->pci_regs[0x43] & 0x40)) + return; + mystique->pci_regs[addr] = val; + if (mystique->pci_regs[0x30] & 0x01) { + uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&mystique->bios_rom.mapping); + return; + + case 0x3c: + mystique->int_line = val; + return; + + case 0x40: + mystique->pci_regs[addr] = val & 0x3f; + break; + case 0x41: + mystique->pci_regs[addr] = val; + break; + case 0x42: + mystique->pci_regs[addr] = val & 0x1f; + break; + case 0x43: + mystique->pci_regs[addr] = val; + if (addr == 0x43) { + if (val & 0x40) { + if (mystique->pci_regs[0x30] & 0x01) { + uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); + mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); + } else + mem_mapping_disable(&mystique->bios_rom.mapping); } else - mem_mapping_disable(&mystique->bios_rom.mapping); - return; + mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, 0x8000); + } + break; - case 0x3c: - mystique->int_line = val; - return; + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + mystique->pci_regs[addr - 0x20] = val; + break; - case 0x40: - mystique->pci_regs[addr] = val & 0x3f; - break; - case 0x41: - mystique->pci_regs[addr] = val; - break; - case 0x42: - mystique->pci_regs[addr] = val & 0x1f; - break; - case 0x43: - mystique->pci_regs[addr] = val; - if (addr == 0x43) { - if (val & 0x40) { - if (mystique->pci_regs[0x30] & 0x01) { - uint32_t addr = (mystique->pci_regs[0x32] << 16) | (mystique->pci_regs[0x33] << 24); - mem_mapping_set_addr(&mystique->bios_rom.mapping, addr, 0x8000); - } else - mem_mapping_disable(&mystique->bios_rom.mapping); - } else - mem_mapping_set_addr(&mystique->bios_rom.mapping, 0x000c0000, 0x8000); - } - break; + case 0x44: + mystique->pci_regs[addr] = val & 0xfc; + break; + case 0x45: + mystique->pci_regs[addr] = val & 0x3f; + break; - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - mystique->pci_regs[addr - 0x20] = val; - break; - - case 0x44: - mystique->pci_regs[addr] = val & 0xfc; - break; - case 0x45: - mystique->pci_regs[addr] = val & 0x3f; - break; - - case 0x48: case 0x49: case 0x4a: case 0x4b: - addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | - (addr & 3); - /* pclog("mystique_ctrl_write_b(%04X, %02X)\n", addr, val); */ - mystique_ctrl_write_b(addr, val, mystique); - break; + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + addr = (mystique->pci_regs[0x44] & 0xfc) | ((mystique->pci_regs[0x45] & 0x3f) << 8) | (addr & 3); + /* pclog("mystique_ctrl_write_b(%04X, %02X)\n", addr, val); */ + mystique_ctrl_write_b(addr, val, mystique); + break; } } - - static void * mystique_init(const device_t *info) { - int c; + int c; mystique_t *mystique = malloc(sizeof(mystique_t)); - char *romfn; + char *romfn; memset(mystique, 0, sizeof(mystique_t)); - mystique->type = info->local; + mystique->type = info->local; - if (mystique->type == MGA_2064W) - romfn = ROM_MILLENNIUM; - else if (mystique->type == MGA_1064SG) - romfn = ROM_MYSTIQUE; - else - romfn = ROM_MYSTIQUE_220; + if (mystique->type == MGA_2064W) + romfn = ROM_MILLENNIUM; + else if (mystique->type == MGA_1064SG) + romfn = ROM_MYSTIQUE; + else + romfn = ROM_MYSTIQUE_220; rom_init(&mystique->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&mystique->bios_rom.mapping); - mystique->vram_size = device_get_config_int("memory"); - mystique->vram_mask = (mystique->vram_size << 20) - 1; + mystique->vram_size = device_get_config_int("memory"); + mystique->vram_mask = (mystique->vram_size << 20) - 1; mystique->vram_mask_w = mystique->vram_mask >> 1; mystique->vram_mask_l = mystique->vram_mask >> 2; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); if (mystique->type == MGA_2064W) { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium); - svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, - mystique_recalctimings, - mystique_in, mystique_out, - NULL, - NULL); - mystique->svga.dac_hwcursor_draw = tvp3026_hwcursor_draw; - mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); - mystique->svga.clock_gen = mystique->svga.ramdac; - mystique->svga.getclock = tvp3026_getclock; - } else { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); - svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, - mystique_recalctimings, - mystique_in, mystique_out, - mystique_hwcursor_draw, - NULL); - mystique->svga.clock_gen = mystique; - mystique->svga.getclock = mystique_getclock; - } + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_millennium); + svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, + mystique_recalctimings, + mystique_in, mystique_out, + NULL, + NULL); + mystique->svga.dac_hwcursor_draw = tvp3026_hwcursor_draw; + mystique->svga.ramdac = device_add(&tvp3026_ramdac_device); + mystique->svga.clock_gen = mystique->svga.ramdac; + mystique->svga.getclock = tvp3026_getclock; + } else { + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_matrox_mystique); + svga_init(info, &mystique->svga, mystique, mystique->vram_size << 20, + mystique_recalctimings, + mystique_in, mystique_out, + mystique_hwcursor_draw, + NULL); + mystique->svga.clock_gen = mystique; + mystique->svga.getclock = mystique_getclock; + } io_sethandler(0x03c0, 0x0020, mystique_in, NULL, NULL, mystique_out, NULL, NULL, mystique); mem_mapping_add(&mystique->ctrl_mapping, 0, 0, - mystique_ctrl_read_b, NULL, mystique_ctrl_read_l, - mystique_ctrl_write_b, NULL, mystique_ctrl_write_l, - NULL, 0, mystique); + mystique_ctrl_read_b, NULL, mystique_ctrl_read_l, + mystique_ctrl_write_b, NULL, mystique_ctrl_write_l, + NULL, 0, mystique); mem_mapping_disable(&mystique->ctrl_mapping); mem_mapping_add(&mystique->lfb_mapping, 0, 0, - mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, - mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, - NULL, 0, mystique); + mystique_readb_linear, mystique_readw_linear, mystique_readl_linear, + mystique_writeb_linear, mystique_writew_linear, mystique_writel_linear, + NULL, 0, mystique); mem_mapping_disable(&mystique->lfb_mapping); mem_mapping_add(&mystique->iload_mapping, 0, 0, - mystique_iload_read_b, NULL, mystique_iload_read_l, - mystique_iload_write_b, NULL, mystique_iload_write_l, - NULL, 0, mystique); + mystique_iload_read_b, NULL, mystique_iload_read_l, + mystique_iload_write_b, NULL, mystique_iload_write_l, + NULL, 0, mystique); mem_mapping_disable(&mystique->iload_mapping); - mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique); + mystique->card = pci_add_card(PCI_ADD_VIDEO, mystique_pci_read, mystique_pci_write, mystique); mystique->pci_regs[0x06] = 0x80; mystique->pci_regs[0x07] = 0 << 1; mystique->pci_regs[0x2c] = mystique->bios_rom.rom[0x7ff8]; @@ -5229,61 +5443,60 @@ mystique_init(const device_t *info) mystique->pci_regs[0x2e] = mystique->bios_rom.rom[0x7ffa]; mystique->pci_regs[0x2f] = mystique->bios_rom.rom[0x7ffb]; - mystique->svga.miscout = 1; - mystique->pci_regs[0x41] = 0x01; /* vgaboot = 1 */ - mystique->pci_regs[0x43] = 0x40; /* biosen = 1 */ + mystique->svga.miscout = 1; + mystique->pci_regs[0x41] = 0x01; /* vgaboot = 1 */ + mystique->pci_regs[0x43] = 0x40; /* biosen = 1 */ for (c = 0; c < 256; c++) { - dither5[c][0][0] = c >> 3; - dither5[c][1][1] = (c + 2) >> 3; - dither5[c][1][0] = (c + 4) >> 3; - dither5[c][0][1] = (c + 6) >> 3; + dither5[c][0][0] = c >> 3; + dither5[c][1][1] = (c + 2) >> 3; + dither5[c][1][0] = (c + 4) >> 3; + dither5[c][0][1] = (c + 6) >> 3; - if (dither5[c][1][1] > 31) - dither5[c][1][1] = 31; - if (dither5[c][1][0] > 31) - dither5[c][1][0] = 31; - if (dither5[c][0][1] > 31) - dither5[c][0][1] = 31; + if (dither5[c][1][1] > 31) + dither5[c][1][1] = 31; + if (dither5[c][1][0] > 31) + dither5[c][1][0] = 31; + if (dither5[c][0][1] > 31) + dither5[c][0][1] = 31; - dither6[c][0][0] = c >> 2; - dither6[c][1][1] = (c + 1) >> 2; - dither6[c][1][0] = (c + 2) >> 2; - dither6[c][0][1] = (c + 3) >> 2; + dither6[c][0][0] = c >> 2; + dither6[c][1][1] = (c + 1) >> 2; + dither6[c][1][0] = (c + 2) >> 2; + dither6[c][0][1] = (c + 3) >> 2; - if (dither6[c][1][1] > 63) - dither6[c][1][1] = 63; - if (dither6[c][1][0] > 63) - dither6[c][1][0] = 63; - if (dither6[c][0][1] > 63) - dither6[c][0][1] = 63; + if (dither6[c][1][1] > 63) + dither6[c][1][1] = 63; + if (dither6[c][1][0] > 63) + dither6[c][1][0] = 63; + if (dither6[c][0][1] > 63) + dither6[c][0][1] = 63; } - mystique->wake_fifo_thread = thread_create_event(); + mystique->wake_fifo_thread = thread_create_event(); mystique->fifo_not_full_event = thread_create_event(); - mystique->thread_run = 1; - mystique->fifo_thread = thread_create(fifo_thread, mystique); - mystique->dma.lock = thread_create_mutex(); + mystique->thread_run = 1; + mystique->fifo_thread = thread_create(fifo_thread, mystique); + mystique->dma.lock = thread_create_mutex(); - timer_add(&mystique->wake_timer, mystique_wake_timer, (void *)mystique, 0); - timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *)mystique, 1); + timer_add(&mystique->wake_timer, mystique_wake_timer, (void *) mystique, 0); + timer_add(&mystique->softrap_pending_timer, mystique_softrap_pending_timer, (void *) mystique, 1); mystique->status = STATUS_ENDPRDMASTS; mystique->svga.vsync_callback = mystique_vsync_callback; - mystique->i2c = i2c_gpio_init("i2c_mga"); + mystique->i2c = i2c_gpio_init("i2c_mga"); mystique->i2c_ddc = i2c_gpio_init("ddc_mga"); - mystique->ddc = ddc_init(i2c_gpio_get_bus(mystique->i2c_ddc)); + mystique->ddc = ddc_init(i2c_gpio_get_bus(mystique->i2c_ddc)); return mystique; } - static void mystique_close(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; mystique->thread_run = 0; thread_set_event(mystique->wake_fifo_thread); @@ -5319,26 +5532,24 @@ mystique_220_available(void) return rom_present(ROM_MYSTIQUE_220); } - static void mystique_speed_changed(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; svga_recalctimings(&mystique->svga); } - static void mystique_force_redraw(void *p) { - mystique_t *mystique = (mystique_t *)p; + mystique_t *mystique = (mystique_t *) p; mystique->svga.fullchange = changeframecount; } static const device_config_t mystique_config[] = { -// clang-format off + // clang-format off { .name = "memory", .description = "Memory size", @@ -5369,49 +5580,44 @@ static const device_config_t mystique_config[] = { // clang-format on }; -const device_t millennium_device = -{ - .name = "Matrox Millennium", +const device_t millennium_device = { + .name = "Matrox Millennium", .internal_name = "millennium", - .flags = DEVICE_PCI, - .local = MGA_2064W, - .init = mystique_init, - .close = mystique_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = MGA_2064W, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, { .available = millennium_available }, .speed_changed = mystique_speed_changed, - .force_redraw = mystique_force_redraw, - .config = mystique_config + .force_redraw = mystique_force_redraw, + .config = mystique_config }; - -const device_t mystique_device = -{ - .name = "Matrox Mystique", +const device_t mystique_device = { + .name = "Matrox Mystique", .internal_name = "mystique", - .flags = DEVICE_PCI, - .local = MGA_1064SG, - .init = mystique_init, - .close = mystique_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = MGA_1064SG, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, { .available = mystique_available }, .speed_changed = mystique_speed_changed, - .force_redraw = mystique_force_redraw, - .config = mystique_config + .force_redraw = mystique_force_redraw, + .config = mystique_config }; - -const device_t mystique_220_device = -{ - .name = "Matrox Mystique 220", +const device_t mystique_220_device = { + .name = "Matrox Mystique 220", .internal_name = "mystique_220", - .flags = DEVICE_PCI, - .local = MGA_1164SG, - .init = mystique_init, - .close = mystique_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = MGA_1164SG, + .init = mystique_init, + .close = mystique_close, + .reset = NULL, { .available = mystique_220_available }, .speed_changed = mystique_speed_changed, - .force_redraw = mystique_force_redraw, - .config = mystique_config + .force_redraw = mystique_force_redraw, + .config = mystique_config }; diff --git a/src/video/vid_nga.c b/src/video/vid_nga.c index befe01671..7710c3655 100644 --- a/src/video/vid_nga.c +++ b/src/video/vid_nga.c @@ -39,509 +39,500 @@ #include <86box/vid_nga.h> #include <86box/vid_cga_comp.h> - - -#define CGA_RGB 0 +#define CGA_RGB 0 #define CGA_COMPOSITE 1 #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 - - -static video_timings_t timing_nga = {VIDEO_ISA, 8,16,32, 8,16,32}; +static video_timings_t timing_nga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; void nga_recalctimings(nga_t *nga) { double _dispontime, _dispofftime, disptime; - if ((nga->cga.cgamode & 1) ) { - disptime = nga->cga.crtc[0] + 1; - _dispontime = nga->cga.crtc[1]; + if ((nga->cga.cgamode & 1)) { + disptime = nga->cga.crtc[0] + 1; + _dispontime = nga->cga.crtc[1]; } else { - disptime = (nga->cga.crtc[0] + 1) << 1; - _dispontime = nga->cga.crtc[1] << 1; + disptime = (nga->cga.crtc[0] + 1) << 1; + _dispontime = nga->cga.crtc[1] << 1; } _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST / 2; + _dispontime *= CGACONST / 2; _dispofftime *= CGACONST / 2; - nga->cga.dispontime = (uint64_t)(_dispontime); - nga->cga.dispofftime = (uint64_t)(_dispofftime); + nga->cga.dispontime = (uint64_t) (_dispontime); + nga->cga.dispofftime = (uint64_t) (_dispofftime); } void nga_out(uint16_t addr, uint8_t val, void *priv) { - nga_t *nga = (nga_t *)priv; - - cga_out(addr, val, &nga->cga); + nga_t *nga = (nga_t *) priv; + cga_out(addr, val, &nga->cga); } uint8_t nga_in(uint16_t addr, void *priv) { - nga_t *nga = (nga_t *)priv; + nga_t *nga = (nga_t *) priv; - return cga_in(addr, &nga->cga); + return cga_in(addr, &nga->cga); } - void nga_waitstates(void *p) { - int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8}; + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; ws = ws_array[cycles & 0xf]; sub_cycles(ws); } - void nga_write(uint32_t addr, uint8_t val, void *priv) { - nga_t *nga = (nga_t *)priv; - int offset; - /* a8000-affff */ - if(!(addr & 0x10000)) - nga->vram_64k[addr & 0x7FFF]=val; - /* b8000-bffff */ - else - nga->cga.vram[addr & 0x7FFF]=val; + nga_t *nga = (nga_t *) priv; + int offset; + /* a8000-affff */ + if (!(addr & 0x10000)) + nga->vram_64k[addr & 0x7FFF] = val; + /* b8000-bffff */ + else + nga->cga.vram[addr & 0x7FFF] = val; - if (nga->cga.snow_enabled) { - /* recreate snow effect */ - offset = ((timer_get_remaining_u64(&nga->cga.timer) / CGACONST) * 4) & 0xfc; - nga->cga.charbuffer[offset] = nga->cga.vram[addr & 0x7fff]; - nga->cga.charbuffer[offset | 1] = nga->cga.vram[addr & 0x7fff]; - } - nga_waitstates(&nga->cga); + if (nga->cga.snow_enabled) { + /* recreate snow effect */ + offset = ((timer_get_remaining_u64(&nga->cga.timer) / CGACONST) * 4) & 0xfc; + nga->cga.charbuffer[offset] = nga->cga.vram[addr & 0x7fff]; + nga->cga.charbuffer[offset | 1] = nga->cga.vram[addr & 0x7fff]; + } + nga_waitstates(&nga->cga); } uint8_t nga_read(uint32_t addr, void *priv) { - nga_t *nga = (nga_t *)priv; - int offset; - uint8_t ret; - /* a8000-affff */ - if(!(addr & 0x10000)) - ret = nga->vram_64k[addr & 0x7FFF]; - else - ret = nga->cga.vram[addr & 0x7FFF]; + nga_t *nga = (nga_t *) priv; + int offset; + uint8_t ret; + /* a8000-affff */ + if (!(addr & 0x10000)) + ret = nga->vram_64k[addr & 0x7FFF]; + else + ret = nga->cga.vram[addr & 0x7FFF]; - nga_waitstates(&nga->cga); + nga_waitstates(&nga->cga); - if (nga->cga.snow_enabled) { - /* recreate snow effect */ - offset = ((timer_get_remaining_u64(&nga->cga.timer) / CGACONST) * 4) & 0xfc; - nga->cga.charbuffer[offset] = nga->cga.vram[addr & 0x7fff]; - nga->cga.charbuffer[offset | 1] = nga->cga.vram[addr & 0x7fff]; - } + if (nga->cga.snow_enabled) { + /* recreate snow effect */ + offset = ((timer_get_remaining_u64(&nga->cga.timer) / CGACONST) * 4) & 0xfc; + nga->cga.charbuffer[offset] = nga->cga.vram[addr & 0x7fff]; + nga->cga.charbuffer[offset | 1] = nga->cga.vram[addr & 0x7fff]; + } - return(ret); + return (ret); } void nga_poll(void *priv) { - nga_t *nga = (nga_t *)priv; - /* set cursor position in memory */ + nga_t *nga = (nga_t *) priv; + /* set cursor position in memory */ uint16_t ca = (nga->cga.crtc[15] | (nga->cga.crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c, xs_temp, ys_temp; - int oldvc; - uint8_t chr, attr; + int drawcursor; + int x, c, xs_temp, ys_temp; + int oldvc; + uint8_t chr, attr; uint16_t dat, dat2; - int cols[4]; - int col; - int oldsc; + int cols[4]; + int col; + int oldsc; - /* graphic mode and not high-res modes */ - if ((nga->cga.cgamode & 2) && !(nga->cga.cgamode & 0x40)) { - /* standard cga mode */ - cga_poll(&nga->cga); - return; - } else { - /* high-res or text mode */ - if (!nga->cga.linepos) { - timer_advance_u64(&nga->cga.timer, nga->cga.dispofftime); - nga->cga.cgastat |= 1; - nga->cga.linepos = 1; - oldsc = nga->cga.sc; - /* if interlaced */ - if ((nga->cga.crtc[8] & 3) == 3) - nga->cga.sc = ((nga->cga.sc << 1) + nga->cga.oddeven) & 7; - if (nga->cga.cgadispon) { - if (nga->cga.displine < nga->cga.firstline) { - nga->cga.firstline = nga->cga.displine; - video_wait_for_buffer(); - } - nga->cga.lastline = nga->cga.displine; - /* 80-col */ - if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 2)) { - /* for each text column */ - for (x = 0; x < nga->cga.crtc[1]; x++) { - /* video output enabled */ - if (nga->cga.cgamode & 8) { - /* character */ - chr = nga->cga.charbuffer[x << 1]; - /* text attributes */ - attr = nga->cga.charbuffer[(x << 1) + 1]; - } else - chr = attr = 0; - /* check if cursor has to be drawn */ - drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron); - /* set foreground */ - cols[1] = (attr & 15) + 16; - /* blink active */ - if (nga->cga.cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - /* attribute 7 active and not cursor */ - if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) { - /* set blinking */ - cols[1] = cols[0]; - } - } else { - /* Set intensity bit */ - cols[0] = (attr >> 4) + 16; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; - } + /* graphic mode and not high-res modes */ + if ((nga->cga.cgamode & 2) && !(nga->cga.cgamode & 0x40)) { + /* standard cga mode */ + cga_poll(&nga->cga); + return; + } else { + /* high-res or text mode */ + if (!nga->cga.linepos) { + timer_advance_u64(&nga->cga.timer, nga->cga.dispofftime); + nga->cga.cgastat |= 1; + nga->cga.linepos = 1; + oldsc = nga->cga.sc; + /* if interlaced */ + if ((nga->cga.crtc[8] & 3) == 3) + nga->cga.sc = ((nga->cga.sc << 1) + nga->cga.oddeven) & 7; + if (nga->cga.cgadispon) { + if (nga->cga.displine < nga->cga.firstline) { + nga->cga.firstline = nga->cga.displine; + video_wait_for_buffer(); + } + nga->cga.lastline = nga->cga.displine; + /* 80-col */ + if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 2)) { + /* for each text column */ + for (x = 0; x < nga->cga.crtc[1]; x++) { + /* video output enabled */ + if (nga->cga.cgamode & 8) { + /* character */ + chr = nga->cga.charbuffer[x << 1]; + /* text attributes */ + attr = nga->cga.charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + /* check if cursor has to be drawn */ + drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron); + /* set foreground */ + cols[1] = (attr & 15) + 16; + /* blink active */ + if (nga->cga.cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + /* attribute 7 active and not cursor */ + if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + } + } else { + /* Set intensity bit */ + cols[0] = (attr >> 4) + 16; + } + if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + } - nga->cga.ma++; - } - } - /* 40-col */ - else if (!(nga->cga.cgamode & 2)) { - /* for each text column */ - for (x = 0; x < nga->cga.crtc[1]; x++) { - if (nga->cga.cgamode & 8) { - chr = nga->cga.vram[((nga->cga.ma << 1) & 0x3fff) + nga->base]; - attr = nga->cga.vram[(((nga->cga.ma << 1) + 1) & 0x3fff) + nga->base]; - } else { - chr = attr = 0; - } - drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron); - /* set foreground */ - cols[1] = (attr & 15) + 16; - /* blink active */ - if (nga->cga.cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) { - /* set blinking */ - cols[1] = cols[0]; - } - } else { - /* Set intensity bit */ - cols[0] = (attr >> 4) + 16; - } + nga->cga.ma++; + } + } + /* 40-col */ + else if (!(nga->cga.cgamode & 2)) { + /* for each text column */ + for (x = 0; x < nga->cga.crtc[1]; x++) { + if (nga->cga.cgamode & 8) { + chr = nga->cga.vram[((nga->cga.ma << 1) & 0x3fff) + nga->base]; + attr = nga->cga.vram[(((nga->cga.ma << 1) + 1) & 0x3fff) + nga->base]; + } else { + chr = attr = 0; + } + drawcursor = ((nga->cga.ma == ca) && nga->cga.con && nga->cga.cursoron); + /* set foreground */ + cols[1] = (attr & 15) + 16; + /* blink active */ + if (nga->cga.cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((nga->cga.cgablink & 8) && (attr & 0x80) && !nga->cga.drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + } + } else { + /* Set intensity bit */ + cols[0] = (attr >> 4) + 16; + } - if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = - buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = - buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; - } + if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[nga->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((nga->cga.sc & 7) << 1) | nga->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + } - nga->cga.ma++; + nga->cga.ma++; + } + } else { + /* high res modes */ + if (nga->cga.cgamode & 0x40) { + /* 640x400x2 mode */ + if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) { + /* + * Scanlines are read in the following order: + * 0b8000-0b9f3f even scans (0,4,...) + * 0ba000-0bbf3f odd scans (2,6,...) + * 0bc000-0bdf3f even scans (1,5,...) + * 0be000-0bff3f odd scans (3,7,...) + */ + dat2 = ((nga->cga.sc & 1) * 0x2000) | (nga->lineff * 0x4000); + cols[0] = 0; + cols[1] = 15 + 16; + /* 640x400x4 mode */ + } else { + cols[0] = (nga->cga.cgacol & 15) | 16; + col = (nga->cga.cgacol & 16) ? 24 : 16; + if (nga->cga.cgamode & 4) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 7; /* White */ + } else if (nga->cga.cgacol & 32) { + cols[1] = col | 3; /* Cyan */ + cols[2] = col | 5; /* Magenta */ + cols[3] = col | 7; /* White */ + } else { + cols[1] = col | 2; /* Green */ + cols[2] = col | 4; /* Red */ + cols[3] = col | 6; /* Yellow */ + } + /* + * Scanlines are read in the following order: + * 0b8000-0bbf3f even scans (0,4,...) + * 0bc000-0bff3f odd scans (1,5,...) + * 0a8000-0abf3f even scans (2,6,...) + * 0ac000-0aff3f odd scans (3,7,...) + */ + dat2 = (nga->cga.sc & 1) * 0x4000; + } + } else { + dat2 = (nga->cga.sc & 1) * 0x2000; + cols[0] = 0; + cols[1] = (nga->cga.cgacol & 15) + 16; + } - } - } else { - /* high res modes */ - if (nga->cga.cgamode & 0x40) { - /* 640x400x2 mode */ - if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) { - /* - * Scanlines are read in the following order: - * 0b8000-0b9f3f even scans (0,4,...) - * 0ba000-0bbf3f odd scans (2,6,...) - * 0bc000-0bdf3f even scans (1,5,...) - * 0be000-0bff3f odd scans (3,7,...) - */ - dat2 = ((nga->cga.sc & 1) * 0x2000) | (nga->lineff * 0x4000); - cols[0] = 0; cols[1] = 15 + 16; - /* 640x400x4 mode */ - } else { - cols[0] = (nga->cga.cgacol & 15) | 16; - col = (nga->cga.cgacol & 16) ? 24 : 16; - if (nga->cga.cgamode & 4) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 7; /* White */ - } else if (nga->cga.cgacol & 32) { - cols[1] = col | 3; /* Cyan */ - cols[2] = col | 5; /* Magenta */ - cols[3] = col | 7; /* White */ - } else { - cols[1] = col | 2; /* Green */ - cols[2] = col | 4; /* Red */ - cols[3] = col | 6; /* Yellow */ - } - /* - * Scanlines are read in the following order: - * 0b8000-0bbf3f even scans (0,4,...) - * 0bc000-0bff3f odd scans (1,5,...) - * 0a8000-0abf3f even scans (2,6,...) - * 0ac000-0aff3f odd scans (3,7,...) - */ - dat2 = (nga->cga.sc & 1) * 0x4000; - } - } - else { - dat2 = (nga->cga.sc & 1) * 0x2000; - cols[0] = 0; cols[1] = (nga->cga.cgacol & 15) + 16; - } + /* for each text column */ + for (x = 0; x < nga->cga.crtc[1]; x++) { + /* video out */ + if (nga->cga.cgamode & 8) { + /* 640x400x2 */ + if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) { + /* read two bytes at a time */ + dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2 + 1]; + /* each pixel is represented by one bit, so draw 16 pixels at a time */ + /* crtc[1] is 40 column, so 40x16=640 pixels */ + for (c = 0; c < 16; c++) { + buffer32->line[nga->cga.displine][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + /* 640x400x4 */ + } else { + /* lines 2,3,6,7,etc. */ + if (nga->cga.sc & 2) + /* read two bytes at a time */ + dat = (nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1]; + /* lines 0,1,4,5,etc. */ + else + /* read two bytes at a time */ + dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1]; + /* each pixel is represented by two bits, so draw 8 pixels at a time */ + /* crtc[1] is 80 column, so 80x8=640 pixels */ + for (c = 0; c < 8; c++) { + buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[dat >> 14]; + dat <<= 2; + } + } + } else { + dat = 0; + } + nga->cga.ma++; + } + } + } else { - /* for each text column */ - for (x = 0; x < nga->cga.crtc[1]; x++) { - /* video out */ - if (nga->cga.cgamode & 8) { - /* 640x400x2 */ - if (nga->cga.cgamode & 0x4 || nga->cga.cgamode & 0x10) { - /* read two bytes at a time */ - dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x1fff) + dat2 + 1]; - /* each pixel is represented by one bit, so draw 16 pixels at a time */ - /* crtc[1] is 40 column, so 40x16=640 pixels */ - for (c = 0; c < 16; c++) { - buffer32->line[nga->cga.displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - /* 640x400x4 */ - } else { - /* lines 2,3,6,7,etc. */ - if (nga->cga.sc & 2) - /* read two bytes at a time */ - dat = (nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->vram_64k[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1]; - /* lines 0,1,4,5,etc. */ - else - /* read two bytes at a time */ - dat = (nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2] << 8) | nga->cga.vram[((nga->cga.ma << 1) & 0x7fff) + dat2 + 1]; - /* each pixel is represented by two bits, so draw 8 pixels at a time */ - /* crtc[1] is 80 column, so 80x8=640 pixels */ - for (c = 0; c < 8; c++) { - buffer32->line[nga->cga.displine][(x << 3) + c + 8] = cols[dat >> 14]; - dat <<= 2; - } - } - } else { - dat = 0; - } - nga->cga.ma++; - } - } - } else { + /* nga specific */ + cols[0] = ((nga->cga.cgamode & 0x12) == 0x12) ? 0 : (nga->cga.cgacol & 15) + 16; + /* 80-col */ + if ((nga->cga.cgamode & 1)) { + hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]); + hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]); + } else { + hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]); + hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]); + } + } - /* nga specific */ - cols[0] = ((nga->cga.cgamode & 0x12) == 0x12) ? 0 : (nga->cga.cgacol & 15) + 16; - /* 80-col */ - if ((nga->cga.cgamode & 1) ) { - hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]); - hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 3) + 16) << 2, cols[0]); - } else { - hline(buffer32, 0, (nga->cga.displine << 1), ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]); - hline(buffer32, 0, (nga->cga.displine << 1) + 1, ((nga->cga.crtc[1] << 4) + 16) << 2, cols[0]); - } + nga->cga.sc = oldsc; + /* vertical sync */ + if (nga->cga.vc == nga->cga.crtc[7] && !nga->cga.sc) + nga->cga.cgastat |= 8; + nga->cga.displine++; + if (nga->cga.displine >= 720) + nga->cga.displine = 0; + } else { + timer_advance_u64(&nga->cga.timer, nga->cga.dispontime); + if (nga->cga.cgadispon) + nga->cga.cgastat &= ~1; + nga->cga.linepos = 0; + /* nga specific */ + nga->lineff ^= 1; - } + /* text mode or 640x400x2 */ + if (nga->lineff && !((nga->cga.cgamode & 1) && (nga->cga.cgamode & 0x40))) { + nga->cga.ma = nga->cga.maback; + /* 640x400x4 */ + } else { + if (nga->cga.vsynctime) { + nga->cga.vsynctime--; + if (!nga->cga.vsynctime) + nga->cga.cgastat &= ~8; + } + /* cursor stop scanline */ + if (nga->cga.sc == (nga->cga.crtc[11] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[11] & 31) >> 1))) { + nga->cga.con = 0; + nga->cga.coff = 1; + } + /* interlaced and max scanline per char reached */ + if ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1)) + nga->cga.maback = nga->cga.ma; - nga->cga.sc = oldsc; - /* vertical sync */ - if (nga->cga.vc == nga->cga.crtc[7] && !nga->cga.sc) - nga->cga.cgastat |= 8; - nga->cga.displine++; - if (nga->cga.displine >= 720) - nga->cga.displine = 0; - } else { - timer_advance_u64(&nga->cga.timer, nga->cga.dispontime); - if (nga->cga.cgadispon) nga->cga.cgastat &= ~1; - nga->cga.linepos = 0; - /* nga specific */ - nga->lineff ^= 1; + if (nga->cga.vadj) { + nga->cga.sc++; + nga->cga.sc &= 31; + nga->cga.ma = nga->cga.maback; + nga->cga.vadj--; + if (!nga->cga.vadj) { + nga->cga.cgadispon = 1; + /* change start of displayed page (crtc 12-13) */ + nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff; + nga->cga.sc = 0; + } + /* nga specific */ + /* end of character line reached */ + } else if (nga->cga.sc == nga->cga.crtc[9] || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1))) { + nga->cga.maback = nga->cga.ma; + nga->cga.sc = 0; + oldvc = nga->cga.vc; + nga->cga.vc++; + nga->cga.vc &= 127; - /* text mode or 640x400x2 */ - if (nga->lineff && !((nga->cga.cgamode & 1) && (nga->cga.cgamode & 0x40))) { - nga->cga.ma = nga->cga.maback; - /* 640x400x4 */ - } else { - if (nga->cga.vsynctime) { - nga->cga.vsynctime--; - if (!nga->cga.vsynctime) - nga->cga.cgastat &= ~8; - } - /* cursor stop scanline */ - if (nga->cga.sc == (nga->cga.crtc[11] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[11] & 31) >> 1))) { - nga->cga.con = 0; - nga->cga.coff = 1; - } - /* interlaced and max scanline per char reached */ - if ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1)) - nga->cga.maback = nga->cga.ma; + /* lines of character displayed */ + if (nga->cga.vc == nga->cga.crtc[6]) + nga->cga.cgadispon = 0; - if (nga->cga.vadj) { - nga->cga.sc++; - nga->cga.sc &= 31; - nga->cga.ma = nga->cga.maback; - nga->cga.vadj--; - if (!nga->cga.vadj) { - nga->cga.cgadispon = 1; - /* change start of displayed page (crtc 12-13) */ - nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff; - nga->cga.sc = 0; - } - /* nga specific */ - /* end of character line reached */ - } else if (nga->cga.sc == nga->cga.crtc[9] || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == (nga->cga.crtc[9] >> 1))) { - nga->cga.maback = nga->cga.ma; - nga->cga.sc = 0; - oldvc = nga->cga.vc; - nga->cga.vc++; - nga->cga.vc &= 127; + /* total vertical lines */ + if (oldvc == nga->cga.crtc[4]) { + nga->cga.vc = 0; + /* adjust vertical lines */ + nga->cga.vadj = nga->cga.crtc[5]; + if (!nga->cga.vadj) { + nga->cga.cgadispon = 1; + /* change start of displayed page (crtc 12-13) */ + nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff; + } + /* cursor start */ + switch (nga->cga.crtc[10] & 0x60) { + case 0x20: + nga->cga.cursoron = 0; + break; + case 0x60: + nga->cga.cursoron = nga->cga.cgablink & 0x10; + break; + default: + nga->cga.cursoron = nga->cga.cgablink & 0x08; + break; + } + } + /* vertical line position */ + if (nga->cga.vc == nga->cga.crtc[7]) { + nga->cga.cgadispon = 0; + nga->cga.displine = 0; + /* nga specific */ + nga->cga.vsynctime = 16; + /* vsync pos */ + if (nga->cga.crtc[7]) { + if ((nga->cga.cgamode & 1)) + /* set screen width */ + x = (nga->cga.crtc[1] << 3) + 16; + else + x = (nga->cga.crtc[1] << 4) + 16; + nga->cga.lastline++; - /* lines of character displayed */ - if (nga->cga.vc == nga->cga.crtc[6]) - nga->cga.cgadispon=0; + xs_temp = x; + ys_temp = (nga->cga.lastline - nga->cga.firstline); - /* total vertical lines */ - if (oldvc == nga->cga.crtc[4]) { - nga->cga.vc = 0; - /* adjust vertical lines */ - nga->cga.vadj = nga->cga.crtc[5]; - if (!nga->cga.vadj) { - nga->cga.cgadispon = 1; - /* change start of displayed page (crtc 12-13) */ - nga->cga.ma = nga->cga.maback = (nga->cga.crtc[13] | (nga->cga.crtc[12] << 8)) & 0x7fff; - } - /* cursor start */ - switch (nga->cga.crtc[10] & 0x60) { - case 0x20: - nga->cga.cursoron = 0; - break; - case 0x60: - nga->cga.cursoron = nga->cga.cgablink & 0x10; - break; - default: - nga->cga.cursoron = nga->cga.cgablink & 0x08; - break; - } - } - /* vertical line position */ - if (nga->cga.vc == nga->cga.crtc[7]) { - nga->cga.cgadispon = 0; - nga->cga.displine = 0; - /* nga specific */ - nga->cga.vsynctime = 16; - /* vsync pos */ - if (nga->cga.crtc[7]) { - if ((nga->cga.cgamode & 1)) - /* set screen width */ - x = (nga->cga.crtc[1] << 3) + 16; - else - x = (nga->cga.crtc[1] << 4) + 16; - nga->cga.lastline++; + if ((xs_temp > 0) && (ys_temp > 0)) { + if (xsize < 64) + xs_temp = 656; + /* nga specific */ + if (ysize < 32) + ys_temp = 400; + if (!enable_overscan) + xs_temp -= 16; - xs_temp = x; - ys_temp = (nga->cga.lastline - nga->cga.firstline); + if ((nga->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + xsize = xs_temp; + ysize = ys_temp; + set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); - if ((xs_temp > 0) && (ys_temp > 0)) { - if (xsize < 64) xs_temp = 656; - /* nga specific */ - if (ysize < 32) ys_temp = 400; - if (!enable_overscan) - xs_temp -= 16; + if (video_force_resize_get()) + video_force_resize_set(0); + } + /* nga specific */ + if (enable_overscan) { + if (nga->cga.composite) + video_blit_memtoscreen(0, (nga->cga.firstline - 8), + xsize, (nga->cga.lastline - nga->cga.firstline) + 16); + else + video_blit_memtoscreen_8(0, (nga->cga.firstline - 8), + xsize, (nga->cga.lastline - nga->cga.firstline) + 16); + } else { + if (nga->cga.composite) + video_blit_memtoscreen(8, nga->cga.firstline, + xsize, (nga->cga.lastline - nga->cga.firstline)); + else + video_blit_memtoscreen_8(8, nga->cga.firstline, + xsize, (nga->cga.lastline - nga->cga.firstline)); + } + } + frames++; + video_res_x = xsize; + video_res_y = ysize; + /* 80-col */ + if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 0x40)) { + video_res_x /= 8; + video_res_y /= (nga->cga.crtc[9] + 1) * 2; + video_bpp = 0; + /* 40-col */ + } else if (!(nga->cga.cgamode & 2)) { + video_res_x /= 16; + video_res_y /= (nga->cga.crtc[9] + 1) * 2; + video_bpp = 0; + } else if (nga->cga.cgamode & 0x40) { + video_res_x /= 8; + video_res_y /= 2; + video_bpp = 1; + } + } + nga->cga.firstline = 1000; + nga->cga.lastline = 0; + nga->cga.cgablink++; + nga->cga.oddeven ^= 1; + } + } else { + nga->cga.sc++; + nga->cga.sc &= 31; + nga->cga.ma = nga->cga.maback; + } - if ((nga->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - xsize = xs_temp; - ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); + if (nga->cga.cgadispon) + nga->cga.cgastat &= ~1; - if (video_force_resize_get()) - video_force_resize_set(0); - } - /* nga specific */ - if (enable_overscan) { - if (nga->cga.composite) - video_blit_memtoscreen(0, (nga->cga.firstline - 8), - xsize, (nga->cga.lastline - nga->cga.firstline) + 16); - else - video_blit_memtoscreen_8(0, (nga->cga.firstline - 8), - xsize, (nga->cga.lastline - nga->cga.firstline) + 16); - } else { - if (nga->cga.composite) - video_blit_memtoscreen(8, nga->cga.firstline, - xsize, (nga->cga.lastline - nga->cga.firstline)); - else - video_blit_memtoscreen_8(8, nga->cga.firstline, - xsize, (nga->cga.lastline - nga->cga.firstline)); - } - } - frames++; - - video_res_x = xsize; - video_res_y = ysize; - /* 80-col */ - if ((nga->cga.cgamode & 1) && !(nga->cga.cgamode & 0x40)) { - video_res_x /= 8; - video_res_y /= (nga->cga.crtc[9] + 1) * 2; - video_bpp = 0; - /* 40-col */ - } else if (!(nga->cga.cgamode & 2)) { - video_res_x /= 16; - video_res_y /= (nga->cga.crtc[9] + 1) * 2; - video_bpp = 0; - } - else if (nga->cga.cgamode & 0x40) { - video_res_x /= 8; - video_res_y /= 2; - video_bpp = 1; - } - } - nga->cga.firstline = 1000; - nga->cga.lastline = 0; - nga->cga.cgablink++; - nga->cga.oddeven ^= 1; - } - } else { - nga->cga.sc++; - nga->cga.sc &= 31; - nga->cga.ma = nga->cga.maback; - } - - if (nga->cga.cgadispon) - nga->cga.cgastat &= ~1; - - /* enable cursor if its scanline was reached */ - if ((nga->cga.sc == (nga->cga.crtc[10] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[10] & 31) >> 1)))) - nga->cga.con = 1; - } - /* 80-columns */ - if (nga->cga.cgadispon && (nga->cga.cgamode & 1) ) { - /* for each character per line */ - for (x = 0; x < (nga->cga.crtc[1] << 1); x++) - nga->cga.charbuffer[x] = nga->cga.vram[(((nga->cga.ma << 1) + x) & 0x3fff) + nga->base]; - } - } - } + /* enable cursor if its scanline was reached */ + if ((nga->cga.sc == (nga->cga.crtc[10] & 31) || ((nga->cga.crtc[8] & 3) == 3 && nga->cga.sc == ((nga->cga.crtc[10] & 31) >> 1)))) + nga->cga.con = 1; + } + /* 80-columns */ + if (nga->cga.cgadispon && (nga->cga.cgamode & 1)) { + /* for each character per line */ + for (x = 0; x < (nga->cga.crtc[1] << 1); x++) + nga->cga.charbuffer[x] = nga->cga.vram[(((nga->cga.ma << 1) + x) & 0x3fff) + nga->base]; + } + } + } } void nga_close(void *priv) { - nga_t *nga = (nga_t *)priv; - free(nga->vram_64k); + nga_t *nga = (nga_t *) priv; + free(nga->vram_64k); free(nga->cga.vram); free(nga); } @@ -549,7 +540,7 @@ nga_close(void *priv) void nga_speed_changed(void *priv) { - nga_t *nga = (nga_t *)priv; + nga_t *nga = (nga_t *) priv; nga_recalctimings(nga); } @@ -557,49 +548,49 @@ nga_speed_changed(void *priv) void * nga_init(const device_t *info) { - int mem; - uint8_t charset; - nga_t *nga = (nga_t *)malloc(sizeof(nga_t)); + int mem; + uint8_t charset; + nga_t *nga = (nga_t *) malloc(sizeof(nga_t)); memset(nga, 0x00, sizeof(nga_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_nga); charset = device_get_config_int("charset"); - loadfont_ex("roms/video/nga/ncr_nga_35122.bin", 1, 4096 * charset); + loadfont_ex("roms/video/nga/ncr_nga_35122.bin", 1, 4096 * charset); - nga->cga.composite = 0; + nga->cga.composite = 0; nga->cga.snow_enabled = device_get_config_int("snow_enabled"); - nga->cga.vram = malloc(0x8000); - nga->vram_64k = malloc(0x8000); + nga->cga.vram = malloc(0x8000); + nga->vram_64k = malloc(0x8000); - timer_add(&nga->cga.timer, nga_poll, nga, 1); + timer_add(&nga->cga.timer, nga_poll, nga, 1); mem_mapping_add(&nga->cga.mapping, 0xb8000, 0x8000, - nga_read, NULL, NULL, - nga_write, NULL, NULL, NULL, 0, nga); + nga_read, NULL, NULL, + nga_write, NULL, NULL, NULL, 0, nga); - mem = device_get_config_int("memory"); + mem = device_get_config_int("memory"); - if (mem > 32) { - /* make optional 32KB addessable */ - mem_mapping_add(&nga->mapping_64k, 0xa8000, 0x8000, - nga_read, NULL, NULL, - nga_write, NULL, NULL, NULL, 0, nga); - } + if (mem > 32) { + /* make optional 32KB addessable */ + mem_mapping_add(&nga->mapping_64k, 0xa8000, 0x8000, + nga_read, NULL, NULL, + nga_write, NULL, NULL, NULL, 0, nga); + } - io_sethandler(0x03d0, 16, nga_in, NULL, NULL, nga_out, NULL, NULL, nga); + io_sethandler(0x03d0, 16, nga_in, NULL, NULL, nga_out, NULL, NULL, nga); overscan_x = overscan_y = 16; - nga->cga.rgb_type = device_get_config_int("rgb_type"); - cga_palette = (nga->cga.rgb_type << 1); + nga->cga.rgb_type = device_get_config_int("rgb_type"); + cga_palette = (nga->cga.rgb_type << 1); cgapal_rebuild(); return nga; } const device_config_t nga_config[] = { -// clang-format off + // clang-format off { .name = "rgb_type", .description = "RGB type", @@ -690,15 +681,15 @@ const device_config_t nga_config[] = { }; const device_t nga_device = { - .name = "NCR NGA", + .name = "NCR NGA", .internal_name = "nga", - .flags = DEVICE_ISA, - .local = 0, - .init = nga_init, - .close = nga_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = nga_init, + .close = nga_close, + .reset = NULL, { .available = NULL }, .speed_changed = nga_speed_changed, - .force_redraw = NULL, - .config = nga_config + .force_redraw = NULL, + .config = nga_config }; diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index cea26a71f..742bbafb0 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -30,19 +30,18 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define BIOS_037C_PATH "roms/video/oti/bios.bin" -#define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.BIN" -#define BIOS_067_M300_08_PATH "roms/machines/m30008/EVC_BIOS.ROM" -#define BIOS_067_M300_15_PATH "roms/machines/m30015/EVC_BIOS.ROM" -#define BIOS_077_PATH "roms/video/oti/oti077.vbi" - +#define BIOS_037C_PATH "roms/video/oti/bios.bin" +#define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.BIN" +#define BIOS_067_M300_08_PATH "roms/machines/m30008/EVC_BIOS.ROM" +#define BIOS_067_M300_15_PATH "roms/machines/m30015/EVC_BIOS.ROM" +#define BIOS_077_PATH "roms/video/oti/oti077.vbi" enum { OTI_037C, OTI_067 = 2, OTI_067_AMA932J, OTI_067_M300 = 4, - OTI_077 = 5 + OTI_077 = 5 }; typedef struct { @@ -50,7 +49,7 @@ typedef struct { rom_t bios_rom; - int index; + int index; uint8_t regs[32]; uint8_t chip_id; @@ -62,396 +61,400 @@ typedef struct { uint32_t vram_mask; } oti_t; -static video_timings_t timing_oti = {VIDEO_ISA, 6, 8,16, 6, 8,16}; - +static video_timings_t timing_oti = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; static void oti_out(uint16_t addr, uint8_t val, void *p) { - oti_t *oti = (oti_t *)p; + oti_t *oti = (oti_t *) p; svga_t *svga = &oti->svga; uint8_t old; uint8_t idx, enable; if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3C3)) - return; + return; - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && - !(svga->miscout & 1)) addr ^= 0x60; + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3C3: - if (!oti->chip_id) { - oti->enable_register = val & 1; - return; - } else - break; - break; + case 0x3C3: + if (!oti->chip_id) { + oti->enable_register = val & 1; + return; + } else + break; + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (oti->chip_id == OTI_077) - sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); - else - svga_out(addr, val, svga); - return; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (oti->chip_id == OTI_077) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + return; - case 0x3D4: - if (oti->chip_id) - svga->crtcreg = val & 0x3f; - else - svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */ - return; + case 0x3D4: + if (oti->chip_id) + svga->crtcreg = val & 0x3f; + else + svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */ + return; - case 0x3D5: - if (oti->chip_id && (svga->crtcreg & 0x20)) - return; - idx = svga->crtcreg; - if (!oti->chip_id) - idx &= 0x1f; - if ((idx < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((idx == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[idx]; - svga->crtc[idx] = val; - if (old != val) { - if ((idx < 0x0e) || (idx > 0x10)) { - if (idx == 0x0c || idx == 0x0d) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - break; + case 0x3D5: + if (oti->chip_id && (svga->crtcreg & 0x20)) + return; + idx = svga->crtcreg; + if (!oti->chip_id) + idx &= 0x1f; + if ((idx < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((idx == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[idx]; + svga->crtc[idx] = val; + if (old != val) { + if ((idx < 0x0e) || (idx > 0x10)) { + if (idx == 0x0c || idx == 0x0d) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; - case 0x3DE: - if (oti->chip_id) - oti->index = val & 0x1f; - else - oti->index = val; - return; + case 0x3DE: + if (oti->chip_id) + oti->index = val & 0x1f; + else + oti->index = val; + return; - case 0x3DF: - idx = oti->index; - if (!oti->chip_id) - idx &= 0x1f; - oti->regs[idx] = val; - switch (idx) { - case 0xD: - if (oti->chip_id == OTI_067) { - svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff; - if (!(val & 0x80)) - svga->vram_display_mask = 0x3ffff; + case 0x3DF: + idx = oti->index; + if (!oti->chip_id) + idx &= 0x1f; + oti->regs[idx] = val; + switch (idx) { + case 0xD: + if (oti->chip_id == OTI_067) { + svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff; + if (!(val & 0x80)) + svga->vram_display_mask = 0x3ffff; - if ((val & 0x80) && oti->vram_size == 256) - mem_mapping_disable(&svga->mapping); - else - mem_mapping_enable(&svga->mapping); - } else if (oti->chip_id == OTI_077) { - svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff; + if ((val & 0x80) && oti->vram_size == 256) + mem_mapping_disable(&svga->mapping); + else + mem_mapping_enable(&svga->mapping); + } else if (oti->chip_id == OTI_077) { + svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff; - switch ((val & 0xc0) >> 6) { - case 0x00: /* 256 kB of memory */ - default: - enable = (oti->vram_size >= 256); - if (val & 0x0c) - svga->vram_display_mask = MIN(oti->vram_mask, 0x3ffff); - break; - case 0x01: /* 1 MB of memory */ - case 0x03: - enable = (oti->vram_size >= 1024); - if (val & 0x0c) - svga->vram_display_mask = MIN(oti->vram_mask, 0xfffff); - break; - case 0x02: /* 512 kB of memory */ - enable = (oti->vram_size >= 512); - if (val & 0x0c) - svga->vram_display_mask = MIN(oti->vram_mask, 0x7ffff); - break; - } + switch ((val & 0xc0) >> 6) { + case 0x00: /* 256 kB of memory */ + default: + enable = (oti->vram_size >= 256); + if (val & 0x0c) + svga->vram_display_mask = MIN(oti->vram_mask, 0x3ffff); + break; + case 0x01: /* 1 MB of memory */ + case 0x03: + enable = (oti->vram_size >= 1024); + if (val & 0x0c) + svga->vram_display_mask = MIN(oti->vram_mask, 0xfffff); + break; + case 0x02: /* 512 kB of memory */ + enable = (oti->vram_size >= 512); + if (val & 0x0c) + svga->vram_display_mask = MIN(oti->vram_mask, 0x7ffff); + break; + } - if (enable) - mem_mapping_enable(&svga->mapping); - else - mem_mapping_disable(&svga->mapping); - } else { - if (val & 0x80) - mem_mapping_disable(&svga->mapping); - else - mem_mapping_enable(&svga->mapping); - } - break; + if (enable) + mem_mapping_enable(&svga->mapping); + else + mem_mapping_disable(&svga->mapping); + } else { + if (val & 0x80) + mem_mapping_disable(&svga->mapping); + else + mem_mapping_enable(&svga->mapping); + } + break; - case 0x11: - svga->read_bank = (val & 0xf) * 65536; - svga->write_bank = (val >> 4) * 65536; - break; - } - return; + case 0x11: + svga->read_bank = (val & 0xf) * 65536; + svga->write_bank = (val >> 4) * 65536; + break; + } + return; } svga_out(addr, val, svga); } - static uint8_t oti_in(uint16_t addr, void *p) { - oti_t *oti = (oti_t *)p; + oti_t *oti = (oti_t *) p; svga_t *svga = &oti->svga; uint8_t idx, temp; if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3C3)) - return 0xff; + return 0xff; - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && - !(svga->miscout & 1)) addr ^= 0x60; + if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3C2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) - temp = 0; - else - temp = 0x10; - break; + case 0x3C2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) + temp = 0; + else + temp = 0x10; + break; - case 0x3C3: - if (oti->chip_id) - temp = svga_in(addr, svga); - else - temp = oti->enable_register; - break; + case 0x3C3: + if (oti->chip_id) + temp = svga_in(addr, svga); + else + temp = oti->enable_register; + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (oti->chip_id == OTI_077) - return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); - return svga_in(addr, svga); + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (oti->chip_id == OTI_077) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); - case 0x3CF: - return svga->gdcreg[svga->gdcaddr & 0xf]; + case 0x3CF: + return svga->gdcreg[svga->gdcaddr & 0xf]; - case 0x3D4: - temp = svga->crtcreg; - break; + case 0x3D4: + temp = svga->crtcreg; + break; - case 0x3D5: - if (oti->chip_id) { - if (svga->crtcreg & 0x20) - temp = 0xff; - else - temp = svga->crtc[svga->crtcreg]; - } else - temp = svga->crtc[svga->crtcreg & 0x1f]; - break; + case 0x3D5: + if (oti->chip_id) { + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + } else + temp = svga->crtc[svga->crtcreg & 0x1f]; + break; - case 0x3DA: - if (oti->chip_id) { - temp = svga_in(addr, svga); - break; - } + case 0x3DA: + if (oti->chip_id) { + temp = svga_in(addr, svga); + break; + } - svga->attrff = 0; - /*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again - and expects the diagnostic bits to equal the current border colour. As I understand - it, the 0x3da active enable status does not include the border time, so this may be - an area where OTI-037C is not entirely VGA compatible.*/ - svga->cgastat &= ~0x30; - /* copy color diagnostic info from the overscan color register */ - switch (svga->attrregs[0x12] & 0x30) - { - case 0x00: /* P0 and P2 */ - if (svga->attrregs[0x11] & 0x01) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x04) - svga->cgastat |= 0x20; - break; - case 0x10: /* P4 and P5 */ - if (svga->attrregs[0x11] & 0x10) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x20) - svga->cgastat |= 0x20; - break; - case 0x20: /* P1 and P3 */ - if (svga->attrregs[0x11] & 0x02) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x08) - svga->cgastat |= 0x20; - break; - case 0x30: /* P6 and P7 */ - if (svga->attrregs[0x11] & 0x40) - svga->cgastat |= 0x10; - if (svga->attrregs[0x11] & 0x80) - svga->cgastat |= 0x20; - break; - } - temp = svga->cgastat; - break; + svga->attrff = 0; + /*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again + and expects the diagnostic bits to equal the current border colour. As I understand + it, the 0x3da active enable status does not include the border time, so this may be + an area where OTI-037C is not entirely VGA compatible.*/ + svga->cgastat &= ~0x30; + /* copy color diagnostic info from the overscan color register */ + switch (svga->attrregs[0x12] & 0x30) { + case 0x00: /* P0 and P2 */ + if (svga->attrregs[0x11] & 0x01) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x04) + svga->cgastat |= 0x20; + break; + case 0x10: /* P4 and P5 */ + if (svga->attrregs[0x11] & 0x10) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x20) + svga->cgastat |= 0x20; + break; + case 0x20: /* P1 and P3 */ + if (svga->attrregs[0x11] & 0x02) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x08) + svga->cgastat |= 0x20; + break; + case 0x30: /* P6 and P7 */ + if (svga->attrregs[0x11] & 0x40) + svga->cgastat |= 0x10; + if (svga->attrregs[0x11] & 0x80) + svga->cgastat |= 0x20; + break; + } + temp = svga->cgastat; + break; - case 0x3DE: - temp = oti->index; - if (oti->chip_id) - temp |= (oti->chip_id << 5); - break; + case 0x3DE: + temp = oti->index; + if (oti->chip_id) + temp |= (oti->chip_id << 5); + break; - case 0x3DF: - idx = oti->index; - if (!oti->chip_id) - idx &= 0x1f; - if (idx == 0x10) - temp = oti->dipswitch_val; - else - temp = oti->regs[idx]; - break; + case 0x3DF: + idx = oti->index; + if (!oti->chip_id) + idx &= 0x1f; + if (idx == 0x10) + temp = oti->dipswitch_val; + else + temp = oti->regs[idx]; + break; - default: - temp = svga_in(addr, svga); - break; + default: + temp = svga_in(addr, svga); + break; } - return(temp); + return (temp); } - static void oti_pos_out(uint16_t addr, uint8_t val, void *p) { - oti_t *oti = (oti_t *)p; + oti_t *oti = (oti_t *) p; if ((val ^ oti->pos) & 8) { - if (val & 8) - io_sethandler(0x03c0, 32, oti_in, NULL, NULL, - oti_out, NULL, NULL, oti); - else - io_removehandler(0x03c0, 32, oti_in, NULL, NULL, - oti_out, NULL, NULL, oti); + if (val & 8) + io_sethandler(0x03c0, 32, oti_in, NULL, NULL, + oti_out, NULL, NULL, oti); + else + io_removehandler(0x03c0, 32, oti_in, NULL, NULL, + oti_out, NULL, NULL, oti); } oti->pos = val; } - static uint8_t oti_pos_in(uint16_t addr, void *p) { - oti_t *oti = (oti_t *)p; + oti_t *oti = (oti_t *) p; - return(oti->pos); + return (oti->pos); } - static float oti_getclock(int clock) { float ret = 0.0; switch (clock) { - case 0: - default: - ret = 25175000.0; - break; - case 1: - ret = 28322000.0; - break; - case 4: - ret = 14318000.0; - break; - case 5: - ret = 16257000.0; - break; - case 7: - ret = 35500000.0; - break; + case 0: + default: + ret = 25175000.0; + break; + case 1: + ret = 28322000.0; + break; + case 4: + ret = 14318000.0; + break; + case 5: + ret = 16257000.0; + break; + case 7: + ret = 35500000.0; + break; } return ret; } - static void oti_recalctimings(svga_t *svga) { - oti_t *oti = (oti_t *)svga->p; - int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3); + oti_t *oti = (oti_t *) svga->p; + int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3); - svga->clock = (cpuclock * (double)(1ull << 32)) / oti_getclock(clk_sel); + svga->clock = (cpuclock * (double) (1ull << 32)) / oti_getclock(clk_sel); if (oti->chip_id > 0) { - if (oti->regs[0x14] & 0x08) svga->ma_latch |= 0x10000; - if (oti->regs[0x16] & 0x08) svga->ma_latch |= 0x20000; + if (oti->regs[0x14] & 0x08) + svga->ma_latch |= 0x10000; + if (oti->regs[0x16] & 0x08) + svga->ma_latch |= 0x20000; - if (oti->regs[0x14] & 0x01) svga->vtotal += 0x400; - if (oti->regs[0x14] & 0x02) svga->dispend += 0x400; - if (oti->regs[0x14] & 0x04) svga->vsyncstart += 0x400; + if (oti->regs[0x14] & 0x01) + svga->vtotal += 0x400; + if (oti->regs[0x14] & 0x02) + svga->dispend += 0x400; + if (oti->regs[0x14] & 0x04) + svga->vsyncstart += 0x400; - svga->interlace = oti->regs[0x14] & 0x80; + svga->interlace = oti->regs[0x14] & 0x80; } - if ((oti->regs[0x0d] & 0x0c) && !(oti->regs[0x0d] & 0x10)) svga->rowoffset <<= 1; + if ((oti->regs[0x0d] & 0x0c) && !(oti->regs[0x0d] & 0x10)) + svga->rowoffset <<= 1; if (svga->bpp == 16) { - svga->render = svga_render_16bpp_highres; - svga->hdisp >>= 1; + svga->render = svga_render_16bpp_highres; + svga->hdisp >>= 1; } else if (svga->bpp == 15) { - svga->render = svga_render_15bpp_highres; - svga->hdisp >>= 1; + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; } } - static void * oti_init(const device_t *info) { - oti_t *oti = malloc(sizeof(oti_t)); - char *romfn = NULL; + oti_t *oti = malloc(sizeof(oti_t)); + char *romfn = NULL; memset(oti, 0x00, sizeof(oti_t)); oti->chip_id = info->local; oti->dipswitch_val = 0x18; - switch(oti->chip_id) { - case OTI_037C: - romfn = BIOS_037C_PATH; - oti->vram_size = 256; - oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */ - /* io_sethandler(0x03c0, 32, - oti_in, NULL, NULL, oti_out, NULL, NULL, oti); */ - break; + switch (oti->chip_id) { + case OTI_037C: + romfn = BIOS_037C_PATH; + oti->vram_size = 256; + oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */ + /* io_sethandler(0x03c0, 32, + oti_in, NULL, NULL, oti_out, NULL, NULL, oti); */ + break; - case OTI_067_AMA932J: - romfn = BIOS_067_AMA932J_PATH; - oti->chip_id = 2; - oti->vram_size = device_get_config_int("memory"); - oti->dipswitch_val |= 0x20; - oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ - io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); - break; + case OTI_067_AMA932J: + romfn = BIOS_067_AMA932J_PATH; + oti->chip_id = 2; + oti->vram_size = device_get_config_int("memory"); + oti->dipswitch_val |= 0x20; + oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ + io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); + break; - case OTI_067_M300: - if (rom_present(BIOS_067_M300_15_PATH)) - romfn = BIOS_067_M300_15_PATH; - else - romfn = BIOS_067_M300_08_PATH; - oti->vram_size = device_get_config_int("memory"); - oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ - io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); - break; + case OTI_067_M300: + if (rom_present(BIOS_067_M300_15_PATH)) + romfn = BIOS_067_M300_15_PATH; + else + romfn = BIOS_067_M300_08_PATH; + oti->vram_size = device_get_config_int("memory"); + oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ + io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); + break; - case OTI_067: - case OTI_077: - romfn = BIOS_077_PATH; - oti->vram_size = device_get_config_int("memory"); - oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ - io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); - break; + case OTI_067: + case OTI_077: + romfn = BIOS_077_PATH; + oti->vram_size = device_get_config_int("memory"); + oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */ + io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti); + break; } if (romfn != NULL) { - rom_init(&oti->bios_rom, romfn, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&oti->bios_rom, romfn, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); } oti->vram_mask = (oti->vram_size << 10) - 1; @@ -459,78 +462,71 @@ oti_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti); svga_init(info, &oti->svga, oti, oti->vram_size << 10, - oti_recalctimings, oti_in, oti_out, NULL, NULL); + oti_recalctimings, oti_in, oti_out, NULL, NULL); - if (oti->chip_id == OTI_077) - oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/ + if (oti->chip_id == OTI_077) + oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/ io_sethandler(0x03c0, 32, - oti_in, NULL, NULL, oti_out, NULL, NULL, oti); + oti_in, NULL, NULL, oti_out, NULL, NULL, oti); - oti->svga.miscout = 1; - oti->svga.packed_chain4 = 1; + oti->svga.miscout = 1; + oti->svga.packed_chain4 = 1; - return(oti); + return (oti); } - static void oti_close(void *p) { - oti_t *oti = (oti_t *)p; + oti_t *oti = (oti_t *) p; svga_close(&oti->svga); free(oti); } - static void oti_speed_changed(void *p) { - oti_t *oti = (oti_t *)p; + oti_t *oti = (oti_t *) p; svga_recalctimings(&oti->svga); } - static void oti_force_redraw(void *p) { - oti_t *oti = (oti_t *)p; + oti_t *oti = (oti_t *) p; oti->svga.fullchange = changeframecount; } - static int oti037c_available(void) { - return(rom_present(BIOS_037C_PATH)); + return (rom_present(BIOS_037C_PATH)); } - static int oti067_ama932j_available(void) { - return(rom_present(BIOS_067_AMA932J_PATH)); + return (rom_present(BIOS_067_AMA932J_PATH)); } - static int oti067_077_available(void) { - return(rom_present(BIOS_077_PATH)); + return (rom_present(BIOS_077_PATH)); } - static int oti067_m300_available(void) { if (rom_present(BIOS_067_M300_15_PATH)) - return(rom_present(BIOS_067_M300_15_PATH)); + return (rom_present(BIOS_067_M300_15_PATH)); else - return(rom_present(BIOS_067_M300_08_PATH)); + return (rom_present(BIOS_067_M300_08_PATH)); } // clang-format off @@ -615,71 +611,71 @@ static const device_config_t oti077_config[] = { // clang-format on const device_t oti037c_device = { - .name = "Oak OTI-037C", + .name = "Oak OTI-037C", .internal_name = "oti037c", - .flags = DEVICE_ISA, - .local = 0, - .init = oti_init, - .close = oti_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = oti_init, + .close = oti_close, + .reset = NULL, { .available = oti037c_available }, .speed_changed = oti_speed_changed, - .force_redraw = oti_force_redraw, - .config = NULL + .force_redraw = oti_force_redraw, + .config = NULL }; const device_t oti067_device = { - .name = "Oak OTI-067", + .name = "Oak OTI-067", .internal_name = "oti067", - .flags = DEVICE_ISA, - .local = 2, - .init = oti_init, - .close = oti_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 2, + .init = oti_init, + .close = oti_close, + .reset = NULL, { .available = oti067_077_available }, .speed_changed = oti_speed_changed, - .force_redraw = oti_force_redraw, - .config = oti067_config + .force_redraw = oti_force_redraw, + .config = oti067_config }; const device_t oti067_m300_device = { - .name = "Oak OTI-067 (Olivetti M300-08/15)", + .name = "Oak OTI-067 (Olivetti M300-08/15)", .internal_name = "oti067_m300", - .flags = DEVICE_ISA, - .local = 4, - .init = oti_init, - .close = oti_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 4, + .init = oti_init, + .close = oti_close, + .reset = NULL, { .available = oti067_m300_available }, .speed_changed = oti_speed_changed, - .force_redraw = oti_force_redraw, - .config = oti067_config + .force_redraw = oti_force_redraw, + .config = oti067_config }; const device_t oti067_ama932j_device = { - .name = "Oak OTI-067 (AMA-932J)", + .name = "Oak OTI-067 (AMA-932J)", .internal_name = "oti067_ama932j", - .flags = DEVICE_ISA, - .local = 3, - .init = oti_init, - .close = oti_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 3, + .init = oti_init, + .close = oti_close, + .reset = NULL, { .available = oti067_ama932j_available }, .speed_changed = oti_speed_changed, - .force_redraw = oti_force_redraw, - .config = oti067_ama932j_config + .force_redraw = oti_force_redraw, + .config = oti067_ama932j_config }; const device_t oti077_device = { - .name = "Oak OTI-077", + .name = "Oak OTI-077", .internal_name = "oti077", - .flags = DEVICE_ISA, - .local = 5, - .init = oti_init, - .close = oti_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 5, + .init = oti_init, + .close = oti_close, + .reset = NULL, { .available = oti067_077_available }, .speed_changed = oti_speed_changed, - .force_redraw = oti_force_redraw, - .config = oti077_config + .force_redraw = oti_force_redraw, + .config = oti077_config }; diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index 0487d691d..20fe30cac 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -40,25 +40,21 @@ #include <86box/vid_ogc.h> #include <86box/vid_cga_comp.h> - - /* * Current bugs: * - Olivetti diagnostics fail with errors: 6845 crtc write / read error out 0000 in 00ff * - Dark blue (almost black) picture in composite mode */ -#define CGA_RGB 0 +#define CGA_RGB 0 #define CGA_COMPOSITE 1 #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 +static video_timings_t timing_ogc = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; - -static video_timings_t timing_ogc = {VIDEO_ISA, 8,16,32, 8,16,32}; - -static uint8_t mdaattr[256][2][2]; +static uint8_t mdaattr[256][2][2]; void ogc_recalctimings(ogc_t *ogc) @@ -66,106 +62,104 @@ ogc_recalctimings(ogc_t *ogc) double _dispontime, _dispofftime, disptime; if (ogc->cga.cgamode & 1) { - disptime = ogc->cga.crtc[0] + 1; - _dispontime = ogc->cga.crtc[1]; + disptime = ogc->cga.crtc[0] + 1; + _dispontime = ogc->cga.crtc[1]; } else { - disptime = (ogc->cga.crtc[0] + 1) << 1; - _dispontime = ogc->cga.crtc[1] << 1; + disptime = (ogc->cga.crtc[0] + 1) << 1; + _dispontime = ogc->cga.crtc[1] << 1; } _dispofftime = disptime - _dispontime; - _dispontime *= CGACONST / 2; + _dispontime *= CGACONST / 2; _dispofftime *= CGACONST / 2; - ogc->cga.dispontime = (uint64_t)(_dispontime); - ogc->cga.dispofftime = (uint64_t)(_dispofftime); + ogc->cga.dispontime = (uint64_t) (_dispontime); + ogc->cga.dispofftime = (uint64_t) (_dispofftime); } void ogc_out(uint16_t addr, uint8_t val, void *priv) { - ogc_t *ogc = (ogc_t *)priv; + ogc_t *ogc = (ogc_t *) priv; - // if (addr >= 0x3c0 && addr <= 0x3cf){ - // addr = addr + 16; - // } + // if (addr >= 0x3c0 && addr <= 0x3cf){ + // addr = addr + 16; + // } switch (addr) { - case 0x3d4: - case 0x3d5: - case 0x3d8: - case 0x3d9: - cga_out(addr, val, &ogc->cga); - break; + case 0x3d4: + case 0x3d5: + case 0x3d8: + case 0x3d9: + cga_out(addr, val, &ogc->cga); + break; - case 0x3de: - /* set control register */ - ogc->ctrl_3de = val; - /* select 1st or 2nd 16k vram block to be used */ - ogc->base = (val & 0x08) ? 0x4000 : 0; - break; - } + case 0x3de: + /* set control register */ + ogc->ctrl_3de = val; + /* select 1st or 2nd 16k vram block to be used */ + ogc->base = (val & 0x08) ? 0x4000 : 0; + break; + } } uint8_t ogc_in(uint16_t addr, void *priv) { - ogc_t *ogc = (ogc_t *)priv; + ogc_t *ogc = (ogc_t *) priv; - // if (addr >= 0x3c0 && addr <= 0x3cf){ - // addr = addr + 16; - // } + // if (addr >= 0x3c0 && addr <= 0x3cf){ + // addr = addr + 16; + // } uint8_t ret = 0xff; switch (addr) { - case 0x3d4: - case 0x3d5: - case 0x3da: - /* - * bits 6-7: 3 = no DEB expansion board installed - * bits 4-5: 2 color, 3 mono - * bit 3: high during 1st half of vertical retrace in character mode (CCA standard) - * bit 2: lightpen switch (CGA standard) - * bit 1: lightpen strobe (CGA standard) - * bit 0: high during retrace (CGA standard) - */ - ret = cga_in(addr, &ogc->cga); - if (addr == 0x3da){ - ret = ret | 0xe0; - if (ogc->mono_display) - ret = ret | 0x10; - break; - } - } + case 0x3d4: + case 0x3d5: + case 0x3da: + /* + * bits 6-7: 3 = no DEB expansion board installed + * bits 4-5: 2 color, 3 mono + * bit 3: high during 1st half of vertical retrace in character mode (CCA standard) + * bit 2: lightpen switch (CGA standard) + * bit 1: lightpen strobe (CGA standard) + * bit 0: high during retrace (CGA standard) + */ + ret = cga_in(addr, &ogc->cga); + if (addr == 0x3da) { + ret = ret | 0xe0; + if (ogc->mono_display) + ret = ret | 0x10; + break; + } + } - return(ret); + return (ret); } - void ogc_waitstates(void *p) { - int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8}; + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; int ws; ws = ws_array[cycles & 0xf]; sub_cycles(ws); } - void ogc_write(uint32_t addr, uint8_t val, void *priv) { - ogc_t *ogc = (ogc_t *)priv; - int offset; + ogc_t *ogc = (ogc_t *) priv; + int offset; - ogc->cga.vram[addr & 0x7FFF]=val; - if (ogc->cga.snow_enabled) { - /* recreate snow effect */ - offset = ((timer_get_remaining_u64(&ogc->cga.timer) / CGACONST) * 4) & 0xfc; - ogc->cga.charbuffer[offset] = ogc->cga.vram[addr & 0x7fff]; - ogc->cga.charbuffer[offset | 1] = ogc->cga.vram[addr & 0x7fff]; - } + ogc->cga.vram[addr & 0x7FFF] = val; + if (ogc->cga.snow_enabled) { + /* recreate snow effect */ + offset = ((timer_get_remaining_u64(&ogc->cga.timer) / CGACONST) * 4) & 0xfc; + ogc->cga.charbuffer[offset] = ogc->cga.vram[addr & 0x7fff]; + ogc->cga.charbuffer[offset | 1] = ogc->cga.vram[addr & 0x7fff]; + } ogc_waitstates(&ogc->cga); } @@ -173,385 +167,381 @@ uint8_t ogc_read(uint32_t addr, void *priv) { - ogc_t *ogc = (ogc_t *)priv; - int offset; + ogc_t *ogc = (ogc_t *) priv; + int offset; - ogc_waitstates(&ogc->cga); + ogc_waitstates(&ogc->cga); - if (ogc->cga.snow_enabled) { - /* recreate snow effect */ - offset = ((timer_get_remaining_u64(&ogc->cga.timer) / CGACONST) * 4) & 0xfc; - ogc->cga.charbuffer[offset] = ogc->cga.vram[addr & 0x7fff]; - ogc->cga.charbuffer[offset | 1] = ogc->cga.vram[addr & 0x7fff]; - } + if (ogc->cga.snow_enabled) { + /* recreate snow effect */ + offset = ((timer_get_remaining_u64(&ogc->cga.timer) / CGACONST) * 4) & 0xfc; + ogc->cga.charbuffer[offset] = ogc->cga.vram[addr & 0x7fff]; + ogc->cga.charbuffer[offset | 1] = ogc->cga.vram[addr & 0x7fff]; + } - return(ogc->cga.vram[addr & 0x7FFF]); + return (ogc->cga.vram[addr & 0x7FFF]); } void ogc_poll(void *priv) { - ogc_t *ogc = (ogc_t *)priv; - uint16_t ca = (ogc->cga.crtc[15] | (ogc->cga.crtc[14] << 8)) & 0x3fff; - int drawcursor; - int x, c, xs_temp, ys_temp; - int oldvc; - uint8_t chr, attr; + ogc_t *ogc = (ogc_t *) priv; + uint16_t ca = (ogc->cga.crtc[15] | (ogc->cga.crtc[14] << 8)) & 0x3fff; + int drawcursor; + int x, c, xs_temp, ys_temp; + int oldvc; + uint8_t chr, attr; uint16_t dat, dat2; - int cols[4]; - int oldsc; - int blink = 0; - int underline = 0; - uint8_t border; + int cols[4]; + int oldsc; + int blink = 0; + int underline = 0; + uint8_t border; - //composito colore appare blu scuro + // composito colore appare blu scuro - /* graphic mode and not mode 40h */ - if (!(ogc->ctrl_3de & 0x1 || !(ogc->cga.cgamode & 2))) { - /* standard cga mode */ - cga_poll(&ogc->cga); - return; - } else { - /* mode 40h or text mode */ - if (!ogc->cga.linepos) { - timer_advance_u64(&ogc->cga.timer, ogc->cga.dispofftime); - ogc->cga.cgastat |= 1; - ogc->cga.linepos = 1; - oldsc = ogc->cga.sc; - if ((ogc->cga.crtc[8] & 3) == 3) - ogc->cga.sc = ((ogc->cga.sc << 1) + ogc->cga.oddeven) & 7; - if (ogc->cga.cgadispon) { - if (ogc->cga.displine < ogc->cga.firstline) { - ogc->cga.firstline = ogc->cga.displine; - video_wait_for_buffer(); - } - ogc->cga.lastline = ogc->cga.displine; - /* 80-col */ - if (ogc->cga.cgamode & 1) { - /* for each text column */ - for (x = 0; x < ogc->cga.crtc[1]; x++) { - /* video output enabled */ - if (ogc->cga.cgamode & 8) { - /* character */ - chr = ogc->cga.charbuffer[x << 1]; - /* text attributes */ - attr = ogc->cga.charbuffer[(x << 1) + 1]; - } else - chr = attr = 0; - /* check if cursor has to be drawn */ - drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron); - /* check if character underline mode should be set */ - underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6)); - if (underline) { - /* set forecolor to white */ - attr = attr | 0x7; - } - blink = 0; - /* set foreground */ - cols[1] = (attr & 15) + 16; - /* blink active */ - if (ogc->cga.cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - /* attribute 7 active and not cursor */ - if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) { - /* set blinking */ - cols[1] = cols[0]; - blink = 1; - } - } else { - /* Set intensity bit */ - cols[0] = (attr >> 4) + 16; - blink = (attr & 0x80) * 8 + 7 + 16; - } - /* character underline active and 7th row of pixels in character height being drawn */ - if (underline && (ogc->cga.sc == 7)) { - /* for each pixel in character width */ - for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; - } + /* graphic mode and not mode 40h */ + if (!(ogc->ctrl_3de & 0x1 || !(ogc->cga.cgamode & 2))) { + /* standard cga mode */ + cga_poll(&ogc->cga); + return; + } else { + /* mode 40h or text mode */ + if (!ogc->cga.linepos) { + timer_advance_u64(&ogc->cga.timer, ogc->cga.dispofftime); + ogc->cga.cgastat |= 1; + ogc->cga.linepos = 1; + oldsc = ogc->cga.sc; + if ((ogc->cga.crtc[8] & 3) == 3) + ogc->cga.sc = ((ogc->cga.sc << 1) + ogc->cga.oddeven) & 7; + if (ogc->cga.cgadispon) { + if (ogc->cga.displine < ogc->cga.firstline) { + ogc->cga.firstline = ogc->cga.displine; + video_wait_for_buffer(); + } + ogc->cga.lastline = ogc->cga.displine; + /* 80-col */ + if (ogc->cga.cgamode & 1) { + /* for each text column */ + for (x = 0; x < ogc->cga.crtc[1]; x++) { + /* video output enabled */ + if (ogc->cga.cgamode & 8) { + /* character */ + chr = ogc->cga.charbuffer[x << 1]; + /* text attributes */ + attr = ogc->cga.charbuffer[(x << 1) + 1]; + } else + chr = attr = 0; + /* check if cursor has to be drawn */ + drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron); + /* check if character underline mode should be set */ + underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6)); + if (underline) { + /* set forecolor to white */ + attr = attr | 0x7; + } + blink = 0; + /* set foreground */ + cols[1] = (attr & 15) + 16; + /* blink active */ + if (ogc->cga.cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + /* attribute 7 active and not cursor */ + if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + blink = 1; + } + } else { + /* Set intensity bit */ + cols[0] = (attr >> 4) + 16; + blink = (attr & 0x80) * 8 + 7 + 16; + } + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline && (ogc->cga.sc == 7)) { + /* for each pixel in character width */ + for (c = 0; c < 8; c++) + buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[ogc->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + } - ogc->cga.ma++; - } - } - /* 40-col */ - else if (!(ogc->cga.cgamode & 2)) { - for (x = 0; x < ogc->cga.crtc[1]; x++) { - if (ogc->cga.cgamode & 8) { - chr = ogc->cga.vram[((ogc->cga.ma << 1) & 0x3fff) + ogc->base]; - attr = ogc->cga.vram[(((ogc->cga.ma << 1) + 1) & 0x3fff) + ogc->base]; - } else { - chr = attr = 0; - } - drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron); - /* check if character underline mode should be set */ - underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6)); - if (underline) { - /* set forecolor to white */ - attr = attr | 0x7; - } - blink = 0; - /* set foreground */ - cols[1] = (attr & 15) + 16; - /* blink active */ - if (ogc->cga.cgamode & 0x20) { - cols[0] = ((attr >> 4) & 7) + 16; - if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) { - /* set blinking */ - cols[1] = cols[0]; - blink = 1; - } - } else { - /* Set intensity bit */ - cols[0] = (attr >> 4) + 16; - blink = (attr & 0x80) * 8 + 7 + 16; - } + ogc->cga.ma++; + } + } + /* 40-col */ + else if (!(ogc->cga.cgamode & 2)) { + for (x = 0; x < ogc->cga.crtc[1]; x++) { + if (ogc->cga.cgamode & 8) { + chr = ogc->cga.vram[((ogc->cga.ma << 1) & 0x3fff) + ogc->base]; + attr = ogc->cga.vram[(((ogc->cga.ma << 1) + 1) & 0x3fff) + ogc->base]; + } else { + chr = attr = 0; + } + drawcursor = ((ogc->cga.ma == ca) && ogc->cga.con && ogc->cga.cursoron); + /* check if character underline mode should be set */ + underline = ((ogc->ctrl_3de & 0x40) && (attr & 0x1) && !(attr & 0x6)); + if (underline) { + /* set forecolor to white */ + attr = attr | 0x7; + } + blink = 0; + /* set foreground */ + cols[1] = (attr & 15) + 16; + /* blink active */ + if (ogc->cga.cgamode & 0x20) { + cols[0] = ((attr >> 4) & 7) + 16; + if ((ogc->cga.cgablink & 8) && (attr & 0x80) && !ogc->cga.drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + blink = 1; + } + } else { + /* Set intensity bit */ + cols[0] = (attr >> 4) + 16; + blink = (attr & 0x80) * 8 + 7 + 16; + } + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline && (ogc->cga.sc == 7)) { + /* for each pixel in character width */ + for (c = 0; c < 8; c++) + buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; + } else { + for (c = 0; c < 8; c++) + buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; + } - /* character underline active and 7th row of pixels in character height being drawn */ - if (underline && (ogc->cga.sc == 7)) { - /* for each pixel in character width */ - for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = mdaattr[attr][blink][1]; - } else if (drawcursor) { - for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15; - } else { - for (c = 0; c < 8; c++) - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 8] = - buffer32->line[ogc->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((ogc->cga.sc & 7) << 1) | ogc->lineff] & (1 << (c ^ 7))) ? 1 : 0]; - } + ogc->cga.ma++; + } + } else { + /* 640x400 mode */ + if (ogc->ctrl_3de & 1) { + dat2 = ((ogc->cga.sc & 1) * 0x4000) | (ogc->lineff * 0x2000); + cols[0] = 0; + cols[1] = 15 + 16; + } else { + dat2 = (ogc->cga.sc & 1) * 0x2000; + cols[0] = 0; + cols[1] = (ogc->cga.cgacol & 15) + 16; + } - ogc->cga.ma++; + for (x = 0; x < ogc->cga.crtc[1]; x++) { + /* video out */ + if (ogc->cga.cgamode & 8) { + dat = (ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2] << 8) | ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2 + 1]; + } else { + dat = 0; + } + ogc->cga.ma++; - } - } else { - /* 640x400 mode */ - if (ogc->ctrl_3de & 1 ) { - dat2 = ((ogc->cga.sc & 1) * 0x4000) | (ogc->lineff * 0x2000); - cols[0] = 0; cols[1] = 15 + 16; - } - else { - dat2 = (ogc->cga.sc & 1) * 0x2000; - cols[0] = 0; cols[1] = (ogc->cga.cgacol & 15) + 16; - } + for (c = 0; c < 16; c++) { + buffer32->line[ogc->cga.displine][(x << 4) + c + 8] = cols[dat >> 15]; + dat <<= 1; + } + } + } + } else { - for (x = 0; x < ogc->cga.crtc[1]; x++) { - /* video out */ - if (ogc->cga.cgamode & 8) { - dat = (ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2] << 8) | ogc->cga.vram[((ogc->cga.ma << 1) & 0x1fff) + dat2 + 1]; - } else { - dat = 0; - } - ogc->cga.ma++; + /* ogc specific */ + cols[0] = ((ogc->cga.cgamode & 0x12) == 0x12) ? 0 : (ogc->cga.cgacol & 15) + 16; + if (ogc->cga.cgamode & 1) { + hline(buffer32, 0, (ogc->cga.displine << 1), ((ogc->cga.crtc[1] << 3) + 16) << 2, cols[0]); + hline(buffer32, 0, (ogc->cga.displine << 1) + 1, ((ogc->cga.crtc[1] << 3) + 16) << 2, cols[0]); + } else { + hline(buffer32, 0, (ogc->cga.displine << 1), ((ogc->cga.crtc[1] << 4) + 16) << 2, cols[0]); + hline(buffer32, 0, (ogc->cga.displine << 1) + 1, ((ogc->cga.crtc[1] << 4) + 16) << 2, cols[0]); + } + } - for (c = 0; c < 16; c++) { - buffer32->line[ogc->cga.displine][(x << 4) + c + 8] = cols[dat >> 15]; - dat <<= 1; - } - } - } - } else { + /* 80 columns */ + if (ogc->cga.cgamode & 1) + x = (ogc->cga.crtc[1] << 3) + 16; + else + x = (ogc->cga.crtc[1] << 4) + 16; - /* ogc specific */ - cols[0] = ((ogc->cga.cgamode & 0x12) == 0x12) ? 0 : (ogc->cga.cgacol & 15) + 16; - if (ogc->cga.cgamode & 1) { - hline(buffer32, 0, (ogc->cga.displine << 1), ((ogc->cga.crtc[1] << 3) + 16) << 2, cols[0]); - hline(buffer32, 0, (ogc->cga.displine << 1) + 1, ((ogc->cga.crtc[1] << 3) + 16) << 2, cols[0]); - } else { - hline(buffer32, 0, (ogc->cga.displine << 1), ((ogc->cga.crtc[1] << 4) + 16) << 2, cols[0]); - hline(buffer32, 0, (ogc->cga.displine << 1) + 1, ((ogc->cga.crtc[1] << 4) + 16) << 2, cols[0]); - } + if (ogc->cga.composite) { + if (ogc->cga.cgamode & 0x10) + border = 0x00; + else + border = ogc->cga.cgacol & 0x0f; - } + Composite_Process(ogc->cga.cgamode, border, x >> 2, buffer32->line[(ogc->cga.displine << 1)]); + Composite_Process(ogc->cga.cgamode, border, x >> 2, buffer32->line[(ogc->cga.displine << 1) + 1]); + } - /* 80 columns */ - if (ogc->cga.cgamode & 1) - x = (ogc->cga.crtc[1] << 3) + 16; - else - x = (ogc->cga.crtc[1] << 4) + 16; + ogc->cga.sc = oldsc; + if (ogc->cga.vc == ogc->cga.crtc[7] && !ogc->cga.sc) + ogc->cga.cgastat |= 8; + ogc->cga.displine++; + if (ogc->cga.displine >= 720) + ogc->cga.displine = 0; + } else { + timer_advance_u64(&ogc->cga.timer, ogc->cga.dispontime); + if (ogc->cga.cgadispon) + ogc->cga.cgastat &= ~1; + ogc->cga.linepos = 0; + /* ogc specific */ + ogc->lineff ^= 1; + if (ogc->lineff) { + ogc->cga.ma = ogc->cga.maback; + } else { + if (ogc->cga.vsynctime) { + ogc->cga.vsynctime--; + if (!ogc->cga.vsynctime) + ogc->cga.cgastat &= ~8; + } + if (ogc->cga.sc == (ogc->cga.crtc[11] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[11] & 31) >> 1))) { + ogc->cga.con = 0; + ogc->cga.coff = 1; + } + if ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1)) + ogc->cga.maback = ogc->cga.ma; + if (ogc->cga.vadj) { + ogc->cga.sc++; + ogc->cga.sc &= 31; + ogc->cga.ma = ogc->cga.maback; + ogc->cga.vadj--; + if (!ogc->cga.vadj) { + ogc->cga.cgadispon = 1; + ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff; + ogc->cga.sc = 0; + } + // potrebbe dare problemi con composito + } else if (ogc->cga.sc == ogc->cga.crtc[9] || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1))) { + ogc->cga.maback = ogc->cga.ma; + ogc->cga.sc = 0; + oldvc = ogc->cga.vc; + ogc->cga.vc++; + ogc->cga.vc &= 127; - if (ogc->cga.composite) { - if (ogc->cga.cgamode & 0x10) - border = 0x00; - else - border = ogc->cga.cgacol & 0x0f; + if (ogc->cga.vc == ogc->cga.crtc[6]) + ogc->cga.cgadispon = 0; - Composite_Process(ogc->cga.cgamode, border, x >> 2, buffer32->line[(ogc->cga.displine << 1)]); - Composite_Process(ogc->cga.cgamode, border, x >> 2, buffer32->line[(ogc->cga.displine << 1) + 1]); - } + if (oldvc == ogc->cga.crtc[4]) { + ogc->cga.vc = 0; + ogc->cga.vadj = ogc->cga.crtc[5]; + if (!ogc->cga.vadj) { + ogc->cga.cgadispon = 1; + ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff; + } + switch (ogc->cga.crtc[10] & 0x60) { + case 0x20: + ogc->cga.cursoron = 0; + break; + case 0x60: + ogc->cga.cursoron = ogc->cga.cgablink & 0x10; + break; + default: + ogc->cga.cursoron = ogc->cga.cgablink & 0x08; + break; + } + } + if (ogc->cga.vc == ogc->cga.crtc[7]) { + ogc->cga.cgadispon = 0; + ogc->cga.displine = 0; + /* ogc specific */ + ogc->cga.vsynctime = (ogc->cga.crtc[3] >> 4) + 1; + if (ogc->cga.crtc[7]) { + if (ogc->cga.cgamode & 1) + x = (ogc->cga.crtc[1] << 3) + 16; + else + x = (ogc->cga.crtc[1] << 4) + 16; + ogc->cga.lastline++; + xs_temp = x; + ys_temp = (ogc->cga.lastline - ogc->cga.firstline); - ogc->cga.sc = oldsc; - if (ogc->cga.vc == ogc->cga.crtc[7] && !ogc->cga.sc) - ogc->cga.cgastat |= 8; - ogc->cga.displine++; - if (ogc->cga.displine >= 720) - ogc->cga.displine = 0; - } else { - timer_advance_u64(&ogc->cga.timer, ogc->cga.dispontime); - if (ogc->cga.cgadispon) ogc->cga.cgastat &= ~1; - ogc->cga.linepos = 0; - /* ogc specific */ - ogc->lineff ^= 1; - if (ogc->lineff) { - ogc->cga.ma = ogc->cga.maback; - } else { - if (ogc->cga.vsynctime) { - ogc->cga.vsynctime--; - if (!ogc->cga.vsynctime) - ogc->cga.cgastat &= ~8; - } - if (ogc->cga.sc == (ogc->cga.crtc[11] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[11] & 31) >> 1))) { - ogc->cga.con = 0; - ogc->cga.coff = 1; - } - if ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1)) - ogc->cga.maback = ogc->cga.ma; - if (ogc->cga.vadj) { - ogc->cga.sc++; - ogc->cga.sc &= 31; - ogc->cga.ma = ogc->cga.maback; - ogc->cga.vadj--; - if (!ogc->cga.vadj) { - ogc->cga.cgadispon = 1; - ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff; - ogc->cga.sc = 0; - } - // potrebbe dare problemi con composito - } else if (ogc->cga.sc == ogc->cga.crtc[9] || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == (ogc->cga.crtc[9] >> 1))) { - ogc->cga.maback = ogc->cga.ma; - ogc->cga.sc = 0; - oldvc = ogc->cga.vc; - ogc->cga.vc++; - ogc->cga.vc &= 127; + if ((xs_temp > 0) && (ys_temp > 0)) { + if (xsize < 64) + xs_temp = 656; + /* ogc specific */ + if (ysize < 32) + ys_temp = 200; + if (!enable_overscan) + xs_temp -= 16; - if (ogc->cga.vc == ogc->cga.crtc[6]) - ogc->cga.cgadispon=0; + if ((ogc->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { + xsize = xs_temp; + ysize = ys_temp; + set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); - if (oldvc == ogc->cga.crtc[4]) { - ogc->cga.vc = 0; - ogc->cga.vadj = ogc->cga.crtc[5]; - if (!ogc->cga.vadj) { - ogc->cga.cgadispon = 1; - ogc->cga.ma = ogc->cga.maback = (ogc->cga.crtc[13] | (ogc->cga.crtc[12] << 8)) & 0x3fff; - } - switch (ogc->cga.crtc[10] & 0x60) { - case 0x20: - ogc->cga.cursoron = 0; - break; - case 0x60: - ogc->cga.cursoron = ogc->cga.cgablink & 0x10; - break; - default: - ogc->cga.cursoron = ogc->cga.cgablink & 0x08; - break; - } - } - if (ogc->cga.vc == ogc->cga.crtc[7]) { - ogc->cga.cgadispon = 0; - ogc->cga.displine = 0; - /* ogc specific */ - ogc->cga.vsynctime = (ogc->cga.crtc[3] >> 4) + 1; - if (ogc->cga.crtc[7]) { - if (ogc->cga.cgamode & 1) - x = (ogc->cga.crtc[1] << 3) + 16; - else - x = (ogc->cga.crtc[1] << 4) + 16; - ogc->cga.lastline++; + if (video_force_resize_get()) + video_force_resize_set(0); + } + /* ogc specific */ + if (enable_overscan) { + if (ogc->cga.composite) + video_blit_memtoscreen(0, (ogc->cga.firstline - 8), + xsize, (ogc->cga.lastline - ogc->cga.firstline) + 16); + else + video_blit_memtoscreen_8(0, (ogc->cga.firstline - 8), + xsize, (ogc->cga.lastline - ogc->cga.firstline) + 16); + } else { + if (ogc->cga.composite) + video_blit_memtoscreen(8, ogc->cga.firstline, + xsize, (ogc->cga.lastline - ogc->cga.firstline)); + else + video_blit_memtoscreen_8(8, ogc->cga.firstline, + xsize, (ogc->cga.lastline - ogc->cga.firstline)); + } + } + frames++; - xs_temp = x; - ys_temp = (ogc->cga.lastline - ogc->cga.firstline); + video_res_x = xsize; + video_res_y = ysize; + /* 80-col */ + if (ogc->cga.cgamode & 1) { + video_res_x /= 8; + video_res_y /= (ogc->cga.crtc[9] + 1) * 2; + video_bpp = 0; + /* 40-col */ + } else if (!(ogc->cga.cgamode & 2)) { + video_res_x /= 16; + video_res_y /= (ogc->cga.crtc[9] + 1) * 2; + video_bpp = 0; + } else if (!(ogc->ctrl_3de & 1)) { + video_res_y /= 2; + video_bpp = 1; + } + } + ogc->cga.firstline = 1000; + ogc->cga.lastline = 0; + ogc->cga.cgablink++; + ogc->cga.oddeven ^= 1; + } + } else { + ogc->cga.sc++; + ogc->cga.sc &= 31; + ogc->cga.ma = ogc->cga.maback; + } - if ((xs_temp > 0) && (ys_temp > 0)) { - if (xsize < 64) xs_temp = 656; - /* ogc specific */ - if (ysize < 32) ys_temp = 200; - if (!enable_overscan) - xs_temp -= 16; + if (ogc->cga.cgadispon) + ogc->cga.cgastat &= ~1; - - if ((ogc->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - xsize = xs_temp; - ysize = ys_temp; - set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0)); - - if (video_force_resize_get()) - video_force_resize_set(0); - } - /* ogc specific */ - if (enable_overscan) { - if (ogc->cga.composite) - video_blit_memtoscreen(0, (ogc->cga.firstline - 8), - xsize, (ogc->cga.lastline - ogc->cga.firstline) + 16); - else - video_blit_memtoscreen_8(0, (ogc->cga.firstline - 8), - xsize, (ogc->cga.lastline - ogc->cga.firstline) + 16); - } else { - if (ogc->cga.composite) - video_blit_memtoscreen(8, ogc->cga.firstline, - xsize, (ogc->cga.lastline - ogc->cga.firstline)); - else - video_blit_memtoscreen_8(8, ogc->cga.firstline, - xsize, (ogc->cga.lastline - ogc->cga.firstline)); - } - } - frames++; - - video_res_x = xsize; - video_res_y = ysize; - /* 80-col */ - if (ogc->cga.cgamode & 1) { - video_res_x /= 8; - video_res_y /= (ogc->cga.crtc[9] + 1) * 2; - video_bpp = 0; - /* 40-col */ - } else if (!(ogc->cga.cgamode & 2)) { - video_res_x /= 16; - video_res_y /= (ogc->cga.crtc[9] + 1) * 2; - video_bpp = 0; - } else if (!(ogc->ctrl_3de & 1)) { - video_res_y /= 2; - video_bpp = 1; - } - } - ogc->cga.firstline = 1000; - ogc->cga.lastline = 0; - ogc->cga.cgablink++; - ogc->cga.oddeven ^= 1; - } - } else { - ogc->cga.sc++; - ogc->cga.sc &= 31; - ogc->cga.ma = ogc->cga.maback; - } - - if (ogc->cga.cgadispon) - ogc->cga.cgastat &= ~1; - - if ((ogc->cga.sc == (ogc->cga.crtc[10] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[10] & 31) >> 1)))) - ogc->cga.con = 1; - } - /* 80-columns */ - if (ogc->cga.cgadispon && (ogc->cga.cgamode & 1)) { - for (x = 0; x < (ogc->cga.crtc[1] << 1); x++) - ogc->cga.charbuffer[x] = ogc->cga.vram[(((ogc->cga.ma << 1) + x) & 0x3fff) + ogc->base]; - } - } - } + if ((ogc->cga.sc == (ogc->cga.crtc[10] & 31) || ((ogc->cga.crtc[8] & 3) == 3 && ogc->cga.sc == ((ogc->cga.crtc[10] & 31) >> 1)))) + ogc->cga.con = 1; + } + /* 80-columns */ + if (ogc->cga.cgadispon && (ogc->cga.cgamode & 1)) { + for (x = 0; x < (ogc->cga.crtc[1] << 1); x++) + ogc->cga.charbuffer[x] = ogc->cga.vram[(((ogc->cga.ma << 1) + x) & 0x3fff) + ogc->base]; + } + } + } } void ogc_close(void *priv) { - ogc_t *ogc = (ogc_t *)priv; + ogc_t *ogc = (ogc_t *) priv; free(ogc->cga.vram); free(ogc); @@ -560,33 +550,36 @@ ogc_close(void *priv) void ogc_speed_changed(void *priv) { - ogc_t *ogc = (ogc_t *)priv; + ogc_t *ogc = (ogc_t *) priv; ogc_recalctimings(ogc); } void -ogc_mdaattr_rebuild(){ - int c; +ogc_mdaattr_rebuild() +{ + int c; - for (c = 0; c < 256; c++) { - mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; - if (c & 8) mdaattr[c][0][1] = 15 + 16; - else mdaattr[c][0][1] = 7 + 16; - } + for (c = 0; c < 256; c++) { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; + if (c & 8) + mdaattr[c][0][1] = 15 + 16; + else + mdaattr[c][0][1] = 7 + 16; + } - mdaattr[0x70][0][1] = 16; - mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; - mdaattr[0xF0][0][1] = 16; - mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; - mdaattr[0x78][0][1] = 16 + 7; - mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; - mdaattr[0xF8][0][1] = 16 + 7; - mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; - mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; - mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; - mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; - mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; + mdaattr[0x70][0][1] = 16; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; + mdaattr[0xF0][0][1] = 16; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; + mdaattr[0x78][0][1] = 16 + 7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; + mdaattr[0xF8][0][1] = 16 + 7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; } /* @@ -598,45 +591,45 @@ void * ogc_init(const device_t *info) { // int display_type; - ogc_t *ogc = (ogc_t *)malloc(sizeof(ogc_t)); + ogc_t *ogc = (ogc_t *) malloc(sizeof(ogc_t)); memset(ogc, 0x00, sizeof(ogc_t)); video_inform(VIDEO_FLAG_TYPE_CGA, &timing_ogc); loadfont("roms/video/ogc/ogc graphics board go380 258 pqbq.bin", 1); - /* composite is not working yet */ - // display_type = device_get_config_int("display_type"); - ogc->cga.composite = 0; // (display_type != CGA_RGB); - ogc->cga.revision = device_get_config_int("composite_type"); + /* composite is not working yet */ + // display_type = device_get_config_int("display_type"); + ogc->cga.composite = 0; // (display_type != CGA_RGB); + ogc->cga.revision = device_get_config_int("composite_type"); ogc->cga.snow_enabled = device_get_config_int("snow_enabled"); - ogc->cga.vram = malloc(0x8000); + ogc->cga.vram = malloc(0x8000); - cga_comp_init(ogc->cga.revision); + cga_comp_init(ogc->cga.revision); timer_add(&ogc->cga.timer, ogc_poll, ogc, 1); mem_mapping_add(&ogc->cga.mapping, 0xb8000, 0x08000, - ogc_read, NULL, NULL, - ogc_write, NULL, NULL, NULL, 0, ogc); + ogc_read, NULL, NULL, + ogc_write, NULL, NULL, NULL, 0, ogc); io_sethandler(0x03d0, 16, ogc_in, NULL, NULL, ogc_out, NULL, NULL, ogc); overscan_x = overscan_y = 16; - ogc->cga.rgb_type = device_get_config_int("rgb_type"); - cga_palette = (ogc->cga.rgb_type << 1); + ogc->cga.rgb_type = device_get_config_int("rgb_type"); + cga_palette = (ogc->cga.rgb_type << 1); cgapal_rebuild(); - ogc_mdaattr_rebuild(); + ogc_mdaattr_rebuild(); - /* color display */ - if (device_get_config_int("rgb_type")==0 || device_get_config_int("rgb_type") == 4) - ogc->mono_display = 0; - else - ogc->mono_display = 1; + /* color display */ + if (device_get_config_int("rgb_type") == 0 || device_get_config_int("rgb_type") == 4) + ogc->mono_display = 0; + else + ogc->mono_display = 1; return ogc; } const device_config_t ogc_m24_config[] = { -// clang-format off + // clang-format off { /* Olivetti / ATT compatible displays */ .name = "rgb_type", @@ -678,29 +671,29 @@ const device_config_t ogc_m24_config[] = { }; const device_t ogc_m24_device = { - .name = "Olivetti M21/M24/M28 (GO317/318/380/709) video card", + .name = "Olivetti M21/M24/M28 (GO317/318/380/709) video card", .internal_name = "ogc_m24", - .flags = DEVICE_ISA, - .local = 0, - .init = ogc_init, - .close = ogc_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = ogc_init, + .close = ogc_close, + .reset = NULL, { .available = NULL }, .speed_changed = ogc_speed_changed, - .force_redraw = NULL, - .config = ogc_m24_config + .force_redraw = NULL, + .config = ogc_m24_config }; -const device_t ogc_device = { - .name = "Olivetti OGC (GO708)", +const device_t ogc_device = { + .name = "Olivetti OGC (GO708)", .internal_name = "ogc", - .flags = DEVICE_ISA, - .local = 0, - .init = ogc_init, - .close = ogc_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = ogc_init, + .close = ogc_close, + .reset = NULL, { .available = NULL }, .speed_changed = ogc_speed_changed, - .force_redraw = NULL, - .config = cga_config + .force_redraw = NULL, + .config = cga_config }; diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 3ca44746c..134947c06 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -33,730 +33,752 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +typedef struct paradise_t { + svga_t svga; -typedef struct paradise_t -{ - svga_t svga; + rom_t bios_rom; - rom_t bios_rom; + uint8_t bank_mask; - uint8_t bank_mask; + enum { + PVGA1A = 0, + WD90C11, + WD90C30 + } type; - enum - { - PVGA1A = 0, - WD90C11, - WD90C30 - } type; + uint32_t vram_mask; - uint32_t vram_mask; + uint32_t read_bank[4], write_bank[4]; - uint32_t read_bank[4], write_bank[4]; + int interlace; + int check, check2; - int interlace; - int check, check2; + struct { + uint8_t reg_block_ptr; + uint8_t reg_idx; + uint8_t disable_autoinc; - struct { - uint8_t reg_block_ptr; - uint8_t reg_idx; - uint8_t disable_autoinc; + uint16_t int_status; + uint16_t blt_ctrl1, blt_ctrl2; + uint16_t srclow, srchigh; + uint16_t dstlow, dsthigh; - uint16_t int_status; - uint16_t blt_ctrl1, blt_ctrl2; - uint16_t srclow, srchigh; - uint16_t dstlow, dsthigh; + uint32_t srcaddr, dstaddr; - uint32_t srcaddr, dstaddr; - - int invalid_block; - } accel; + int invalid_block; + } accel; } paradise_t; -static video_timings_t timing_paradise_pvga1a = {VIDEO_ISA, 6, 8, 16, 6, 8, 16}; -static video_timings_t timing_paradise_wd90c = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; +static video_timings_t timing_paradise_pvga1a = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; +static video_timings_t timing_paradise_wd90c = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; void paradise_remap(paradise_t *paradise); -uint8_t paradise_in(uint16_t addr, void *p) +uint8_t +paradise_in(uint16_t addr, void *p) { - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; + paradise_t *paradise = (paradise_t *) p; + svga_t *svga = ¶dise->svga; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3c5: - if (svga->seqaddr > 7) - { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return 0xff; - if (svga->seqaddr > 0x12) - return 0xff; - return svga->seqregs[svga->seqaddr & 0x1f]; - } - break; + switch (addr) { + case 0x3c5: + if (svga->seqaddr > 7) { + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) + return 0xff; + if (svga->seqaddr > 0x12) + return 0xff; + return svga->seqregs[svga->seqaddr & 0x1f]; + } + break; - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (paradise->type == WD90C30) - return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); - return svga_in(addr, svga); + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (paradise->type == WD90C30) + return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga); + return svga_in(addr, svga); - case 0x3cf: - if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { - if (svga->gdcreg[0x0f] & 0x10) - return 0xff; - } - switch (svga->gdcaddr) { - case 0x0b: - if (paradise->type == WD90C30) { - if (paradise->vram_mask == ((512 << 10) - 1)) { - svga->gdcreg[0x0b] |= 0xc0; - svga->gdcreg[0x0b] &= ~0x40; - } - } - return svga->gdcreg[0x0b]; - - case 0x0f: - return (svga->gdcreg[0x0f] & 0x17) | 0x80; - } - break; - - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) - return 0xff; - if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) - return 0xff; - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - -void paradise_out(uint16_t addr, uint8_t val, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - uint8_t old; - - if (paradise->vram_mask <= ((512 << 10) - 1)) - paradise->bank_mask = 0x7f; - else - paradise->bank_mask = 0xff; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c5: - if (svga->seqaddr > 7) { - if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) - return; - svga->seqregs[svga->seqaddr & 0x1f] = val; - if (svga->seqaddr == 0x11) { - paradise_remap(paradise); - } - return; - } - break; - - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (paradise->type == WD90C30) - sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); - else - svga_out(addr, val, svga); - return; - - case 0x3cf: - if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { - if ((svga->gdcreg[0x0f] & 7) != 5) - return; - } - - switch (svga->gdcaddr) { - case 6: - if ((svga->gdcreg[6] & 0x0c) != (val & 0x0c)) { - switch (val & 0x0c) { - case 0x00: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x04: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x08: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0x0c: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - svga->gdcreg[6] = val; - paradise_remap(paradise); - return; - - case 9: - case 0x0a: - svga->gdcreg[svga->gdcaddr] = val & paradise->bank_mask; - paradise_remap(paradise); - return; - case 0x0b: - svga->gdcreg[0x0b] = val; - paradise_remap(paradise); - return; - } - break; - - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5) - return; - if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + case 0x3cf: + if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { + if (svga->gdcreg[0x0f] & 0x10) + return 0xff; + } + switch (svga->gdcaddr) { + case 0x0b: + if (paradise->type == WD90C30) { + if (paradise->vram_mask == ((512 << 10) - 1)) { + svga->gdcreg[0x0b] |= 0xc0; + svga->gdcreg[0x0b] &= ~0x40; } - } - break; + } + return svga->gdcreg[0x0b]; - case 0x46e8: - io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_disable(¶dise->svga.mapping); - if (val & 8) - { - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - mem_mapping_enable(¶dise->svga.mapping); + case 0x0f: + return (svga->gdcreg[0x0f] & 0x17) | 0x80; + } + break; + + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) + return 0xff; + if (svga->crtcreg > 0x29 && svga->crtcreg < 0x30 && (svga->crtc[0x29] & 0x88) != 0x80) + return 0xff; + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); +} + +void +paradise_out(uint16_t addr, uint8_t val, void *p) +{ + paradise_t *paradise = (paradise_t *) p; + svga_t *svga = ¶dise->svga; + uint8_t old; + + if (paradise->vram_mask <= ((512 << 10) - 1)) + paradise->bank_mask = 0x7f; + else + paradise->bank_mask = 0xff; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3c5: + if (svga->seqaddr > 7) { + if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48) + return; + svga->seqregs[svga->seqaddr & 0x1f] = val; + if (svga->seqaddr == 0x11) { + paradise_remap(paradise); } - break; + return; + } + break; + + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + if (paradise->type == WD90C30) + sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + return; + + case 0x3cf: + if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { + if ((svga->gdcreg[0x0f] & 7) != 5) + return; + } + + switch (svga->gdcaddr) { + case 6: + if ((svga->gdcreg[6] & 0x0c) != (val & 0x0c)) { + switch (val & 0x0c) { + case 0x00: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x04: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x08: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0x0c: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + svga->gdcreg[6] = val; + paradise_remap(paradise); + return; + + case 9: + case 0x0a: + svga->gdcreg[svga->gdcaddr] = val & paradise->bank_mask; + paradise_remap(paradise); + return; + case 0x0b: + svga->gdcreg[0x0b] = val; + paradise_remap(paradise); + return; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((paradise->type == PVGA1A) && (svga->crtcreg & 0x20)) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if (svga->crtcreg > 0x29 && (svga->crtc[0x29] & 7) != 5) + return; + if (svga->crtcreg >= 0x31 && svga->crtcreg <= 0x37) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + + case 0x46e8: + io_removehandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_disable(¶dise->svga.mapping); + if (val & 8) { + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + mem_mapping_enable(¶dise->svga.mapping); + } + break; + } + + svga_out(addr, val, svga); +} + +void +paradise_remap(paradise_t *paradise) +{ + svga_t *svga = ¶dise->svga; + paradise->check = 0; + + if (svga->seqregs[0x11] & 0x80) { + paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; + paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[0x0a] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } else if (svga->gdcreg[0x0b] & 0x08) { + if (svga->gdcreg[6] & 0x0c) { + paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[0x0a] << 12; + paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; + paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } else { + paradise->read_bank[0] = paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; + paradise->read_bank[1] = paradise->write_bank[1] = (svga->gdcreg[0xa] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->read_bank[2] = paradise->write_bank[2] = svga->gdcreg[9] << 12; + paradise->read_bank[3] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } + } else { + paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; + paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[9] << 12; + paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); + } - svga_out(addr, val, svga); + if ((((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4 && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[6] >> 2) & 3) == 1)) + paradise->check = 1; + + if (paradise->bank_mask == 0x7f) { + paradise->read_bank[1] &= 0x7ffff; + paradise->write_bank[1] &= 0x7ffff; + } } -void paradise_remap(paradise_t *paradise) +void +paradise_recalctimings(svga_t *svga) { - svga_t *svga = ¶dise->svga; - paradise->check = 0; + paradise_t *paradise = (paradise_t *) svga->p; - if (svga->seqregs[0x11] & 0x80) { - paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; - paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; - paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[0x0a] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } else if (svga->gdcreg[0x0b] & 0x08) { - if (svga->gdcreg[6] & 0x0c) { - paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[0x0a] << 12; - paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[0x0a] << 12; - paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } else { - paradise->read_bank[0] = paradise->write_bank[0] = svga->gdcreg[0x0a] << 12; - paradise->read_bank[1] = paradise->write_bank[1] = (svga->gdcreg[0xa] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->read_bank[2] = paradise->write_bank[2] = svga->gdcreg[9] << 12; - paradise->read_bank[3] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } - } else { - paradise->read_bank[0] = paradise->read_bank[2] = svga->gdcreg[9] << 12; - paradise->read_bank[1] = paradise->read_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - paradise->write_bank[0] = paradise->write_bank[2] = svga->gdcreg[9] << 12; - paradise->write_bank[1] = paradise->write_bank[3] = (svga->gdcreg[9] << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); - } + svga->lowres = !(svga->gdcreg[0x0e] & 0x01); - if ((((svga->gdcreg[0x0b] & 0xc0) == 0xc0) && !svga->chain4 && (svga->crtc[0x14] & 0x40) && ((svga->gdcreg[6] >> 2) & 3) == 1)) - paradise->check = 1; + if (paradise->type == WD90C30) { + if (svga->crtc[0x3e] & 0x01) + svga->vtotal |= 0x400; + if (svga->crtc[0x3e] & 0x02) + svga->dispend |= 0x400; + if (svga->crtc[0x3e] & 0x04) + svga->vsyncstart |= 0x400; + if (svga->crtc[0x3e] & 0x08) + svga->vblankstart |= 0x400; + if (svga->crtc[0x3e] & 0x10) + svga->split |= 0x400; - if (paradise->bank_mask == 0x7f) { - paradise->read_bank[1] &= 0x7ffff; - paradise->write_bank[1] &= 0x7ffff; - } + svga->interlace = !!(svga->crtc[0x2d] & 0x20); + + if (!svga->interlace && svga->lowres && (svga->hdisp >= 1024) && ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to + a windowed DOS box in Win3.x*/ + svga->interlace = 1; + } + } + + if (paradise->type < WD90C30) { + if (svga->bpp >= 8 && !svga->lowres) { + svga->render = svga_render_8bpp_highres; + } + } else { + if (svga->bpp >= 8 && !svga->lowres) { + if (svga->bpp == 16) { + svga->render = svga_render_16bpp_highres; + svga->hdisp >>= 1; + } else if (svga->bpp == 15) { + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + } else { + svga->render = svga_render_8bpp_highres; + } + } + } } -void paradise_recalctimings(svga_t *svga) +static void +paradise_write(uint32_t addr, uint8_t val, void *p) { - paradise_t *paradise = (paradise_t *) svga->p; + paradise_t *paradise = (paradise_t *) p; + svga_t *svga = ¶dise->svga; + uint32_t prev_addr, prev_addr2; - svga->lowres = !(svga->gdcreg[0x0e] & 0x01); + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - if (paradise->type == WD90C30) { - if (svga->crtc[0x3e] & 0x01) svga->vtotal |= 0x400; - if (svga->crtc[0x3e] & 0x02) svga->dispend |= 0x400; - if (svga->crtc[0x3e] & 0x04) svga->vsyncstart |= 0x400; - if (svga->crtc[0x3e] & 0x08) svga->vblankstart |= 0x400; - if (svga->crtc[0x3e] & 0x10) svga->split |= 0x400; + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } - svga->interlace = !!(svga->crtc[0x2d] & 0x20); + svga_write_linear(addr, val, svga); +} +static void +paradise_writew(uint32_t addr, uint16_t val, void *p) +{ + paradise_t *paradise = (paradise_t *) p; + svga_t *svga = ¶dise->svga; + uint32_t prev_addr, prev_addr2; - if (!svga->interlace && svga->lowres && (svga->hdisp >= 1024) && - ((svga->gdcreg[5] & 0x60) == 0) && (svga->miscout >= 0x27) && - (svga->miscout <= 0x2f) && ((svga->gdcreg[6] & 1) || - (svga->attrregs[0x10] & 1))) { /*Horrible tweak to re-enable the interlace after returning to - a windowed DOS box in Win3.x*/ - svga->interlace = 1; - } - } + addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; - if (paradise->type < WD90C30) { - if (svga->bpp >= 8 && !svga->lowres) { - svga->render = svga_render_8bpp_highres; - } - } else { - if (svga->bpp >= 8 && !svga->lowres) { - if (svga->bpp == 16) { - svga->render = svga_render_16bpp_highres; - svga->hdisp >>= 1; - } else if (svga->bpp == 15) { - svga->render = svga_render_15bpp_highres; - svga->hdisp >>= 1; - } else { - svga->render = svga_render_8bpp_highres; - } - } - } + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } + + svga_writew_linear(addr, val, svga); } -static void paradise_write(uint32_t addr, uint8_t val, void *p) +static uint8_t +paradise_read(uint32_t addr, void *p) { - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - uint32_t prev_addr, prev_addr2; + paradise_t *paradise = (paradise_t *) p; + svga_t *svga = ¶dise->svga; + uint32_t prev_addr, prev_addr2; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; - /*Could be done in a better way but it works.*/ - if (!svga->lowres) { - if (paradise->check) { - prev_addr = addr & 3; - prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } - } - } + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } - svga_write_linear(addr, val, svga); + return svga_read_linear(addr, svga); } -static void paradise_writew(uint32_t addr, uint16_t val, void *p) +static uint16_t +paradise_readw(uint32_t addr, void *p) { - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - uint32_t prev_addr, prev_addr2; + paradise_t *paradise = (paradise_t *) p; + svga_t *svga = ¶dise->svga; + uint32_t prev_addr, prev_addr2; - addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; + addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; - /*Could be done in a better way but it works.*/ - if (!svga->lowres) { - if (paradise->check) { - prev_addr = addr & 3; - prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } - } - } + /*Could be done in a better way but it works.*/ + if (!svga->lowres) { + if (paradise->check) { + prev_addr = addr & 3; + prev_addr2 = addr & 0xfffc; + if ((addr & 3) == 3) { + if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 2) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 1) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x00000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } else if ((addr & 3) == 0) { + if ((addr & 0x30000) == 0x30000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x20000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + else if ((addr & 0x30000) == 0x10000) + addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; + } + } + } - svga_writew_linear(addr, val, svga); + return svga_readw_linear(addr, svga); } -static uint8_t paradise_read(uint32_t addr, void *p) +void * +paradise_init(const device_t *info, uint32_t memsize) { - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - uint32_t prev_addr, prev_addr2; + paradise_t *paradise = malloc(sizeof(paradise_t)); + svga_t *svga = ¶dise->svga; + memset(paradise, 0, sizeof(paradise_t)); - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + if (info->local == PVGA1A) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_paradise_pvga1a); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_paradise_wd90c); - /*Could be done in a better way but it works.*/ - if (!svga->lowres) { - if (paradise->check) { - prev_addr = addr & 3; - prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } - } - } + switch (info->local) { + case PVGA1A: + svga_init(info, svga, paradise, memsize, /*256kb*/ + paradise_recalctimings, + paradise_in, paradise_out, + NULL, + NULL); + paradise->vram_mask = memsize - 1; + svga->decode_mask = memsize - 1; + break; + case WD90C11: + svga_init(info, svga, paradise, 1 << 19, /*512kb*/ + paradise_recalctimings, + paradise_in, paradise_out, + NULL, + NULL); + paradise->vram_mask = (1 << 19) - 1; + svga->decode_mask = (1 << 19) - 1; + break; + case WD90C30: + svga_init(info, svga, paradise, memsize, + paradise_recalctimings, + paradise_in, paradise_out, + NULL, + NULL); + paradise->vram_mask = memsize - 1; + svga->decode_mask = memsize - 1; + svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/ + break; + } - return svga_read_linear(addr, svga); -} -static uint16_t paradise_readw(uint32_t addr, void *p) -{ - paradise_t *paradise = (paradise_t *)p; - svga_t *svga = ¶dise->svga; - uint32_t prev_addr, prev_addr2; + mem_mapping_set_handler(&svga->mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); + mem_mapping_set_p(&svga->mapping, paradise); - addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; + io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - /*Could be done in a better way but it works.*/ - if (!svga->lowres) { - if (paradise->check) { - prev_addr = addr & 3; - prev_addr2 = addr & 0xfffc; - if ((addr & 3) == 3) { - if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 2) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 1) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x00000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } else if ((addr & 3) == 0) { - if ((addr & 0x30000) == 0x30000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x20000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - else if ((addr & 0x30000) == 0x10000) - addr = (addr >> 16) | (prev_addr << 16) | prev_addr2; - } - } - } + /* Common to all three types. */ + svga->crtc[0x31] = 'W'; + svga->crtc[0x32] = 'D'; + svga->crtc[0x33] = '9'; + svga->crtc[0x34] = '0'; + svga->crtc[0x35] = 'C'; - return svga_readw_linear(addr, svga); + switch (info->local) { + case WD90C11: + svga->crtc[0x36] = '1'; + svga->crtc[0x37] = '1'; + io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); + break; + case WD90C30: + svga->crtc[0x36] = '3'; + svga->crtc[0x37] = '0'; + break; + } + + svga->bpp = 8; + svga->miscout = 1; + + paradise->type = info->local; + + return paradise; } -void *paradise_init(const device_t *info, uint32_t memsize) +static void * +paradise_pvga1a_ncr3302_init(const device_t *info) { - paradise_t *paradise = malloc(sizeof(paradise_t)); - svga_t *svga = ¶dise->svga; - memset(paradise, 0, sizeof(paradise_t)); + paradise_t *paradise = paradise_init(info, 1 << 18); - if (info->local == PVGA1A) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_paradise_pvga1a); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_paradise_wd90c); + if (paradise) + rom_init(¶dise->bios_rom, "roms/machines/3302/c000-wd_1987-1989-740011-003058-019c.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - switch(info->local) { - case PVGA1A: - svga_init(info, svga, paradise, memsize, /*256kb*/ - paradise_recalctimings, - paradise_in, paradise_out, - NULL, - NULL); - paradise->vram_mask = memsize - 1; - svga->decode_mask = memsize - 1; - break; - case WD90C11: - svga_init(info, svga, paradise, 1 << 19, /*512kb*/ - paradise_recalctimings, - paradise_in, paradise_out, - NULL, - NULL); - paradise->vram_mask = (1 << 19) - 1; - svga->decode_mask = (1 << 19) - 1; - break; - case WD90C30: - svga_init(info, svga, paradise, memsize, - paradise_recalctimings, - paradise_in, paradise_out, - NULL, - NULL); - paradise->vram_mask = memsize - 1; - svga->decode_mask = memsize - 1; - svga->ramdac = device_add(&sc11487_ramdac_device); /*Actually a Winbond W82c487-80, probably a clone.*/ - break; - } - - mem_mapping_set_handler(&svga->mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL); - mem_mapping_set_p(&svga->mapping, paradise); - - io_sethandler(0x03c0, 0x0020, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - - /* Common to all three types. */ - svga->crtc[0x31] = 'W'; - svga->crtc[0x32] = 'D'; - svga->crtc[0x33] = '9'; - svga->crtc[0x34] = '0'; - svga->crtc[0x35] = 'C'; - - switch(info->local) { - case WD90C11: - svga->crtc[0x36] = '1'; - svga->crtc[0x37] = '1'; - io_sethandler(0x46e8, 0x0001, paradise_in, NULL, NULL, paradise_out, NULL, NULL, paradise); - break; - case WD90C30: - svga->crtc[0x36] = '3'; - svga->crtc[0x37] = '0'; - break; - } - - svga->bpp = 8; - svga->miscout = 1; - - paradise->type = info->local; - - return paradise; + return paradise; } -static void *paradise_pvga1a_ncr3302_init(const device_t *info) +static void * +paradise_pvga1a_pc2086_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 1 << 18); - if (paradise) - rom_init(¶dise->bios_rom, "roms/machines/3302/c000-wd_1987-1989-740011-003058-019c.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (paradise) + rom_init(¶dise->bios_rom, "roms/machines/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return paradise; + return paradise; } -static void *paradise_pvga1a_pc2086_init(const device_t *info) +static void * +paradise_pvga1a_pc3086_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise = paradise_init(info, 1 << 18); - if (paradise) - rom_init(¶dise->bios_rom, "roms/machines/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (paradise) + rom_init(¶dise->bios_rom, "roms/machines/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return paradise; + return paradise; } -static void *paradise_pvga1a_pc3086_init(const device_t *info) +static void * +paradise_pvga1a_standalone_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 1 << 18); + paradise_t *paradise; + uint32_t memory = 512; - if (paradise) - rom_init(¶dise->bios_rom, "roms/machines/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + memory = device_get_config_int("memory"); + memory <<= 10; - return paradise; + paradise = paradise_init(info, memory); + + if (paradise) + rom_init(¶dise->bios_rom, "roms/video/pvga1a/BIOS.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + return paradise; } -static void *paradise_pvga1a_standalone_init(const device_t *info) +static int +paradise_pvga1a_standalone_available(void) { - paradise_t *paradise; - uint32_t memory = 512; - - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_init(info, memory); - - if (paradise) - rom_init(¶dise->bios_rom, "roms/video/pvga1a/BIOS.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; + return rom_present("roms/video/pvga1a/BIOS.BIN"); } -static int paradise_pvga1a_standalone_available(void) +static void * +paradise_wd90c11_megapc_init(const device_t *info) { - return rom_present("roms/video/pvga1a/BIOS.BIN"); + paradise_t *paradise = paradise_init(info, 0); + + if (paradise) + rom_init_interleaved(¶dise->bios_rom, + "roms/machines/megapc/41651-bios lo.u18", + "roms/machines/megapc/211253-bios hi.u19", + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + return paradise; } -static void *paradise_wd90c11_megapc_init(const device_t *info) +static void * +paradise_wd90c11_standalone_init(const device_t *info) { - paradise_t *paradise = paradise_init(info, 0); + paradise_t *paradise = paradise_init(info, 0); - if (paradise) - rom_init_interleaved(¶dise->bios_rom, - "roms/machines/megapc/41651-bios lo.u18", - "roms/machines/megapc/211253-bios hi.u19", - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (paradise) + rom_init(¶dise->bios_rom, "roms/video/wd90c11/WD90C11.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return paradise; + return paradise; } -static void *paradise_wd90c11_standalone_init(const device_t *info) +static int +paradise_wd90c11_standalone_available(void) { - paradise_t *paradise = paradise_init(info, 0); - - if (paradise) - rom_init(¶dise->bios_rom, "roms/video/wd90c11/WD90C11.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; + return rom_present("roms/video/wd90c11/WD90C11.VBI"); } -static int paradise_wd90c11_standalone_available(void) +static void * +paradise_wd90c30_standalone_init(const device_t *info) { - return rom_present("roms/video/wd90c11/WD90C11.VBI"); + paradise_t *paradise; + uint32_t memory = 512; + + memory = device_get_config_int("memory"); + memory <<= 10; + + paradise = paradise_init(info, memory); + + if (paradise) + rom_init(¶dise->bios_rom, "roms/video/wd90c30/90C30-LR.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + return paradise; } -static void *paradise_wd90c30_standalone_init(const device_t *info) +static int +paradise_wd90c30_standalone_available(void) { - paradise_t *paradise; - uint32_t memory = 512; - - memory = device_get_config_int("memory"); - memory <<= 10; - - paradise = paradise_init(info, memory); - - if (paradise) - rom_init(¶dise->bios_rom, "roms/video/wd90c30/90C30-LR.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; + return rom_present("roms/video/wd90c30/90C30-LR.VBI"); } -static int paradise_wd90c30_standalone_available(void) +void +paradise_close(void *p) { - return rom_present("roms/video/wd90c30/90C30-LR.VBI"); + paradise_t *paradise = (paradise_t *) p; + + svga_close(¶dise->svga); + + free(paradise); } -void paradise_close(void *p) +void +paradise_speed_changed(void *p) { - paradise_t *paradise = (paradise_t *)p; + paradise_t *paradise = (paradise_t *) p; - svga_close(¶dise->svga); - - free(paradise); + svga_recalctimings(¶dise->svga); } -void paradise_speed_changed(void *p) +void +paradise_force_redraw(void *p) { - paradise_t *paradise = (paradise_t *)p; + paradise_t *paradise = (paradise_t *) p; - svga_recalctimings(¶dise->svga); -} - -void paradise_force_redraw(void *p) -{ - paradise_t *paradise = (paradise_t *)p; - - paradise->svga.fullchange = changeframecount; + paradise->svga.fullchange = changeframecount; } const device_t paradise_pvga1a_pc2086_device = { - .name = "Paradise PVGA1A (Amstrad PC2086)", + .name = "Paradise PVGA1A (Amstrad PC2086)", .internal_name = "pvga1a_pc2086", - .flags = 0, - .local = PVGA1A, - .init = paradise_pvga1a_pc2086_init, - .close = paradise_close, - .reset = NULL, + .flags = 0, + .local = PVGA1A, + .init = paradise_pvga1a_pc2086_init, + .close = paradise_close, + .reset = NULL, { .available = NULL }, .speed_changed = paradise_speed_changed, - .force_redraw = paradise_force_redraw, - .config = NULL + .force_redraw = paradise_force_redraw, + .config = NULL }; const device_t paradise_pvga1a_pc3086_device = { - .name = "Paradise PVGA1A (Amstrad PC3086)", + .name = "Paradise PVGA1A (Amstrad PC3086)", .internal_name = "pvga1a_pc3086", - .flags = 0, - .local = PVGA1A, - .init = paradise_pvga1a_pc3086_init, - .close = paradise_close, - .reset = NULL, + .flags = 0, + .local = PVGA1A, + .init = paradise_pvga1a_pc3086_init, + .close = paradise_close, + .reset = NULL, { .available = NULL }, .speed_changed = paradise_speed_changed, - .force_redraw = paradise_force_redraw, - .config = NULL + .force_redraw = paradise_force_redraw, + .config = NULL }; static const device_config_t paradise_pvga1a_config[] = { + // clang-format off { .name = "memory", .description = "Memory size", @@ -779,66 +801,67 @@ static const device_config_t paradise_pvga1a_config[] = { { .type = CONFIG_END } + // clang-format on }; const device_t paradise_pvga1a_ncr3302_device = { - .name = "Paradise PVGA1A (NCR 3302)", + .name = "Paradise PVGA1A (NCR 3302)", .internal_name = "pvga1a_ncr3302", - .flags = 0, - .local = PVGA1A, - .init = paradise_pvga1a_ncr3302_init, - .close = paradise_close, - .reset = NULL, + .flags = 0, + .local = PVGA1A, + .init = paradise_pvga1a_ncr3302_init, + .close = paradise_close, + .reset = NULL, { .available = NULL }, .speed_changed = paradise_speed_changed, - .force_redraw = paradise_force_redraw, - .config = paradise_pvga1a_config + .force_redraw = paradise_force_redraw, + .config = paradise_pvga1a_config }; const device_t paradise_pvga1a_device = { - .name = "Paradise PVGA1A", + .name = "Paradise PVGA1A", .internal_name = "pvga1a", - .flags = DEVICE_ISA, - .local = PVGA1A, - .init = paradise_pvga1a_standalone_init, - .close = paradise_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = PVGA1A, + .init = paradise_pvga1a_standalone_init, + .close = paradise_close, + .reset = NULL, { .available = paradise_pvga1a_standalone_available }, .speed_changed = paradise_speed_changed, - .force_redraw = paradise_force_redraw, - .config = paradise_pvga1a_config + .force_redraw = paradise_force_redraw, + .config = paradise_pvga1a_config }; const device_t paradise_wd90c11_megapc_device = { - .name = "Paradise WD90C11 (Amstrad MegaPC)", + .name = "Paradise WD90C11 (Amstrad MegaPC)", .internal_name = "wd90c11_megapc", - .flags = 0, - .local = WD90C11, - .init = paradise_wd90c11_megapc_init, - .close = paradise_close, - .reset = NULL, + .flags = 0, + .local = WD90C11, + .init = paradise_wd90c11_megapc_init, + .close = paradise_close, + .reset = NULL, { .available = NULL }, .speed_changed = paradise_speed_changed, - .force_redraw = paradise_force_redraw, - .config = NULL + .force_redraw = paradise_force_redraw, + .config = NULL }; const device_t paradise_wd90c11_device = { - .name = "Paradise WD90C11-LR", + .name = "Paradise WD90C11-LR", .internal_name = "wd90c11", - .flags = DEVICE_ISA, - .local = WD90C11, - .init = paradise_wd90c11_standalone_init, - .close = paradise_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = WD90C11, + .init = paradise_wd90c11_standalone_init, + .close = paradise_close, + .reset = NULL, { .available = paradise_wd90c11_standalone_available }, .speed_changed = paradise_speed_changed, - .force_redraw = paradise_force_redraw, - .config = NULL + .force_redraw = paradise_force_redraw, + .config = NULL }; static const device_config_t paradise_wd90c30_config[] = { -// clang-format off + // clang-format off { .name = "memory", .description = "Memory size", @@ -865,15 +888,15 @@ static const device_config_t paradise_wd90c30_config[] = { }; const device_t paradise_wd90c30_device = { - .name = "Paradise WD90C30-LR", + .name = "Paradise WD90C30-LR", .internal_name = "wd90c30", - .flags = DEVICE_ISA, - .local = WD90C30, - .init = paradise_wd90c30_standalone_init, - .close = paradise_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = WD90C30, + .init = paradise_wd90c30_standalone_init, + .close = paradise_close, + .reset = NULL, { .available = paradise_wd90c30_standalone_available }, .speed_changed = paradise_speed_changed, - .force_redraw = paradise_force_redraw, - .config = paradise_wd90c30_config + .force_redraw = paradise_force_redraw, + .config = paradise_wd90c30_config }; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index d810536b3..dddbaee45 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -92,15 +92,13 @@ #include <86box/vid_cga.h> #include <86box/vid_pgc.h> +#define PGC_CGA_WIDTH 640 +#define PGC_CGA_HEIGHT 400 -#define PGC_CGA_WIDTH 640 -#define PGC_CGA_HEIGHT 400 - -#define HWORD(u) ((u) >> 16) -#define LWORD(u) ((u) & 0xffff) - -#define WAKE_DELAY (TIMER_USEC * 500) +#define HWORD(u) ((u) >> 16) +#define LWORD(u) ((u) &0xffff) +#define WAKE_DELAY (TIMER_USEC * 500) static const char *pgc_err_msgs[] = { "Range \r", @@ -117,43 +115,37 @@ static const char *pgc_err_msgs[] = { "Unknown \r" }; - /* Initial palettes */ static const uint32_t init_palette[6][256] = { #include <86box/vid_pgc_palette.h> }; - -static video_timings_t timing_pgc = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; - +static video_timings_t timing_pgc = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; #ifdef ENABLE_PGC_LOG int pgc_do_log = ENABLE_PGC_LOG; - static void pgc_log(const char *fmt, ...) { va_list ap; if (pgc_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define pgc_log(fmt, ...) +# define pgc_log(fmt, ...) #endif - static inline int is_whitespace(char ch) { return (ch != 0 && strchr(" \r\n\t,;()+-", ch) != NULL); } - /* * Write a byte to the output buffer. * @@ -164,56 +156,55 @@ static int output_byte(pgc_t *dev, uint8_t val) { /* If output buffer full, wait for it to empty. */ - while (!dev->stopped && dev->mapram[0x302] == (uint8_t)(dev->mapram[0x303] - 1)) { - pgc_log("PGC: output buffer state: %02x %02x Sleeping\n", - dev->mapram[0x302], dev->mapram[0x303]); - dev->waiting_output_fifo = 1; - pgc_sleep(dev); + while (!dev->stopped && dev->mapram[0x302] == (uint8_t) (dev->mapram[0x303] - 1)) { + pgc_log("PGC: output buffer state: %02x %02x Sleeping\n", + dev->mapram[0x302], dev->mapram[0x303]); + dev->waiting_output_fifo = 1; + pgc_sleep(dev); } if (dev->mapram[0x3ff]) { - /* Reset triggered. */ - pgc_reset(dev); - return 0; + /* Reset triggered. */ + pgc_reset(dev); + return 0; } dev->mapram[0x100 + dev->mapram[0x302]] = val; dev->mapram[0x302]++; pgc_log("PGC: output %02x: new state: %02x %02x\n", val, - dev->mapram[0x302], dev->mapram[0x303]); + dev->mapram[0x302], dev->mapram[0x303]); return 1; } - /* Helper to write an entire string to the output buffer. */ static int output_string(pgc_t *dev, const char *s) { while (*s) { - if (! output_byte(dev, *s)) return 0; - s++; + if (!output_byte(dev, *s)) + return 0; + s++; } return 1; } - /* As output_byte, for the error buffer. */ static int error_byte(pgc_t *dev, uint8_t val) { /* If error buffer full, wait for it to empty. */ while (!dev->stopped && dev->mapram[0x304] == dev->mapram[0x305] - 1) { - dev->waiting_error_fifo = 1; - pgc_sleep(dev); + dev->waiting_error_fifo = 1; + pgc_sleep(dev); } if (dev->mapram[0x3ff]) { - /* Reset triggered. */ - pgc_reset(dev); - return 0; + /* Reset triggered. */ + pgc_reset(dev); + return 0; } dev->mapram[0x200 + dev->mapram[0x304]] = val; @@ -222,20 +213,19 @@ error_byte(pgc_t *dev, uint8_t val) return 1; } - /* As output_string, for the error buffer. */ static int error_string(pgc_t *dev, const char *s) { while (*s) { - if (! error_byte(dev, *s)) return 0; - s++; + if (!error_byte(dev, *s)) + return 0; + s++; } return 1; } - /* * Read next byte from the input buffer. * @@ -247,17 +237,17 @@ input_byte(pgc_t *dev, uint8_t *result) { /* If input buffer empty, wait for it to fill. */ while (!dev->stopped && (dev->mapram[0x300] == dev->mapram[0x301])) { - dev->waiting_input_fifo = 1; - pgc_sleep(dev); + dev->waiting_input_fifo = 1; + pgc_sleep(dev); } if (dev->stopped) - return 0; + return 0; if (dev->mapram[0x3ff]) { - /* Reset triggered. */ - pgc_reset(dev); - return 0; + /* Reset triggered. */ + pgc_reset(dev); + return 0; } *result = dev->mapram[dev->mapram[0x301]]; @@ -266,7 +256,6 @@ input_byte(pgc_t *dev, uint8_t *result) return 1; } - /* * Read a byte and interpret as ASCII. * @@ -278,17 +267,17 @@ input_char(pgc_t *dev, char *result) uint8_t ch; while (1) { - if (! dev->inputbyte(dev, &ch)) return 0; + if (!dev->inputbyte(dev, &ch)) + return 0; - ch &= 0x7f; - if (ch == '\r' || ch == '\n' || ch == '\t' || ch >= ' ') { - *result = toupper(ch); - return 1; - } + ch &= 0x7f; + if (ch == '\r' || ch == '\n' || ch == '\t' || ch >= ' ') { + *result = toupper(ch); + return 1; + } } } - /* * Read in the next command. * @@ -298,53 +287,54 @@ static int read_command(pgc_t *dev) { if (dev->stopped) - return 0; + return 0; if (dev->clcur) - return pgc_clist_byte(dev, &dev->hex_command); + return pgc_clist_byte(dev, &dev->hex_command); if (dev->ascii_mode) { - char ch; - int count = 0; + char ch; + int count = 0; - while (count < 7) { - if (dev->stopped) return 0; + while (count < 7) { + if (dev->stopped) + return 0; - if (! input_char(dev, &ch)) return 0; + if (!input_char(dev, &ch)) + return 0; - if (is_whitespace(ch)) { - /* Pad to 6 characters */ - while (count < 6) - dev->asc_command[count++] = ' '; - dev->asc_command[6] = 0; + if (is_whitespace(ch)) { + /* Pad to 6 characters */ + while (count < 6) + dev->asc_command[count++] = ' '; + dev->asc_command[6] = 0; - return 1; - } - dev->asc_command[count++] = toupper(ch); - } + return 1; + } + dev->asc_command[count++] = toupper(ch); + } - return 1; + return 1; } return dev->inputbyte(dev, &dev->hex_command); } - /* Read in the next command and parse it. */ static int parse_command(pgc_t *dev, const pgc_cmd_t **pcmd) { const pgc_cmd_t *cmd; - char match[7]; + char match[7]; - *pcmd = NULL; + *pcmd = NULL; dev->hex_command = 0; memset(dev->asc_command, ' ', 6); dev->asc_command[6] = 0; - if (! read_command(dev)) { - /* PGC has been reset. */ - return 0; + if (!read_command(dev)) { + /* PGC has been reset. */ + return 0; } /* @@ -354,32 +344,31 @@ parse_command(pgc_t *dev, const pgc_cmd_t **pcmd) * or the core list (terminated with '@') */ for (cmd = dev->commands; cmd->ascii[0] != '@'; cmd++) { - /* End of subclass command list, chain to core. */ - if (cmd->ascii[0] == '*') - cmd = dev->master; + /* End of subclass command list, chain to core. */ + if (cmd->ascii[0] == '*') + cmd = dev->master; - /* If in ASCII mode match on the ASCII command. */ - if (dev->ascii_mode && !dev->clcur) { - sprintf(match, "%-6.6s", cmd->ascii); - if (! strncmp(match, dev->asc_command, 6)) { - *pcmd = cmd; - dev->hex_command = cmd->hex; - break; - } - } else { - /* Otherwise match on the hex command. */ - if (cmd->hex == dev->hex_command) { - sprintf(dev->asc_command, "%-6.6s", cmd->ascii); - *pcmd = cmd; - break; - } - } + /* If in ASCII mode match on the ASCII command. */ + if (dev->ascii_mode && !dev->clcur) { + sprintf(match, "%-6.6s", cmd->ascii); + if (!strncmp(match, dev->asc_command, 6)) { + *pcmd = cmd; + dev->hex_command = cmd->hex; + break; + } + } else { + /* Otherwise match on the hex command. */ + if (cmd->hex == dev->hex_command) { + sprintf(dev->asc_command, "%-6.6s", cmd->ascii); + *pcmd = cmd; + break; + } + } } return 1; } - /* * Beginning of a command list. * @@ -390,48 +379,47 @@ static void hndl_clbeg(pgc_t *dev) { const pgc_cmd_t *cmd; - uint8_t param = 0; - pgc_cl_t cl; + uint8_t param = 0; + pgc_cl_t cl; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; pgc_log("PGC: CLBEG(%i)\n", param); memset(&cl, 0x00, sizeof(pgc_cl_t)); while (1) { - if (! parse_command(dev, &cmd)) { - /* PGC has been reset. */ - return; - } - if (!cmd) { - pgc_error(dev, PGC_ERROR_OPCODE); - return; - } else if (dev->hex_command == 0x71) { - /* CLEND */ - dev->clist[param] = cl; - return; - } else { - if (! pgc_cl_append(&cl, dev->hex_command)) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - return; - } + if (!parse_command(dev, &cmd)) { + /* PGC has been reset. */ + return; + } + if (!cmd) { + pgc_error(dev, PGC_ERROR_OPCODE); + return; + } else if (dev->hex_command == 0x71) { + /* CLEND */ + dev->clist[param] = cl; + return; + } else { + if (!pgc_cl_append(&cl, dev->hex_command)) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + return; + } - if (cmd->parser) { - if (! (*cmd->parser)(dev, &cl, cmd->p)) - return; - } - } + if (cmd->parser) { + if (!(*cmd->parser)(dev, &cl, cmd->p)) + return; + } + } } } - static void hndl_clend(pgc_t *dev) { /* Should not happen outside a CLBEG. */ } - /* * Execute a command list. * @@ -442,90 +430,91 @@ static void hndl_clrun(pgc_t *dev) { pgc_cl_t *clprev = dev->clcur; - uint8_t param = 0; + uint8_t param = 0; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; - dev->clcur = &dev->clist[param]; - dev->clcur->rdptr = 0; + dev->clcur = &dev->clist[param]; + dev->clcur->rdptr = 0; dev->clcur->repeat = 1; - dev->clcur->chain = clprev; + dev->clcur->chain = clprev; } - /* Execute a command list multiple times. */ static void hndl_cloop(pgc_t *dev) { pgc_cl_t *clprev = dev->clcur; - uint8_t param = 0; - int16_t repeat = 0; + uint8_t param = 0; + int16_t repeat = 0; - if (! pgc_param_byte(dev, ¶m)) return; - if (! pgc_param_word(dev, &repeat)) return; + if (!pgc_param_byte(dev, ¶m)) + return; + if (!pgc_param_word(dev, &repeat)) + return; - dev->clcur = &dev->clist[param]; - dev->clcur->rdptr = 0; + dev->clcur = &dev->clist[param]; + dev->clcur->rdptr = 0; dev->clcur->repeat = repeat; - dev->clcur->chain = clprev; + dev->clcur->chain = clprev; } - /* Read back a command list. */ static void hndl_clread(pgc_t *dev) { - uint8_t param = 0; + uint8_t param = 0; uint32_t n; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; for (n = 0; n < dev->clist[param].wrptr; n++) { - if (! pgc_result_byte(dev, dev->clist[param].list[n])) - return; + if (!pgc_result_byte(dev, dev->clist[param].list[n])) + return; } } - /* Delete a command list. */ static void hndl_cldel(pgc_t *dev) { uint8_t param = 0; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; memset(&dev->clist[param], 0, sizeof(pgc_cl_t)); } - /* Clear the screen to a specified color. */ static void hndl_clears(pgc_t *dev) { - uint8_t param = 0; + uint8_t param = 0; uint32_t y; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; for (y = 0; y < dev->screenh; y++) - memset(dev->vram + y * dev->maxw, param, dev->screenw); + memset(dev->vram + y * dev->maxw, param, dev->screenw); } - /* Select drawing color. */ static void hndl_color(pgc_t *dev) { uint8_t param = 0; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; pgc_log("PGC: COLOR(%i)\n", param); dev->color = param; } - /* * Set drawing mode. * @@ -537,107 +526,113 @@ hndl_linfun(pgc_t *dev) { uint8_t param = 0; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; pgc_log("PGC: LINFUN(%i)\n", param); if (param < 2) - dev->draw_mode = param; + dev->draw_mode = param; else - pgc_error(dev, PGC_ERROR_RANGE); + pgc_error(dev, PGC_ERROR_RANGE); } - /* Set the line drawing pattern. */ static void hndl_linpat(pgc_t *dev) { uint16_t param = 0; - if (! pgc_param_word(dev, (int16_t *)¶m)) return; + if (!pgc_param_word(dev, (int16_t *) ¶m)) + return; pgc_log("PGC: LINPAT(0x%04x)\n", param); dev->line_pattern = param; } - /* Set the polygon fill mode (0=hollow, 1=filled, 2=fast fill). */ static void hndl_prmfil(pgc_t *dev) { uint8_t param = 0; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; pgc_log("PGC: PRMFIL(%i)\n", param); if (param < 3) - dev->fill_mode = param; + dev->fill_mode = param; else - pgc_error(dev, PGC_ERROR_RANGE); + pgc_error(dev, PGC_ERROR_RANGE); } - /* Set the 2D drawing position. */ static void hndl_move(pgc_t *dev) { int32_t x = 0, y = 0; - if (! pgc_param_coord(dev, &x)) return; - if (! pgc_param_coord(dev, &y)) return; + if (!pgc_param_coord(dev, &x)) + return; + if (!pgc_param_coord(dev, &y)) + return; pgc_log("PCG: MOVE %x.%04x,%x.%04x\n", - HWORD(x), LWORD(x), HWORD(y), LWORD(y)); + HWORD(x), LWORD(x), HWORD(y), LWORD(y)); dev->x = x; dev->y = y; } - /* Set the 3D drawing position. */ static void hndl_move3(pgc_t *dev) { int32_t x = 0, y = 0, z = 0; - if (! pgc_param_coord(dev, &x)) return; - if (! pgc_param_coord(dev, &y)) return; - if (! pgc_param_coord(dev, &z)) return; + if (!pgc_param_coord(dev, &x)) + return; + if (!pgc_param_coord(dev, &y)) + return; + if (!pgc_param_coord(dev, &z)) + return; dev->x = x; dev->y = y; dev->z = z; } - /* Relative move (2D). */ static void hndl_mover(pgc_t *dev) { int32_t x = 0, y = 0; - if (! pgc_param_coord(dev, &x)) return; - if (! pgc_param_coord(dev, &y)) return; + if (!pgc_param_coord(dev, &x)) + return; + if (!pgc_param_coord(dev, &y)) + return; dev->x += x; dev->y += y; } - /* Relative move (3D). */ static void hndl_mover3(pgc_t *dev) { int32_t x = 0, y = 0, z = 0; - if (! pgc_param_coord(dev, &x)) return; - if (! pgc_param_coord(dev, &y)) return; - if (! pgc_param_coord(dev, &z)) return; + if (!pgc_param_coord(dev, &x)) + return; + if (!pgc_param_coord(dev, &y)) + return; + if (!pgc_param_coord(dev, &z)) + return; dev->x += x; dev->y += y; dev->z += z; } - /* Given raster coordinates, find the matching address in PGC video RAM. */ uint8_t * pgc_vram_addr(pgc_t *dev, int16_t x, int16_t y) @@ -645,19 +640,18 @@ pgc_vram_addr(pgc_t *dev, int16_t x, int16_t y) int offset; /* We work from the bottom left-hand corner. */ - if (y < 0 || (uint32_t)y >= dev->maxh || - x < 0 || (uint32_t)x >= dev->maxw) return NULL; + if (y < 0 || (uint32_t) y >= dev->maxh || x < 0 || (uint32_t) x >= dev->maxw) + return NULL; offset = (dev->maxh - 1 - y) * (dev->maxw) + x; pgc_log("PGC: vram_addr(x=%i,y=%i) = %i\n", x, y, offset); - if (offset < 0 || (uint32_t)offset >= (dev->maxw * dev->maxh)) - return NULL; + if (offset < 0 || (uint32_t) offset >= (dev->maxw * dev->maxh)) + return NULL; return &dev->vram[offset]; } - /* * Write a screen pixel. * X and Y are raster coordinates, ink is the value to write. @@ -668,21 +662,19 @@ pgc_write_pixel(pgc_t *dev, uint16_t x, uint16_t y, uint8_t ink) uint8_t *vram; /* Suppress out-of-range writes; clip to viewport. */ - if (x < dev->vp_x1 || x > dev->vp_x2 || x >= dev->maxw || - y < dev->vp_y1 || y > dev->vp_y2 || y >= dev->maxh) { - pgc_log("PGC: write_pixel clipped: (%i,%i) " - "vp_x1=%i vp_y1=%i vp_x2=%i vp_y2=%i " - "ink=0x%02x\n", - x, y, dev->vp_x1, dev->vp_y1, dev->vp_x2, dev->vp_y2, ink); - return; + if (x < dev->vp_x1 || x > dev->vp_x2 || x >= dev->maxw || y < dev->vp_y1 || y > dev->vp_y2 || y >= dev->maxh) { + pgc_log("PGC: write_pixel clipped: (%i,%i) " + "vp_x1=%i vp_y1=%i vp_x2=%i vp_y2=%i " + "ink=0x%02x\n", + x, y, dev->vp_x1, dev->vp_y1, dev->vp_x2, dev->vp_y2, ink); + return; } vram = pgc_vram_addr(dev, x, y); if (vram) - *vram = ink; + *vram = ink; } - /* Read a screen pixel (x and y are raster coordinates). */ uint8_t pgc_read_pixel(pgc_t *dev, uint16_t x, uint16_t y) @@ -691,16 +683,15 @@ pgc_read_pixel(pgc_t *dev, uint16_t x, uint16_t y) /* Suppress out-of-range reads. */ if (x >= dev->maxw || y >= dev->maxh) - return 0; + return 0; vram = pgc_vram_addr(dev, x, y); if (vram) - return *vram; + return *vram; return 0; } - /* * Plot a point in the current color and draw mode. Raster coordinates. * @@ -713,42 +704,42 @@ pgc_plot(pgc_t *dev, uint16_t x, uint16_t y) uint8_t *vram; /* Only allow plotting within the current viewport. */ - if (x < dev->vp_x1 || x > dev->vp_x2 || x >= dev->maxw || - y < dev->vp_y1 || y > dev->vp_y2 || y >= dev->maxh) { - pgc_log("PGC: plot clipped: (%i,%i) %i <= x <= %i; %i <= y <= %i; " - "mode=%i ink=0x%02x\n", x, y, - dev->vp_x1, dev->vp_x2, dev->vp_y1, dev->vp_y2, - dev->draw_mode, dev->color); - return; + if (x < dev->vp_x1 || x > dev->vp_x2 || x >= dev->maxw || y < dev->vp_y1 || y > dev->vp_y2 || y >= dev->maxh) { + pgc_log("PGC: plot clipped: (%i,%i) %i <= x <= %i; %i <= y <= %i; " + "mode=%i ink=0x%02x\n", + x, y, + dev->vp_x1, dev->vp_x2, dev->vp_y1, dev->vp_y2, + dev->draw_mode, dev->color); + return; } vram = pgc_vram_addr(dev, x, y); - if (! vram) return; + if (!vram) + return; /* TODO: Does not implement the PGC plane mask (set by MASK). */ switch (dev->draw_mode) { - default: - case 0: /* WRITE */ - *vram = dev->color; - break; + default: + case 0: /* WRITE */ + *vram = dev->color; + break; - case 1: /* INVERT */ - *vram ^= 0xff; - break; + case 1: /* INVERT */ + *vram ^= 0xff; + break; - case 2: /* XOR color */ - //FIXME: see notes - *vram ^= dev->color; - break; + case 2: /* XOR color */ + // FIXME: see notes + *vram ^= dev->color; + break; - case 3: /* AND color */ - //FIXME: see notes - *vram &= dev->color; - break; + case 3: /* AND color */ + // FIXME: see notes + *vram &= dev->color; + break; } } - /* * Draw a line (using raster coordinates). * @@ -763,42 +754,42 @@ pgc_draw_line_r(pgc_t *dev, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint { int32_t dx, dy, sx, sy, err, e2; - dx = abs(x1 - x0); - dy = abs(y1 - y0); - sx = (x0 < x1) ? 1 : -1; - sy = (y0 < y1) ? 1 : -1; + dx = abs(x1 - x0); + dy = abs(y1 - y0); + sx = (x0 < x1) ? 1 : -1; + sy = (y0 < y1) ? 1 : -1; err = (dx > dy ? dx : -dy) / 2; for (;;) { - if (linemask & 0x8000) { - pgc_plot(dev, x0, y0); - linemask = (linemask << 1) | 1; - } else - linemask = (linemask << 1); + if (linemask & 0x8000) { + pgc_plot(dev, x0, y0); + linemask = (linemask << 1) | 1; + } else + linemask = (linemask << 1); - if (x0 == x1 && y0 == y1) break; + if (x0 == x1 && y0 == y1) + break; - e2 = err; - if (e2 > -dx) { - err -= dy; - x0 += sx; - } - if (e2 < dy) { - err += dx; - y0 += sy; - } + e2 = err; + if (e2 > -dx) { + err -= dy; + x0 += sx; + } + if (e2 < dy) { + err += dx; + y0 += sy; + } } return linemask; } - /* Draw a line (using PGC fixed-point coordinates). */ uint16_t pgc_draw_line(pgc_t *dev, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint16_t linemask) { pgc_log("pgc_draw_line: (%i,%i) to (%i,%i)\n", - x0 >> 16, y0 >> 16, x1 >> 16, y1 >> 16); + x0 >> 16, y0 >> 16, x1 >> 16, y1 >> 16); /* Convert from PGC fixed-point to device coordinates */ x0 >>= 16; @@ -812,7 +803,6 @@ pgc_draw_line(pgc_t *dev, int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint16 return pgc_draw_line_r(dev, x0, y0, x1, y1, linemask); } - /* * Draw a horizontal line in the current fill pattern * (using raster coordinates). @@ -824,104 +814,106 @@ pgc_fill_line_r(pgc_t *dev, int32_t x0, int32_t x1, int32_t y0) int32_t x; if (x0 > x1) { - x = x1; - x1 = x0; - x0 = x; + x = x1; + x1 = x0; + x0 = x; } for (x = x0; x <= x1; x++) { - if (dev->fill_pattern[y0 & 0x0F] & mask) - pgc_plot(dev, x, y0); - mask = mask >> 1; - if (mask == 0) mask = 0x8000; + if (dev->fill_pattern[y0 & 0x0F] & mask) + pgc_plot(dev, x, y0); + mask = mask >> 1; + if (mask == 0) + mask = 0x8000; } } - /* For sorting polygon nodes. */ static int compare_double(const void *a, const void *b) { - const double *da = (const double *)a; - const double *db = (const double *)b; + const double *da = (const double *) a; + const double *db = (const double *) b; - if (*da < *db) return 1; - if (*da > *db) return -1; + if (*da < *db) + return 1; + if (*da > *db) + return -1; return 0; } - /* Draw a filled polygon (using PGC fixed-point coordinates). */ void pgc_fill_polygon(pgc_t *dev, unsigned corners, int32_t *x, int32_t *y) { - double *nodex; - double *dx; - double *dy; + double *nodex; + double *dx; + double *dy; unsigned n, nodes, i, j; - double ymin, ymax, ypos; + double ymin, ymax, ypos; pgc_log("PGC: fill_polygon(%i corners)\n", corners); if (!x || !y || (corners < 2)) - return; /* Degenerate polygon */ + return; /* Degenerate polygon */ - nodex = (double *)malloc(corners * sizeof(double)); - dx = (double *)malloc(corners * sizeof(double)); - dy = (double *)malloc(corners * sizeof(double)); + nodex = (double *) malloc(corners * sizeof(double)); + dx = (double *) malloc(corners * sizeof(double)); + dy = (double *) malloc(corners * sizeof(double)); if (!nodex || !dx || !dy) { - if (nodex) { - free(nodex); - nodex = NULL; - } - if (dx) { - free(dx); - dx = NULL; - } - if (dy) { - free(dy); - dy = NULL; - } - return; + if (nodex) { + free(nodex); + nodex = NULL; + } + if (dx) { + free(dx); + dx = NULL; + } + if (dy) { + free(dy); + dy = NULL; + } + return; } ymin = ymax = y[0] / 65536.0; for (n = 0; n < corners; n++) { - /* Convert from PGC fixed-point to native floating-point. */ - dx[n] = x[n] / 65536.0; - dy[n] = y[n] / 65536.0; + /* Convert from PGC fixed-point to native floating-point. */ + dx[n] = x[n] / 65536.0; + dy[n] = y[n] / 65536.0; - if (dy[n] < ymin) ymin = dy[n]; - if (dy[n] > ymax) ymax = dy[n]; + if (dy[n] < ymin) + ymin = dy[n]; + if (dy[n] > ymax) + ymax = dy[n]; } /* Polygon fill. Based on */ /* For each row, work out where the polygon lines intersect with * that row. */ for (ypos = ymin; ypos <= ymax; ypos++) { - nodes = 0; - j = corners - 1; - for (i = 0; i < corners; i++) { - if ((dy[i] < ypos && dy[j] >= ypos) || - (dy[j] < ypos && dy[i] >= ypos)) /* Line crosses */ { - nodex[nodes++] = dx[i] + (ypos-dy[i])/(dy[j]-dy[i]) * (dx[j] - dx[i]); - } - j = i; - } + nodes = 0; + j = corners - 1; + for (i = 0; i < corners; i++) { + if ((dy[i] < ypos && dy[j] >= ypos) || (dy[j] < ypos && dy[i] >= ypos)) /* Line crosses */ { + nodex[nodes++] = dx[i] + (ypos - dy[i]) / (dy[j] - dy[i]) * (dx[j] - dx[i]); + } + j = i; + } - /* Sort the intersections. */ - if (nodes) - qsort(nodex, nodes, sizeof(double), compare_double); + /* Sort the intersections. */ + if (nodes) + qsort(nodex, nodes, sizeof(double), compare_double); - /* And fill between them. */ - for (i = 0; i < nodes; i += 2) { - int16_t x1 = (int16_t)nodex[i], x2 = (int16_t)nodex[i + 1], - y1 = (int16_t)ypos, y2 = (int16_t)ypos; - pgc_sto_raster(dev, &x1, &y1); - pgc_sto_raster(dev, &x2, &y2); - pgc_fill_line_r(dev, x1, x2, y1); - } + /* And fill between them. */ + for (i = 0; i < nodes; i += 2) { + int16_t x1 = (int16_t) nodex[i], x2 = (int16_t) nodex[i + 1], + y1 = (int16_t) ypos, y2 = (int16_t) ypos; + pgc_sto_raster(dev, &x1, &y1); + pgc_sto_raster(dev, &x2, &y2); + pgc_fill_line_r(dev, x1, x2, y1); + } } free(nodex); @@ -929,86 +921,85 @@ pgc_fill_polygon(pgc_t *dev, unsigned corners, int32_t *x, int32_t *y) free(dy); } - /* Draw a filled ellipse (using PGC fixed-point coordinates). */ void pgc_draw_ellipse(pgc_t *dev, int32_t x, int32_t y) { /* Convert from PGC fixed-point to native floating-point. */ - double h = y / 65536.0; - double w = x / 65536.0; - double y0 = dev->y / 65536.0; - double x0 = dev->x / 65536.0; - double ypos, xpos; - double x1; - double xlast = 0.0; + double h = y / 65536.0; + double w = x / 65536.0; + double y0 = dev->y / 65536.0; + double x0 = dev->x / 65536.0; + double ypos, xpos; + double x1; + double xlast = 0.0; int16_t linemask = dev->line_pattern; pgc_log("PGC: ellipse(color=%i drawmode=%i fill=%i)\n", - dev->color, dev->draw_mode, dev->fill_mode); + dev->color, dev->draw_mode, dev->fill_mode); pgc_dto_raster(dev, &x0, &y0); for (ypos = 0; ypos <= h; ypos++) { - if (ypos == 0) { - if (dev->fill_mode) - pgc_fill_line_r(dev, (uint16_t)(x0 - w), - (uint16_t)(x0 + w), (uint16_t)y0); - if (linemask & 0x8000) { - pgc_plot(dev, (uint16_t)(x0 + w), (uint16_t)y0); - pgc_plot(dev, (uint16_t)(x0 - w), (uint16_t)y0); - linemask = (linemask << 1) | 1; - } else - linemask = linemask << 1; + if (ypos == 0) { + if (dev->fill_mode) + pgc_fill_line_r(dev, (uint16_t) (x0 - w), + (uint16_t) (x0 + w), (uint16_t) y0); + if (linemask & 0x8000) { + pgc_plot(dev, (uint16_t) (x0 + w), (uint16_t) y0); + pgc_plot(dev, (uint16_t) (x0 - w), (uint16_t) y0); + linemask = (linemask << 1) | 1; + } else + linemask = linemask << 1; - xlast = w; - } else { - x1 = sqrt((h * h) - (ypos * ypos)) * w / h; + xlast = w; + } else { + x1 = sqrt((h * h) - (ypos * ypos)) * w / h; - if (dev->fill_mode) { - pgc_fill_line_r(dev, (uint16_t)(x0 - x1), - (uint16_t)(x0 + x1), - (uint16_t)(y0 + ypos)); - pgc_fill_line_r(dev, (uint16_t)(x0 - x1), - (uint16_t)(x0 + x1), - (uint16_t)(y0 - ypos)); - } + if (dev->fill_mode) { + pgc_fill_line_r(dev, (uint16_t) (x0 - x1), + (uint16_t) (x0 + x1), + (uint16_t) (y0 + ypos)); + pgc_fill_line_r(dev, (uint16_t) (x0 - x1), + (uint16_t) (x0 + x1), + (uint16_t) (y0 - ypos)); + } - /* Draw border. */ - for (xpos = xlast; xpos >= x1; xpos--) { - if (linemask & 0x8000) { - pgc_plot(dev, (uint16_t)(x0 + xpos), - (uint16_t)(y0 + ypos)); - pgc_plot(dev, (uint16_t)(x0 - xpos), - (uint16_t)(y0 + ypos)); - pgc_plot(dev, (uint16_t)(x0 + xpos), - (uint16_t)(y0 - ypos)); - pgc_plot(dev, (uint16_t)(x0 - xpos), - (uint16_t)(y0 - ypos)); - linemask = (linemask << 1) | 1; - } else - linemask = linemask << 1; - } + /* Draw border. */ + for (xpos = xlast; xpos >= x1; xpos--) { + if (linemask & 0x8000) { + pgc_plot(dev, (uint16_t) (x0 + xpos), + (uint16_t) (y0 + ypos)); + pgc_plot(dev, (uint16_t) (x0 - xpos), + (uint16_t) (y0 + ypos)); + pgc_plot(dev, (uint16_t) (x0 + xpos), + (uint16_t) (y0 - ypos)); + pgc_plot(dev, (uint16_t) (x0 - xpos), + (uint16_t) (y0 - ypos)); + linemask = (linemask << 1) | 1; + } else + linemask = linemask << 1; + } - xlast = x1; - } + xlast = x1; + } } } - /* Handle the ELIPSE (sic) command. */ static void hndl_ellipse(pgc_t *dev) { int32_t x = 0, y = 0; - if (! pgc_param_coord(dev, &x)) return; - if (! pgc_param_coord(dev, &y)) return; + if (!pgc_param_coord(dev, &x)) + return; + if (!pgc_param_coord(dev, &y)) + return; pgc_draw_ellipse(dev, x, y); } - /* Handle the POLY command. */ static void hndl_poly(pgc_t *dev) @@ -1018,16 +1009,18 @@ hndl_poly(pgc_t *dev) int32_t y[256]; int32_t n; - if (! pgc_param_byte(dev, &count)) return; + if (!pgc_param_byte(dev, &count)) + return; pgc_log("PGC: POLY (%i)\n", count); for (n = 0; n < count; n++) { - if (! pgc_param_coord(dev, &x[n])) return; - if (! pgc_param_coord(dev, &y[n])) return; + if (!pgc_param_coord(dev, &x[n])) + return; + if (!pgc_param_coord(dev, &y[n])) + return; } } - /* Parse but don't execute a POLY command (for adding to a command list) */ static int parse_poly(pgc_t *dev, pgc_cl_t *cl, int c) @@ -1037,36 +1030,36 @@ parse_poly(pgc_t *dev, pgc_cl_t *cl, int c) #ifdef ENABLE_PGC_LOG pgc_log("PCG: parse_poly\n"); #endif - if (! pgc_param_byte(dev, &count)) return 0; + if (!pgc_param_byte(dev, &count)) + return 0; pgc_log("PCG: parse_poly: count=%02x\n", count); - if (! pgc_cl_append(cl, count)) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - return 0; + if (!pgc_cl_append(cl, count)) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + return 0; } pgc_log("PCG: parse_poly: parse %i coords\n", 2 * count); return pgc_parse_coords(dev, cl, 2 * count); } - /* Handle the DISPLAY command. */ static void hndl_display(pgc_t *dev) { uint8_t param; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; pgc_log("PGC: DISPLAY(%i)\n", param); if (param > 1) - pgc_error(dev, PGC_ERROR_RANGE); + pgc_error(dev, PGC_ERROR_RANGE); else - pgc_setdisplay(dev, param); + pgc_setdisplay(dev, param); } - /* Handle the IMAGEW command (memory to screen blit). */ static void hndl_imagew(pgc_t *dev) @@ -1074,68 +1067,72 @@ hndl_imagew(pgc_t *dev) int16_t row, col1, col2; uint8_t v1, v2; - if (! pgc_param_word(dev, &row)) return; - if (! pgc_param_word(dev, &col1)) return; - if (! pgc_param_word(dev, &col2)) return; + if (!pgc_param_word(dev, &row)) + return; + if (!pgc_param_word(dev, &col1)) + return; + if (!pgc_param_word(dev, &col2)) + return; - if ((uint32_t)row >= dev->screenh || - (uint32_t)col1 >= dev->maxw || (uint32_t)col2 >= dev->maxw) { - pgc_error(dev, PGC_ERROR_RANGE); - return; + if ((uint32_t) row >= dev->screenh || (uint32_t) col1 >= dev->maxw || (uint32_t) col2 >= dev->maxw) { + pgc_error(dev, PGC_ERROR_RANGE); + return; } /* In ASCII mode, what is written is a stream of bytes. */ if (dev->ascii_mode) { - while (col1 <= col2) { - if (! pgc_param_byte(dev, &v1)) return; - pgc_write_pixel(dev, col1, row, v1); - col1++; - } + while (col1 <= col2) { + if (!pgc_param_byte(dev, &v1)) + return; + pgc_write_pixel(dev, col1, row, v1); + col1++; + } - return; + return; } /* In hex mode, it's RLE compressed. */ while (col1 <= col2) { - if (! pgc_param_byte(dev, &v1)) return; + if (!pgc_param_byte(dev, &v1)) + return; - if (v1 & 0x80) { - /* Literal run. */ - v1 -= 0x7f; - while (col1 <= col2 && v1 != 0) { - if (! pgc_param_byte(dev, &v2)) return; - pgc_write_pixel(dev, col1, row, v2); - col1++; - v1--; - } - } else { - /* Repeated run. */ - if (! pgc_param_byte(dev, &v2)) return; + if (v1 & 0x80) { + /* Literal run. */ + v1 -= 0x7f; + while (col1 <= col2 && v1 != 0) { + if (!pgc_param_byte(dev, &v2)) + return; + pgc_write_pixel(dev, col1, row, v2); + col1++; + v1--; + } + } else { + /* Repeated run. */ + if (!pgc_param_byte(dev, &v2)) + return; - v1++; - while (col1 <= col2 && v1 != 0) { - pgc_write_pixel(dev, col1, row, v2); - col1++; - v1--; - } - } + v1++; + while (col1 <= col2 && v1 != 0) { + pgc_write_pixel(dev, col1, row, v2); + col1++; + v1--; + } + } } } - /* Select one of the built-in palettes. */ static void init_lut(pgc_t *dev, int param) { if (param >= 0 && param < 6) - memcpy(dev->palette, init_palette[param], sizeof(dev->palette)); + memcpy(dev->palette, init_palette[param], sizeof(dev->palette)); else if (param == 0xff) - memcpy(dev->palette, dev->userpal, sizeof(dev->palette)); + memcpy(dev->palette, dev->userpal, sizeof(dev->palette)); else - pgc_error(dev, PGC_ERROR_RANGE); + pgc_error(dev, PGC_ERROR_RANGE); } - /* Save the current palette. */ static void hndl_lutsav(pgc_t *dev) @@ -1143,57 +1140,56 @@ hndl_lutsav(pgc_t *dev) memcpy(dev->userpal, dev->palette, sizeof(dev->palette)); } - /* Handle LUTINT (select palette). */ static void hndl_lutint(pgc_t *dev) { uint8_t param; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; init_lut(dev, param); } - /* Handle LUTRD (read palette register). */ static void hndl_lutrd(pgc_t *dev) { - uint8_t param; + uint8_t param; uint32_t col; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; col = dev->palette[param]; pgc_result_byte(dev, (col >> 20) & 0x0f); pgc_result_byte(dev, (col >> 12) & 0x0f); - pgc_result_byte(dev, (col >> 4) & 0x0f); + pgc_result_byte(dev, (col >> 4) & 0x0f); } - /* Handle LUT (write palette register). */ static void hndl_lut(pgc_t *dev) { uint8_t param[4]; - int n; + int n; for (n = 0; n < 4; n++) { - if (! pgc_param_byte(dev, ¶m[n])) return; - if (n > 0 && param[n] > 15) { - pgc_error(dev, PGC_ERROR_RANGE); - param[n] &= 0x0f; - } + if (!pgc_param_byte(dev, ¶m[n])) + return; + if (n > 0 && param[n] > 15) { + pgc_error(dev, PGC_ERROR_RANGE); + param[n] &= 0x0f; + } } dev->palette[param[0]] = makecol((param[1] * 0x11), - (param[2] * 0x11), - (param[3] * 0x11)); + (param[2] * 0x11), + (param[3] * 0x11)); } - /* * LUT8RD and LUT8 are extensions implemented by several PGC clones, * so here are functions that implement them even though they aren't @@ -1202,49 +1198,49 @@ hndl_lut(pgc_t *dev) void pgc_hndl_lut8rd(pgc_t *dev) { - uint8_t param; + uint8_t param; uint32_t col; - if (! pgc_param_byte(dev, ¶m)) return; + if (!pgc_param_byte(dev, ¶m)) + return; col = dev->palette[param]; pgc_result_byte(dev, (col >> 16) & 0xff); - pgc_result_byte(dev, (col >> 8) & 0xff); + pgc_result_byte(dev, (col >> 8) & 0xff); pgc_result_byte(dev, col & 0xff); } - void pgc_hndl_lut8(pgc_t *dev) { uint8_t param[4]; - int n; + int n; for (n = 0; n < 4; n++) - if (! pgc_param_byte(dev, ¶m[n])) return; + if (!pgc_param_byte(dev, ¶m[n])) + return; dev->palette[param[0]] = makecol((param[1]), (param[2]), (param[3])); } - /* Handle AREAPT (set 16x16 fill pattern). */ static void hndl_areapt(pgc_t *dev) { int16_t pat[16]; - int n; + int n; for (n = 0; n < 16; n++) - if (! pgc_param_word(dev, &pat[n])) return; + if (!pgc_param_word(dev, &pat[n])) + return; pgc_log("PGC: AREAPT(%04x %04x %04x %04x...)\n", - pat[0] & 0xffff, pat[1] & 0xffff, pat[2] & 0xffff, pat[3] & 0xffff); + pat[0] & 0xffff, pat[1] & 0xffff, pat[2] & 0xffff, pat[3] & 0xffff); memcpy(dev->fill_pattern, pat, sizeof(dev->fill_pattern)); } - /* Handle CA (select ASCII mode). */ static void hndl_ca(pgc_t *dev) @@ -1252,7 +1248,6 @@ hndl_ca(pgc_t *dev) dev->ascii_mode = 1; } - /* Handle CX (select hex mode). */ static void hndl_cx(pgc_t *dev) @@ -1260,7 +1255,6 @@ hndl_cx(pgc_t *dev) dev->ascii_mode = 0; } - /* * CA and CX remain valid in hex mode; they are handled * as command 0x43 ('C') with a one-byte parameter. @@ -1270,16 +1264,16 @@ hndl_c(pgc_t *dev) { uint8_t param; - if (! dev->inputbyte(dev, ¶m)) return; + if (!dev->inputbyte(dev, ¶m)) + return; if (param == 'A') - dev->ascii_mode = 1; + dev->ascii_mode = 1; if (param == 'X') - dev->ascii_mode = 0; + dev->ascii_mode = 0; } - /* RESETF resets the PGC. */ static void hndl_resetf(pgc_t *dev) @@ -1287,37 +1281,37 @@ hndl_resetf(pgc_t *dev) pgc_reset(dev); } - /* TJUST sets text justify settings. */ static void hndl_tjust(pgc_t *dev) { uint8_t param[2]; - if (! dev->inputbyte(dev, ¶m[0])) return; - if (! dev->inputbyte(dev, ¶m[1])) return; + if (!dev->inputbyte(dev, ¶m[0])) + return; + if (!dev->inputbyte(dev, ¶m[1])) + return; if (param[0] >= 1 && param[0] <= 3 && param[1] >= 1 && param[1] <= 3) { - dev->tjust_h = param[0]; - dev->tjust_v = param[1]; + dev->tjust_h = param[0]; + dev->tjust_v = param[1]; } else - pgc_error(dev, PGC_ERROR_RANGE); + pgc_error(dev, PGC_ERROR_RANGE); } - /* TSIZE controls text horizontal spacing. */ static void hndl_tsize(pgc_t *pgc) { int32_t param = 0; - if (! pgc_param_coord(pgc, ¶m)) return; + if (!pgc_param_coord(pgc, ¶m)) + return; pgc_log("PGC: TSIZE %i\n", param); pgc->tsize = param; } - /* * VWPORT sets up the viewport (roughly, the clip rectangle) in * raster coordinates, measured from the bottom left of the screen. @@ -1327,38 +1321,44 @@ hndl_vwport(pgc_t *dev) { int16_t x1, x2, y1, y2; - if (! pgc_param_word(dev, &x1)) return; - if (! pgc_param_word(dev, &x2)) return; - if (! pgc_param_word(dev, &y1)) return; - if (! pgc_param_word(dev, &y2)) return; + if (!pgc_param_word(dev, &x1)) + return; + if (!pgc_param_word(dev, &x2)) + return; + if (!pgc_param_word(dev, &y1)) + return; + if (!pgc_param_word(dev, &y2)) + return; - pgc_log("PGC: VWPORT %i,%i,%i,%i\n", x1,x2,y1,y2); + pgc_log("PGC: VWPORT %i,%i,%i,%i\n", x1, x2, y1, y2); dev->vp_x1 = x1; dev->vp_x2 = x2; dev->vp_y1 = y1; dev->vp_y2 = y2; } - /* WINDOW defines the coordinate system in use. */ static void hndl_window(pgc_t *dev) { int16_t x1, x2, y1, y2; - if (! pgc_param_word(dev, &x1)) return; - if (! pgc_param_word(dev, &x2)) return; - if (! pgc_param_word(dev, &y1)) return; - if (! pgc_param_word(dev, &y2)) return; + if (!pgc_param_word(dev, &x1)) + return; + if (!pgc_param_word(dev, &x2)) + return; + if (!pgc_param_word(dev, &y1)) + return; + if (!pgc_param_word(dev, &y2)) + return; - pgc_log("PGC: WINDOW %i,%i,%i,%i\n", x1,x2,y1,y2); + pgc_log("PGC: WINDOW %i,%i,%i,%i\n", x1, x2, y1, y2); dev->win_x1 = x1; dev->win_x2 = x2; dev->win_y1 = y1; dev->win_y2 = y2; } - /* * The list of commands implemented by this mini-PGC. * @@ -1383,74 +1383,73 @@ hndl_window(pgc_t *dev) * */ static const pgc_cmd_t pgc_commands[] = { - { "AREAPT", 0xe7, hndl_areapt, pgc_parse_words, 16 }, - { "AP", 0xe7, hndl_areapt, pgc_parse_words, 16 }, - { "~~~~~~", 0x43, hndl_c, NULL, 0 }, - { "CA", 0xd2, hndl_ca, NULL, 0 }, - { "CLBEG", 0x70, hndl_clbeg, NULL, 0 }, - { "CB", 0x70, hndl_clbeg, NULL, 0 }, - { "CLDEL", 0x74, hndl_cldel, pgc_parse_bytes, 1 }, - { "CD", 0x74, hndl_cldel, pgc_parse_bytes, 1 }, - { "CLEND", 0x71, hndl_clend, NULL, 0 }, - { "CLRUN", 0x72, hndl_clrun, pgc_parse_bytes, 1 }, - { "CR", 0x72, hndl_clrun, pgc_parse_bytes, 1 }, - { "CLRD", 0x75, hndl_clread, pgc_parse_bytes, 1 }, - { "CRD", 0x75, hndl_clread, pgc_parse_bytes, 1 }, - { "CLOOP", 0x73, hndl_cloop, NULL, 0 }, - { "CL", 0x73, hndl_cloop, NULL, 0 }, - { "CLEARS", 0x0f, hndl_clears, pgc_parse_bytes, 1 }, - { "CLS", 0x0f, hndl_clears, pgc_parse_bytes, 1 }, - { "COLOR", 0x06, hndl_color, pgc_parse_bytes, 1 }, - { "C", 0x06, hndl_color, pgc_parse_bytes, 1 }, - { "CX", 0xd1, hndl_cx, NULL, 0 }, - { "DISPLA", 0xd0, hndl_display, pgc_parse_bytes, 1 }, - { "DI", 0xd0, hndl_display, pgc_parse_bytes, 1 }, - { "ELIPSE", 0x39, hndl_ellipse, pgc_parse_coords, 2 }, - { "EL", 0x39, hndl_ellipse, pgc_parse_coords, 2 }, - { "IMAGEW", 0xd9, hndl_imagew, NULL, 0 }, - { "IW", 0xd9, hndl_imagew, NULL, 0 }, - { "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 }, - { "LF", 0xeb, hndl_linfun, pgc_parse_bytes, 1 }, - { "LINPAT", 0xea, hndl_linpat, pgc_parse_words, 1 }, - { "LP", 0xea, hndl_linpat, pgc_parse_words, 1 }, - { "LUTINT", 0xec, hndl_lutint, pgc_parse_bytes, 1 }, - { "LI", 0xec, hndl_lutint, pgc_parse_bytes, 1 }, - { "LUTRD", 0x50, hndl_lutrd, pgc_parse_bytes, 1 }, - { "LUTSAV", 0xed, hndl_lutsav, NULL, 0 }, - { "LUT", 0xee, hndl_lut, pgc_parse_bytes, 4 }, - { "MOVE", 0x10, hndl_move, pgc_parse_coords, 2 }, - { "M", 0x10, hndl_move, pgc_parse_coords, 2 }, - { "MOVE3", 0x12, hndl_move3, pgc_parse_coords, 3 }, - { "M3", 0x12, hndl_move3, pgc_parse_coords, 3 }, - { "MOVER", 0x11, hndl_mover, pgc_parse_coords, 2 }, - { "MR", 0x11, hndl_mover, pgc_parse_coords, 2 }, - { "MOVER3", 0x13, hndl_mover3, pgc_parse_coords, 3 }, - { "MR3", 0x13, hndl_mover3, pgc_parse_coords, 3 }, - { "PRMFIL", 0xe9, hndl_prmfil, pgc_parse_bytes, 1 }, - { "PF", 0xe9, hndl_prmfil, pgc_parse_bytes, 1 }, - { "POLY", 0x30, hndl_poly, parse_poly, 0 }, - { "P", 0x30, hndl_poly, parse_poly, 0 }, - { "RESETF", 0x04, hndl_resetf, NULL, 0 }, - { "RF", 0x04, hndl_resetf, NULL, 0 }, - { "TJUST", 0x85, hndl_tjust, pgc_parse_bytes, 2 }, - { "TJ", 0x85, hndl_tjust, pgc_parse_bytes, 2 }, - { "TSIZE", 0x81, hndl_tsize, pgc_parse_coords, 1 }, - { "TS", 0x81, hndl_tsize, pgc_parse_coords, 1 }, - { "VWPORT", 0xb2, hndl_vwport, pgc_parse_words, 4 }, - { "VWP", 0xb2, hndl_vwport, pgc_parse_words, 4 }, - { "WINDOW", 0xb3, hndl_window, pgc_parse_words, 4 }, - { "WI", 0xb3, hndl_window, pgc_parse_words, 4 }, + {"AREAPT", 0xe7, hndl_areapt, pgc_parse_words, 16}, + { "AP", 0xe7, hndl_areapt, pgc_parse_words, 16}, + { "~~~~~~", 0x43, hndl_c, NULL, 0 }, + { "CA", 0xd2, hndl_ca, NULL, 0 }, + { "CLBEG", 0x70, hndl_clbeg, NULL, 0 }, + { "CB", 0x70, hndl_clbeg, NULL, 0 }, + { "CLDEL", 0x74, hndl_cldel, pgc_parse_bytes, 1 }, + { "CD", 0x74, hndl_cldel, pgc_parse_bytes, 1 }, + { "CLEND", 0x71, hndl_clend, NULL, 0 }, + { "CLRUN", 0x72, hndl_clrun, pgc_parse_bytes, 1 }, + { "CR", 0x72, hndl_clrun, pgc_parse_bytes, 1 }, + { "CLRD", 0x75, hndl_clread, pgc_parse_bytes, 1 }, + { "CRD", 0x75, hndl_clread, pgc_parse_bytes, 1 }, + { "CLOOP", 0x73, hndl_cloop, NULL, 0 }, + { "CL", 0x73, hndl_cloop, NULL, 0 }, + { "CLEARS", 0x0f, hndl_clears, pgc_parse_bytes, 1 }, + { "CLS", 0x0f, hndl_clears, pgc_parse_bytes, 1 }, + { "COLOR", 0x06, hndl_color, pgc_parse_bytes, 1 }, + { "C", 0x06, hndl_color, pgc_parse_bytes, 1 }, + { "CX", 0xd1, hndl_cx, NULL, 0 }, + { "DISPLA", 0xd0, hndl_display, pgc_parse_bytes, 1 }, + { "DI", 0xd0, hndl_display, pgc_parse_bytes, 1 }, + { "ELIPSE", 0x39, hndl_ellipse, pgc_parse_coords, 2 }, + { "EL", 0x39, hndl_ellipse, pgc_parse_coords, 2 }, + { "IMAGEW", 0xd9, hndl_imagew, NULL, 0 }, + { "IW", 0xd9, hndl_imagew, NULL, 0 }, + { "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 }, + { "LF", 0xeb, hndl_linfun, pgc_parse_bytes, 1 }, + { "LINPAT", 0xea, hndl_linpat, pgc_parse_words, 1 }, + { "LP", 0xea, hndl_linpat, pgc_parse_words, 1 }, + { "LUTINT", 0xec, hndl_lutint, pgc_parse_bytes, 1 }, + { "LI", 0xec, hndl_lutint, pgc_parse_bytes, 1 }, + { "LUTRD", 0x50, hndl_lutrd, pgc_parse_bytes, 1 }, + { "LUTSAV", 0xed, hndl_lutsav, NULL, 0 }, + { "LUT", 0xee, hndl_lut, pgc_parse_bytes, 4 }, + { "MOVE", 0x10, hndl_move, pgc_parse_coords, 2 }, + { "M", 0x10, hndl_move, pgc_parse_coords, 2 }, + { "MOVE3", 0x12, hndl_move3, pgc_parse_coords, 3 }, + { "M3", 0x12, hndl_move3, pgc_parse_coords, 3 }, + { "MOVER", 0x11, hndl_mover, pgc_parse_coords, 2 }, + { "MR", 0x11, hndl_mover, pgc_parse_coords, 2 }, + { "MOVER3", 0x13, hndl_mover3, pgc_parse_coords, 3 }, + { "MR3", 0x13, hndl_mover3, pgc_parse_coords, 3 }, + { "PRMFIL", 0xe9, hndl_prmfil, pgc_parse_bytes, 1 }, + { "PF", 0xe9, hndl_prmfil, pgc_parse_bytes, 1 }, + { "POLY", 0x30, hndl_poly, parse_poly, 0 }, + { "P", 0x30, hndl_poly, parse_poly, 0 }, + { "RESETF", 0x04, hndl_resetf, NULL, 0 }, + { "RF", 0x04, hndl_resetf, NULL, 0 }, + { "TJUST", 0x85, hndl_tjust, pgc_parse_bytes, 2 }, + { "TJ", 0x85, hndl_tjust, pgc_parse_bytes, 2 }, + { "TSIZE", 0x81, hndl_tsize, pgc_parse_coords, 1 }, + { "TS", 0x81, hndl_tsize, pgc_parse_coords, 1 }, + { "VWPORT", 0xb2, hndl_vwport, pgc_parse_words, 4 }, + { "VWP", 0xb2, hndl_vwport, pgc_parse_words, 4 }, + { "WINDOW", 0xb3, hndl_window, pgc_parse_words, 4 }, + { "WI", 0xb3, hndl_window, pgc_parse_words, 4 }, - { "@@@@@@", 0x00, NULL, NULL, 0 } + { "@@@@@@", 0x00, NULL, NULL, 0 } }; - /* When the wake timer expires, that's when the drawing thread is actually * woken */ static void wake_timer(void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; #ifdef ENABLE_PGC_LOG pgc_log("PGC: woke up\n"); @@ -1459,7 +1458,6 @@ wake_timer(void *priv) thread_set_event(dev->pgc_wake_thread); } - /* * The PGC drawing thread main loop. * @@ -1468,7 +1466,7 @@ wake_timer(void *priv) static void pgc_thread(void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; const pgc_cmd_t *cmd; #ifdef ENABLE_PGC_LOG @@ -1476,28 +1474,28 @@ pgc_thread(void *priv) #endif for (;;) { - if (! parse_command(dev, &cmd)) { - /* Are we shutting down? */ - if (dev->stopped) { + if (!parse_command(dev, &cmd)) { + /* Are we shutting down? */ + if (dev->stopped) { #ifdef ENABLE_PGC_LOG - pgc_log("PGC: Thread stopping...\n"); + pgc_log("PGC: Thread stopping...\n"); #endif - dev->stopped = 0; - break; - } + dev->stopped = 0; + break; + } - /* Nope, just a reset. */ - continue; - } + /* Nope, just a reset. */ + continue; + } - pgc_log("PGC: Command: [%02x] '%s' found = %i\n", - dev->hex_command, dev->asc_command, (cmd != NULL)); + pgc_log("PGC: Command: [%02x] '%s' found = %i\n", + dev->hex_command, dev->asc_command, (cmd != NULL)); - if (cmd) { - dev->result_count = 0; - (*cmd->handler)(dev); - } else - pgc_error(dev, PGC_ERROR_OPCODE); + if (cmd) { + dev->result_count = 0; + (*cmd->handler)(dev); + } else + pgc_error(dev, PGC_ERROR_OPCODE); } #ifdef ENABLE_PGC_LOG @@ -1505,7 +1503,6 @@ pgc_thread(void *priv) #endif } - /* Parameter passed is not a number: abort. */ static int err_digit(pgc_t *dev) @@ -1513,27 +1510,28 @@ err_digit(pgc_t *dev) uint8_t asc; do { - /* Swallow everything until the next separator */ - if (! dev->inputbyte(dev, &asc)) return 0; - } while (! is_whitespace(asc)); + /* Swallow everything until the next separator */ + if (!dev->inputbyte(dev, &asc)) + return 0; + } while (!is_whitespace(asc)); pgc_error(dev, PGC_ERROR_DIGIT); return 0; } - /* Output a byte, either as hex or ASCII depending on the mode. */ int pgc_result_byte(pgc_t *dev, uint8_t val) { char buf[20]; - if (! dev->ascii_mode) - return output_byte(dev, val); + if (!dev->ascii_mode) + return output_byte(dev, val); if (dev->result_count) { - if (! output_byte(dev, ',')) return 0; + if (!output_byte(dev, ',')) + return 0; } sprintf(buf, "%i", val); dev->result_count++; @@ -1541,20 +1539,21 @@ pgc_result_byte(pgc_t *dev, uint8_t val) return output_string(dev, buf); } - /* Output a word, either as hex or ASCII depending on the mode. */ int pgc_result_word(pgc_t *dev, int16_t val) { char buf[20]; - if (! dev->ascii_mode) { - if (! output_byte(dev, val & 0xFF)) return 0; - return output_byte(dev, val >> 8); + if (!dev->ascii_mode) { + if (!output_byte(dev, val & 0xFF)) + return 0; + return output_byte(dev, val >> 8); } if (dev->result_count) { - if (! output_byte(dev, ',')) return 0; + if (!output_byte(dev, ',')) + return 0; } sprintf(buf, "%i", val); dev->result_count++; @@ -1562,26 +1561,24 @@ pgc_result_word(pgc_t *dev, int16_t val) return output_string(dev, buf); } - /* Report an error, either in ASCII or in hex. */ int pgc_error(pgc_t *dev, int err) { if (dev->mapram[0x307]) { - /* Errors enabled? */ - if (dev->ascii_mode) { - if (err >= PGC_ERROR_RANGE && err <= PGC_ERROR_MISSING) - return error_string(dev, pgc_err_msgs[err]); - return error_string(dev, "Unknown error\r"); - } else { - return error_byte(dev, err); - } + /* Errors enabled? */ + if (dev->ascii_mode) { + if (err >= PGC_ERROR_RANGE && err <= PGC_ERROR_MISSING) + return error_string(dev, pgc_err_msgs[err]); + return error_string(dev, "Unknown error\r"); + } else { + return error_byte(dev, err); + } } return 1; } - /* Initialize RAM and registers to default values. */ void pgc_reset(pgc_t *dev) @@ -1592,20 +1589,20 @@ pgc_reset(pgc_t *dev) /* The 'CGA disable' jumper is not currently implemented. */ dev->mapram[0x30b] = dev->cga_enabled = 1; - dev->mapram[0x30c] = dev->cga_enabled; - dev->mapram[0x30d] = dev->cga_enabled; + dev->mapram[0x30c] = dev->cga_enabled; + dev->mapram[0x30d] = dev->cga_enabled; - dev->mapram[0x3f8] = 0x03; /* minor version */ - dev->mapram[0x3f9] = 0x01; /* minor version */ - dev->mapram[0x3fb] = 0xa5; /* } */ - dev->mapram[0x3fc] = 0x5a; /* PGC self-test passed */ - dev->mapram[0x3fd] = 0x55; /* } */ - dev->mapram[0x3fe] = 0x5a; /* } */ + dev->mapram[0x3f8] = 0x03; /* minor version */ + dev->mapram[0x3f9] = 0x01; /* minor version */ + dev->mapram[0x3fb] = 0xa5; /* } */ + dev->mapram[0x3fc] = 0x5a; /* PGC self-test passed */ + dev->mapram[0x3fd] = 0x55; /* } */ + dev->mapram[0x3fe] = 0x5a; /* } */ - dev->ascii_mode = 1; /* start off in ASCII mode */ + dev->ascii_mode = 1; /* start off in ASCII mode */ dev->line_pattern = 0xffff; memset(dev->fill_pattern, 0xff, sizeof(dev->fill_pattern)); - dev->color = 0xff; + dev->color = 0xff; dev->tjust_h = 1; dev->tjust_v = 1; @@ -1621,10 +1618,10 @@ pgc_reset(pgc_t *dev) /* Empty command lists. */ for (n = 0; n < 256; n++) { - dev->clist[n].wrptr = 0; - dev->clist[n].rdptr = 0; - dev->clist[n].repeat = 0; - dev->clist[n].chain = 0; + dev->clist[n].wrptr = 0; + dev->clist[n].rdptr = 0; + dev->clist[n].repeat = 0; + dev->clist[n].chain = 0; } dev->clcur = NULL; @@ -1637,33 +1634,31 @@ pgc_reset(pgc_t *dev) hndl_lutsav(dev); } - /* Switch between CGA mode (DISPLAY 1) and native mode (DISPLAY 0). */ void pgc_setdisplay(pgc_t *dev, int cga) { pgc_log("PGC: setdisplay(%i): cga_selected=%i cga_enabled=%i\n", - cga, dev->cga_selected, dev->cga_enabled); + cga, dev->cga_selected, dev->cga_enabled); if (dev->cga_selected != (dev->cga_enabled && cga)) { - dev->cga_selected = (dev->cga_enabled && cga); - dev->displine = 0; + dev->cga_selected = (dev->cga_enabled && cga); + dev->displine = 0; - if (dev->cga_selected) { - mem_mapping_enable(&dev->cga_mapping); - dev->screenw = PGC_CGA_WIDTH; - dev->screenh = PGC_CGA_HEIGHT; - } else { - mem_mapping_disable(&dev->cga_mapping); - dev->screenw = dev->visw; - dev->screenh = dev->vish; - } + if (dev->cga_selected) { + mem_mapping_enable(&dev->cga_mapping); + dev->screenw = PGC_CGA_WIDTH; + dev->screenh = PGC_CGA_HEIGHT; + } else { + mem_mapping_disable(&dev->cga_mapping); + dev->screenw = dev->visw; + dev->screenh = dev->vish; + } - pgc_recalctimings(dev); + pgc_recalctimings(dev); } } - /* * When idle, the PGC drawing thread sleeps. pgc_wake() awakens it - but * not immediately. Like the Voodoo, it has a short delay so that writes @@ -1673,70 +1668,66 @@ void pgc_wake(pgc_t *dev) { if (!timer_is_enabled(&dev->wake_timer)) - timer_set_delay_u64(&dev->wake_timer, WAKE_DELAY); + timer_set_delay_u64(&dev->wake_timer, WAKE_DELAY); } - /* Wait for more input data, or for output to drain. */ void pgc_sleep(pgc_t *dev) { pgc_log("PGC: sleeping on %i %i %i %i 0x%02x 0x%02x\n", - dev->stopped, - dev->waiting_input_fifo, dev->waiting_output_fifo, - dev->waiting_error_fifo, dev->mapram[0x300], dev->mapram[0x301]); + dev->stopped, + dev->waiting_input_fifo, dev->waiting_output_fifo, + dev->waiting_error_fifo, dev->mapram[0x300], dev->mapram[0x301]); /* Avoid entering waiting state. */ if (dev->stopped) { - dev->waiting_input_fifo = 0; - dev->waiting_output_fifo = 0; - return; + dev->waiting_input_fifo = 0; + dev->waiting_output_fifo = 0; + return; } /* Race condition: If host wrote to the PGC during the that * won't be noticed */ - if (dev->waiting_input_fifo && - dev->mapram[0x300] != dev->mapram[0x301]) { - dev->waiting_input_fifo = 0; - return; + if (dev->waiting_input_fifo && dev->mapram[0x300] != dev->mapram[0x301]) { + dev->waiting_input_fifo = 0; + return; } /* Same if they read. */ - if (dev->waiting_output_fifo && - dev->mapram[0x302] != (uint8_t)(dev->mapram[0x303] - 1)) { - dev->waiting_output_fifo = 0; - return; + if (dev->waiting_output_fifo && dev->mapram[0x302] != (uint8_t) (dev->mapram[0x303] - 1)) { + dev->waiting_output_fifo = 0; + return; } thread_wait_event(dev->pgc_wake_thread, -1); thread_reset_event(dev->pgc_wake_thread); } - /* Pull the next byte from the current command list. */ int pgc_clist_byte(pgc_t *dev, uint8_t *val) { - if (dev->clcur == NULL) return 0; + if (dev->clcur == NULL) + return 0; if (dev->clcur->rdptr < dev->clcur->wrptr) - *val = dev->clcur->list[dev->clcur->rdptr++]; + *val = dev->clcur->list[dev->clcur->rdptr++]; else - *val = 0; + *val = 0; /* If we've reached the end, reset to the beginning and * (if repeating) run the repeat */ if (dev->clcur->rdptr >= dev->clcur->wrptr) { - dev->clcur->rdptr = 0; - dev->clcur->repeat--; - if (dev->clcur->repeat == 0) - dev->clcur = dev->clcur->chain; + dev->clcur->rdptr = 0; + dev->clcur->repeat--; + if (dev->clcur->repeat == 0) + dev->clcur = dev->clcur->chain; } return 1; } - /* * Read in a byte, either as hex (1 byte) or ASCII (decimal). * Returns 0 if PGC reset detected while the value is being read. @@ -1747,24 +1738,24 @@ pgc_param_byte(pgc_t *dev, uint8_t *val) int32_t c; if (dev->clcur) - return pgc_clist_byte(dev, val); + return pgc_clist_byte(dev, val); - if (! dev->ascii_mode) - return dev->inputbyte(dev, val); + if (!dev->ascii_mode) + return dev->inputbyte(dev, val); - if (! pgc_param_coord(dev, &c)) return 0; + if (!pgc_param_coord(dev, &c)) + return 0; - c = (c >> 16); /* drop fractional part */ + c = (c >> 16); /* drop fractional part */ if (c > 255) { - pgc_error(dev, PGC_ERROR_RANGE); - return 0; + pgc_error(dev, PGC_ERROR_RANGE); + return 0; } - *val = (uint8_t)c; + *val = (uint8_t) c; return 1; } - /* * Read in a word, either as hex (2 bytes) or ASCII (decimal). * Returns 0 if PGC reset detected while the value is being read. @@ -1776,41 +1767,44 @@ pgc_param_word(pgc_t *dev, int16_t *val) int32_t c; if (dev->clcur) { - if (! pgc_clist_byte(dev, &lo)) return 0; - if (! pgc_clist_byte(dev, &hi)) return 0; - *val = (((int16_t)hi) << 8) | lo; + if (!pgc_clist_byte(dev, &lo)) + return 0; + if (!pgc_clist_byte(dev, &hi)) + return 0; + *val = (((int16_t) hi) << 8) | lo; - return 1; + return 1; } - if (! dev->ascii_mode) { - if (! dev->inputbyte(dev, &lo)) return 0; - if (! dev->inputbyte(dev, &hi)) return 0; - *val = (((int16_t)hi) << 8) | lo; + if (!dev->ascii_mode) { + if (!dev->inputbyte(dev, &lo)) + return 0; + if (!dev->inputbyte(dev, &hi)) + return 0; + *val = (((int16_t) hi) << 8) | lo; - return 1; + return 1; } - if (! pgc_param_coord(dev, &c)) return 0; + if (!pgc_param_coord(dev, &c)) + return 0; c = (c >> 16); if (c > 0x7fff || c < -0x7fff) { - pgc_error(dev, PGC_ERROR_RANGE); - return 0; + pgc_error(dev, PGC_ERROR_RANGE); + return 0; } - *val = (int16_t)c; + *val = (int16_t) c; return 1; } - typedef enum { PS_MAIN, PS_FRACTION, PS_EXPONENT } parse_state_t; - /* * Read in a PGC coordinate. * @@ -1821,136 +1815,143 @@ typedef enum { int pgc_param_coord(pgc_t *dev, int32_t *value) { - uint8_t asc; - int sign = 1; - int esign = 1; - int n; - uint16_t dp = 1; - uint16_t integer = 0; - uint16_t frac = 0; - uint16_t exponent = 0; - uint32_t res; + uint8_t asc; + int sign = 1; + int esign = 1; + int n; + uint16_t dp = 1; + uint16_t integer = 0; + uint16_t frac = 0; + uint16_t exponent = 0; + uint32_t res; parse_state_t state = PS_MAIN; - uint8_t encoded[4]; + uint8_t encoded[4]; /* If there is a command list running, pull the bytes out of that * command list */ if (dev->clcur) { - for (n = 0; n < 4; n++) - if (! pgc_clist_byte(dev, &encoded[n])) return 0; - integer = (((int16_t)encoded[1]) << 8) | encoded[0]; - frac = (((int16_t)encoded[3]) << 8) | encoded[2]; + for (n = 0; n < 4; n++) + if (!pgc_clist_byte(dev, &encoded[n])) + return 0; + integer = (((int16_t) encoded[1]) << 8) | encoded[0]; + frac = (((int16_t) encoded[3]) << 8) | encoded[2]; - *value = (((int32_t)integer) << 16) | frac; - return 1; + *value = (((int32_t) integer) << 16) | frac; + return 1; } /* If in hex mode, read in the encoded integer and fraction parts * from the hex stream */ - if (! dev->ascii_mode) { - for (n = 0; n < 4; n++) - if (! dev->inputbyte(dev, &encoded[n])) return 0; - integer = (((int16_t)encoded[1]) << 8) | encoded[0]; - frac = (((int16_t)encoded[3]) << 8) | encoded[2]; + if (!dev->ascii_mode) { + for (n = 0; n < 4; n++) + if (!dev->inputbyte(dev, &encoded[n])) + return 0; + integer = (((int16_t) encoded[1]) << 8) | encoded[0]; + frac = (((int16_t) encoded[3]) << 8) | encoded[2]; - *value = (((int32_t)integer) << 16) | frac; - return 1; + *value = (((int32_t) integer) << 16) | frac; + return 1; } /* Parsing an ASCII value; skip separators. */ do { - if (! dev->inputbyte(dev, &asc)) return 0; - if (asc == '-') sign = -1; - } while (is_whitespace(asc)); + if (!dev->inputbyte(dev, &asc)) + return 0; + if (asc == '-') + sign = -1; + } while (is_whitespace(asc)); /* There had better be a digit next. */ - if (! isdigit(asc)) { - pgc_error(dev, PGC_ERROR_MISSING); - return 0; + if (!isdigit(asc)) { + pgc_error(dev, PGC_ERROR_MISSING); + return 0; } do { - switch (asc) { - /* Decimal point is acceptable in 'main' state - * (start of fraction) not otherwise */ - case '.': - if (state == PS_MAIN) { - if (! dev->inputbyte(dev, &asc)) return 0; - state = PS_FRACTION; - continue; - } else { - pgc_error(dev, PGC_ERROR_MISSING); - return err_digit(dev); - } - break; + switch (asc) { + /* Decimal point is acceptable in 'main' state + * (start of fraction) not otherwise */ + case '.': + if (state == PS_MAIN) { + if (!dev->inputbyte(dev, &asc)) + return 0; + state = PS_FRACTION; + continue; + } else { + pgc_error(dev, PGC_ERROR_MISSING); + return err_digit(dev); + } + break; - /* Scientific notation. */ - case 'd': - case 'D': - case 'e': - case 'E': - esign = 1; - if (! dev->inputbyte(dev, &asc)) return 0; - if (asc == '-') { - sign = -1; - if (! dev->inputbyte(dev, &asc)) return 0; - } - state = PS_EXPONENT; - continue; + /* Scientific notation. */ + case 'd': + case 'D': + case 'e': + case 'E': + esign = 1; + if (!dev->inputbyte(dev, &asc)) + return 0; + if (asc == '-') { + sign = -1; + if (!dev->inputbyte(dev, &asc)) + return 0; + } + state = PS_EXPONENT; + continue; - /* Should be a number or a separator. */ - default: - if (is_whitespace(asc)) break; - if (! isdigit(asc)) { - pgc_error(dev, PGC_ERROR_MISSING); - return err_digit(dev); - } - asc -= '0'; /* asc is digit */ + /* Should be a number or a separator. */ + default: + if (is_whitespace(asc)) + break; + if (!isdigit(asc)) { + pgc_error(dev, PGC_ERROR_MISSING); + return err_digit(dev); + } + asc -= '0'; /* asc is digit */ - switch (state) { - case PS_MAIN: - integer = (integer * 10)+asc; - if (integer & 0x8000) { - /* Overflow */ - pgc_error(dev, PGC_ERROR_RANGE); - integer = 0x7fff; - } - break; + switch (state) { + case PS_MAIN: + integer = (integer * 10) + asc; + if (integer & 0x8000) { + /* Overflow */ + pgc_error(dev, PGC_ERROR_RANGE); + integer = 0x7fff; + } + break; - case PS_FRACTION: - frac = (frac * 10) + asc; - dp *= 10; - break; + case PS_FRACTION: + frac = (frac * 10) + asc; + dp *= 10; + break; - case PS_EXPONENT: - exponent = (exponent * 10)+asc; - break; - } + case PS_EXPONENT: + exponent = (exponent * 10) + asc; + break; + } + } - } - - if (! dev->inputbyte(dev, &asc)) return 0; - } while (! is_whitespace(asc)); + if (!dev->inputbyte(dev, &asc)) + return 0; + } while (!is_whitespace(asc)); res = (frac << 16) / dp; pgc_log("PGC: integer=%u frac=%u exponent=%u dp=%i res=0x%08lx\n", - integer, frac, exponent, dp, res); + integer, frac, exponent, dp, res); res = (res & 0xffff) | (integer << 16); if (exponent) { - for (n = 0; n < exponent; n++) { - if (esign > 0) - res *= 10; - else - res /= 10; - } + for (n = 0; n < exponent; n++) { + if (esign > 0) + res *= 10; + else + res /= 10; + } } - *value = sign*res; + *value = sign * res; return 1; } - /* * Add a byte to a command list. * @@ -1962,26 +1963,26 @@ pgc_cl_append(pgc_cl_t *list, uint8_t v) uint8_t *buf; if (list->listmax == 0 || list->list == NULL) { - list->list = (uint8_t *)malloc(4096); - if (!list->list) { + list->list = (uint8_t *) malloc(4096); + if (!list->list) { #ifdef ENABLE_PGC_LOG - pgc_log("PGC: out of memory initializing command list\n"); + pgc_log("PGC: out of memory initializing command list\n"); #endif - return 0; - } - list->listmax = 4096; + return 0; + } + list->listmax = 4096; } while (list->wrptr >= list->listmax) { - buf = (uint8_t *)realloc(list->list, 2 * list->listmax); - if (!buf) { + buf = (uint8_t *) realloc(list->list, 2 * list->listmax); + if (!buf) { #ifdef ENABLE_PGC_LOG - pgc_log("PGC: out of memory growing command list\n"); + pgc_log("PGC: out of memory growing command list\n"); #endif - return 0; - } - list->list = buf; - list->listmax *= 2; + return 0; + } + list->list = buf; + list->listmax *= 2; } list->list[list->wrptr++] = v; @@ -1989,30 +1990,29 @@ pgc_cl_append(pgc_cl_t *list, uint8_t v) return 1; } - /* Parse but don't execute a command with a fixed number of byte parameters. */ int pgc_parse_bytes(pgc_t *dev, pgc_cl_t *cl, int count) { - uint8_t *param = (uint8_t *)malloc(count); - int n; + uint8_t *param = (uint8_t *) malloc(count); + int n; - if (! param) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - return 0; + if (!param) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + return 0; } for (n = 0; n < count; n++) { - if (! pgc_param_byte(dev, ¶m[n])) { - free(param); - return 0; - } + if (!pgc_param_byte(dev, ¶m[n])) { + free(param); + return 0; + } - if (! pgc_cl_append(cl, param[n])) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - free(param); - return 0; - } + if (!pgc_cl_append(cl, param[n])) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } } free(param); @@ -2020,31 +2020,29 @@ pgc_parse_bytes(pgc_t *dev, pgc_cl_t *cl, int count) return 1; } - /* Parse but don't execute a command with a fixed number of word parameters. */ int pgc_parse_words(pgc_t *dev, pgc_cl_t *cl, int count) { - int16_t *param = (int16_t *)malloc(count * sizeof(int16_t)); - int n; + int16_t *param = (int16_t *) malloc(count * sizeof(int16_t)); + int n; - if (! param) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - return 0; + if (!param) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + return 0; } for (n = 0; n < count; n++) { - if (! pgc_param_word(dev, ¶m[n])) { - free(param); - return 0; - } + if (!pgc_param_word(dev, ¶m[n])) { + free(param); + return 0; + } - if (!pgc_cl_append(cl, param[n] & 0xff) || - !pgc_cl_append(cl, param[n] >> 8)) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - free(param); - return 0; - } + if (!pgc_cl_append(cl, param[n] & 0xff) || !pgc_cl_append(cl, param[n] >> 8)) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } } free(param); @@ -2052,24 +2050,23 @@ pgc_parse_words(pgc_t *dev, pgc_cl_t *cl, int count) return 1; } - /* Parse but don't execute a command with a fixed number of coord parameters */ int pgc_parse_coords(pgc_t *dev, pgc_cl_t *cl, int count) { - int32_t *param = (int32_t *)malloc(count * sizeof(int32_t)); - int n; + int32_t *param = (int32_t *) malloc(count * sizeof(int32_t)); + int n; - if (! param) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - return 0; + if (!param) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + return 0; } for (n = 0; n < count; n++) { - if (! pgc_param_coord(dev, ¶m[n])) { - free(param); - return 0; - } + if (!pgc_param_coord(dev, ¶m[n])) { + free(param); + return 0; + } } /* Here is how the real PGC serializes coords: @@ -2078,17 +2075,15 @@ pgc_parse_coords(pgc_t *dev, pgc_cl_t *cl, int count) * 100.3 -> 64 00 CD 4C ie 0064.4CCD */ for (n = 0; n < count; n++) { - /* Serialize integer part. */ - if (!pgc_cl_append(cl, (param[n] >> 16) & 0xff) || - !pgc_cl_append(cl, (param[n] >> 24) & 0xff) || + /* Serialize integer part. */ + if (!pgc_cl_append(cl, (param[n] >> 16) & 0xff) || !pgc_cl_append(cl, (param[n] >> 24) & 0xff) || - /* Serialize fraction part. */ - !pgc_cl_append(cl, (param[n] ) & 0xff) || - !pgc_cl_append(cl, (param[n] >> 8) & 0xff)) { - pgc_error(dev, PGC_ERROR_OVERFLOW); - free(param); - return 0; - } + /* Serialize fraction part. */ + !pgc_cl_append(cl, (param[n]) & 0xff) || !pgc_cl_append(cl, (param[n] >> 8) & 0xff)) { + pgc_error(dev, PGC_ERROR_OVERFLOW); + free(param); + return 0; + } } free(param); @@ -2096,7 +2091,6 @@ pgc_parse_coords(pgc_t *dev, pgc_cl_t *cl, int count) return 1; } - /* Convert coordinates based on the current window / viewport to raster * coordinates. */ void @@ -2112,7 +2106,6 @@ pgc_dto_raster(pgc_t *dev, double *x, double *y) pgc_log("PGC: coords to raster: (%f, %f) -> (%f, %f)\n", x0, y0, *x, *y); } - /* Overloads that take ints. */ void pgc_sto_raster(pgc_t *dev, int16_t *x, int16_t *y) @@ -2120,106 +2113,102 @@ pgc_sto_raster(pgc_t *dev, int16_t *x, int16_t *y) double xd = *x, yd = *y; pgc_dto_raster(dev, &xd, &yd); - *x = (int16_t)xd; - *y = (int16_t)yd; + *x = (int16_t) xd; + *y = (int16_t) yd; } - void pgc_ito_raster(pgc_t *dev, int32_t *x, int32_t *y) { double xd = *x, yd = *y; pgc_dto_raster(dev, &xd, &yd); - *x = (int32_t)xd; - *y = (int32_t)yd; + *x = (int32_t) xd; + *y = (int32_t) yd; } - void pgc_recalctimings(pgc_t *dev) { double disptime, _dispontime, _dispofftime; - double pixel_clock = (cpuclock * (double)(1ull << 32)) / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock); + double pixel_clock = (cpuclock * (double) (1ull << 32)) / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock); /* Use a fixed 640x400 display. */ - disptime = dev->screenw + 11; - _dispontime = dev->screenw * pixel_clock; - _dispofftime = (disptime - dev->screenw) * pixel_clock; - dev->dispontime = (uint64_t)(_dispontime); - dev->dispofftime = (uint64_t)(_dispofftime); + disptime = dev->screenw + 11; + _dispontime = dev->screenw * pixel_clock; + _dispofftime = (disptime - dev->screenw) * pixel_clock; + dev->dispontime = (uint64_t) (_dispontime); + dev->dispofftime = (uint64_t) (_dispofftime); } - /* Write to CGA registers are copied into the transfer memory buffer. */ void pgc_out(uint16_t addr, uint8_t val, void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; pgc_log("PGC: out(%04x, %02x)\n", addr, val); - switch(addr) { - case 0x03d0: /* CRTC Index register */ - case 0x03d2: - case 0x03d4: - case 0x03d6: - dev->mapram[0x03d0] = val; - break; + switch (addr) { + case 0x03d0: /* CRTC Index register */ + case 0x03d2: + case 0x03d4: + case 0x03d6: + dev->mapram[0x03d0] = val; + break; - case 0x03d1: /* CRTC Data register */ - case 0x03d3: - case 0x03d5: - case 0x03d7: - if (dev->mapram[0x03d0] < 18) - dev->mapram[0x03e0 + dev->mapram[0x03d0]] = val; - break; + case 0x03d1: /* CRTC Data register */ + case 0x03d3: + case 0x03d5: + case 0x03d7: + if (dev->mapram[0x03d0] < 18) + dev->mapram[0x03e0 + dev->mapram[0x03d0]] = val; + break; - case 0x03d8: /* CRTC Mode Control register */ - dev->mapram[0x03d8] = val; - break; + case 0x03d8: /* CRTC Mode Control register */ + dev->mapram[0x03d8] = val; + break; - case 0x03d9: /* CRTC Color Select register */ - dev->mapram[0x03d9] = val; - break; + case 0x03d9: /* CRTC Color Select register */ + dev->mapram[0x03d9] = val; + break; } } - /* Read back the CGA registers. */ uint8_t pgc_in(uint16_t addr, void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; uint8_t ret = 0xff; - switch(addr) { - case 0x03d0: /* CRTC Index register */ - case 0x03d2: - case 0x03d4: - case 0x03d6: - ret = dev->mapram[0x03d0]; - break; + switch (addr) { + case 0x03d0: /* CRTC Index register */ + case 0x03d2: + case 0x03d4: + case 0x03d6: + ret = dev->mapram[0x03d0]; + break; - case 0x03d1: /* CRTC Data register */ - case 0x03d3: - case 0x03d5: - case 0x03d7: - if (dev->mapram[0x03d0] < 18) - ret = dev->mapram[0x03e0 + dev->mapram[0x03d0]]; - break; + case 0x03d1: /* CRTC Data register */ + case 0x03d3: + case 0x03d5: + case 0x03d7: + if (dev->mapram[0x03d0] < 18) + ret = dev->mapram[0x03e0 + dev->mapram[0x03d0]]; + break; - case 0x03d8: /* CRTC Mode Control register */ - ret = dev->mapram[0x03d8]; - break; + case 0x03d8: /* CRTC Mode Control register */ + ret = dev->mapram[0x03d8]; + break; - case 0x03d9: /* CRTC Color Select register */ - ret = dev->mapram[0x03d9]; - break; + case 0x03d9: /* CRTC Color Select register */ + ret = dev->mapram[0x03d9]; + break; - case 0x03da: /* CRTC Status register */ - ret = dev->mapram[0x03da]; - break; + case 0x03da: /* CRTC Status register */ + ret = dev->mapram[0x03da]; + break; } pgc_log("PGC: in(%04x) = %02x\n", addr, ret); @@ -2227,13 +2216,12 @@ pgc_in(uint16_t addr, void *priv) return ret; } - /* Memory write to the transfer buffer. */ /* TODO: Check the CGA mapping repeat stuff. */ void pgc_write(uint32_t addr, uint8_t val, void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; /* * It seems variable whether the PGC maps 1K or 2K at 0xc6000. @@ -2241,154 +2229,146 @@ pgc_write(uint32_t addr, uint8_t val, void *priv) * Map 2K here in case a clone requires it. */ if (addr >= 0xc6000 && addr < 0xc6800) { - addr &= 0x7ff; + addr &= 0x7ff; - /* If one of the FIFOs has been updated, this may cause - * the drawing thread to be woken */ + /* If one of the FIFOs has been updated, this may cause + * the drawing thread to be woken */ - if (dev->mapram[addr] != val) { - dev->mapram[addr] = val; + if (dev->mapram[addr] != val) { + dev->mapram[addr] = val; - switch (addr) { - case 0x300: /* input write pointer */ - if (dev->waiting_input_fifo && - dev->mapram[0x300] != dev->mapram[0x301]) { - dev->waiting_input_fifo = 0; - pgc_wake(dev); - } - break; + switch (addr) { + case 0x300: /* input write pointer */ + if (dev->waiting_input_fifo && dev->mapram[0x300] != dev->mapram[0x301]) { + dev->waiting_input_fifo = 0; + pgc_wake(dev); + } + break; - case 0x303: /* output read pointer */ - if (dev->waiting_output_fifo && - dev->mapram[0x302] != (uint8_t)(dev->mapram[0x303] - 1)) { - dev->waiting_output_fifo = 0; - pgc_wake(dev); - } - break; + case 0x303: /* output read pointer */ + if (dev->waiting_output_fifo && dev->mapram[0x302] != (uint8_t) (dev->mapram[0x303] - 1)) { + dev->waiting_output_fifo = 0; + pgc_wake(dev); + } + break; - case 0x305: /* error read pointer */ - if (dev->waiting_error_fifo && - dev->mapram[0x304] != (uint8_t)(dev->mapram[0x305] - 1)) { - dev->waiting_error_fifo = 0; - pgc_wake(dev); - } - break; + case 0x305: /* error read pointer */ + if (dev->waiting_error_fifo && dev->mapram[0x304] != (uint8_t) (dev->mapram[0x305] - 1)) { + dev->waiting_error_fifo = 0; + pgc_wake(dev); + } + break; - case 0x306: /* cold start flag */ - /* XXX This should be in IM-1024 specific code */ - dev->mapram[0x306] = 0; - break; + case 0x306: /* cold start flag */ + /* XXX This should be in IM-1024 specific code */ + dev->mapram[0x306] = 0; + break; - case 0x30c: /* display type */ - pgc_setdisplay(priv, dev->mapram[0x30c]); - dev->mapram[0x30d] = dev->mapram[0x30c]; - break; + case 0x30c: /* display type */ + pgc_setdisplay(priv, dev->mapram[0x30c]); + dev->mapram[0x30d] = dev->mapram[0x30c]; + break; - case 0x3ff: /* reboot the PGC */ - pgc_wake(dev); - break; - } - } + case 0x3ff: /* reboot the PGC */ + pgc_wake(dev); + break; + } + } } if (addr >= 0xb8000 && addr < 0xc0000 && dev->cga_selected) { - addr &= 0x3fff; - dev->cga_vram[addr] = val; + addr &= 0x3fff; + dev->cga_vram[addr] = val; } } - /* TODO: Check the CGA mapping repeat stuff. */ uint8_t pgc_read(uint32_t addr, void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; uint8_t ret = 0xff; if (addr >= 0xc6000 && addr < 0xc6800) { - addr &= 0x7ff; - ret = dev->mapram[addr]; + addr &= 0x7ff; + ret = dev->mapram[addr]; } else if (addr >= 0xb8000 && addr < 0xc0000 && dev->cga_selected) { - addr &= 0x3fff; - ret = dev->cga_vram[addr]; + addr &= 0x3fff; + ret = dev->cga_vram[addr]; } return ret; } - /* Draw the display in CGA (640x400) text mode. */ void pgc_cga_text(pgc_t *dev, int w) { - int x, c; - uint8_t chr, attr; - int drawcursor = 0; + int x, c; + uint8_t chr, attr; + int drawcursor = 0; uint32_t cols[2]; - int pitch = (dev->mapram[0x3e9] + 1) * 2; - uint16_t sc = (dev->displine & 0x0f) % pitch; - uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; - uint16_t ca = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff; + int pitch = (dev->mapram[0x3e9] + 1) * 2; + uint16_t sc = (dev->displine & 0x0f) % pitch; + uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; + uint16_t ca = (dev->mapram[0x3ef] | (dev->mapram[0x3ee] << 8)) & 0x3fff; uint8_t *addr; uint32_t val; - int cw = (w == 80) ? 8 : 16; + int cw = (w == 80) ? 8 : 16; addr = &dev->cga_vram[((ma + ((dev->displine / pitch) * w)) * 2) & 0x3ffe]; ma += (dev->displine / pitch) * w; for (x = 0; x < w; x++) { - chr = *addr++; - attr = *addr++; + chr = *addr++; + attr = *addr++; - /* Cursor enabled? */ - if (ma == ca && (dev->cgablink & 8) && - (dev->mapram[0x3ea] & 0x60) != 0x20) { - drawcursor = ((dev->mapram[0x3ea] & 0x1f) <= (sc >> 1)) && - ((dev->mapram[0x3eb] & 0x1f) >= (sc >> 1)); - } else - drawcursor = 0; + /* Cursor enabled? */ + if (ma == ca && (dev->cgablink & 8) && (dev->mapram[0x3ea] & 0x60) != 0x20) { + drawcursor = ((dev->mapram[0x3ea] & 0x1f) <= (sc >> 1)) && ((dev->mapram[0x3eb] & 0x1f) >= (sc >> 1)); + } else + drawcursor = 0; - if (dev->mapram[0x3d8] & 0x20) { - cols[1] = (attr & 15) + 16; - cols[0] = ((attr >> 4) & 7) + 16; - if ((dev->cgablink & 8) && (attr & 0x80) && !drawcursor) - cols[1] = cols[0]; - } else { - cols[1] = (attr & 15) + 16; - cols[0] = (attr >> 4) + 16; - } - - for (c = 0; c < cw; c++) { - if (drawcursor) - val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f; - else - val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; - if (cw == 8) /* 80x25 CGA text screen. */ - buffer32->line[dev->displine][(x * cw) + c] = val; - else { /* 40x25 CGA text screen. */ - buffer32->line[dev->displine][(x * cw) + (c * 2)] = val; - buffer32->line[dev->displine][(x * cw) + (c * 2) + 1] = val; + if (dev->mapram[0x3d8] & 0x20) { + cols[1] = (attr & 15) + 16; + cols[0] = ((attr >> 4) & 7) + 16; + if ((dev->cgablink & 8) && (attr & 0x80) && !drawcursor) + cols[1] = cols[0]; + } else { + cols[1] = (attr & 15) + 16; + cols[0] = (attr >> 4) + 16; } - } - ma++; + for (c = 0; c < cw; c++) { + if (drawcursor) + val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f; + else + val = cols[(fontdatm[chr + dev->fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + if (cw == 8) /* 80x25 CGA text screen. */ + buffer32->line[dev->displine][(x * cw) + c] = val; + else { /* 40x25 CGA text screen. */ + buffer32->line[dev->displine][(x * cw) + (c * 2)] = val; + buffer32->line[dev->displine][(x * cw) + (c * 2) + 1] = val; + } + } + + ma++; } } - /* Draw the display in CGA (320x200) graphics mode. */ void pgc_cga_gfx40(pgc_t *dev) { - int x, c; + int x, c; uint32_t cols[4]; - int col; + int col; uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; uint8_t *addr; uint16_t dat; cols[0] = (dev->mapram[0x3d9] & 15) + 16; - col = ((dev->mapram[0x3d9] & 16) ? 8 : 0) + 16; + col = ((dev->mapram[0x3d9] & 16) ? 8 : 0) + 16; /* From John Elliott's site: On a real CGA, if bit 2 of port 03D8h and bit 5 of port 03D9h are both set, @@ -2396,37 +2376,35 @@ pgc_cga_gfx40(pgc_t *dev) magenta/cyan/white. You still get red/cyan/white if bit 5 of port 03D9h is not set. This is a firmware issue rather than hardware. */ if (dev->mapram[0x3d9] & 32) { - cols[1] = col | 3; - cols[2] = col | 5; - cols[3] = col | 7; + cols[1] = col | 3; + cols[2] = col | 5; + cols[3] = col | 7; } else if (dev->mapram[0x3d8] & 4) { - cols[1] = col | 3; - cols[2] = col | 4; - cols[3] = col | 7; + cols[1] = col | 3; + cols[2] = col | 4; + cols[3] = col | 7; } else { - cols[1] = col | 2; - cols[2] = col | 4; - cols[3] = col | 6; + cols[1] = col | 2; + cols[2] = col | 4; + cols[3] = col | 6; } for (x = 0; x < 40; x++) { - addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; - dat = (addr[0] << 8) | addr[1]; - dev->ma++; - for (c = 0; c < 8; c++) { - buffer32->line[dev->displine][(x << 4) + (c << 1)] = - buffer32->line[dev->displine][(x << 4) + (c << 1) + 1] = cols[dat >> 14]; - dat <<= 2; - } + addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; + dat = (addr[0] << 8) | addr[1]; + dev->ma++; + for (c = 0; c < 8; c++) { + buffer32->line[dev->displine][(x << 4) + (c << 1)] = buffer32->line[dev->displine][(x << 4) + (c << 1) + 1] = cols[dat >> 14]; + dat <<= 2; + } } } - /* Draw the display in CGA (640x200) graphics mode. */ void pgc_cga_gfx80(pgc_t *dev) { - int x, c; + int x, c; uint32_t cols[2]; uint16_t ma = (dev->mapram[0x3ed] | (dev->mapram[0x3ec] << 8)) & 0x3fff; uint8_t *addr; @@ -2436,179 +2414,175 @@ pgc_cga_gfx80(pgc_t *dev) cols[1] = (dev->mapram[0x3d9] & 15) + 16; for (x = 0; x < 40; x++) { - addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; - dat = (addr[0] << 8) | addr[1]; - dev->ma++; - for (c = 0; c < 16; c++) { - buffer32->line[dev->displine][(x << 4) + c] = cols[dat >> 15]; - dat <<= 1; - } + addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff]; + dat = (addr[0] << 8) | addr[1]; + dev->ma++; + for (c = 0; c < 16; c++) { + buffer32->line[dev->displine][(x << 4) + c] = cols[dat >> 15]; + dat <<= 1; + } } } - /* Draw the screen in CGA mode. */ void pgc_cga_poll(pgc_t *dev) { uint32_t cols[2]; - if (! dev->linepos) { - timer_advance_u64(&dev->timer, dev->dispofftime); - dev->mapram[0x03da] |= 1; - dev->linepos = 1; + if (!dev->linepos) { + timer_advance_u64(&dev->timer, dev->dispofftime); + dev->mapram[0x03da] |= 1; + dev->linepos = 1; - if (dev->cgadispon) { - if (dev->displine == 0) - video_wait_for_buffer(); + if (dev->cgadispon) { + if (dev->displine == 0) + video_wait_for_buffer(); - if ((dev->mapram[0x03d8] & 0x12) == 0x12) - pgc_cga_gfx80(dev); - else if (dev->mapram[0x03d8] & 0x02) - pgc_cga_gfx40(dev); - else if (dev->mapram[0x03d8] & 0x01) - pgc_cga_text(dev, 80); - else - pgc_cga_text(dev, 40); - } else { - cols[0] = ((dev->mapram[0x03d8] & 0x12) == 0x12) ? 0 : ((dev->mapram[0x03d9] & 15) + 16); - hline(buffer32, 0, dev->displine, PGC_CGA_WIDTH, cols[0]); - } + if ((dev->mapram[0x03d8] & 0x12) == 0x12) + pgc_cga_gfx80(dev); + else if (dev->mapram[0x03d8] & 0x02) + pgc_cga_gfx40(dev); + else if (dev->mapram[0x03d8] & 0x01) + pgc_cga_text(dev, 80); + else + pgc_cga_text(dev, 40); + } else { + cols[0] = ((dev->mapram[0x03d8] & 0x12) == 0x12) ? 0 : ((dev->mapram[0x03d9] & 15) + 16); + hline(buffer32, 0, dev->displine, PGC_CGA_WIDTH, cols[0]); + } - if (++dev->displine == PGC_CGA_HEIGHT) { - dev->mapram[0x3da] |= 8; - dev->cgadispon = 0; - } - if (dev->displine == PGC_CGA_HEIGHT + 32) { - dev->mapram[0x3da] &= ~8; - dev->cgadispon = 1; - dev->displine = 0; - } + if (++dev->displine == PGC_CGA_HEIGHT) { + dev->mapram[0x3da] |= 8; + dev->cgadispon = 0; + } + if (dev->displine == PGC_CGA_HEIGHT + 32) { + dev->mapram[0x3da] &= ~8; + dev->cgadispon = 1; + dev->displine = 0; + } } else { - if (dev->cgadispon) - dev->mapram[0x3da] &= ~1; - timer_advance_u64(&dev->timer, dev->dispontime); - dev->linepos = 0; + if (dev->cgadispon) + dev->mapram[0x3da] &= ~1; + timer_advance_u64(&dev->timer, dev->dispontime); + dev->linepos = 0; - if (dev->displine == PGC_CGA_HEIGHT) { - if (PGC_CGA_WIDTH != xsize || PGC_CGA_HEIGHT != ysize) { - xsize = PGC_CGA_WIDTH; - ysize = PGC_CGA_HEIGHT; - set_screen_size(xsize, ysize); + if (dev->displine == PGC_CGA_HEIGHT) { + if (PGC_CGA_WIDTH != xsize || PGC_CGA_HEIGHT != ysize) { + xsize = PGC_CGA_WIDTH; + ysize = PGC_CGA_HEIGHT; + set_screen_size(xsize, ysize); - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen_8(0, 0, xsize, ysize); - frames++; + if (video_force_resize_get()) + video_force_resize_set(0); + } + video_blit_memtoscreen_8(0, 0, xsize, ysize); + frames++; - /* We have a fixed 640x400 screen for CGA modes. */ - video_res_x = PGC_CGA_WIDTH; - video_res_y = PGC_CGA_HEIGHT; - switch (dev->mapram[0x3d8] & 0x12) { - case 0x12: - video_bpp = 1; - break; + /* We have a fixed 640x400 screen for CGA modes. */ + video_res_x = PGC_CGA_WIDTH; + video_res_y = PGC_CGA_HEIGHT; + switch (dev->mapram[0x3d8] & 0x12) { + case 0x12: + video_bpp = 1; + break; - case 0x02: - video_bpp = 2; - break; + case 0x02: + video_bpp = 2; + break; - default: - video_bpp = 0; - break; - } - dev->cgablink++; - } + default: + video_bpp = 0; + break; + } + dev->cgablink++; + } } } - /* Draw the screen in CGA or native mode. */ void pgc_poll(void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; uint32_t x, y; if (dev->cga_selected) { - pgc_cga_poll(dev); - return; + pgc_cga_poll(dev); + return; } /* Not CGA, so must be native mode. */ - if (! dev->linepos) { - timer_advance_u64(&dev->timer, dev->dispofftime); - dev->mapram[0x3da] |= 1; - dev->linepos = 1; - if (dev->cgadispon && (uint32_t)dev->displine < dev->maxh) { - if (dev->displine == 0) - video_wait_for_buffer(); + if (!dev->linepos) { + timer_advance_u64(&dev->timer, dev->dispofftime); + dev->mapram[0x3da] |= 1; + dev->linepos = 1; + if (dev->cgadispon && (uint32_t) dev->displine < dev->maxh) { + if (dev->displine == 0) + video_wait_for_buffer(); - /* Don't know why pan needs to be multiplied by -2, but - * the IM1024 driver uses PAN -112 for an offset of - * 224. */ - y = dev->displine - 2 * dev->pan_y; - for (x = 0; x < dev->screenw; x++) { - if (x + dev->pan_x < dev->maxw) - buffer32->line[dev->displine][x] = dev->palette[dev->vram[y * dev->maxw + x]]; - else - buffer32->line[dev->displine][x] = dev->palette[0]; - } - } else { - hline(buffer32, 0, dev->displine, dev->screenw, dev->palette[0]); - } + /* Don't know why pan needs to be multiplied by -2, but + * the IM1024 driver uses PAN -112 for an offset of + * 224. */ + y = dev->displine - 2 * dev->pan_y; + for (x = 0; x < dev->screenw; x++) { + if (x + dev->pan_x < dev->maxw) + buffer32->line[dev->displine][x] = dev->palette[dev->vram[y * dev->maxw + x]]; + else + buffer32->line[dev->displine][x] = dev->palette[0]; + } + } else { + hline(buffer32, 0, dev->displine, dev->screenw, dev->palette[0]); + } - if (++dev->displine == dev->screenh) { - dev->mapram[0x3da] |= 8; - dev->cgadispon = 0; - } + if (++dev->displine == dev->screenh) { + dev->mapram[0x3da] |= 8; + dev->cgadispon = 0; + } - if (dev->displine == dev->screenh + 32) { - dev->mapram[0x3da] &= ~8; - dev->cgadispon = 1; - dev->displine = 0; - } + if (dev->displine == dev->screenh + 32) { + dev->mapram[0x3da] &= ~8; + dev->cgadispon = 1; + dev->displine = 0; + } } else { - if (dev->cgadispon) - dev->mapram[0x3da] &= ~1; - timer_advance_u64(&dev->timer, dev->dispontime); - dev->linepos = 0; + if (dev->cgadispon) + dev->mapram[0x3da] &= ~1; + timer_advance_u64(&dev->timer, dev->dispontime); + dev->linepos = 0; - if (dev->displine == dev->screenh) { - if (dev->screenw != xsize || dev->screenh != ysize) { - xsize = dev->screenw; - ysize = dev->screenh; - set_screen_size(xsize, ysize); + if (dev->displine == dev->screenh) { + if (dev->screenw != xsize || dev->screenh != ysize) { + xsize = dev->screenw; + ysize = dev->screenh; + set_screen_size(xsize, ysize); - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen(0, 0, xsize, ysize); - frames++; + if (video_force_resize_get()) + video_force_resize_set(0); + } + video_blit_memtoscreen(0, 0, xsize, ysize); + frames++; - video_res_x = dev->screenw; - video_res_y = dev->screenh; - video_bpp = 8; - dev->cgablink++; - } + video_res_x = dev->screenw; + video_res_y = dev->screenh; + video_bpp = 8; + dev->cgablink++; + } } } - void pgc_speed_changed(void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; pgc_recalctimings(dev); } - void pgc_close_common(void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; /* * Close down the worker thread by setting a @@ -2618,11 +2592,11 @@ pgc_close_common(void *priv) #ifdef ENABLE_PGC_LOG pgc_log("PGC: telling thread to stop...\n"); #endif - dev->stopped = 1; + dev->stopped = 1; dev->mapram[0x3ff] = 1; if (dev->waiting_input_fifo || dev->waiting_output_fifo) { - /* Do an immediate wake-up. */ - wake_timer(priv); + /* Do an immediate wake-up. */ + wake_timer(priv); } /* Wait for thread to stop. */ @@ -2636,23 +2610,21 @@ pgc_close_common(void *priv) #endif if (dev->cga_vram) - free(dev->cga_vram); + free(dev->cga_vram); if (dev->vram) - free(dev->vram); + free(dev->vram); } - void pgc_close(void *priv) { - pgc_t *dev = (pgc_t *)priv; + pgc_t *dev = (pgc_t *) priv; pgc_close_common(priv); free(dev); } - /* * Initialization code common to the PGC and its subclasses. * @@ -2662,7 +2634,7 @@ pgc_close(void *priv) */ void pgc_init(pgc_t *dev, int maxw, int maxh, int visw, int vish, - int (*inpbyte)(pgc_t *, uint8_t *), double npc) + int (*inpbyte)(pgc_t *, uint8_t *), double npc) { int i; @@ -2670,58 +2642,57 @@ pgc_init(pgc_t *dev, int maxw, int maxh, int visw, int vish, because of the emulator's granularity - the original mapping will conflict with hard disk controller BIOS'es. */ mem_mapping_add(&dev->mapping, 0xc4000, 16384, - pgc_read,NULL,NULL, pgc_write,NULL,NULL, - NULL, MEM_MAPPING_EXTERNAL, dev); + pgc_read, NULL, NULL, pgc_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, dev); mem_mapping_add(&dev->cga_mapping, 0xb8000, 32768, - pgc_read,NULL,NULL, pgc_write,NULL,NULL, - NULL, MEM_MAPPING_EXTERNAL, dev); + pgc_read, NULL, NULL, pgc_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, dev); io_sethandler(0x03d0, 16, - pgc_in,NULL,NULL, pgc_out,NULL,NULL, dev); + pgc_in, NULL, NULL, pgc_out, NULL, NULL, dev); dev->maxw = maxw; dev->maxh = maxh; dev->visw = visw; dev->vish = vish; - dev->vram = (uint8_t *)malloc(maxw * maxh); + dev->vram = (uint8_t *) malloc(maxw * maxh); memset(dev->vram, 0x00, maxw * maxh); - dev->cga_vram = (uint8_t *)malloc(16384); + dev->cga_vram = (uint8_t *) malloc(16384); memset(dev->cga_vram, 0x00, 16384); /* Create and initialize command lists. */ - dev->clist = (pgc_cl_t *)malloc(256 * sizeof(pgc_cl_t)); + dev->clist = (pgc_cl_t *) malloc(256 * sizeof(pgc_cl_t)); memset(dev->clist, 0x00, 256 * sizeof(pgc_cl_t)); for (i = 0; i < 256; i++) { - dev->clist[i].list = NULL; - dev->clist[i].listmax = 0; - dev->clist[i].wrptr = 0; - dev->clist[i].rdptr = 0; - dev->clist[i].repeat = 0; - dev->clist[i].chain = NULL; + dev->clist[i].list = NULL; + dev->clist[i].listmax = 0; + dev->clist[i].wrptr = 0; + dev->clist[i].rdptr = 0; + dev->clist[i].repeat = 0; + dev->clist[i].chain = NULL; } - dev->clcur = NULL; + dev->clcur = NULL; dev->native_pixel_clock = npc; pgc_reset(dev); dev->inputbyte = inpbyte; dev->master = dev->commands = pgc_commands; - dev->pgc_wake_thread = thread_create_event(); - dev->pgc_thread = thread_create(pgc_thread, dev); + dev->pgc_wake_thread = thread_create_event(); + dev->pgc_thread = thread_create(pgc_thread, dev); timer_add(&dev->timer, pgc_poll, dev, 1); timer_add(&dev->wake_timer, wake_timer, dev, 0); } - static void * pgc_standalone_init(const device_t *info) { pgc_t *dev; - dev = (pgc_t *)malloc(sizeof(pgc_t)); + dev = (pgc_t *) malloc(sizeof(pgc_t)); memset(dev, 0x00, sizeof(pgc_t)); dev->type = info->local; @@ -2730,20 +2701,19 @@ pgc_standalone_init(const device_t *info) video_inform(VIDEO_FLAG_TYPE_CGA, &timing_pgc); - return(dev); + return (dev); } - const device_t pgc_device = { - .name = "PGC", + .name = "PGC", .internal_name = "pgc", - .flags = DEVICE_ISA, - .local = 0, - .init = pgc_standalone_init, - .close = pgc_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = pgc_standalone_init, + .close = pgc_close, + .reset = NULL, { .available = NULL }, .speed_changed = pgc_speed_changed, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index 2eb82626b..66d87bb2e 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -29,86 +29,84 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> - -#define BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN" +#define BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN" typedef struct { - const char *name; - int type; + const char *name; + int type; - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - uint8_t bank3d6, - bank3d7; + uint8_t bank3d6, + bank3d7; - uint32_t vram_size, - vram_mask; + uint32_t vram_size, + vram_mask; } rtg_t; +static video_timings_t timing_rtg_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_rtg_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10}; - -static void rtg_recalcbanking(rtg_t *dev) +static void +rtg_recalcbanking(rtg_t *dev) { - svga_t *svga = &dev->svga; + svga_t *svga = &dev->svga; - svga->write_bank = (dev->bank3d7 & 0x0f) * 65536; + svga->write_bank = (dev->bank3d7 & 0x0f) * 65536; - if (svga->gdcreg[0x0f] & 4) - svga->read_bank = (dev->bank3d6 & 0x0f) * 65536; - else - svga->read_bank = svga->write_bank; + if (svga->gdcreg[0x0f] & 4) + svga->read_bank = (dev->bank3d6 & 0x0f) * 65536; + else + svga->read_bank = svga->write_bank; } - static uint8_t rtg_in(uint16_t addr, void *priv) { - rtg_t *dev = (rtg_t *)priv; + rtg_t *dev = (rtg_t *) priv; svga_t *svga = &dev->svga; - uint8_t ret = 0; + uint8_t ret = 0; - if (((addr & 0xfff0) == 0x3d0 || - (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3ce: - return svga->gdcaddr; + case 0x3ce: + return svga->gdcaddr; - case 0x3cf: - if (svga->gdcaddr == 0x0c) - return svga->gdcreg[0x0c] | 4; - else if ((svga->gdcaddr > 8) && (svga->gdcaddr != 0x0c)) - return svga->gdcreg[svga->gdcaddr]; - break; + case 0x3cf: + if (svga->gdcaddr == 0x0c) + return svga->gdcreg[0x0c] | 4; + else if ((svga->gdcaddr > 8) && (svga->gdcaddr != 0x0c)) + return svga->gdcreg[svga->gdcaddr]; + break; - case 0x3d4: - return svga->crtcreg; + case 0x3d4: + return svga->crtcreg; - case 0x3d5: - if (!(svga->crtc[0x1e] & 0x80) && (svga->crtcreg > 0x18)) - return 0xff; - if (svga->crtcreg == 0x1a) - return dev->type << 6; - if (svga->crtcreg == 0x1e) { - if (dev->vram_size == 1024) - ret = 2; - else if (dev->vram_size == 512) - ret = 1; - else - ret = 0; - return svga->crtc[0x1e] | ret; - } - return svga->crtc[svga->crtcreg]; + case 0x3d5: + if (!(svga->crtc[0x1e] & 0x80) && (svga->crtcreg > 0x18)) + return 0xff; + if (svga->crtcreg == 0x1a) + return dev->type << 6; + if (svga->crtcreg == 0x1e) { + if (dev->vram_size == 1024) + ret = 2; + else if (dev->vram_size == 512) + ret = 1; + else + ret = 0; + return svga->crtc[0x1e] | ret; + } + return svga->crtc[svga->crtcreg]; - case 0x3d6: - return dev->bank3d6; + case 0x3d6: + return dev->bank3d6; - case 0x3d7: - return dev->bank3d7; - } + case 0x3d7: + return dev->bank3d7; + } return svga_in(addr, svga); } @@ -116,81 +114,80 @@ rtg_in(uint16_t addr, void *priv) static void rtg_out(uint16_t addr, uint8_t val, void *priv) { - rtg_t *dev = (rtg_t *)priv; + rtg_t *dev = (rtg_t *) priv; svga_t *svga = &dev->svga; uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || - (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; switch (addr) { - case 0x3ce: - svga->gdcaddr = val; - return; + case 0x3ce: + svga->gdcaddr = val; + return; - case 0x3cf: - if (svga->gdcaddr > 8) { - svga->gdcreg[svga->gdcaddr] = val; + case 0x3cf: + if (svga->gdcaddr > 8) { + svga->gdcreg[svga->gdcaddr] = val; - switch (svga->gdcaddr) { - case 0x0b: - case 0x0c: - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; + switch (svga->gdcaddr) { + case 0x0b: + case 0x0c: + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; - case 0x0f: - rtg_recalcbanking(dev); - return; - } - } - break; + case 0x0f: + rtg_recalcbanking(dev); + return; + } + } + break; - case 0x3d4: - svga->crtcreg = val & 0x3f; - return; + case 0x3d4: + svga->crtcreg = val & 0x3f; + return; - case 0x3d5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; + case 0x3d5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - if (svga->crtc[0x1e] & 0x80) { - switch (svga->crtcreg) { - case 0x19: - svga->vram_display_mask = (val & 0x20) ? dev->vram_mask : 0x3ffff; - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; - } - } + if (svga->crtc[0x1e] & 0x80) { + switch (svga->crtcreg) { + case 0x19: + svga->vram_display_mask = (val & 0x20) ? dev->vram_mask : 0x3ffff; + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + } + } - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - break; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; - case 0x3d6: - dev->bank3d6 = val; - rtg_recalcbanking(dev); - return; + case 0x3d6: + dev->bank3d6 = val; + rtg_recalcbanking(dev); + return; - case 0x3d7: - dev->bank3d7 = val; - rtg_recalcbanking(dev); - return; + case 0x3d7: + dev->bank3d7 = val; + rtg_recalcbanking(dev); + return; } svga_out(addr, val, svga); @@ -199,159 +196,156 @@ rtg_out(uint16_t addr, uint8_t val, void *priv) static void rtg_recalctimings(svga_t *svga) { - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17); + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17); - svga->interlace = (svga->crtc[0x19] & 1); + svga->interlace = (svga->crtc[0x19] & 1); - svga->lowres = svga->attrregs[0x10] & 0x40; + svga->lowres = svga->attrregs[0x10] & 0x40; - /*Clock table not available, currently a guesswork*/ - switch (((svga->miscout >> 2) & 3) | ((svga->gdcreg[0x0c] & 0x20) >> 3)) { - case 0: - case 1: - break; - case 2: - svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; - break; - case 3: - svga->clock = (cpuclock * (double)(1ull << 32)) / 65100000.0; - break; - case 4: - svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; - break; - case 5: - svga->clock = (cpuclock * (double)(1ull << 32)) / 50000000.0; - break; - case 6: - svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; - break; - case 7: - svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; - break; - } + /*Clock table not available, currently a guesswork*/ + switch (((svga->miscout >> 2) & 3) | ((svga->gdcreg[0x0c] & 0x20) >> 3)) { + case 0: + case 1: + break; + case 2: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + case 3: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65100000.0; + break; + case 4: + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; + break; + case 5: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50000000.0; + break; + case 6: + svga->clock = (cpuclock * (double) (1ull << 32)) / 80000000.0; + break; + case 7: + svga->clock = (cpuclock * (double) (1ull << 32)) / 75000000.0; + break; + } - switch (svga->gdcreg[0x0c] & 3) { - case 1: - svga->clock /= 1.5; - break; - case 2: - svga->clock /= 2; - break; - case 3: - svga->clock /= 4; - break; - } + switch (svga->gdcreg[0x0c] & 3) { + case 1: + svga->clock /= 1.5; + break; + case 2: + svga->clock /= 2; + break; + case 3: + svga->clock /= 4; + break; + } - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else { - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - svga->hdisp++; - svga->hdisp *= 8; + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else { + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + svga->hdisp++; + svga->hdisp *= 8; - if (svga->hdisp == 1280) - svga->rowoffset >>= 1; + if (svga->hdisp == 1280) + svga->rowoffset >>= 1; - svga->render = svga_render_4bpp_highres; - } - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: case 0x60: - svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); - svga->hdisp++; - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - if (svga->crtc[0x19] & 2) { - if (svga->hdisp == 1280) { - svga->hdisp >>= 1; - } else - svga->rowoffset <<= 1; + svga->render = svga_render_4bpp_highres; + } + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: + svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); + svga->hdisp++; + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + if (svga->crtc[0x19] & 2) { + if (svga->hdisp == 1280) { + svga->hdisp >>= 1; + } else + svga->rowoffset <<= 1; - svga->render = svga_render_8bpp_highres; - } else { - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - } - break; - } - } + svga->render = svga_render_8bpp_highres; + } else { + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + } + break; + } + } } static void * rtg_init(const device_t *info) { const char *fn; - rtg_t *dev; + rtg_t *dev; - dev = (rtg_t *)malloc(sizeof(rtg_t)); + dev = (rtg_t *) malloc(sizeof(rtg_t)); memset(dev, 0x00, sizeof(rtg_t)); dev->name = info->name; dev->type = info->local; - fn = BIOS_ROM_PATH; + fn = BIOS_ROM_PATH; - switch(dev->type) { - case 2: /* ISA RTG3106 */ - dev->vram_size = device_get_config_int("memory") << 10; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa); - svga_init(info, &dev->svga, dev, dev->vram_size, - rtg_recalctimings, rtg_in, rtg_out, - NULL, NULL); - io_sethandler(0x03c0, 32, - rtg_in,NULL,NULL, rtg_out,NULL,NULL, dev); - break; + switch (dev->type) { + case 2: /* ISA RTG3106 */ + dev->vram_size = device_get_config_int("memory") << 10; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa); + svga_init(info, &dev->svga, dev, dev->vram_size, + rtg_recalctimings, rtg_in, rtg_out, + NULL, NULL); + io_sethandler(0x03c0, 32, + rtg_in, NULL, NULL, rtg_out, NULL, NULL, dev); + break; } - dev->svga.bpp = 8; - dev->svga.miscout = 1; + dev->svga.bpp = 8; + dev->svga.miscout = 1; dev->vram_mask = dev->vram_size - 1; rom_init(&dev->bios_rom, (char *) fn, - 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - return(dev); + return (dev); } - static void rtg_close(void *priv) { - rtg_t *dev = (rtg_t *)priv; + rtg_t *dev = (rtg_t *) priv; svga_close(&dev->svga); free(dev); } - static void rtg_speed_changed(void *priv) { - rtg_t *dev = (rtg_t *)priv; + rtg_t *dev = (rtg_t *) priv; svga_recalctimings(&dev->svga); } - static void rtg_force_redraw(void *priv) { - rtg_t *dev = (rtg_t *)priv; + rtg_t *dev = (rtg_t *) priv; dev->svga.fullchange = changeframecount; } - static int rtg_available(void) { @@ -359,7 +353,7 @@ rtg_available(void) } static const device_config_t rtg_config[] = { -// clang-format off + // clang-format off { .name = "memory", .description = "Memory size", @@ -390,15 +384,15 @@ static const device_config_t rtg_config[] = { }; const device_t realtek_rtg3106_device = { - .name = "Realtek RTG3106 (ISA)", + .name = "Realtek RTG3106 (ISA)", .internal_name = "rtg3106", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 2, - .init = rtg_init, - .close = rtg_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 2, + .init = rtg_init, + .close = rtg_close, + .reset = NULL, { .available = rtg_available }, .speed_changed = rtg_speed_changed, - .force_redraw = rtg_force_redraw, - .config = rtg_config + .force_redraw = rtg_force_redraw, + .config = rtg_config }; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index b6a1af232..9b7e8679c 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -38,342 +38,335 @@ #include <86box/vid_svga_render.h> #include "cpu.h" -#define ROM_ORCHID_86C911 "roms/video/s3/BIOS.BIN" -#define ROM_DIAMOND_STEALTH_VRAM "roms/video/s3/Diamond Stealth VRAM BIOS v2.31 U14.BIN" -#define ROM_AMI_86C924 "roms/video/s3/S3924AMI.BIN" -#define ROM_METHEUS_86C928 "roms/video/s3/928.VBI" -#define ROM_SPEA_MERCURY_LITE_PCI "roms/video/s3/SPEAVGA.VBI" -#define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" -#define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" -#define ROM_MIROCRYSTAL8S_805 "roms/video/s3/S3_805VL_ATT20C491_miroCRYSTAL_8s_ver1.4.BIN" -#define ROM_MIROCRYSTAL10SD_805 "roms/video/s3/MIROcrystal10SD_VLB.VBI" -#define ROM_MIROCRYSTAL20SV_964_VLB "roms/video/s3/S3_964VL_BT485_27C256_miroCRYSTAL_20sv_ver1.2.bin" -#define ROM_MIROCRYSTAL20SV_964_PCI "roms/video/s3/mirocrystal.VBI" -#define ROM_MIROCRYSTAL20SD_864_VLB "roms/video/s3/Miro20SD.BIN" -#define ROM_PHOENIX_86C80X "roms/video/s3/805.VBI" -#define ROM_PARADISE_BAHAMAS64 "roms/video/s3/bahamas64.bin" -#define ROM_PHOENIX_VISION864 "roms/video/s3/86c864p.bin" -#define ROM_DIAMOND_STEALTH64_964 "roms/video/s3/964_107h.rom" -#define ROM_PHOENIX_TRIO32 "roms/video/s3/86c732p.bin" -#define ROM_SPEA_MIRAGE_P64 "roms/video/s3/S3_764VL_SPEAMirageP64VL_ver5_03.BIN" -#define ROM_NUMBER9_9FX "roms/video/s3/s3_764.bin" -#define ROM_PHOENIX_TRIO64 "roms/video/s3/86c764x1.bin" -#define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" -#define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.bin" -#define ROM_PHOENIX_TRIO64VPLUS "roms/video/s3/64V1506.ROM" -#define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" -#define ROM_ELSAWIN2KPROX_964 "roms/video/s3/elsaw20004m.BIN" -#define ROM_ELSAWIN2KPROX "roms/video/s3/elsaw20008m.BIN" -#define ROM_NUMBER9_9FX_531 "roms/video/s3/numbernine.BIN" -#define ROM_PHOENIX_VISION868 "roms/video/s3/1-DSV3868.BIN" -#define ROM_MIROVIDEO40SV_ERGO_968_PCI "roms/video/s3/S3_968PCI_TVP3026_miroVideo40SV_PCI_1.04.BIN" -#define ROM_SPEA_MERCURY_P64V "roms/video/s3/S3_968PCI_TVP3026_SPEAMecuryP64V_ver1.01.BIN" -#define ROM_NUMBER9_9FX_771 "roms/video/s3/no9motionfx771.BIN" -#define ROM_PHOENIX_VISION968 "roms/video/s3/1-DSV3968P.BIN" +#define ROM_ORCHID_86C911 "roms/video/s3/BIOS.BIN" +#define ROM_DIAMOND_STEALTH_VRAM "roms/video/s3/Diamond Stealth VRAM BIOS v2.31 U14.BIN" +#define ROM_AMI_86C924 "roms/video/s3/S3924AMI.BIN" +#define ROM_METHEUS_86C928 "roms/video/s3/928.VBI" +#define ROM_SPEA_MERCURY_LITE_PCI "roms/video/s3/SPEAVGA.VBI" +#define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" +#define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" +#define ROM_MIROCRYSTAL8S_805 "roms/video/s3/S3_805VL_ATT20C491_miroCRYSTAL_8s_ver1.4.BIN" +#define ROM_MIROCRYSTAL10SD_805 "roms/video/s3/MIROcrystal10SD_VLB.VBI" +#define ROM_MIROCRYSTAL20SV_964_VLB "roms/video/s3/S3_964VL_BT485_27C256_miroCRYSTAL_20sv_ver1.2.bin" +#define ROM_MIROCRYSTAL20SV_964_PCI "roms/video/s3/mirocrystal.VBI" +#define ROM_MIROCRYSTAL20SD_864_VLB "roms/video/s3/Miro20SD.BIN" +#define ROM_PHOENIX_86C80X "roms/video/s3/805.VBI" +#define ROM_PARADISE_BAHAMAS64 "roms/video/s3/bahamas64.bin" +#define ROM_PHOENIX_VISION864 "roms/video/s3/86c864p.bin" +#define ROM_DIAMOND_STEALTH64_964 "roms/video/s3/964_107h.rom" +#define ROM_PHOENIX_TRIO32 "roms/video/s3/86c732p.bin" +#define ROM_SPEA_MIRAGE_P64 "roms/video/s3/S3_764VL_SPEAMirageP64VL_ver5_03.BIN" +#define ROM_NUMBER9_9FX "roms/video/s3/s3_764.bin" +#define ROM_PHOENIX_TRIO64 "roms/video/s3/86c764x1.bin" +#define ROM_DIAMOND_STEALTH64_764 "roms/video/s3/stealt64.bin" +#define ROM_TRIO64V2_DX_VBE20 "roms/video/s3/86c775_2.bin" +#define ROM_PHOENIX_TRIO64VPLUS "roms/video/s3/64V1506.ROM" +#define ROM_DIAMOND_STEALTH_SE "roms/video/s3/DiamondStealthSE.VBI" +#define ROM_ELSAWIN2KPROX_964 "roms/video/s3/elsaw20004m.BIN" +#define ROM_ELSAWIN2KPROX "roms/video/s3/elsaw20008m.BIN" +#define ROM_NUMBER9_9FX_531 "roms/video/s3/numbernine.BIN" +#define ROM_PHOENIX_VISION868 "roms/video/s3/1-DSV3868.BIN" +#define ROM_MIROVIDEO40SV_ERGO_968_PCI "roms/video/s3/S3_968PCI_TVP3026_miroVideo40SV_PCI_1.04.BIN" +#define ROM_SPEA_MERCURY_P64V "roms/video/s3/S3_968PCI_TVP3026_SPEAMecuryP64V_ver1.01.BIN" +#define ROM_NUMBER9_9FX_771 "roms/video/s3/no9motionfx771.BIN" +#define ROM_PHOENIX_VISION968 "roms/video/s3/1-DSV3968P.BIN" -enum -{ - S3_NUMBER9_9FX, - S3_PARADISE_BAHAMAS64, - S3_DIAMOND_STEALTH64_964, - S3_PHOENIX_TRIO32, - S3_PHOENIX_TRIO64, - S3_PHOENIX_TRIO64_ONBOARD, - S3_PHOENIX_VISION864, - S3_DIAMOND_STEALTH64_764, - S3_SPEA_MIRAGE_86C801, - S3_SPEA_MIRAGE_86C805, - S3_PHOENIX_86C801, - S3_PHOENIX_86C805, - S3_ORCHID_86C911, - S3_METHEUS_86C928, - S3_AMI_86C924, - S3_TRIO64V2_DX, - S3_TRIO64V2_DX_ONBOARD, - S3_PHOENIX_TRIO64VPLUS, - S3_PHOENIX_TRIO64VPLUS_ONBOARD, - S3_DIAMOND_STEALTH_SE, - S3_DIAMOND_STEALTH_VRAM, - S3_ELSAWIN2KPROX_964, - S3_ELSAWIN2KPROX, - S3_PHOENIX_VISION868, - S3_MIROVIDEO40SV_ERGO_968, - S3_MIROCRYSTAL10SD_805, - S3_SPEA_MIRAGE_P64, - S3_SPEA_MERCURY_P64V, - S3_MIROCRYSTAL20SV_964, - S3_MIROCRYSTAL20SD_864, - S3_PHOENIX_VISION968, - S3_MIROCRYSTAL8S_805, - S3_NUMBER9_9FX_531, - S3_NUMBER9_9FX_771, - S3_SPEA_MERCURY_LITE_PCI, - S3_86C805_ONBOARD +enum { + S3_NUMBER9_9FX, + S3_PARADISE_BAHAMAS64, + S3_DIAMOND_STEALTH64_964, + S3_PHOENIX_TRIO32, + S3_PHOENIX_TRIO64, + S3_PHOENIX_TRIO64_ONBOARD, + S3_PHOENIX_VISION864, + S3_DIAMOND_STEALTH64_764, + S3_SPEA_MIRAGE_86C801, + S3_SPEA_MIRAGE_86C805, + S3_PHOENIX_86C801, + S3_PHOENIX_86C805, + S3_ORCHID_86C911, + S3_METHEUS_86C928, + S3_AMI_86C924, + S3_TRIO64V2_DX, + S3_TRIO64V2_DX_ONBOARD, + S3_PHOENIX_TRIO64VPLUS, + S3_PHOENIX_TRIO64VPLUS_ONBOARD, + S3_DIAMOND_STEALTH_SE, + S3_DIAMOND_STEALTH_VRAM, + S3_ELSAWIN2KPROX_964, + S3_ELSAWIN2KPROX, + S3_PHOENIX_VISION868, + S3_MIROVIDEO40SV_ERGO_968, + S3_MIROCRYSTAL10SD_805, + S3_SPEA_MIRAGE_P64, + S3_SPEA_MERCURY_P64V, + S3_MIROCRYSTAL20SV_964, + S3_MIROCRYSTAL20SD_864, + S3_PHOENIX_VISION968, + S3_MIROCRYSTAL8S_805, + S3_NUMBER9_9FX_531, + S3_NUMBER9_9FX_771, + S3_SPEA_MERCURY_LITE_PCI, + S3_86C805_ONBOARD }; - -enum -{ - S3_86C911 = 0x00, - S3_86C924 = 0x02, - S3_86C928 = 0x04, - S3_86C928PCI = 0x06, - S3_86C801 = 0x07, - S3_86C805 = 0x08, - S3_VISION964 = 0x18, - S3_VISION968 = 0x20, - S3_VISION864 = 0x28, - S3_VISION868 = 0x30, - S3_TRIO32 = 0x38, - S3_TRIO64 = 0x40, - S3_TRIO64V = 0x48, - S3_TRIO64V2 = 0x50 +enum { + S3_86C911 = 0x00, + S3_86C924 = 0x02, + S3_86C928 = 0x04, + S3_86C928PCI = 0x06, + S3_86C801 = 0x07, + S3_86C805 = 0x08, + S3_VISION964 = 0x18, + S3_VISION968 = 0x20, + S3_VISION864 = 0x28, + S3_VISION868 = 0x30, + S3_TRIO32 = 0x38, + S3_TRIO64 = 0x40, + S3_TRIO64V = 0x48, + S3_TRIO64V2 = 0x50 }; +static video_timings_t timing_s3_86c911 = { .type = VIDEO_ISA, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_86c801 = { .type = VIDEO_ISA, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_86c805 = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_86c928pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; +static video_timings_t timing_s3_stealth64_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; +static video_timings_t timing_s3_stealth64_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; +static video_timings_t timing_s3_vision864_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_vision864_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_vision868_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_vision868_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 4, .write_l = 5, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_vision964_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_vision964_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_vision968_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_vision968_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 20, .read_w = 20, .read_l = 35 }; +static video_timings_t timing_s3_trio32_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 3, .write_l = 5, .read_b = 26, .read_w = 26, .read_l = 42 }; +static video_timings_t timing_s3_trio32_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 3, .write_l = 5, .read_b = 26, .read_w = 26, .read_l = 42 }; +static video_timings_t timing_s3_trio64_vlb = { .type = VIDEO_BUS, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; +static video_timings_t timing_s3_trio64_pci = { .type = VIDEO_PCI, .write_b = 3, .write_w = 2, .write_l = 4, .read_b = 25, .read_w = 25, .read_l = 40 }; -static video_timings_t timing_s3_86c911 = {VIDEO_ISA, 4, 4, 5, 20, 20, 35}; -static video_timings_t timing_s3_86c801 = {VIDEO_ISA, 4, 4, 5, 20, 20, 35}; -static video_timings_t timing_s3_86c805 = {VIDEO_BUS, 4, 4, 5, 20, 20, 35}; -static video_timings_t timing_s3_86c928pci = {VIDEO_PCI, 2, 2, 4, 26, 26, 42}; -static video_timings_t timing_s3_stealth64_vlb = {VIDEO_BUS, 2, 2, 4, 26, 26, 42}; -static video_timings_t timing_s3_stealth64_pci = {VIDEO_PCI, 2, 2, 4, 26, 26, 42}; -static video_timings_t timing_s3_vision864_vlb = {VIDEO_BUS, 4, 4, 5, 20, 20, 35}; -static video_timings_t timing_s3_vision864_pci = {VIDEO_PCI, 4, 4, 5, 20, 20, 35}; -static video_timings_t timing_s3_vision868_vlb = {VIDEO_BUS, 4, 4, 5, 20, 20, 35}; -static video_timings_t timing_s3_vision868_pci = {VIDEO_PCI, 4, 4, 5, 20, 20, 35}; -static video_timings_t timing_s3_vision964_vlb = {VIDEO_BUS, 2, 2, 4, 20, 20, 35}; -static video_timings_t timing_s3_vision964_pci = {VIDEO_PCI, 2, 2, 4, 20, 20, 35}; -static video_timings_t timing_s3_vision968_vlb = {VIDEO_BUS, 2, 2, 4, 20, 20, 35}; -static video_timings_t timing_s3_vision968_pci = {VIDEO_PCI, 2, 2, 4, 20, 20, 35}; -static video_timings_t timing_s3_trio32_vlb = {VIDEO_BUS, 4, 3, 5, 26, 26, 42}; -static video_timings_t timing_s3_trio32_pci = {VIDEO_PCI, 4, 3, 5, 26, 26, 42}; -static video_timings_t timing_s3_trio64_vlb = {VIDEO_BUS, 3, 2, 4, 25, 25, 40}; -static video_timings_t timing_s3_trio64_pci = {VIDEO_PCI, 3, 2, 4, 25, 25, 40}; - -enum -{ - VRAM_4MB = 0, - VRAM_8MB = 3, - VRAM_2MB = 4, - VRAM_1MB = 6, - VRAM_512KB = 7 +enum { + VRAM_4MB = 0, + VRAM_8MB = 3, + VRAM_2MB = 4, + VRAM_1MB = 6, + VRAM_512KB = 7 }; -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) -#define FIFO_ENTRIES (s3->fifo_write_idx - s3->fifo_read_idx) -#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= (FIFO_SIZE - 4)) -#define FIFO_EMPTY (s3->fifo_read_idx == s3->fifo_write_idx) +#define FIFO_ENTRIES (s3->fifo_write_idx - s3->fifo_read_idx) +#define FIFO_FULL ((s3->fifo_write_idx - s3->fifo_read_idx) >= (FIFO_SIZE - 4)) +#define FIFO_EMPTY (s3->fifo_read_idx == s3->fifo_write_idx) -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24), - FIFO_OUT_BYTE = (0x04 << 24), - FIFO_OUT_WORD = (0x05 << 24), - FIFO_OUT_DWORD = (0x06 << 24) +enum { + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), + FIFO_WRITE_DWORD = (0x03 << 24), + FIFO_OUT_BYTE = (0x04 << 24), + FIFO_OUT_WORD = (0x05 << 24), + FIFO_OUT_DWORD = (0x06 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; -typedef struct s3_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - mem_mapping_t new_mmio_mapping; +typedef struct s3_t { + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + mem_mapping_t new_mmio_mapping; - uint8_t has_bios; - rom_t bios_rom; + uint8_t has_bios; + rom_t bios_rom; - svga_t svga; + svga_t svga; - uint8_t bank; - uint8_t ma_ext; - int width, bpp; + uint8_t bank; + uint8_t ma_ext; + int width, bpp; - int chip; - int pci, vlb; - int atbus; + int chip; + int pci, vlb; + int atbus; - uint8_t id, id_ext, id_ext_pci; + uint8_t id, id_ext, id_ext_pci; - uint8_t int_line; + uint8_t int_line; - int packed_mmio; + int packed_mmio; - uint32_t linear_base, linear_size; + uint32_t linear_base, linear_size; - uint8_t pci_regs[256]; - int card; + uint8_t pci_regs[256]; + int card; - uint32_t vram_mask; - uint8_t data_available; + uint32_t vram_mask; + uint8_t data_available; - int card_type; + int card_type; - struct - { - uint16_t subsys_cntl; - uint16_t setup_md; - uint8_t advfunc_cntl; - uint16_t cur_y, cur_y2, cur_y_bitres; - uint16_t cur_x, cur_x2, cur_x_bitres; - uint16_t x2, ropmix; - uint16_t pat_x, pat_y; - int16_t desty_axstp, desty_axstp2; - int16_t destx_distp; - int16_t err_term, err_term2; - int16_t maj_axis_pcnt, maj_axis_pcnt2; - uint16_t cmd, cmd2; - uint16_t short_stroke; - uint32_t pat_bg_color, pat_fg_color; - uint32_t bkgd_color; - uint32_t frgd_color; - uint32_t wrt_mask; - uint32_t rd_mask; - uint32_t color_cmp; - uint8_t bkgd_mix; - uint8_t frgd_mix; - uint16_t multifunc_cntl; - uint16_t multifunc[16]; - uint8_t pix_trans[4]; - int ssv_state; + struct + { + uint16_t subsys_cntl; + uint16_t setup_md; + uint8_t advfunc_cntl; + uint16_t cur_y, cur_y2, cur_y_bitres; + uint16_t cur_x, cur_x2, cur_x_bitres; + uint16_t x2, ropmix; + uint16_t pat_x, pat_y; + int16_t desty_axstp, desty_axstp2; + int16_t destx_distp; + int16_t err_term, err_term2; + int16_t maj_axis_pcnt, maj_axis_pcnt2; + uint16_t cmd, cmd2; + uint16_t short_stroke; + uint32_t pat_bg_color, pat_fg_color; + uint32_t bkgd_color; + uint32_t frgd_color; + uint32_t wrt_mask; + uint32_t rd_mask; + uint32_t color_cmp; + uint8_t bkgd_mix; + uint8_t frgd_mix; + uint16_t multifunc_cntl; + uint16_t multifunc[16]; + uint8_t pix_trans[4]; + int ssv_state; - int cx, cy; - int px, py; - int sx, sy; - int dx, dy; - uint32_t src, dest, pattern; + int cx, cy; + int px, py; + int sx, sy; + int dx, dy; + uint32_t src, dest, pattern; - int poly_cx, poly_cx2; - int poly_cy, poly_cy2; - int poly_line_cx; - int point_1_updated, point_2_updated; - int poly_dx1, poly_dx2; - int poly_x; + int poly_cx, poly_cx2; + int poly_cy, poly_cy2; + int poly_line_cx; + int point_1_updated, point_2_updated; + int poly_dx1, poly_dx2; + int poly_x; - uint32_t dat_buf; - int dat_count; - int b2e8_pix, temp_cnt; - uint8_t cur_x_bit12, cur_y_bit12; - int ssv_len; - uint8_t ssv_dir; - uint8_t ssv_draw; + uint32_t dat_buf; + int dat_count; + int b2e8_pix, temp_cnt; + uint8_t cur_x_bit12, cur_y_bit12; + int ssv_len; + uint8_t ssv_dir; + uint8_t ssv_draw; - /*For non-threaded FIFO*/ - int setup_fifo_slot; - int draw_fifo_slot; - int setup_fifo, setup_fifo2; - int draw_fifo, draw_fifo2; - } accel; + /*For non-threaded FIFO*/ + int setup_fifo_slot; + int draw_fifo_slot; + int setup_fifo, setup_fifo2; + int draw_fifo, draw_fifo2; + } accel; - struct { - uint32_t nop; - uint32_t cntl; - uint32_t stretch_filt_const; - uint32_t src_dst_step; - uint32_t crop; - uint32_t src_base, dest_base; - uint32_t src, dest; - uint32_t srcbase, dstbase; - int32_t dda_init_accumulator; - int32_t k1, k2; - int dm_index; - int dither_matrix_idx; - int src_step, dst_step; - int sx, sx_backup, sy; - double cx, dx; - double cy, dy; - int sx_scale_int, sx_scale_int_backup; - double sx_scale; - double sx_scale_dec; - double sx_scale_inc; - double sx_scale_backup; - double sx_scale_len; - int dither, host_data, scale_down; - int input; - int len, start; - int odf, idf, yuv; - volatile int busy; - } videoengine; + struct { + uint32_t nop; + uint32_t cntl; + uint32_t stretch_filt_const; + uint32_t src_dst_step; + uint32_t crop; + uint32_t src_base, dest_base; + uint32_t src, dest; + uint32_t srcbase, dstbase; + int32_t dda_init_accumulator; + int32_t k1, k2; + int dm_index; + int dither_matrix_idx; + int src_step, dst_step; + int sx, sx_backup, sy; + double cx, dx; + double cy, dy; + int sx_scale_int, sx_scale_int_backup; + double sx_scale; + double sx_scale_dec; + double sx_scale_inc; + double sx_scale_backup; + double sx_scale_len; + int dither, host_data, scale_down; + int input; + int len, start; + int odf, idf, yuv; + volatile int busy; + } videoengine; - struct - { - uint32_t pri_ctrl; - uint32_t chroma_ctrl; - uint32_t sec_ctrl; - uint32_t chroma_upper_bound; - uint32_t sec_filter; - uint32_t blend_ctrl; - uint32_t pri_fb0, pri_fb1; - uint32_t pri_stride; - uint32_t buffer_ctrl; - uint32_t sec_fb0, sec_fb1; - uint32_t sec_stride; - uint32_t overlay_ctrl; - int32_t k1_vert_scale; - int32_t k2_vert_scale; - int32_t dda_vert_accumulator; - int32_t k1_horiz_scale; - int32_t k2_horiz_scale; - int32_t dda_horiz_accumulator; - uint32_t fifo_ctrl; - uint32_t pri_start; - uint32_t pri_size; - uint32_t sec_start; - uint32_t sec_size; + struct + { + uint32_t pri_ctrl; + uint32_t chroma_ctrl; + uint32_t sec_ctrl; + uint32_t chroma_upper_bound; + uint32_t sec_filter; + uint32_t blend_ctrl; + uint32_t pri_fb0, pri_fb1; + uint32_t pri_stride; + uint32_t buffer_ctrl; + uint32_t sec_fb0, sec_fb1; + uint32_t sec_stride; + uint32_t overlay_ctrl; + int32_t k1_vert_scale; + int32_t k2_vert_scale; + int32_t dda_vert_accumulator; + int32_t k1_horiz_scale; + int32_t k2_horiz_scale; + int32_t dda_horiz_accumulator; + uint32_t fifo_ctrl; + uint32_t pri_start; + uint32_t pri_size; + uint32_t sec_start; + uint32_t sec_size; - int sdif; + int sdif; - int pri_x, pri_y, pri_w, pri_h; - int sec_x, sec_y, sec_w, sec_h; - } streams; + int pri_x, pri_y, pri_w, pri_h; + int sec_x, sec_y, sec_w, sec_h; + } streams; - fifo_entry_t fifo[FIFO_SIZE]; - volatile int fifo_read_idx, fifo_write_idx; + fifo_entry_t fifo[FIFO_SIZE]; + volatile int fifo_read_idx, fifo_write_idx; - uint8_t fifo_thread_run; + uint8_t fifo_thread_run; - thread_t *fifo_thread; - event_t *wake_fifo_thread; - event_t *fifo_not_full_event; + thread_t *fifo_thread; + event_t *wake_fifo_thread; + event_t *fifo_not_full_event; - int blitter_busy; - uint64_t blitter_time; - uint64_t status_time; + int blitter_busy; + uint64_t blitter_time; + uint64_t status_time; - uint8_t subsys_cntl, subsys_stat; + uint8_t subsys_cntl, subsys_stat; - uint32_t hwc_fg_col, hwc_bg_col; - int hwc_col_stack_pos; + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; - int translate; - int enable_8514; - int color_16bit; - volatile int busy, force_busy; + int translate; + int enable_8514; + int color_16bit; + volatile int busy, force_busy; - uint8_t thread_run, serialport; - void *i2c, *ddc; + uint8_t thread_run, serialport; + void *i2c, *ddc; - int vram; + int vram; } s3_t; -#define INT_VSY (1 << 0) -#define INT_GE_BSY (1 << 1) -#define INT_FIFO_OVR (1 << 2) -#define INT_FIFO_EMP (1 << 3) -#define INT_MASK 0xf +#define INT_VSY (1 << 0) +#define INT_GE_BSY (1 << 1) +#define INT_FIFO_OVR (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_MASK 0xf #define SERIAL_PORT_SCW (1 << 0) #define SERIAL_PORT_SDW (1 << 1) @@ -382,156 +375,157 @@ typedef struct s3_t static void s3_updatemapping(s3_t *s3); -static void s3_accel_write(uint32_t addr, uint8_t val, void *p); -static void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); -static void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); -static uint8_t s3_accel_read(uint32_t addr, void *p); +static void s3_accel_write(uint32_t addr, uint8_t val, void *p); +static void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); +static void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); +static uint8_t s3_accel_read(uint32_t addr, void *p); static uint16_t s3_accel_read_w(uint32_t addr, void *p); static uint32_t s3_accel_read_l(uint32_t addr, void *p); -static void s3_out(uint16_t addr, uint8_t val, void *p); +static void s3_out(uint16_t addr, uint8_t val, void *p); static uint8_t s3_in(uint16_t addr, void *p); -static void s3_accel_out(uint16_t port, uint8_t val, void *p); -static void s3_accel_out_w(uint16_t port, uint16_t val, void *p); -static void s3_accel_out_l(uint16_t port, uint32_t val, void *p); -static uint8_t s3_accel_in(uint16_t port, void *p); +static void s3_accel_out(uint16_t port, uint8_t val, void *p); +static void s3_accel_out_w(uint16_t port, uint16_t val, void *p); +static void s3_accel_out_l(uint16_t port, uint32_t val, void *p); +static uint8_t s3_accel_in(uint16_t port, void *p); static uint16_t s3_accel_in_w(uint16_t port, void *p); static uint32_t s3_accel_in_l(uint16_t port, void *p); -static uint8_t s3_pci_read(int func, int addr, void *p); -static void s3_pci_write(int func, int addr, uint8_t val, void *p); +static uint8_t s3_pci_read(int func, int addr, void *p); +static void s3_pci_write(int func, int addr, uint8_t val, void *p); /*Remap address for chain-4/doubleword style layout. These will stay for convenience.*/ static __inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4 || svga->force_old_addr) - return in_addr; + if (svga->packed_chain4 || svga->force_old_addr) + return in_addr; - return ((in_addr << 2) & 0x3fff0) | - ((in_addr >> 14) & 0xc) | - (in_addr & ~0x3fffc); + return ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3fffc); } static __inline uint32_t dword_remap_w(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4 || svga->force_old_addr) - return in_addr; + if (svga->packed_chain4 || svga->force_old_addr) + return in_addr; - return ((in_addr << 2) & 0x1fff8) | - ((in_addr >> 14) & 0x6) | - (in_addr & ~0x1fffe); + return ((in_addr << 2) & 0x1fff8) | ((in_addr >> 14) & 0x6) | (in_addr & ~0x1fffe); } static __inline uint32_t dword_remap_l(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4 || svga->force_old_addr) - return in_addr; + if (svga->packed_chain4 || svga->force_old_addr) + return in_addr; - return ((in_addr << 2) & 0xfffc) | - ((in_addr >> 14) & 0x3) | - (in_addr & ~0xffff); + return ((in_addr << 2) & 0xfffc) | ((in_addr >> 14) & 0x3) | (in_addr & ~0xffff); } static __inline void wake_fifo_thread(s3_t *s3) { - thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } static void s3_wait_fifo_idle(s3_t *s3) { - while (!FIFO_EMPTY) { - wake_fifo_thread(s3); - thread_wait_event(s3->fifo_not_full_event, 1); - } + while (!FIFO_EMPTY) { + wake_fifo_thread(s3); + thread_wait_event(s3->fifo_not_full_event, 1); + } } static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) { - fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; - if (FIFO_FULL) { - thread_reset_event(s3->fifo_not_full_event); - if (FIFO_FULL) { - thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ - } - } + if (FIFO_FULL) { + thread_reset_event(s3->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(s3->fifo_not_full_event, -1); /*Wait for room in ringbuffer*/ + } + } - fifo->val = val; - fifo->addr_type = (addr & FIFO_ADDR) | type; + fifo->val = val; + fifo->addr_type = (addr & FIFO_ADDR) | type; - s3->fifo_write_idx++; + s3->fifo_write_idx++; - if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) - wake_fifo_thread(s3); + if (FIFO_ENTRIES > 0xe000 || FIFO_ENTRIES < 8) + wake_fifo_thread(s3); } static void s3_update_irqs(s3_t *s3) { - if (!s3->pci) - return; + if (!s3->pci) + return; - if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) { - pci_set_irq(s3->card, PCI_INTA); - } else { - pci_clear_irq(s3->card, PCI_INTA); - } + if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) { + pci_set_irq(s3->card, PCI_INTA); + } else { + pci_clear_irq(s3->card, PCI_INTA); + } } -void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); -void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv); +void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); +void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv); static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); -#define WRITE8(addr, var, val) switch ((addr) & 3) \ - { \ - case 0: var = (var & 0xffffff00) | (val); break; \ - case 1: var = (var & 0xffff00ff) | ((val) << 8); break; \ - case 2: var = (var & 0xff00ffff) | ((val) << 16); break; \ - case 3: var = (var & 0x00ffffff) | ((val) << 24); break; \ - } - +#define WRITE8(addr, var, val) \ + switch ((addr) &3) { \ + case 0: \ + var = (var & 0xffffff00) | (val); \ + break; \ + case 1: \ + var = (var & 0xffff00ff) | ((val) << 8); \ + break; \ + case 2: \ + var = (var & 0xff00ffff) | ((val) << 16); \ + break; \ + case 3: \ + var = (var & 0x00ffffff) | ((val) << 24); \ + break; \ + } #define READ_PIXTRANS_BYTE_IO(n) \ - s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + n)) & s3->vram_mask]; \ + s3->accel.pix_trans[n] = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + n)) & s3->vram_mask]; #define READ_PIXTRANS_BYTE_MM \ - temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ + temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; -#define READ_PIXTRANS_WORD \ - if (s3->bpp == 0 && !s3->color_16bit) { \ - temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ - temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ - } else { \ - temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 1)]; \ - } +#define READ_PIXTRANS_WORD \ + if (s3->bpp == 0 && !s3->color_16bit) { \ + temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ + temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ + } else { \ + temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 1)]; \ + } -#define READ_PIXTRANS_LONG \ - if (s3->bpp == 0 && !s3->color_16bit) { \ - temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ - temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ - temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \ - temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 3)) & s3->vram_mask] << 24); \ - } else { \ - temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 1)]; \ - temp |= (vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx + 2)) & (s3->vram_mask >> 1)] << 16); \ - } +#define READ_PIXTRANS_LONG \ + if (s3->bpp == 0 && !s3->color_16bit) { \ + temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ + temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ + temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \ + temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 3)) & s3->vram_mask] << 24); \ + } else { \ + temp = vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx)) & (s3->vram_mask >> 1)]; \ + temp |= (vram_w[dword_remap_w(svga, (s3->accel.dest + s3->accel.cx + 2)) & (s3->vram_mask >> 1)] << 16); \ + } static int s3_cpu_src(s3_t *s3) { if (!(s3->accel.cmd & 0x100)) - return 0; + return 0; if (s3->chip >= S3_VISION964) - return 1; + return 1; if (s3->accel.cmd & 1) - return 1; + return 1; return 0; } @@ -540,13 +534,13 @@ static int s3_cpu_dest(s3_t *s3) { if (!(s3->accel.cmd & 0x100)) - return 0; + return 0; if (s3->chip >= S3_VISION964) - return 0; + return 0; if (s3->accel.cmd & 1) - return 0; + return 0; return 1; } @@ -554,13 +548,10 @@ s3_cpu_dest(s3_t *s3) static int s3_enable_fifo(s3_t *s3) { - svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || - (s3->chip == S3_TRIO64V) || (s3->chip == S3_TRIO64V2) || - (s3->chip == S3_VISION864) || (s3->chip == S3_VISION964) || - (s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) - return 1; /* FIFO always enabled on these chips. */ + if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_TRIO64V) || (s3->chip == S3_TRIO64V2) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_VISION868)) + return 1; /* FIFO always enabled on these chips. */ return !!((svga->crtc[0x40] & 0x08) || (s3->accel.advfunc_cntl & 0x40)); } @@ -568,140 +559,140 @@ s3_enable_fifo(s3_t *s3) static void s3_accel_out_pixtrans_w(s3_t *s3, uint16_t val) { - svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(8, 1, val | (val << 16), 0, s3); - } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - } else { - if (s3->color_16bit) - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - } - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } else { - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - break; - case 0x400: - if (svga->crtc[0x53] & 0x08) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(32, 1, val | (val << 16), 0, s3); - } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); - } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); - } else { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); - } else - s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); - } - break; - case 0x600: - if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } - } - } - break; - } - } + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + s3_accel_start(8, 1, val | (val << 16), 0, s3); + } else + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + } else { + if (s3->color_16bit) + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + } + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } else { + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + break; + case 0x400: + if (svga->crtc[0x53] & 0x08) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + s3_accel_start(32, 1, val | (val << 16), 0, s3); + } else + s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + } else + s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + } else { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } else + s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + } else + s3_accel_start(4, 1, 0xffffffff, val | (val << 16), s3); + } + break; + case 0x600: + if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } + } + } + break; + } + } } static void s3_accel_out_pixtrans_l(s3_t *s3, uint32_t val) { - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } else { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } else { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - } else { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - break; - case 0x400: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } else - s3_accel_start(4, 1, 0xffffffff, val, s3); - } else - s3_accel_start(4, 1, 0xffffffff, val, s3); - break; - case 0x600: - if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); - s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); - s3_accel_start(8, 1, val & 0xff, 0, s3); - } - } - } - break; - } - } + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } else { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } else { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } else { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } + } else { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } + break; + case 0x400: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } else + s3_accel_start(4, 1, 0xffffffff, val, s3); + } else + s3_accel_start(4, 1, 0xffffffff, val, s3); + break; + case 0x600: + if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(8, 1, (val >> 24) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 16) & 0xff, 0, s3); + s3_accel_start(8, 1, (val >> 8) & 0xff, 0, s3); + s3_accel_start(8, 1, val & 0xff, 0, s3); + } + } + } + break; + } + } } static void @@ -710,670 +701,745 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) svga_t *svga = &s3->svga; switch (port) { - case 0x8148: case 0x82e8: - s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; - s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; - s3->accel.poly_cy = s3->accel.cur_y; - break; - case 0x8149: case 0x82e9: - s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff) | (val << 8); - s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_y_bit12 = val & 0x10; - s3->accel.poly_cy = s3->accel.cur_y; - break; - case 0x814a: case 0x82ea: - s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; - s3->accel.poly_cy2 = s3->accel.cur_y2; - break; - case 0x814b: case 0x82eb: - s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x0f) << 8); - s3->accel.poly_cy2 = s3->accel.cur_y2; - break; + case 0x8148: + case 0x82e8: + s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff00) | val; + s3->accel.cur_y = (s3->accel.cur_y & 0xf00) | val; + s3->accel.poly_cy = s3->accel.cur_y; + break; + case 0x8149: + case 0x82e9: + s3->accel.cur_y_bitres = (s3->accel.cur_y_bitres & 0xff) | (val << 8); + s3->accel.cur_y = (s3->accel.cur_y & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_y_bit12 = val & 0x10; + s3->accel.poly_cy = s3->accel.cur_y; + break; + case 0x814a: + case 0x82ea: + s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xf00) | val; + s3->accel.poly_cy2 = s3->accel.cur_y2; + break; + case 0x814b: + case 0x82eb: + s3->accel.cur_y2 = (s3->accel.cur_y2 & 0xff) | ((val & 0x0f) << 8); + s3->accel.poly_cy2 = s3->accel.cur_y2; + break; - case 0x8548: case 0x86e8: - s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; - s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; - s3->accel.poly_cx = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - break; - case 0x8549: case 0x86e9: - s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff) | (val << 8); - s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); - s3->accel.cur_x_bit12 = val & 0x10; - s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - break; - case 0x854a: case 0x86ea: - s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; - s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; - break; - case 0x854b: case 0x86eb: - s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x0f) << 8); - s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; - break; + case 0x8548: + case 0x86e8: + s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff00) | val; + s3->accel.cur_x = (s3->accel.cur_x & 0xf00) | val; + s3->accel.poly_cx = s3->accel.cur_x << 20; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + break; + case 0x8549: + case 0x86e9: + s3->accel.cur_x_bitres = (s3->accel.cur_x_bitres & 0xff) | (val << 8); + s3->accel.cur_x = (s3->accel.cur_x & 0xff) | ((val & 0x0f) << 8); + s3->accel.cur_x_bit12 = val & 0x10; + s3->accel.poly_cx = s3->accel.poly_x = s3->accel.cur_x << 20; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + break; + case 0x854a: + case 0x86ea: + s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xf00) | val; + s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; + break; + case 0x854b: + case 0x86eb: + s3->accel.cur_x2 = (s3->accel.cur_x2 & 0xff) | ((val & 0x0f) << 8); + s3->accel.poly_cx2 = s3->accel.cur_x2 << 20; + break; - case 0xcae8: - case 0x8948: case 0x8ae8: - s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; - s3->accel.point_1_updated = 1; - break; - case 0xcae9: - case 0x8949: case 0x8ae9: - s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.desty_axstp |= ~0x3fff; - s3->accel.point_1_updated = 1; - break; - case 0x894a: case 0x8aea: - s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; - s3->accel.point_2_updated = 1; - break; - case 0x849b: case 0x8aeb: - s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.desty_axstp2 |= ~0x3fff; - s3->accel.point_2_updated = 1; - break; + case 0xcae8: + case 0x8948: + case 0x8ae8: + s3->accel.desty_axstp = (s3->accel.desty_axstp & 0x3f00) | val; + s3->accel.point_1_updated = 1; + break; + case 0xcae9: + case 0x8949: + case 0x8ae9: + s3->accel.desty_axstp = (s3->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.desty_axstp |= ~0x3fff; + s3->accel.point_1_updated = 1; + break; + case 0x894a: + case 0x8aea: + s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0x3f00) | val; + s3->accel.point_2_updated = 1; + break; + case 0x849b: + case 0x8aeb: + s3->accel.desty_axstp2 = (s3->accel.desty_axstp2 & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.desty_axstp2 |= ~0x3fff; + s3->accel.point_2_updated = 1; + break; - case 0x8d48: case 0x8ee8: - s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; - s3->accel.point_1_updated = 1; - break; - case 0x8d49: case 0x8ee9: - s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.destx_distp |= ~0x3fff; - s3->accel.point_1_updated = 1; - break; - case 0x8d4a: case 0x8eea: - s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; - s3->accel.point_2_updated = 1; - break; - case 0x8d4b: case 0x8eeb: - s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0x0f) << 8); - s3->accel.point_2_updated = 1; - break; + case 0x8d48: + case 0x8ee8: + s3->accel.destx_distp = (s3->accel.destx_distp & 0x3f00) | val; + s3->accel.point_1_updated = 1; + break; + case 0x8d49: + case 0x8ee9: + s3->accel.destx_distp = (s3->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.destx_distp |= ~0x3fff; + s3->accel.point_1_updated = 1; + break; + case 0x8d4a: + case 0x8eea: + s3->accel.x2 = (s3->accel.x2 & 0xf00) | val; + s3->accel.point_2_updated = 1; + break; + case 0x8d4b: + case 0x8eeb: + s3->accel.x2 = (s3->accel.x2 & 0xff) | ((val & 0x0f) << 8); + s3->accel.point_2_updated = 1; + break; - case 0x9148: case 0x92e8: - s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; - break; - case 0x9149: case 0x92e9: - s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.err_term |= ~0x3fff; - break; - case 0x914a: case 0x92ea: - s3->accel.err_term2 = (s3->accel.err_term2 & 0x3f00) | val; - break; - case 0x914b: case 0x92eb: - s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8); - if (val & 0x20) - s3->accel.err_term2 |= ~0x3fff; - break; + case 0x9148: + case 0x92e8: + s3->accel.err_term = (s3->accel.err_term & 0x3f00) | val; + break; + case 0x9149: + case 0x92e9: + s3->accel.err_term = (s3->accel.err_term & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.err_term |= ~0x3fff; + break; + case 0x914a: + case 0x92ea: + s3->accel.err_term2 = (s3->accel.err_term2 & 0x3f00) | val; + break; + case 0x914b: + case 0x92eb: + s3->accel.err_term2 = (s3->accel.err_term2 & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + s3->accel.err_term2 |= ~0x3fff; + break; - case 0x9548: case 0x96e8: - s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xf00) | val; - break; - case 0x9459: case 0x96e9: - s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt |= ~0x0fff; - break; - case 0x954a: case 0x96ea: - s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xf00) | val; - break; - case 0x954b: case 0x96eb: - s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8); - if (val & 0x08) - s3->accel.maj_axis_pcnt2 |= ~0x0fff; - break; + case 0x9548: + case 0x96e8: + s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xf00) | val; + break; + case 0x9459: + case 0x96e9: + s3->accel.maj_axis_pcnt = (s3->accel.maj_axis_pcnt & 0xff) | ((val & 0x0f) << 8); + if (val & 0x08) + s3->accel.maj_axis_pcnt |= ~0x0fff; + break; + case 0x954a: + case 0x96ea: + s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xf00) | val; + break; + case 0x954b: + case 0x96eb: + s3->accel.maj_axis_pcnt2 = (s3->accel.maj_axis_pcnt2 & 0xff) | ((val & 0x0f) << 8); + if (val & 0x08) + s3->accel.maj_axis_pcnt2 |= ~0x0fff; + break; - case 0x9948: case 0x9ae8: - s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; - s3->data_available = 0; - s3->accel.b2e8_pix = 0; - break; - case 0x9949: case 0x9ae9: - s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); - s3->accel.ssv_state = 0; - s3_accel_start(-1, 0, 0xffffffff, 0, s3); - s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ - break; + case 0x9948: + case 0x9ae8: + s3->accel.cmd = (s3->accel.cmd & 0xff00) | val; + s3->data_available = 0; + s3->accel.b2e8_pix = 0; + break; + case 0x9949: + case 0x9ae9: + s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); + s3->accel.ssv_state = 0; + s3_accel_start(-1, 0, 0xffffffff, 0, s3); + s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ + break; - case 0x994a: case 0x9aea: - s3->accel.cmd2 = (s3->accel.cmd2 & 0xff00) | val; - break; - case 0x994b: case 0x9aeb: - s3->accel.cmd2 = (s3->accel.cmd2 & 0xff) | (val << 8); - break; + case 0x994a: + case 0x9aea: + s3->accel.cmd2 = (s3->accel.cmd2 & 0xff00) | val; + break; + case 0x994b: + case 0x9aeb: + s3->accel.cmd2 = (s3->accel.cmd2 & 0xff) | (val << 8); + break; - case 0x9d48: case 0x9ee8: - s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; - break; - case 0x9d49: case 0x9ee9: - s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); - s3->accel.ssv_state = 1; + case 0x9d48: + case 0x9ee8: + s3->accel.short_stroke = (s3->accel.short_stroke & 0xff00) | val; + break; + case 0x9d49: + case 0x9ee9: + s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); + s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x_bit12) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y_bit12) + s3->accel.cy |= ~0xfff; - if (s3->accel.cmd & 0x1000) { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - } else { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - } - break; + if (s3->accel.cmd & 0x1000) { + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + } else { + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + } + break; - case 0xa148: case 0xa2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - break; - case 0xa149: case 0xa2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xa14a: case 0xa2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - } - break; - case 0xa14b: case 0xa2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xa148: + case 0xa2e8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + break; + case 0xa149: + case 0xa2e9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xa14a: + case 0xa2ea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + } + break; + case 0xa14b: + case 0xa2eb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xa548: case 0xa6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - break; - case 0xa549: case 0xa6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xa54a: case 0xa6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - } - break; - case 0xa54b: case 0xa6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xa548: + case 0xa6e8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + break; + case 0xa549: + case 0xa6e9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xa54a: + case 0xa6ea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + } + break; + case 0xa54b: + case 0xa6eb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + else + s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xa948: case 0xaae8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - break; - case 0xa949: case 0xaae9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xa94a: case 0xaaea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - } - break; - case 0xa94b: case 0xaaeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xa948: + case 0xaae8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + break; + case 0xa949: + case 0xaae9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xa94a: + case 0xaaea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + } + break; + case 0xa94b: + case 0xaaeb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xad48: case 0xaee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - break; - case 0xad49: case 0xaee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xad4a: case 0xaeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - } - break; - case 0xad4b: case 0xaeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xad48: + case 0xaee8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + break; + case 0xad49: + case 0xaee9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xad4a: + case 0xaeea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + } + break; + case 0xad4b: + case 0xaeeb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + else + s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xb148: case 0xb2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - break; - case 0xb149: case 0xb2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xb14a: case 0xb2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - } - break; - case 0xb14b: case 0xb2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xb148: + case 0xb2e8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + break; + case 0xb149: + case 0xb2e9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xb14a: + case 0xb2ea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + } + break; + case 0xb14b: + case 0xb2eb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + else + s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xb548: case 0xb6e8: - s3->accel.bkgd_mix = val; - break; + case 0xb548: + case 0xb6e8: + s3->accel.bkgd_mix = val; + break; - case 0xb948: case 0xbae8: - s3->accel.frgd_mix = val; - break; + case 0xb948: + case 0xbae8: + s3->accel.frgd_mix = val; + break; - case 0xbd48: case 0xbee8: - s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; - break; - case 0xbd49: case 0xbee9: - s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); - s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; - break; + case 0xbd48: + case 0xbee8: + s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff00) | val; + break; + case 0xbd49: + case 0xbee9: + s3->accel.multifunc_cntl = (s3->accel.multifunc_cntl & 0xff) | (val << 8); + s3->accel.multifunc[s3->accel.multifunc_cntl >> 12] = s3->accel.multifunc_cntl & 0xfff; + break; - case 0xd148: case 0xd2e8: - s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; - break; - case 0xd149: case 0xd2e9: - s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); - break; - case 0xe548: case 0xe6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; - break; - case 0xe549: case 0xe6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xe54a: case 0xe6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; - } - break; - case 0xe54b: case 0xe6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; - case 0xe948: case 0xeae8: - s3->accel.pat_y = (s3->accel.pat_y & 0xf00) | val; - break; - case 0xe949: case 0xeae9: - s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); - break; - case 0xe94a: case 0xeaea: - s3->accel.pat_x = (s3->accel.pat_x & 0xf00) | val; - break; - case 0xe94b: case 0xeaeb: - s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); - break; - case 0xed48: case 0xeee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; - break; - case 0xed49: case 0xeee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); - if (!(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.multifunc[0xe] ^= 0x10; - break; - case 0xed4a: case 0xeeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; - } - break; - case 0xed4b: case 0xeeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); - s3->accel.multifunc[0xe] ^= 0x10; - } - break; + case 0xd148: + case 0xd2e8: + s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; + break; + case 0xd149: + case 0xd2e9: + s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); + break; + case 0xe548: + case 0xe6e8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; + break; + case 0xe549: + case 0xe6e9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xe54a: + case 0xe6ea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; + } + break; + case 0xe54b: + case 0xe6eb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; + case 0xe948: + case 0xeae8: + s3->accel.pat_y = (s3->accel.pat_y & 0xf00) | val; + break; + case 0xe949: + case 0xeae9: + s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); + break; + case 0xe94a: + case 0xeaea: + s3->accel.pat_x = (s3->accel.pat_x & 0xf00) | val; + break; + case 0xe94b: + case 0xeaeb: + s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); + break; + case 0xed48: + case 0xeee8: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; + break; + case 0xed49: + case 0xeee9: + if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + break; + case 0xed4a: + case 0xeeea: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; + } + break; + case 0xed4b: + case 0xeeeb: + if (s3->accel.multifunc[0xe] & 0x200) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else if (s3->bpp == 3) { + if (s3->accel.multifunc[0xe] & 0x10) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + s3->accel.multifunc[0xe] ^= 0x10; + } + break; - case 0xe148: case 0xe2e8: - s3->accel.b2e8_pix = 0; - if (s3_cpu_dest(s3)) - break; - s3->accel.pix_trans[0] = val; - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else { - if (s3->color_16bit) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), 0, s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); - } else { - if (s3->chip != S3_86C928PCI && s3->chip != S3_86C928) { - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); - } - } - break; - } - } - break; - case 0xe149: case 0xe2e9: - s3->accel.b2e8_pix = 0; - if (s3_cpu_dest(s3)) - break; - s3->accel.pix_trans[1] = val; - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } else { - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - break; - case 0x200: - /*Windows 95's built-in driver expects this to be loaded regardless of the byte swap bit (0xE2E9) in the 86c928 ISA/VLB*/ - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); - else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - } - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - } - break; - case 0x400: - if (svga->crtc[0x53] & 0x08) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - break; - case 0x600: - if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - } - } - } - break; - } - } - break; - case 0xe14a: case 0xe2ea: - if (s3_cpu_dest(s3)) - break; - s3->accel.pix_trans[2] = val; - break; - case 0xe14b: case 0xe2eb: - if (s3_cpu_dest(s3)) - break; - s3->accel.pix_trans[3] = val; - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - break; - case 0x200: - /*Windows 95's built-in driver expects the upper 16 bits to be loaded instead of the whole 32-bit one, regardless of the byte swap bit (0xE2EB) in the 86c928 ISA/VLB card*/ - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), 0, s3); - else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } - } - } else { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { - s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } - } - break; - case 0x400: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } else - s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - break; - case 0x600: - if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - } - } - } - break; - } - } - break; - } + case 0xe148: + case 0xe2e8: + s3->accel.b2e8_pix = 0; + if (s3_cpu_dest(s3)) + break; + s3->accel.pix_trans[0] = val; + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else { + if (s3->color_16bit) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), 0, s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); + } else { + if (s3->chip != S3_86C928PCI && s3->chip != S3_86C928) { + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3); + } + } + break; + } + } + break; + case 0xe149: + case 0xe2e9: + s3->accel.b2e8_pix = 0; + if (s3_cpu_dest(s3)) + break; + s3->accel.pix_trans[1] = val; + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } else { + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + break; + case 0x200: + /*Windows 95's built-in driver expects this to be loaded regardless of the byte swap bit (0xE2E9) in the 86c928 ISA/VLB*/ + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + else + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + } else { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { + s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + } + } else { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { + s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8)); + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + } + break; + case 0x400: + if (svga->crtc[0x53] & 0x08) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + else + s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } else + s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + break; + case 0x600: + if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + } + } + } + break; + } + } + break; + case 0xe14a: + case 0xe2ea: + if (s3_cpu_dest(s3)) + break; + s3->accel.pix_trans[2] = val; + break; + case 0xe14b: + case 0xe2eb: + if (s3_cpu_dest(s3)) + break; + s3->accel.pix_trans[3] = val; + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + break; + case 0x200: + /*Windows 95's built-in driver expects the upper 16 bits to be loaded instead of the whole 32-bit one, regardless of the byte swap bit (0xE2EB) in the 86c928 ISA/VLB card*/ + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + s3_accel_start(16, 1, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), 0, s3); + else + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + } else { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { + s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } + } + } else { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) { + s3_accel_out_pixtrans_w(s3, s3->accel.pix_trans[2] | (s3->accel.pix_trans[3] << 8)); + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[3] | (s3->accel.pix_trans[2] << 8) | (s3->accel.pix_trans[1] << 16) | (s3->accel.pix_trans[0] << 24), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } + } + break; + case 0x400: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(32, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + else + s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } else + s3_accel_start(4, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + break; + case 0x600: + if (s3->chip == S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868 || s3->chip >= S3_TRIO64V) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + s3_accel_start(8, 1, s3->accel.pix_trans[3], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[2], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[1], 0, s3); + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + } + } + } + break; + } + } + break; + } } static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { - if (port != 0x9ee8 && port != 0x9d48) { - if (port == 0xb2e8 || port == 0xb148) { - s3->accel.b2e8_pix = 1; - } else { - s3->accel.b2e8_pix = 0; - } - s3_accel_out_pixtrans_w(s3, val); - } else { - s3->accel.short_stroke = val; - s3->accel.ssv_state = 1; + if (port != 0x9ee8 && port != 0x9d48) { + if (port == 0xb2e8 || port == 0xb148) { + s3->accel.b2e8_pix = 1; + } else { + s3->accel.b2e8_pix = 0; + } + s3_accel_out_pixtrans_w(s3, val); + } else { + s3->accel.short_stroke = val; + s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x_bit12) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y_bit12) + s3->accel.cy |= ~0xfff; - if (s3->accel.cmd & 0x1000) { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - } else { - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); - s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); - } - } + if (s3->accel.cmd & 0x1000) { + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + } else { + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); + } + } } - static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (port == 0xb2e8 || port == 0xb148) { - s3->accel.b2e8_pix = 1; - } else { - s3->accel.b2e8_pix = 0; - } + if (port == 0xb2e8 || port == 0xb148) { + s3->accel.b2e8_pix = 1; + } else { + s3->accel.b2e8_pix = 0; + } - s3_accel_out_pixtrans_l(s3, val); + s3_accel_out_pixtrans_l(s3, val); } static void @@ -1382,2860 +1448,3065 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) svga_t *svga = &s3->svga; if (s3->packed_mmio) { - int addr_lo = addr & 1; - if (svga->crtc[0x53] & 0x08) { - if ((addr >= 0x08000) && (addr <= 0x0803f)) - s3_pci_write(0, addr & 0xff, val, s3); - } + int addr_lo = addr & 1; + if (svga->crtc[0x53] & 0x08) { + if ((addr >= 0x08000) && (addr <= 0x0803f)) + s3_pci_write(0, addr & 0xff, val, s3); + } - switch (addr & 0x1fffe) { - case 0x8100: addr = 0x82e8; break; /*ALT_CURXY*/ - case 0x8102: addr = 0x86e8; break; + switch (addr & 0x1fffe) { + case 0x8100: + addr = 0x82e8; + break; /*ALT_CURXY*/ + case 0x8102: + addr = 0x86e8; + break; - case 0x8104: addr = 0x82ea; break; /*ALT_CURXY2*/ - case 0x8106: addr = 0x86ea; break; + case 0x8104: + addr = 0x82ea; + break; /*ALT_CURXY2*/ + case 0x8106: + addr = 0x86ea; + break; - case 0x8108: addr = 0x8ae8; break; /*ALT_STEP*/ - case 0x810a: addr = 0x8ee8; break; + case 0x8108: + addr = 0x8ae8; + break; /*ALT_STEP*/ + case 0x810a: + addr = 0x8ee8; + break; - case 0x810c: addr = 0x8aea; break; /*ALT_STEP2*/ - case 0x810e: addr = 0x8eea; break; + case 0x810c: + addr = 0x8aea; + break; /*ALT_STEP2*/ + case 0x810e: + addr = 0x8eea; + break; - case 0x8110: addr = 0x92e8; break; /*ALT_ERR*/ - case 0x8112: addr = 0x92ee; break; + case 0x8110: + addr = 0x92e8; + break; /*ALT_ERR*/ + case 0x8112: + addr = 0x92ee; + break; - case 0x8118: addr = 0x9ae8; break; /*ALT_CMD*/ - case 0x811a: addr = 0x9aea; break; + case 0x8118: + addr = 0x9ae8; + break; /*ALT_CMD*/ + case 0x811a: + addr = 0x9aea; + break; - case 0x811c: addr = 0x9ee8; break; + case 0x811c: + addr = 0x9ee8; + break; - case 0x8120: case 0x8122: /*BKGD_COLOR*/ - WRITE8(addr, s3->accel.bkgd_color, val); - return; + case 0x8120: + case 0x8122: /*BKGD_COLOR*/ + WRITE8(addr, s3->accel.bkgd_color, val); + return; - case 0x8124: case 0x8126: /*FRGD_COLOR*/ - WRITE8(addr, s3->accel.frgd_color, val); - return; + case 0x8124: + case 0x8126: /*FRGD_COLOR*/ + WRITE8(addr, s3->accel.frgd_color, val); + return; - case 0x8128: case 0x812a: /*WRT_MASK*/ - WRITE8(addr, s3->accel.wrt_mask, val); - return; + case 0x8128: + case 0x812a: /*WRT_MASK*/ + WRITE8(addr, s3->accel.wrt_mask, val); + return; - case 0x812c: case 0x812e: /*RD_MASK*/ - WRITE8(addr, s3->accel.rd_mask, val); - return; + case 0x812c: + case 0x812e: /*RD_MASK*/ + WRITE8(addr, s3->accel.rd_mask, val); + return; - case 0x8130: case 0x8132: /*COLOR_CMP*/ - WRITE8(addr, s3->accel.color_cmp, val); - return; + case 0x8130: + case 0x8132: /*COLOR_CMP*/ + WRITE8(addr, s3->accel.color_cmp, val); + return; - case 0x8134: addr = 0xb6e8; break; /*ALT_MIX*/ - case 0x8136: addr = 0xbae8; break; + case 0x8134: + addr = 0xb6e8; + break; /*ALT_MIX*/ + case 0x8136: + addr = 0xbae8; + break; - case 0x8138: /*SCISSORS_T*/ - WRITE8(addr & 1, s3->accel.multifunc[1], val); - return; - case 0x813a: /*SCISSORS_L*/ - WRITE8(addr & 1, s3->accel.multifunc[2], val); - return; - case 0x813c: /*SCISSORS_B*/ - WRITE8(addr & 1, s3->accel.multifunc[3], val); - return; - case 0x813e: /*SCISSORS_R*/ - WRITE8(addr & 1, s3->accel.multifunc[4], val); - return; + case 0x8138: /*SCISSORS_T*/ + WRITE8(addr & 1, s3->accel.multifunc[1], val); + return; + case 0x813a: /*SCISSORS_L*/ + WRITE8(addr & 1, s3->accel.multifunc[2], val); + return; + case 0x813c: /*SCISSORS_B*/ + WRITE8(addr & 1, s3->accel.multifunc[3], val); + return; + case 0x813e: /*SCISSORS_R*/ + WRITE8(addr & 1, s3->accel.multifunc[4], val); + return; - case 0x8140: /*PIX_CNTL*/ - WRITE8(addr & 1, s3->accel.multifunc[0xa], val); - return; - case 0x8142: /*MULT_MISC2*/ - WRITE8(addr & 1, s3->accel.multifunc[0xd], val); - return; - case 0x8144: /*MULT_MISC*/ - WRITE8(addr & 1, s3->accel.multifunc[0xe], val); - return; - case 0x8146: /*READ_SEL*/ - WRITE8(addr & 1, s3->accel.multifunc[0xf], val); - return; + case 0x8140: /*PIX_CNTL*/ + WRITE8(addr & 1, s3->accel.multifunc[0xa], val); + return; + case 0x8142: /*MULT_MISC2*/ + WRITE8(addr & 1, s3->accel.multifunc[0xd], val); + return; + case 0x8144: /*MULT_MISC*/ + WRITE8(addr & 1, s3->accel.multifunc[0xe], val); + return; + case 0x8146: /*READ_SEL*/ + WRITE8(addr & 1, s3->accel.multifunc[0xf], val); + return; - case 0x8148: /*ALT_PCNT*/ - WRITE8(addr & 1, s3->accel.multifunc[0], val); - return; - case 0x814a: addr = 0x96e8; break; - case 0x814c: addr = 0x96ea; break; + case 0x8148: /*ALT_PCNT*/ + WRITE8(addr & 1, s3->accel.multifunc[0], val); + return; + case 0x814a: + addr = 0x96e8; + break; + case 0x814c: + addr = 0x96ea; + break; - case 0x8150: addr = 0xd2e8; break; + case 0x8150: + addr = 0xd2e8; + break; - case 0x8154: addr = 0x8ee8; break; - case 0x8156: addr = 0x96e8; break; + case 0x8154: + addr = 0x8ee8; + break; + case 0x8156: + addr = 0x96e8; + break; - case 0x8164: case 0x8166: - WRITE8(addr, s3->accel.pat_bg_color, val); - return; + case 0x8164: + case 0x8166: + WRITE8(addr, s3->accel.pat_bg_color, val); + return; - case 0x8168: addr = 0xeae8; break; - case 0x816a: addr = 0xeaea; break; + case 0x8168: + addr = 0xeae8; + break; + case 0x816a: + addr = 0xeaea; + break; - case 0x816c: case 0x816e: - WRITE8(addr, s3->accel.pat_fg_color, val); - return; - } - addr |= addr_lo; + case 0x816c: + case 0x816e: + WRITE8(addr, s3->accel.pat_fg_color, val); + return; + } + addr |= addr_lo; } if (svga->crtc[0x53] & 0x08) { - if ((addr & 0x1ffff) < 0x8000) { - if (s3->accel.cmd & 0x100) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } - } else { - switch (addr & 0x1ffff) { - case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: - case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: - case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: - case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: - case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: - case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: - case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: - case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: - case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: - case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: - case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: - case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - s3_out(addr & 0x3ff, val, s3); - break; - case 0x8504: - s3->subsys_stat &= ~val; - s3_update_irqs(s3); - break; - case 0x8505: - s3->subsys_cntl = val; - s3_update_irqs(s3); - break; - case 0x850c: - s3->accel.advfunc_cntl = val; - s3_updatemapping(s3); - break; - case 0xff20: - s3->serialport = val; - i2c_gpio_set(s3->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); - break; - default: - s3_accel_out_fifo(s3, addr & 0xffff, val); - break; - } - } + if ((addr & 0x1ffff) < 0x8000) { + if (s3->accel.cmd & 0x100) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } else + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } + } else { + switch (addr & 0x1ffff) { + case 0x83b0: + case 0x83b1: + case 0x83b2: + case 0x83b3: + case 0x83b4: + case 0x83b5: + case 0x83b6: + case 0x83b7: + case 0x83b8: + case 0x83b9: + case 0x83ba: + case 0x83bb: + case 0x83bc: + case 0x83bd: + case 0x83be: + case 0x83bf: + case 0x83c0: + case 0x83c1: + case 0x83c2: + case 0x83c3: + case 0x83c4: + case 0x83c5: + case 0x83c6: + case 0x83c7: + case 0x83c8: + case 0x83c9: + case 0x83ca: + case 0x83cb: + case 0x83cc: + case 0x83cd: + case 0x83ce: + case 0x83cf: + case 0x83d0: + case 0x83d1: + case 0x83d2: + case 0x83d3: + case 0x83d4: + case 0x83d5: + case 0x83d6: + case 0x83d7: + case 0x83d8: + case 0x83d9: + case 0x83da: + case 0x83db: + case 0x83dc: + case 0x83dd: + case 0x83de: + case 0x83df: + s3_out(addr & 0x3ff, val, s3); + break; + case 0x8504: + s3->subsys_stat &= ~val; + s3_update_irqs(s3); + break; + case 0x8505: + s3->subsys_cntl = val; + s3_update_irqs(s3); + break; + case 0x850c: + s3->accel.advfunc_cntl = val; + s3_updatemapping(s3); + break; + case 0xff20: + s3->serialport = val; + i2c_gpio_set(s3->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); + break; + default: + s3_accel_out_fifo(s3, addr & 0xffff, val); + break; + } + } } else { - if (addr & 0x8000) { - s3_accel_out_fifo(s3, addr & 0xffff, val); - } else { - if (s3->accel.cmd & 0x100) { - if ((s3->accel.cmd & 0x600) == 0x200) { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } else { - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } else - s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); - } - } - } + if (addr & 0x8000) { + s3_accel_out_fifo(s3, addr & 0xffff, val); + } else { + if (s3->accel.cmd & 0x100) { + if ((s3->accel.cmd & 0x600) == 0x200) { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(16, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } else + s3_accel_start(2, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } else { + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, val | (val << 8) | (val << 16) | (val << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } else + s3_accel_start(1, 1, 0xffffffff, val | (val << 8) | (val << 16) | (val << 24), s3); + } + } + } } } static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { - svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; - if (svga->crtc[0x53] & 0x08) { - if ((addr & 0x1fffe) < 0x8000) { - s3_accel_out_pixtrans_w(s3, val); - } else { - switch (addr & 0x1fffe) { - case 0x83d4: - default: - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - break; - case 0xff20: - s3_accel_write_fifo(s3, addr, val); - break; - case 0x811c: - s3_accel_out_fifo_w(s3, 0x9ee8, val); - break; - } - } - } else { - if (addr & 0x8000) { - if (addr == 0x811c) - s3_accel_out_fifo_w(s3, 0x9ee8, val); - else { - if (addr == 0xe2e8 || addr == 0xe2ea) { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) - s3_accel_out_pixtrans_w(s3, val); - else { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } - } else { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } - } - } else { - s3_accel_out_pixtrans_w(s3, val); - } - } + if (svga->crtc[0x53] & 0x08) { + if ((addr & 0x1fffe) < 0x8000) { + s3_accel_out_pixtrans_w(s3, val); + } else { + switch (addr & 0x1fffe) { + case 0x83d4: + default: + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + break; + case 0xff20: + s3_accel_write_fifo(s3, addr, val); + break; + case 0x811c: + s3_accel_out_fifo_w(s3, 0x9ee8, val); + break; + } + } + } else { + if (addr & 0x8000) { + if (addr == 0x811c) + s3_accel_out_fifo_w(s3, 0x9ee8, val); + else { + if (addr == 0xe2e8 || addr == 0xe2ea) { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + s3_accel_out_pixtrans_w(s3, val); + else { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + } + } else { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + } + } + } else { + s3_accel_out_pixtrans_w(s3, val); + } + } } - static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { svga_t *svga = &s3->svga; if (svga->crtc[0x53] & 0x08) { - if ((addr & 0x1fffc) < 0x8000 || ((addr & 0x1fffc) >= 0x10000 && (addr & 0x1fffc) < 0x18000)) { - if ((addr & 0x1fffc) >= 0x10000 && (addr & 0x1fffc) < 0x18000) { - s3_visionx68_video_engine_op(val, s3); - } else if ((addr & 0x1fffc) < 0x8000) { - s3_accel_out_pixtrans_l(s3, val); - } - } else { - switch (addr & 0x1fffc) { - case 0x8180: - s3->streams.pri_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x8184: - s3->streams.chroma_ctrl = val; - break; - case 0x8190: - s3->streams.sec_ctrl = val; - s3->streams.dda_horiz_accumulator = val & 0xfff; - if (val & (1 << 11)) - s3->streams.dda_horiz_accumulator |= 0xfffff800; - s3->streams.sdif = (val >> 24) & 7; - break; - case 0x8194: - s3->streams.chroma_upper_bound = val; - break; - case 0x8198: - s3->streams.sec_filter = val; - s3->streams.k1_horiz_scale = val & 0x7ff; - if (val & (1 << 10)) - s3->streams.k1_horiz_scale |= 0xfffff800; - s3->streams.k2_horiz_scale = (val >> 16) & 0x7ff; - if ((val >> 16) & (1 << 10)) - s3->streams.k2_horiz_scale |= 0xfffff800; - break; - case 0x81a0: - s3->streams.blend_ctrl = val; - break; - case 0x81c0: - s3->streams.pri_fb0 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c4: - s3->streams.pri_fb1 = val & 0x3fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c8: - s3->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81cc: - s3->streams.buffer_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d0: - s3->streams.sec_fb0 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d4: - s3->streams.sec_fb1 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d8: - s3->streams.sec_stride = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81dc: - s3->streams.overlay_ctrl = val; - break; - case 0x81e0: - s3->streams.k1_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - s3->streams.k1_vert_scale |= 0xfffff800; - break; - case 0x81e4: - s3->streams.k2_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - s3->streams.k2_vert_scale |= 0xfffff800; - break; - case 0x81e8: - s3->streams.dda_vert_accumulator = val & 0xfff; - if (val & (1 << 11)) - s3->streams.dda_vert_accumulator |= 0xfffff800; - break; - case 0x81ec: - s3->streams.fifo_ctrl = val; - break; - case 0x81f0: - s3->streams.pri_start = val; - s3->streams.pri_x = (val >> 16) & 0x7ff; - s3->streams.pri_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f4: - s3->streams.pri_size = val; - s3->streams.pri_w = (val >> 16) & 0x7ff; - s3->streams.pri_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f8: - s3->streams.sec_start = val; - s3->streams.sec_x = (val >> 16) & 0x7ff; - s3->streams.sec_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81fc: - s3->streams.sec_size = val; - s3->streams.sec_w = (val >> 16) & 0x7ff; - s3->streams.sec_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; + if ((addr & 0x1fffc) < 0x8000 || ((addr & 0x1fffc) >= 0x10000 && (addr & 0x1fffc) < 0x18000)) { + if ((addr & 0x1fffc) >= 0x10000 && (addr & 0x1fffc) < 0x18000) { + s3_visionx68_video_engine_op(val, s3); + } else if ((addr & 0x1fffc) < 0x8000) { + s3_accel_out_pixtrans_l(s3, val); + } + } else { + switch (addr & 0x1fffc) { + case 0x8180: + s3->streams.pri_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x8184: + s3->streams.chroma_ctrl = val; + break; + case 0x8190: + s3->streams.sec_ctrl = val; + s3->streams.dda_horiz_accumulator = val & 0xfff; + if (val & (1 << 11)) + s3->streams.dda_horiz_accumulator |= 0xfffff800; + s3->streams.sdif = (val >> 24) & 7; + break; + case 0x8194: + s3->streams.chroma_upper_bound = val; + break; + case 0x8198: + s3->streams.sec_filter = val; + s3->streams.k1_horiz_scale = val & 0x7ff; + if (val & (1 << 10)) + s3->streams.k1_horiz_scale |= 0xfffff800; + s3->streams.k2_horiz_scale = (val >> 16) & 0x7ff; + if ((val >> 16) & (1 << 10)) + s3->streams.k2_horiz_scale |= 0xfffff800; + break; + case 0x81a0: + s3->streams.blend_ctrl = val; + break; + case 0x81c0: + s3->streams.pri_fb0 = val & 0x3fffff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81c4: + s3->streams.pri_fb1 = val & 0x3fffff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81c8: + s3->streams.pri_stride = val & 0xfff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81cc: + s3->streams.buffer_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d0: + s3->streams.sec_fb0 = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d4: + s3->streams.sec_fb1 = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d8: + s3->streams.sec_stride = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81dc: + s3->streams.overlay_ctrl = val; + break; + case 0x81e0: + s3->streams.k1_vert_scale = val & 0x7ff; + if (val & (1 << 10)) + s3->streams.k1_vert_scale |= 0xfffff800; + break; + case 0x81e4: + s3->streams.k2_vert_scale = val & 0x7ff; + if (val & (1 << 10)) + s3->streams.k2_vert_scale |= 0xfffff800; + break; + case 0x81e8: + s3->streams.dda_vert_accumulator = val & 0xfff; + if (val & (1 << 11)) + s3->streams.dda_vert_accumulator |= 0xfffff800; + break; + case 0x81ec: + s3->streams.fifo_ctrl = val; + break; + case 0x81f0: + s3->streams.pri_start = val; + s3->streams.pri_x = (val >> 16) & 0x7ff; + s3->streams.pri_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81f4: + s3->streams.pri_size = val; + s3->streams.pri_w = (val >> 16) & 0x7ff; + s3->streams.pri_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81f8: + s3->streams.sec_start = val; + s3->streams.sec_x = (val >> 16) & 0x7ff; + s3->streams.sec_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81fc: + s3->streams.sec_size = val; + s3->streams.sec_w = (val >> 16) & 0x7ff; + s3->streams.sec_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; - case 0x8504: - s3->subsys_stat &= ~(val & 0xff); - s3->subsys_cntl = (val >> 8); - s3_update_irqs(s3); - break; + case 0x8504: + s3->subsys_stat &= ~(val & 0xff); + s3->subsys_cntl = (val >> 8); + s3_update_irqs(s3); + break; - case 0x850c: - s3->accel.advfunc_cntl = val & 0xff; - s3_updatemapping(s3); - break; + case 0x850c: + s3->accel.advfunc_cntl = val & 0xff; + s3_updatemapping(s3); + break; - case 0xff20: - s3_accel_write_fifo(s3, addr, val); - break; + case 0xff20: + s3_accel_write_fifo(s3, addr, val); + break; - case 0x18080: - s3->videoengine.nop = 1; - break; + case 0x18080: + s3->videoengine.nop = 1; + break; - case 0x18088: - s3->videoengine.cntl = val; - s3->videoengine.dda_init_accumulator = val & 0xfff; - s3->videoengine.odf = (val >> 16) & 7; - s3->videoengine.yuv = !!(val & (1 << 19)); - s3->videoengine.idf = (val >> 20) & 7; - s3->videoengine.dither = !!(val & (1 << 29)); - s3->videoengine.dm_index = (val >> 23) & 7; - break; + case 0x18088: + s3->videoengine.cntl = val; + s3->videoengine.dda_init_accumulator = val & 0xfff; + s3->videoengine.odf = (val >> 16) & 7; + s3->videoengine.yuv = !!(val & (1 << 19)); + s3->videoengine.idf = (val >> 20) & 7; + s3->videoengine.dither = !!(val & (1 << 29)); + s3->videoengine.dm_index = (val >> 23) & 7; + break; - case 0x1808c: - s3->videoengine.stretch_filt_const = val; - s3->videoengine.k2 = val & 0x7ff; - s3->videoengine.k1 = (val >> 16) & 0x7ff; - s3->videoengine.host_data = !!(val & (1 << 30)); - s3->videoengine.scale_down = !!(val & (1 << 31)); - break; + case 0x1808c: + s3->videoengine.stretch_filt_const = val; + s3->videoengine.k2 = val & 0x7ff; + s3->videoengine.k1 = (val >> 16) & 0x7ff; + s3->videoengine.host_data = !!(val & (1 << 30)); + s3->videoengine.scale_down = !!(val & (1 << 31)); + break; - case 0x18090: - s3->videoengine.src_dst_step = val; - s3->videoengine.dst_step = val & 0x1fff; - s3->videoengine.src_step = (val >> 16) & 0x1fff; - break; + case 0x18090: + s3->videoengine.src_dst_step = val; + s3->videoengine.dst_step = val & 0x1fff; + s3->videoengine.src_step = (val >> 16) & 0x1fff; + break; - case 0x18094: - s3->videoengine.crop = val; - s3->videoengine.len = val & 0xfff; - s3->videoengine.start = (val >> 16) & 0xfff; - s3->videoengine.input = 1; - break; + case 0x18094: + s3->videoengine.crop = val; + s3->videoengine.len = val & 0xfff; + s3->videoengine.start = (val >> 16) & 0xfff; + s3->videoengine.input = 1; + break; - case 0x18098: - s3->videoengine.src_base = val & 0xffffff; - break; + case 0x18098: + s3->videoengine.src_base = val & 0xffffff; + break; - case 0x1809c: - s3->videoengine.dest_base = val & 0xffffff; - break; + case 0x1809c: + s3->videoengine.dest_base = val & 0xffffff; + break; - default: - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - break; - } - } + default: + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + s3_accel_write_fifo(s3, addr + 2, val >> 16); + s3_accel_write_fifo(s3, addr + 3, val >> 24); + break; + } + } } else { - if (addr & 0x8000) { - if (addr == 0xe2e8) { - if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) - s3_accel_out_pixtrans_l(s3, val); - else { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - } - } else { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - } - } else { - s3_accel_out_pixtrans_l(s3, val); - } + if (addr & 0x8000) { + if (addr == 0xe2e8) { + if (s3->chip == S3_86C928 || s3->chip == S3_86C928PCI) + s3_accel_out_pixtrans_l(s3, val); + else { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + s3_accel_write_fifo(s3, addr + 2, val >> 16); + s3_accel_write_fifo(s3, addr + 3, val >> 24); + } + } else { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + s3_accel_write_fifo(s3, addr + 2, val >> 16); + s3_accel_write_fifo(s3, addr + 3, val >> 24); + } + } else { + s3_accel_out_pixtrans_l(s3, val); + } } } - static void s3_vblank_start(svga_t *svga) { - s3_t *s3 = (s3_t *)svga->p; + s3_t *s3 = (s3_t *) svga->p; - s3->subsys_stat |= INT_VSY; - s3_update_irqs(s3); + s3->subsys_stat |= INT_VSY; + s3_update_irqs(s3); } - static uint32_t s3_hwcursor_convert_addr(svga_t *svga) { if ((svga->bpp == 8) && ((svga->gdcreg[5] & 0x60) >= 0x20) && (svga->crtc[0x45] & 0x10)) { - if ((svga->gdcreg[5] & 0x60) >= 0x40) - return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; - else if ((svga->gdcreg[5] & 0x60) == 0x20) - return ((svga->hwcursor_latch.addr & 0xfffff0ff) | ((svga->hwcursor_latch.addr & 0x300) << 2)) | 0x300; - else - return svga->hwcursor_latch.addr; + if ((svga->gdcreg[5] & 0x60) >= 0x40) + return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; + else if ((svga->gdcreg[5] & 0x60) == 0x20) + return ((svga->hwcursor_latch.addr & 0xfffff0ff) | ((svga->hwcursor_latch.addr & 0x300) << 2)) | 0x300; + else + return svga->hwcursor_latch.addr; } else - return svga->hwcursor_latch.addr; + return svga->hwcursor_latch.addr; } - - static void s3_hwcursor_draw(svga_t *svga, int displine) { - s3_t *s3 = (s3_t *)svga->p; - int x, shift = 1; - int width = 16; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg, bg; - uint32_t real_addr; - uint32_t remapped_addr; + s3_t *s3 = (s3_t *) svga->p; + int x, shift = 1; + int width = 16; + uint16_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg, bg; + uint32_t real_addr; + uint32_t remapped_addr; - switch (svga->bpp) - { - case 15: - fg = video_15to32[s3->hwc_fg_col & 0xffff]; - bg = video_15to32[s3->hwc_bg_col & 0xffff]; - if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { - if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { - if (!(svga->crtc[0x45] & 0x04)) { - shift = 2; - width = 8; - } - } - } - break; - - case 16: - fg = video_16to32[s3->hwc_fg_col & 0xffff]; - bg = video_16to32[s3->hwc_bg_col & 0xffff]; - if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { - if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { - if (!(svga->crtc[0x45] & 0x04)) { - shift = 2; - width = 8; - } - } else if (s3->card_type == S3_MIROCRYSTAL10SD_805) { - if (!(svga->crtc[0x45] & 0x04)) { - offset <<= 1; - } - } - } - break; - - case 24: - fg = s3->hwc_fg_col; - bg = s3->hwc_bg_col; - break; - - case 32: - fg = s3->hwc_fg_col; - bg = s3->hwc_bg_col; - break; - - default: - if (s3->chip >= S3_TRIO32) - { - fg = svga->pallook[s3->hwc_fg_col & 0xff]; - bg = svga->pallook[s3->hwc_bg_col & 0xff]; - } - else - { - fg = svga->pallook[svga->crtc[0xe]]; - bg = svga->pallook[svga->crtc[0xf]]; - } - break; - } - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; - - real_addr = s3_hwcursor_convert_addr(svga); - - for (x = 0; x < 64; x += 16) - { - remapped_addr = dword_remap(svga, real_addr); - - dat[0] = (svga->vram[remapped_addr & s3->vram_mask] << 8) | svga->vram[(remapped_addr + 1) & s3->vram_mask]; - dat[1] = (svga->vram[(remapped_addr + 2) & s3->vram_mask] << 8) | svga->vram[(remapped_addr + 3) & s3->vram_mask]; - - if (svga->crtc[0x55] & 0x10) { - /*X11*/ - for (xx = 0; xx < 16; xx++) { - if (offset >= 0) { - if (dat[0] & 0x8000) - buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; - } - - offset++; - dat[0] <<= shift; - dat[1] <<= shift; - } - } else { - /*Windows*/ - for (xx = 0; xx < width; xx++) { - if (offset >= 0) { - if (!(dat[0] & 0x8000)) - buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; - else if (dat[1] & 0x8000) - buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; - } - - offset++; - dat[0] <<= shift; - dat[1] <<= shift; - } + switch (svga->bpp) { + case 15: + fg = video_15to32[s3->hwc_fg_col & 0xffff]; + bg = video_15to32[s3->hwc_bg_col & 0xffff]; + if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { + if (!(svga->crtc[0x45] & 0x04)) { + shift = 2; + width = 8; + } } - svga->hwcursor_latch.addr += 4; - real_addr = s3_hwcursor_convert_addr(svga); - } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + } + break; + + case 16: + fg = video_16to32[s3->hwc_fg_col & 0xffff]; + bg = video_16to32[s3->hwc_bg_col & 0xffff]; + if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805) { + if (!(svga->crtc[0x45] & 0x04)) { + shift = 2; + width = 8; + } + } else if (s3->card_type == S3_MIROCRYSTAL10SD_805) { + if (!(svga->crtc[0x45] & 0x04)) { + offset <<= 1; + } + } + } + break; + + case 24: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; + + case 32: + fg = s3->hwc_fg_col; + bg = s3->hwc_bg_col; + break; + + default: + if (s3->chip >= S3_TRIO32) { + fg = svga->pallook[s3->hwc_fg_col & 0xff]; + bg = svga->pallook[s3->hwc_bg_col & 0xff]; + } else { + fg = svga->pallook[svga->crtc[0xe]]; + bg = svga->pallook[svga->crtc[0xf]]; + } + break; + } + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; + + real_addr = s3_hwcursor_convert_addr(svga); + + for (x = 0; x < 64; x += 16) { + remapped_addr = dword_remap(svga, real_addr); + + dat[0] = (svga->vram[remapped_addr & s3->vram_mask] << 8) | svga->vram[(remapped_addr + 1) & s3->vram_mask]; + dat[1] = (svga->vram[(remapped_addr + 2) & s3->vram_mask] << 8) | svga->vram[(remapped_addr + 3) & s3->vram_mask]; + + if (svga->crtc[0x55] & 0x10) { + /*X11*/ + for (xx = 0; xx < 16; xx++) { + if (offset >= 0) { + if (dat[0] & 0x8000) + buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; + } + + offset++; + dat[0] <<= shift; + dat[1] <<= shift; + } + } else { + /*Windows*/ + for (xx = 0; xx < width; xx++) { + if (offset >= 0) { + if (!(dat[0] & 0x8000)) + buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; + else if (dat[1] & 0x8000) + buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; + } + + offset++; + dat[0] <<= shift; + dat[1] <<= shift; + } + } + svga->hwcursor_latch.addr += 4; + real_addr = s3_hwcursor_convert_addr(svga); + } + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; } -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) -#define DECODE_YCbCr() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - \ - y1 = src[0]; \ - Cr = src[1] - 0x80; \ - y2 = src[2]; \ - Cb = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) +#define DECODE_YCbCr() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) /*Both YUV formats are untested*/ -#define DECODE_YUV211() \ - do \ - { \ - uint8_t y1, y2, y3, y4; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - y2 = (298 * (src[2] - 16)) >> 8; \ - V = src[3] - 0x80; \ - y3 = (298 * (src[4] - 16)) >> 8; \ - y4 = (298 * (src[5] - 16)) >> 8; \ - src += 6; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - r[x_write+2] = y3 + dR; \ - CLAMP(r[x_write+2]); \ - g[x_write+2] = y3 - dG; \ - CLAMP(g[x_write+2]); \ - b[x_write+2] = y3 + dB; \ - CLAMP(b[x_write+2]); \ - \ - r[x_write+3] = y4 + dR; \ - CLAMP(r[x_write+3]); \ - g[x_write+3] = y4 - dG; \ - CLAMP(g[x_write+3]); \ - b[x_write+3] = y4 + dB; \ - CLAMP(b[x_write+3]); \ - \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_YUV211() \ + do { \ + uint8_t y1, y2, y3, y4; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + y2 = (298 * (src[2] - 16)) >> 8; \ + V = src[3] - 0x80; \ + y3 = (298 * (src[4] - 16)) >> 8; \ + y4 = (298 * (src[5] - 16)) >> 8; \ + src += 6; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + r[x_write + 2] = y3 + dR; \ + CLAMP(r[x_write + 2]); \ + g[x_write + 2] = y3 - dG; \ + CLAMP(g[x_write + 2]); \ + b[x_write + 2] = y3 + dB; \ + CLAMP(b[x_write + 2]); \ + \ + r[x_write + 3] = y4 + dR; \ + CLAMP(r[x_write + 3]); \ + g[x_write + 3] = y4 - dG; \ + CLAMP(g[x_write + 3]); \ + b[x_write + 3] = y4 + dB; \ + CLAMP(b[x_write + 3]); \ + \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_YUV422() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - V = src[2] - 0x80; \ - y2 = (298 * (src[3] - 16)) >> 8; \ - src += 4; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) +#define DECODE_YUV422() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + V = src[2] - 0x80; \ + y2 = (298 * (src[3] - 16)) >> 8; \ + src += 4; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) -#define DECODE_RGB555() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ - b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB555() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *) src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ + b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_RGB565() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ - b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB565() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *) src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ + b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_RGB888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 3; \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB888() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 3; \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_XRGB8888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 4; \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_XRGB8888() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 4; \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define OVERLAY_SAMPLE() \ - do \ - { \ - switch (s3->streams.sdif) \ - { \ - case 1: \ - DECODE_YCbCr(); \ - break; \ - case 2: \ - DECODE_YUV422(); \ - break; \ - case 3: \ - DECODE_RGB555(); \ - break; \ - case 4: \ - DECODE_YUV211(); \ - break; \ - case 5: \ - DECODE_RGB565(); \ - break; \ - case 6: \ - DECODE_RGB888(); \ - break; \ - case 7: \ - default: \ - DECODE_XRGB8888(); \ - break; \ - } \ - } while (0) +#define OVERLAY_SAMPLE() \ + do { \ + switch (s3->streams.sdif) { \ + case 1: \ + DECODE_YCbCr(); \ + break; \ + case 2: \ + DECODE_YUV422(); \ + break; \ + case 3: \ + DECODE_RGB555(); \ + break; \ + case 4: \ + DECODE_YUV211(); \ + break; \ + case 5: \ + DECODE_RGB565(); \ + break; \ + case 6: \ + DECODE_RGB888(); \ + break; \ + case 7: \ + default: \ + DECODE_XRGB8888(); \ + break; \ + } \ + } while (0) - -static void s3_trio64v_overlay_draw(svga_t *svga, int displine) +static void +s3_trio64v_overlay_draw(svga_t *svga, int displine) { - s3_t *s3 = (s3_t *)svga->p; - int offset = (s3->streams.sec_x - s3->streams.pri_x) + 1; - int h_acc = s3->streams.dda_horiz_accumulator; - int r[8], g[8], b[8]; - int x_size, x_read = 4, x_write = 4; - int x; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay_latch.addr]; + s3_t *s3 = (s3_t *) svga->p; + int offset = (s3->streams.sec_x - s3->streams.pri_x) + 1; + int h_acc = s3->streams.dda_horiz_accumulator; + int r[8], g[8], b[8]; + int x_size, x_read = 4, x_write = 4; + int x; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - p = &(buffer32->line[displine][offset + svga->x_add]); + p = &(buffer32->line[displine][offset + svga->x_add]); - if ((offset + s3->streams.sec_w) > s3->streams.pri_w) - x_size = (s3->streams.pri_w - s3->streams.sec_x) + 1; - else - x_size = s3->streams.sec_w + 1; + if ((offset + s3->streams.sec_w) > s3->streams.pri_w) + x_size = (s3->streams.pri_w - s3->streams.sec_x) + 1; + else + x_size = s3->streams.sec_w + 1; - OVERLAY_SAMPLE(); + OVERLAY_SAMPLE(); - for (x = 0; x < x_size; x++) - { - *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); + for (x = 0; x < x_size; x++) { + *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - h_acc += s3->streams.k1_horiz_scale; - if (h_acc >= 0) - { - if ((x_read ^ (x_read + 1)) & ~3) - OVERLAY_SAMPLE(); - x_read = (x_read + 1) & 7; + h_acc += s3->streams.k1_horiz_scale; + if (h_acc >= 0) { + if ((x_read ^ (x_read + 1)) & ~3) + OVERLAY_SAMPLE(); + x_read = (x_read + 1) & 7; - h_acc += (s3->streams.k2_horiz_scale - s3->streams.k1_horiz_scale); - } + h_acc += (s3->streams.k2_horiz_scale - s3->streams.k1_horiz_scale); } + } - svga->overlay_latch.v_acc += s3->streams.k1_vert_scale; - if (svga->overlay_latch.v_acc >= 0) - { - svga->overlay_latch.v_acc += (s3->streams.k2_vert_scale - s3->streams.k1_vert_scale); - svga->overlay_latch.addr += s3->streams.sec_stride; - } + svga->overlay_latch.v_acc += s3->streams.k1_vert_scale; + if (svga->overlay_latch.v_acc >= 0) { + svga->overlay_latch.v_acc += (s3->streams.k2_vert_scale - s3->streams.k1_vert_scale); + svga->overlay_latch.addr += s3->streams.sec_stride; + } } static void s3_io_remove_alt(s3_t *s3) { - if (!s3->translate) - return; + if (!s3->translate) + return; - io_removehandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x4948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8d48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); - io_removehandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xad48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip >= S3_86C928) - io_removehandler(0xb148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - else - io_removehandler(0xb148, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - io_removehandler(0xb548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xb948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xbd48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xd148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xe148, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - io_removehandler(0xe548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xe948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xed48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x4948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8d48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_removehandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xa948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xad48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip >= S3_86C928) + io_removehandler(0xb148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + else + io_removehandler(0xb148, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_removehandler(0xb548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xb948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xbd48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xd148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xe148, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_removehandler(0xe548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xe948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xed48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); } static void s3_io_remove(s3_t *s3) { - io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); - io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip >= S3_86C928) - io_removehandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - else - io_removehandler(0xb2e8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xcae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - io_removehandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xeae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xeee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0xfee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip >= S3_86C928) + io_removehandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + else + io_removehandler(0xb2e8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_removehandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xcae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_removehandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xeae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xeee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0xfee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - s3_io_remove_alt(s3); + s3_io_remove_alt(s3); } static void s3_io_set_alt(s3_t *s3) { - svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; - if (!s3->translate) - return; + if (!s3->translate) + return; - if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) { - return; - } + if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) { + return; + } - io_sethandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x4948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip == S3_TRIO64 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - { - io_sethandler(0x8148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8d48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - else - { - io_sethandler(0x8148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8d48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - io_sethandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - else - io_sethandler(0x9948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); - io_sethandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xad48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip >= S3_86C928) - io_sethandler(0xb148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - else - io_sethandler(0xb148, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - io_sethandler(0xb548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xb948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbd48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe148, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { - io_sethandler(0xd148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xed48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } + io_sethandler(0x4148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x4548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x4948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip == S3_TRIO64 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { + io_sethandler(0x8148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8d48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } else { + io_sethandler(0x8148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8d48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } + if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) + io_sethandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + else + io_sethandler(0x9948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_sethandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xa948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xad48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip >= S3_86C928) + io_sethandler(0xb148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + else + io_sethandler(0xb148, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_sethandler(0xb548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xb948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xbd48, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xe148, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { + io_sethandler(0xd148, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xe548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xe948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xed48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } } static void s3_io_set(s3_t *s3) { - svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; - s3_io_remove(s3); + s3_io_remove(s3); - io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + io_sethandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); - if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) { - return; - } + if ((s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (svga->seqregs[9] & 0x80)) { + return; + } - io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip == S3_TRIO64 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - { - io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - else - { - io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - io_sethandler(0x9ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - else - io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); - io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - if (s3->chip >= S3_86C928) - io_sethandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - else - io_sethandler(0xb2e8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xcae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); - if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { - io_sethandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xeae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_sethandler(0xeee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - } - io_sethandler(0xfee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip == S3_TRIO64 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { + io_sethandler(0x82e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x86e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } else { + io_sethandler(0x82e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x86e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x8ee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x92e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } + if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) + io_sethandler(0x9ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + else + io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xaae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xaee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + if (s3->chip >= S3_86C928) + io_sethandler(0xb2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + else + io_sethandler(0xb2e8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + io_sethandler(0xb6e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xbae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xbee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xcae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xe2e8, 0x0004, s3_accel_in, s3_accel_in_w, s3_accel_in_l, s3_accel_out, s3_accel_out_w, s3_accel_out_l, s3); + if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { + io_sethandler(0xd2e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xe6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xeae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0xeee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + } + io_sethandler(0xfee8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - s3_io_set_alt(s3); + s3_io_set_alt(s3); } static void s3_out(uint16_t addr, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - uint8_t old, mask; - int rs2, rs3; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + uint8_t old, mask; + int rs2, rs3; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3c2: - if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_86C928)) { - if ((s3->card_type != S3_SPEA_MERCURY_P64V) && (s3->card_type != S3_MIROVIDEO40SV_ERGO_968)) { - if (((val >> 2) & 3) != 3) - icd2061_write(svga->clock_gen, (val >> 2) & 3); - } - } - break; - - case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) - { - svga->seqregs[svga->seqaddr] = val; - switch (svga->seqaddr) - { - case 0x12: case 0x13: - svga_recalctimings(svga); - return; - } - } - if (svga->seqaddr == 4) /*Chain-4 - update banking*/ - { - if (val & 0x08) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - } else if (svga->seqaddr == 9) { - svga->seqregs[svga->seqaddr] = val & 0x80; - s3_io_set(s3); - return; - } else if (svga->seqaddr == 0xa) { - svga->seqregs[svga->seqaddr] = val & 0x80; - return; - } else if (s3->chip >= S3_VISION964) { - if (svga->seqaddr == 0x08) { - svga->seqregs[svga->seqaddr] = val & 0x0f; - return; - } else if ((svga->seqaddr == 0x0d) && (svga->seqregs[0x08] == 0x06)) { - svga->seqregs[svga->seqaddr] = val; - svga->dpms = ((s3->chip >= S3_VISION964) && (svga->seqregs[0x0d] & 0x50)) || (svga->crtc[0x56] & ((s3->chip >= S3_TRIO32) ? 0x06 : 0x20)); - svga_recalctimings(svga); - return; - } - } - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if ((svga->crtc[0x55] & 0x03) == 0x00) - rs2 = !!(svga->crtc[0x43] & 0x02); - else - rs2 = (svga->crtc[0x55] & 0x01); - if (s3->chip >= S3_TRIO32) - svga_out(addr, val, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - if (!(svga->crtc[0x45] & 0x20) || (s3->chip == S3_86C928)) - rs3 = !!(svga->crtc[0x55] & 0x02); - else - rs3 = 0; - bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || - s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { - rs3 = !!(svga->crtc[0x55] & 0x02); - tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) - att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) { - sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - } else if (s3->card_type == S3_NUMBER9_9FX_531) - att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - else - sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); - return; - - case 0x3D4: - svga->crtcreg = (s3->chip == S3_TRIO64V2) ? val : (val & 0x7f); - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && - (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && - (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) - return; - if ((svga->crtcreg >= 0x40) && ((svga->crtc[0x39] & 0xe0) != 0xa0)) - return; - if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) - return; - if ((s3->chip == S3_TRIO64V2) && (svga->crtcreg >= 0x80)) - return; - if ((s3->chip <= S3_86C924) && (svga->crtcreg >= 0x50)) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - switch (svga->crtcreg) - { - case 0x31: - s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); - svga->force_dword_mode = !!(val & 0x08); - break; - case 0x32: - if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) - svga->vram_display_mask = 0x3ffff; - else - svga->vram_display_mask = s3->vram_mask; - break; - - case 0x40: - s3->enable_8514 = (val & 0x01); - break; - - case 0x50: - mask = 0xc0; - if (s3->chip != S3_86C801) - mask |= 0x01; - switch (svga->crtc[0x50] & mask) - { - case 0x00: s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; break; - case 0x01: s3->width = 1152; break; - case 0x40: s3->width = 640; break; - case 0x80: s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 4)) ? 1600 : 800; break; - case 0x81: s3->width = 1600; break; - case 0xc0: s3->width = 1280; break; - } - s3->bpp = (svga->crtc[0x50] >> 4) & 3; - break; - - case 0x5c: - if ((val & 0xa0) == 0x80) - i2c_gpio_set(s3->i2c, !!(val & 0x40), !!(val & 0x10)); - if (s3->card_type == S3_PHOENIX_VISION868 || s3->card_type == S3_PHOENIX_VISION968) { - if ((val & 0x20) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) - svga->dac_addr |= 0x20; - } else if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968) { - if ((val & 0x80) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) - svga->dac_addr |= 0x02; - } - break; - - case 0x69: - if (s3->chip >= S3_VISION964) - s3->ma_ext = val & 0x1f; - break; - - case 0x35: - s3->bank = (s3->bank & 0x70) | (val & 0xf); - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - break; - - case 0x51: - if (s3->chip == S3_86C801 || s3->chip == S3_86C805) { - s3->bank = (s3->bank & 0x6f) | ((val & 0x4) << 2); - s3->ma_ext = (s3->ma_ext & ~0x4) | ((val & 1) << 2); - } else { - s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); - s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); - } - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - break; - - case 0x6a: - if (s3->chip >= S3_VISION964) { - s3->bank = val; - if (svga->chain4) - svga->write_bank = svga->read_bank = s3->bank << 16; - else - svga->write_bank = svga->read_bank = s3->bank << 14; - } - break; - - case 0x45: - if (s3->chip == S3_VISION964 || s3->chip == S3_VISION968) - break; - svga->hwcursor.ena = val & 1; - break; - case 0x46: case 0x47: case 0x48: case 0x49: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - if (s3->chip == S3_VISION964 || s3->chip == S3_VISION968) - break; - svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; - if (svga->bpp == 32) svga->hwcursor.x >>= 1; - svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x4e] & 0x3f; - svga->hwcursor.yoff = svga->crtc[0x4f] & 0x3f; - svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - if ((s3->chip >= S3_TRIO32) && svga->bpp == 32) - svga->hwcursor.x <<= 1; - else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 15 || svga->bpp == 16)) { - if ((s3->card_type == S3_MIROCRYSTAL10SD_805) && !(svga->crtc[0x45] & 0x04) && svga->bpp == 16) - svga->hwcursor.x >>= 2; - else - svga->hwcursor.x >>= 1; - } else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 24)) - svga->hwcursor.x /= 3; - break; - - case 0x4a: - switch (s3->hwc_col_stack_pos) - { - case 0: - s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; - break; - case 1: - s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); - break; - case 2: - s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); - break; - } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; - break; - case 0x4b: - switch (s3->hwc_col_stack_pos) - { - case 0: - s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; - break; - case 1: - s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); - break; - case 2: - s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); - break; - } - s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; - break; - - case 0x53: - case 0x58: case 0x59: case 0x5a: - s3_updatemapping(s3); - break; - - case 0x55: - if (s3->chip == S3_86C928) { - if ((val & 0x08) || ((val & 0x20) == 0x20)) { - svga->hwcursor_draw = NULL; - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - } else { - svga->hwcursor_draw = s3_hwcursor_draw; - svga->dac_hwcursor_draw = NULL; - } - } - break; - - case 0x42: - if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_86C928)) { - if (((svga->miscout >> 2) & 3) == 3) - icd2061_write(svga->clock_gen, svga->crtc[0x42] & 0x0f); - } - break; - - case 0x43: - if (s3->chip < S3_VISION964) { - s3_io_remove_alt(s3); - s3->translate = !!(val & 0x10); - s3_io_set_alt(s3); - } - break; - - case 0x56: - svga->dpms = ((s3->chip >= S3_VISION964) && (svga->seqregs[0x0d] & 0x50)) || (svga->crtc[0x56] & ((s3->chip >= S3_TRIO32) ? 0x06 : 0x20)); - old = ~val; /* force recalc */ - break; - - case 0x67: - if (s3->chip >= S3_TRIO32) { - switch (val >> 4) - { - case 3: svga->bpp = 15; break; - case 5: svga->bpp = 16; break; - case 7: svga->bpp = 24; break; - case 13: svga->bpp = 32; break; - default: svga->bpp = 8; break; - } - } - break; - } - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - if ((((svga->crtc[0x67] & 0xc) != 0xc) && (s3->chip >= S3_TRIO64V)) || (s3->chip < S3_TRIO64V)) - svga->ma_latch |= (s3->ma_ext << 16); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } + switch (addr) { + case 0x3c2: + if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_86C928)) { + if ((s3->card_type != S3_SPEA_MERCURY_P64V) && (s3->card_type != S3_MIROVIDEO40SV_ERGO_968)) { + if (((val >> 2) & 3) != 3) + icd2061_write(svga->clock_gen, (val >> 2) & 3); } - break; - } - svga_out(addr, val, svga); + } + break; + + case 0x3c5: + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { + svga->seqregs[svga->seqaddr] = val; + switch (svga->seqaddr) { + case 0x12: + case 0x13: + svga_recalctimings(svga); + return; + } + } + if (svga->seqaddr == 4) /*Chain-4 - update banking*/ + { + if (val & 0x08) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + } else if (svga->seqaddr == 9) { + svga->seqregs[svga->seqaddr] = val & 0x80; + s3_io_set(s3); + return; + } else if (svga->seqaddr == 0xa) { + svga->seqregs[svga->seqaddr] = val & 0x80; + return; + } else if (s3->chip >= S3_VISION964) { + if (svga->seqaddr == 0x08) { + svga->seqregs[svga->seqaddr] = val & 0x0f; + return; + } else if ((svga->seqaddr == 0x0d) && (svga->seqregs[0x08] == 0x06)) { + svga->seqregs[svga->seqaddr] = val; + svga->dpms = ((s3->chip >= S3_VISION964) && (svga->seqregs[0x0d] & 0x50)) || (svga->crtc[0x56] & ((s3->chip >= S3_TRIO32) ? 0x06 : 0x20)); + svga_recalctimings(svga); + return; + } + } + break; + + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if ((svga->crtc[0x55] & 0x03) == 0x00) + rs2 = !!(svga->crtc[0x43] & 0x02); + else + rs2 = (svga->crtc[0x55] & 0x01); + if (s3->chip >= S3_TRIO32) + svga_out(addr, val, svga); + else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { + if (!(svga->crtc[0x45] & 0x20) || (s3->chip == S3_86C928)) + rs3 = !!(svga->crtc[0x55] & 0x02); + else + rs3 = 0; + bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) + ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); + else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { + rs3 = !!(svga->crtc[0x55] & 0x02); + tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) + att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + else if (s3->chip <= S3_86C924) { + sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + } else if (s3->card_type == S3_NUMBER9_9FX_531) + att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); + else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + else + sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + return; + + case 0x3D4: + svga->crtcreg = (s3->chip == S3_TRIO64V2) ? val : (val & 0x7f); + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) + return; + if ((svga->crtcreg >= 0x40) && ((svga->crtc[0x39] & 0xe0) != 0xa0)) + return; + if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) + return; + if ((s3->chip == S3_TRIO64V2) && (svga->crtcreg >= 0x80)) + return; + if ((s3->chip <= S3_86C924) && (svga->crtcreg >= 0x50)) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + + switch (svga->crtcreg) { + case 0x31: + s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + svga->force_dword_mode = !!(val & 0x08); + break; + case 0x32: + if ((svga->crtc[0x31] & 0x30) && (svga->crtc[0x51] & 0x01) && (val & 0x40)) + svga->vram_display_mask = 0x3ffff; + else + svga->vram_display_mask = s3->vram_mask; + break; + + case 0x40: + s3->enable_8514 = (val & 0x01); + break; + + case 0x50: + mask = 0xc0; + if (s3->chip != S3_86C801) + mask |= 0x01; + switch (svga->crtc[0x50] & mask) { + case 0x00: + s3->width = (svga->crtc[0x31] & 2) ? 2048 : 1024; + break; + case 0x01: + s3->width = 1152; + break; + case 0x40: + s3->width = 640; + break; + case 0x80: + s3->width = ((s3->chip > S3_86C805) && (s3->accel.advfunc_cntl & 4)) ? 1600 : 800; + break; + case 0x81: + s3->width = 1600; + break; + case 0xc0: + s3->width = 1280; + break; + } + s3->bpp = (svga->crtc[0x50] >> 4) & 3; + break; + + case 0x5c: + if ((val & 0xa0) == 0x80) + i2c_gpio_set(s3->i2c, !!(val & 0x40), !!(val & 0x10)); + if (s3->card_type == S3_PHOENIX_VISION868 || s3->card_type == S3_PHOENIX_VISION968) { + if ((val & 0x20) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) + svga->dac_addr |= 0x20; + } else if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968) { + if ((val & 0x80) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) + svga->dac_addr |= 0x02; + } + break; + + case 0x69: + if (s3->chip >= S3_VISION964) + s3->ma_ext = val & 0x1f; + break; + + case 0x35: + s3->bank = (s3->bank & 0x70) | (val & 0xf); + if (svga->chain4) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + break; + + case 0x51: + if (s3->chip == S3_86C801 || s3->chip == S3_86C805) { + s3->bank = (s3->bank & 0x6f) | ((val & 0x4) << 2); + s3->ma_ext = (s3->ma_ext & ~0x4) | ((val & 1) << 2); + } else { + s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); + s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); + } + if (svga->chain4) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + break; + + case 0x6a: + if (s3->chip >= S3_VISION964) { + s3->bank = val; + if (svga->chain4) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; + } + break; + + case 0x45: + if (s3->chip == S3_VISION964 || s3->chip == S3_VISION968) + break; + svga->hwcursor.ena = val & 1; + break; + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + if (s3->chip == S3_VISION964 || s3->chip == S3_VISION968) + break; + svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; + if (svga->bpp == 32) + svga->hwcursor.x >>= 1; + svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x4e] & 0x3f; + svga->hwcursor.yoff = svga->crtc[0x4f] & 0x3f; + svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); + if ((s3->chip >= S3_TRIO32) && svga->bpp == 32) + svga->hwcursor.x <<= 1; + else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 15 || svga->bpp == 16)) { + if ((s3->card_type == S3_MIROCRYSTAL10SD_805) && !(svga->crtc[0x45] & 0x04) && svga->bpp == 16) + svga->hwcursor.x >>= 2; + else + svga->hwcursor.x >>= 1; + } else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && (svga->bpp == 24)) + svga->hwcursor.x /= 3; + break; + + case 0x4a: + switch (s3->hwc_col_stack_pos) { + case 0: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_fg_col = (s3->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_fg_col = (s3->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; + break; + case 0x4b: + switch (s3->hwc_col_stack_pos) { + case 0: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xffff00) | val; + break; + case 1: + s3->hwc_bg_col = (s3->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + s3->hwc_bg_col = (s3->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + s3->hwc_col_stack_pos = (s3->hwc_col_stack_pos + 1) & 3; + break; + + case 0x53: + case 0x58: + case 0x59: + case 0x5a: + s3_updatemapping(s3); + break; + + case 0x55: + if (s3->chip == S3_86C928) { + if ((val & 0x08) || ((val & 0x20) == 0x20)) { + svga->hwcursor_draw = NULL; + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + } else { + svga->hwcursor_draw = s3_hwcursor_draw; + svga->dac_hwcursor_draw = NULL; + } + } + break; + + case 0x42: + if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968) || (s3->chip == S3_86C928)) { + if (((svga->miscout >> 2) & 3) == 3) + icd2061_write(svga->clock_gen, svga->crtc[0x42] & 0x0f); + } + break; + + case 0x43: + if (s3->chip < S3_VISION964) { + s3_io_remove_alt(s3); + s3->translate = !!(val & 0x10); + s3_io_set_alt(s3); + } + break; + + case 0x56: + svga->dpms = ((s3->chip >= S3_VISION964) && (svga->seqregs[0x0d] & 0x50)) || (svga->crtc[0x56] & ((s3->chip >= S3_TRIO32) ? 0x06 : 0x20)); + old = ~val; /* force recalc */ + break; + + case 0x67: + if (s3->chip >= S3_TRIO32) { + switch (val >> 4) { + case 3: + svga->bpp = 15; + break; + case 5: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; + case 13: + svga->bpp = 32; + break; + default: + svga->bpp = 8; + break; + } + } + break; + } + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + if ((((svga->crtc[0x67] & 0xc) != 0xc) && (s3->chip >= S3_TRIO64V)) || (s3->chip < S3_TRIO64V)) + svga->ma_latch |= (s3->ma_ext << 16); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + } + svga_out(addr, val, svga); } static uint8_t s3_in(uint16_t addr, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - int rs2, rs3; - uint8_t temp; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + int rs2, rs3; + uint8_t temp; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3c1: - if (svga->attraddr > 0x14) - return 0xff; - break; + switch (addr) { + case 0x3c1: + if (svga->attraddr > 0x14) + return 0xff; + break; - case 0x3c2: - if (s3->chip <= S3_86C924) - return svga_in(addr, svga) | 0x10; - break; + case 0x3c2: + if (s3->chip <= S3_86C924) + return svga_in(addr, svga) | 0x10; + break; - case 0x3c5: - if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { - temp = svga->seqregs[svga->seqaddr]; - /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not - get stuck in an infinite loop. */ - if ((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) && (svga->seqaddr == 0x17)) - svga->seqregs[svga->seqaddr] ^= 0x01; - return temp; - } - break; - - case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - return svga_in(addr, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || - s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { - rs3 = !!(svga->crtc[0x55] & 0x02); - return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) - return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) - return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->card_type == S3_NUMBER9_9FX_531) - return att498_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - return sc1502x_ramdac_in(addr, svga->ramdac, svga); - else - return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); - break; - - case 0x3d4: - return svga->crtcreg; - case 0x3d5: - switch (svga->crtcreg) - { - case 0x2d: return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; /*Extended chip ID*/ - case 0x2e: return s3->id_ext; /*New chip ID*/ - case 0x2f: return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision level*/ - case 0x30: return s3->id; /*Chip ID*/ - case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); - case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); - case 0x45: s3->hwc_col_stack_pos = 0; break; - case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); - case 0x5c: /* General Output Port Register */ - temp = svga->crtc[svga->crtcreg] & 0xa0; - if (((svga->miscout >> 2) & 3) == 3) - temp |= svga->crtc[0x42] & 0x0f; - else - temp |= ((svga->miscout >> 2) & 3); - if ((temp & 0xa0) == 0xa0) { - if ((svga->crtc[0x5c] & 0x40) && i2c_gpio_get_scl(s3->i2c)) - temp |= 0x40; - if ((svga->crtc[0x5c] & 0x10) && i2c_gpio_get_sda(s3->i2c)) - temp |= 0x10; - } - return temp; - case 0x69: return s3->ma_ext; - case 0x6a: return s3->bank; - /* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C - to be mirrors of 59 and 5A. */ - case 0x6b: - if (s3->chip != S3_TRIO64V2) { - if (svga->crtc[0x53] & 0x08) { - return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); - } else { - return svga->crtc[0x59]; - } - } else - return svga->crtc[0x6b]; - break; - case 0x6c: - if (s3->chip != S3_TRIO64V2) { - if (svga->crtc[0x53] & 0x08) { - return 0x00; - } else - return (svga->crtc[0x5a] & 0x80); - } else - return svga->crtc[0x6c]; - break; - } - return svga->crtc[svga->crtcreg]; - } - return svga_in(addr, svga); -} - -static void s3_recalctimings(svga_t *svga) -{ - s3_t *s3 = (s3_t *)svga->p; - int clk_sel = (svga->miscout >> 2) & 3; - - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ - svga->gdcreg[5] |= 0x40; - } - } - } - - svga->ma_latch |= (s3->ma_ext << 16); - if (s3->chip >= S3_86C928) { - svga->hdisp = svga->hdisp_old; - - if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; - if (svga->crtc[0x5d] & 0x02) { - svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); - } - if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; - if (svga->crtc[0x5e] & 0x02) svga->dispend |= 0x400; - if (svga->crtc[0x5e] & 0x04) svga->vblankstart |= 0x400; - if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; - if (svga->crtc[0x5e] & 0x40) svga->split |= 0x400; - if (s3->accel.advfunc_cntl & 0x01) - svga->split = 0x7fff; - if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) svga->rowoffset |= 0x100; - } - if (!svga->rowoffset) svga->rowoffset = 256; - - if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { - if (s3->card_type == S3_ELSAWIN2KPROX_964) - ibm_rgb528_recalctimings(svga->ramdac, svga); - else - bt48x_recalctimings(svga->ramdac, svga); - } else if (s3->chip == S3_VISION968) { - if (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968) - tvp3026_recalctimings(svga->ramdac, svga); - else - ibm_rgb528_recalctimings(svga->ramdac, svga); - } else - svga->interlace = !!(svga->crtc[0x42] & 0x20); - - if ((((svga->miscout >> 2) & 3) == 3) && s3->chip < S3_TRIO32) - clk_sel = svga->crtc[0x42] & 0x0f; - - svga->clock = (cpuclock * (double)(1ull << 32)) / svga->getclock(clk_sel, svga->clock_gen); - - switch (svga->crtc[0x67] >> 4) { - case 3: case 5: case 7: - svga->clock /= 2; - break; - } - - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); - - if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || - s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || - s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 || - s3->card_type == S3_NUMBER9_9FX_531 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { - if (!(svga->crtc[0x5e] & 0x04)) - svga->vblankstart = svga->dispend; - if (svga->bpp != 32) { - if (svga->crtc[0x31] & 2) /*This is needed if the pixel width gets set with delays*/ - s3->width = 2048; - else { - if (s3->card_type == S3_MIROCRYSTAL10SD_805) { - if (svga->hdisp == 1280 && s3->width == 1024) { - s3->width = 1280; - } - } - } - } else { - if (s3->card_type == S3_NUMBER9_9FX_531) { - if (svga->hdisp == 1600 && s3->width == 1600) - s3->width = 800; - } - } - } else if (s3->chip == S3_86C928) { - if (svga->bpp == 15) { - if (s3->width == 800) - s3->width = 1024; - } - } - - if ((svga->crtc[0x43] & 0x08) && (s3->color_16bit == 0) && (s3->chip <= S3_86C805)) { - s3->color_16bit = 1; - s3->width = 1024; - } else if (!(svga->crtc[0x43] & 0x08) && (s3->color_16bit == 1) && (s3->chip <= S3_86C805)) { - s3->color_16bit = 0; - if (s3->chip <= S3_86C924) { - if (s3->accel.advfunc_cntl & 4) - s3->width = 1024; - else - s3->width = 640; - } - } - - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - if (s3->chip != S3_VISION868) { - if (s3->chip == S3_86C928) { - if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; - } else if ((s3->chip != S3_86C801) && (s3->chip != S3_86C805) && (s3->chip != S3_TRIO32) && - (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968)) { - if (s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; - } else if ((s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->card_type == S3_ELSAWIN2KPROX)) { - if (s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; - } else if (s3->card_type == S3_SPEA_MERCURY_P64V) { - if (s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; - } else if (s3->card_type == S3_NUMBER9_9FX_771) - svga->hdisp <<= 1; - - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SD_864 || - s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { - if (svga->hdisp != 1408) - svga->hdisp = s3->width; - if (s3->card_type == S3_MIROCRYSTAL20SD_864) { - if (s3->width == 2048 || s3->width == 1600 || s3->width == 800) { - switch (svga->dispend) { - case 400: - case 480: - svga->hdisp = 640; - break; - - case 576: - svga->hdisp = 768; - break; - - case 600: - if (s3->width == 1600) - s3->width = 800; - svga->hdisp = 800; - break; - - case 768: - svga->hdisp = 1024; - break; - - case 864: - svga->hdisp = 1152; - break; - - case 1024: - if (svga->vtotal == 1066) - svga->hdisp = 1280; - break; - } - } - } - } - if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL8S_805) { - if (svga->rowoffset == 256 && (((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04)))) - svga->rowoffset >>= 1; - } - } - break; - case 15: - svga->render = svga_render_15bpp_highres; - if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && - (s3->card_type != S3_SPEA_MIRAGE_86C805)) { - if (s3->chip == S3_86C928) - svga->hdisp <<= 1; - else if (s3->chip != S3_VISION968) - svga->hdisp >>= 1; - } - if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && - (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964)) { - if (s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; - else if (s3->card_type == S3_NUMBER9_9FX_771) - svga->hdisp <<= 1; - } - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || - s3->card_type == S3_SPEA_MERCURY_P64V) { - if (svga->hdisp == (1408*2)) - svga->hdisp >>= 1; - else - svga->hdisp = s3->width; - } - - if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || - s3->card_type == S3_SPEA_MERCURY_LITE_PCI) - svga->hdisp = s3->width; - break; - case 16: - svga->render = svga_render_16bpp_highres; - if ((s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->card_type == S3_ELSAWIN2KPROX)) { - if (s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; - } - if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && - (s3->card_type != S3_SPEA_MIRAGE_86C805)) { - if (s3->chip == S3_86C928) - svga->hdisp <<= 1; - else if (s3->chip != S3_VISION968) - svga->hdisp >>= 1; - } else if ((s3->card_type == S3_SPEA_MIRAGE_86C801) || (s3->card_type == S3_SPEA_MIRAGE_86C805)) - svga->hdisp >>= 1; - if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && - (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964)) { - if (s3->width == 1280 || s3->width == 1600) - svga->hdisp <<= 1; - else if (s3->card_type == S3_NUMBER9_9FX_771) - svga->hdisp <<= 1; - } - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || - s3->card_type == S3_SPEA_MERCURY_P64V) { - if (svga->hdisp == (1408*2)) - svga->hdisp >>= 1; - else - svga->hdisp = s3->width; - } - - if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || - s3->card_type == S3_SPEA_MERCURY_LITE_PCI) - svga->hdisp = s3->width; - break; - case 24: - svga->render = svga_render_24bpp_highres; - if (s3->chip != S3_VISION968) { - if (s3->chip != S3_86C928 && s3->chip != S3_86C801 && s3->chip != S3_86C805) - svga->hdisp /= 3; - else - svga->hdisp = (svga->hdisp * 2) / 3; - - if (s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { - if (s3->width == 2048) - switch (svga->dispend) { - case 480: - svga->hdisp = 640; - break; - } - } - } else { - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || - s3->card_type == S3_SPEA_MERCURY_P64V) - svga->hdisp = s3->width; - } - break; - case 32: - svga->render = svga_render_32bpp_highres; - if ((s3->chip < S3_TRIO32) && (s3->chip != S3_VISION964) && - (s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) { - if (s3->chip == S3_VISION868) - svga->hdisp >>= 1; - else - svga->hdisp >>= 2; - } - if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V || - s3->card_type == S3_NUMBER9_9FX_771)) - svga->hdisp <<= 1; - if (s3->card_type == S3_NUMBER9_9FX_771) { - if (svga->hdisp == 832) - svga->hdisp -= 32; + case 0x3c5: + if (svga->seqaddr >= 0x10 && svga->seqaddr < 0x20) { + temp = svga->seqregs[svga->seqaddr]; + /* This is needed for the Intel Advanced/ATX's built-in S3 Trio64V+ BIOS to not + get stuck in an infinite loop. */ + if ((s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) && (svga->seqaddr == 0x17)) + svga->seqregs[svga->seqaddr] ^= 0x01; + return temp; } - if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SV_964 || - s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || - s3->card_type == S3_SPEA_MERCURY_P64V) { - svga->hdisp = s3->width; - if (s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964) { - if (s3->width == 800 || s3->width == 1024 || s3->width == 1600) { - switch (svga->dispend) { - case 400: - case 480: - svga->hdisp = 640; - break; + break; - case 576: - if (s3->width == 1600) - s3->width = 800; - svga->hdisp = 768; - break; + case 0x3c6: + case 0x3c7: + case 0x3c8: + case 0x3c9: + rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); + if (s3->chip >= S3_TRIO32) + return svga_in(addr, svga); + else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { + rs3 = !!(svga->crtc[0x55] & 0x02); + return bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) + return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); + else if ((s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968))) { + rs3 = !!(svga->crtc[0x55] & 0x02); + return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && (s3->card_type != S3_MIROCRYSTAL10SD_805 && s3->card_type != S3_MIROCRYSTAL8S_805)) + return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); + else if (s3->chip <= S3_86C924) + return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); + else if (s3->card_type == S3_NUMBER9_9FX_531) + return att498_ramdac_in(addr, rs2, svga->ramdac, svga); + else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) + return sc1502x_ramdac_in(addr, svga->ramdac, svga); + else + return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); + break; - case 600: - if (s3->width == 1600) - s3->width = 800; - svga->hdisp = 800; - break; - } - } - } - } - break; - } - } else { - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) { - if (svga->bpp == 8) { - svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/ - if (svga->hdisp <= 1024) - s3->width = 1024; - } - } - } else { - if (s3->chip <= S3_86C924) - s3->width = 1024; - } - } - } + case 0x3d4: + return svga->crtcreg; + case 0x3d5: + switch (svga->crtcreg) { + case 0x2d: + return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; /*Extended chip ID*/ + case 0x2e: + return s3->id_ext; /*New chip ID*/ + case 0x2f: + return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision level*/ + case 0x30: + return s3->id; /*Chip ID*/ + case 0x31: + return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); + case 0x35: + return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); + case 0x45: + s3->hwc_col_stack_pos = 0; + break; + case 0x51: + return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); + case 0x5c: /* General Output Port Register */ + temp = svga->crtc[svga->crtcreg] & 0xa0; + if (((svga->miscout >> 2) & 3) == 3) + temp |= svga->crtc[0x42] & 0x0f; + else + temp |= ((svga->miscout >> 2) & 3); + if ((temp & 0xa0) == 0xa0) { + if ((svga->crtc[0x5c] & 0x40) && i2c_gpio_get_scl(s3->i2c)) + temp |= 0x40; + if ((svga->crtc[0x5c] & 0x10) && i2c_gpio_get_sda(s3->i2c)) + temp |= 0x10; + } + return temp; + case 0x69: + return s3->ma_ext; + case 0x6a: + return s3->bank; + /* Phoenix S3 video BIOS'es seem to expect CRTC registers 6B and 6C + to be mirrors of 59 and 5A. */ + case 0x6b: + if (s3->chip != S3_TRIO64V2) { + if (svga->crtc[0x53] & 0x08) { + return (s3->chip == S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); + } else { + return svga->crtc[0x59]; + } + } else + return svga->crtc[0x6b]; + break; + case 0x6c: + if (s3->chip != S3_TRIO64V2) { + if (svga->crtc[0x53] & 0x08) { + return 0x00; + } else + return (svga->crtc[0x5a] & 0x80); + } else + return svga->crtc[0x6c]; + break; + } + return svga->crtc[svga->crtcreg]; + } + return svga_in(addr, svga); } -static void s3_trio64v_recalctimings(svga_t *svga) +static void +s3_recalctimings(svga_t *svga) { - s3_t *s3 = (s3_t *)svga->p; - int clk_sel = (svga->miscout >> 2) & 3; + s3_t *s3 = (s3_t *) svga->p; + int clk_sel = (svga->miscout >> 2) & 3; - if (!svga->scrblank && svga->attr_palette_enable) { - if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { - if (svga->crtc[0x3a] & 0x10) /*256+ color register*/ - svga->gdcreg[5] |= 0x40; - } - } - svga->hdisp = svga->hdisp_old; - if (svga->crtc[0x5d] & 0x01) svga->htotal |= 0x100; - if (svga->crtc[0x5d] & 0x02) { - svga->hdisp_time |= 0x100; - svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); - } - if (svga->crtc[0x5e] & 0x01) svga->vtotal |= 0x400; - if (svga->crtc[0x5e] & 0x02) svga->dispend |= 0x400; - if (svga->crtc[0x5e] & 0x04) svga->vblankstart |= 0x400; - if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; - if (svga->crtc[0x5e] & 0x40) svga->split |= 0x400; - svga->interlace = svga->crtc[0x42] & 0x20; - - svga->clock = (cpuclock * (double)(1ull << 32)) / svga->getclock(clk_sel, svga->clock_gen); - - if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ - { - svga->ma_latch |= (s3->ma_ext << 16); - if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) svga->rowoffset |= 0x100; - if (!svga->rowoffset) svga->rowoffset = 256; - - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); - - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - svga->hdisp >>= 1; - break; - case 16: - svga->render = svga_render_16bpp_highres; - svga->hdisp >>= 1; - break; - case 24: - svga->render = svga_render_24bpp_highres; - svga->hdisp /= 3; - break; - case 32: - svga->render = svga_render_32bpp_highres; - break; - } - } - } - else /*Streams mode*/ - { - if (s3->streams.buffer_ctrl & 1) - svga->ma_latch = s3->streams.pri_fb1 >> 2; - else - svga->ma_latch = s3->streams.pri_fb0 >> 2; - - svga->hdisp = s3->streams.pri_w + 1; - if (s3->streams.pri_h < svga->dispend) - svga->dispend = s3->streams.pri_h; - - svga->overlay.x = s3->streams.sec_x - s3->streams.pri_x; - svga->overlay.y = s3->streams.sec_y - s3->streams.pri_y; - svga->overlay.cur_ysize = s3->streams.sec_h; - - if (s3->streams.buffer_ctrl & 2) - svga->overlay.addr = s3->streams.sec_fb1; - else - svga->overlay.addr = s3->streams.sec_fb0; - - svga->overlay.ena = (svga->overlay.x >= 0); - svga->overlay.v_acc = s3->streams.dda_vert_accumulator; - svga->rowoffset = s3->streams.pri_stride >> 3; - - switch ((s3->streams.pri_ctrl >> 24) & 0x7) - { - case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; - break; - case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_15bpp_highres; - break; - case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_16bpp_highres; - break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; - break; - case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; - break; - } + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (svga->crtc[0x3a] & 0x10) { /*256+ color register*/ + svga->gdcreg[5] |= 0x40; + } } + } + + svga->ma_latch |= (s3->ma_ext << 16); + if (s3->chip >= S3_86C928) { + svga->hdisp = svga->hdisp_old; + + if (svga->crtc[0x5d] & 0x01) + svga->htotal |= 0x100; + if (svga->crtc[0x5d] & 0x02) { + svga->hdisp_time |= 0x100; + svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + } + if (svga->crtc[0x5e] & 0x01) + svga->vtotal |= 0x400; + if (svga->crtc[0x5e] & 0x02) + svga->dispend |= 0x400; + if (svga->crtc[0x5e] & 0x04) + svga->vblankstart |= 0x400; + if (svga->crtc[0x5e] & 0x10) + svga->vsyncstart |= 0x400; + if (svga->crtc[0x5e] & 0x40) + svga->split |= 0x400; + if (s3->accel.advfunc_cntl & 0x01) + svga->split = 0x7fff; + if (svga->crtc[0x51] & 0x30) + svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) + svga->rowoffset |= 0x100; + } + if (!svga->rowoffset) + svga->rowoffset = 256; + + if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { + if (s3->card_type == S3_ELSAWIN2KPROX_964) + ibm_rgb528_recalctimings(svga->ramdac, svga); + else + bt48x_recalctimings(svga->ramdac, svga); + } else if (s3->chip == S3_VISION968) { + if (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968) + tvp3026_recalctimings(svga->ramdac, svga); + else + ibm_rgb528_recalctimings(svga->ramdac, svga); + } else + svga->interlace = !!(svga->crtc[0x42] & 0x20); + + if ((((svga->miscout >> 2) & 3) == 3) && s3->chip < S3_TRIO32) + clk_sel = svga->crtc[0x42] & 0x0f; + + svga->clock = (cpuclock * (double) (1ull << 32)) / svga->getclock(clk_sel, svga->clock_gen); + + switch (svga->crtc[0x67] >> 4) { + case 3: + case 5: + case 7: + svga->clock /= 2; + break; + } + + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + + if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 || s3->card_type == S3_NUMBER9_9FX_531 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { + if (!(svga->crtc[0x5e] & 0x04)) + svga->vblankstart = svga->dispend; + if (svga->bpp != 32) { + if (svga->crtc[0x31] & 2) /*This is needed if the pixel width gets set with delays*/ + s3->width = 2048; + else { + if (s3->card_type == S3_MIROCRYSTAL10SD_805) { + if (svga->hdisp == 1280 && s3->width == 1024) { + s3->width = 1280; + } + } + } + } else { + if (s3->card_type == S3_NUMBER9_9FX_531) { + if (svga->hdisp == 1600 && s3->width == 1600) + s3->width = 800; + } + } + } else if (s3->chip == S3_86C928) { + if (svga->bpp == 15) { + if (s3->width == 800) + s3->width = 1024; + } + } + + if ((svga->crtc[0x43] & 0x08) && (s3->color_16bit == 0) && (s3->chip <= S3_86C805)) { + s3->color_16bit = 1; + s3->width = 1024; + } else if (!(svga->crtc[0x43] & 0x08) && (s3->color_16bit == 1) && (s3->chip <= S3_86C805)) { + s3->color_16bit = 0; + if (s3->chip <= S3_86C924) { + if (s3->accel.advfunc_cntl & 4) + s3->width = 1024; + else + s3->width = 640; + } + } + + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + if (s3->chip != S3_VISION868) { + if (s3->chip == S3_86C928) { + if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600) + svga->hdisp <<= 1; + } else if ((s3->chip != S3_86C801) && (s3->chip != S3_86C805) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968)) { + if (s3->width == 1280 || s3->width == 1600) + svga->hdisp <<= 1; + } else if ((s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->card_type == S3_ELSAWIN2KPROX)) { + if (s3->width == 1280 || s3->width == 1600) + svga->hdisp <<= 1; + } else if (s3->card_type == S3_SPEA_MERCURY_P64V) { + if (s3->width == 1280 || s3->width == 1600) + svga->hdisp <<= 1; + } else if (s3->card_type == S3_NUMBER9_9FX_771) + svga->hdisp <<= 1; + + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { + if (svga->hdisp != 1408) + svga->hdisp = s3->width; + if (s3->card_type == S3_MIROCRYSTAL20SD_864) { + if (s3->width == 2048 || s3->width == 1600 || s3->width == 800) { + switch (svga->dispend) { + case 400: + case 480: + svga->hdisp = 640; + break; + + case 576: + svga->hdisp = 768; + break; + + case 600: + if (s3->width == 1600) + s3->width = 800; + svga->hdisp = 800; + break; + + case 768: + svga->hdisp = 1024; + break; + + case 864: + svga->hdisp = 1152; + break; + + case 1024: + if (svga->vtotal == 1066) + svga->hdisp = 1280; + break; + } + } + } + } + if (s3->card_type == S3_MIROCRYSTAL10SD_805 || s3->card_type == S3_MIROCRYSTAL8S_805) { + if (svga->rowoffset == 256 && (((svga->crtc[0x51] & 0x30) == 0x00 && !(svga->crtc[0x43] & 0x04)))) + svga->rowoffset >>= 1; + } + } + break; + case 15: + svga->render = svga_render_15bpp_highres; + if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { + if (s3->chip == S3_86C928) + svga->hdisp <<= 1; + else if (s3->chip != S3_VISION968) + svga->hdisp >>= 1; + } + if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964)) { + if (s3->width == 1280 || s3->width == 1600) + svga->hdisp <<= 1; + else if (s3->card_type == S3_NUMBER9_9FX_771) + svga->hdisp <<= 1; + } + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { + if (svga->hdisp == (1408 * 2)) + svga->hdisp >>= 1; + else + svga->hdisp = s3->width; + } + + if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) + svga->hdisp = s3->width; + break; + case 16: + svga->render = svga_render_16bpp_highres; + if ((s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->card_type == S3_ELSAWIN2KPROX)) { + if (s3->width == 1280 || s3->width == 1600) + svga->hdisp <<= 1; + } + if ((s3->chip != S3_VISION964) && (s3->card_type != S3_SPEA_MIRAGE_86C801) && (s3->card_type != S3_SPEA_MIRAGE_86C805)) { + if (s3->chip == S3_86C928) + svga->hdisp <<= 1; + else if (s3->chip != S3_VISION968) + svga->hdisp >>= 1; + } else if ((s3->card_type == S3_SPEA_MIRAGE_86C801) || (s3->card_type == S3_SPEA_MIRAGE_86C805)) + svga->hdisp >>= 1; + if ((s3->chip != S3_VISION868) && (s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64) && (s3->chip != S3_VISION964)) { + if (s3->width == 1280 || s3->width == 1600) + svga->hdisp <<= 1; + else if (s3->card_type == S3_NUMBER9_9FX_771) + svga->hdisp <<= 1; + } + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { + if (svga->hdisp == (1408 * 2)) + svga->hdisp >>= 1; + else + svga->hdisp = s3->width; + } + + if (s3->card_type == S3_SPEA_MIRAGE_86C801 || s3->card_type == S3_SPEA_MIRAGE_86C805 || s3->card_type == S3_SPEA_MERCURY_LITE_PCI) + svga->hdisp = s3->width; + break; + case 24: + svga->render = svga_render_24bpp_highres; + if (s3->chip != S3_VISION968) { + if (s3->chip != S3_86C928 && s3->chip != S3_86C801 && s3->chip != S3_86C805) + svga->hdisp /= 3; + else + svga->hdisp = (svga->hdisp * 2) / 3; + + if (s3->card_type == S3_SPEA_MERCURY_LITE_PCI) { + if (s3->width == 2048) + switch (svga->dispend) { + case 480: + svga->hdisp = 640; + break; + } + } + } else { + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) + svga->hdisp = s3->width; + } + break; + case 32: + svga->render = svga_render_32bpp_highres; + if ((s3->chip < S3_TRIO32) && (s3->chip != S3_VISION964) && (s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) { + if (s3->chip == S3_VISION868) + svga->hdisp >>= 1; + else + svga->hdisp >>= 2; + } + if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_NUMBER9_9FX_771)) + svga->hdisp <<= 1; + if (s3->card_type == S3_NUMBER9_9FX_771) { + if (svga->hdisp == 832) + svga->hdisp -= 32; + } + if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968 || s3->card_type == S3_MIROCRYSTAL20SV_964 || s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_SPEA_MERCURY_P64V) { + svga->hdisp = s3->width; + if (s3->card_type == S3_MIROCRYSTAL20SD_864 || s3->card_type == S3_MIROCRYSTAL20SV_964) { + if (s3->width == 800 || s3->width == 1024 || s3->width == 1600) { + switch (svga->dispend) { + case 400: + case 480: + svga->hdisp = 640; + break; + + case 576: + if (s3->width == 1600) + s3->width = 800; + svga->hdisp = 768; + break; + + case 600: + if (s3->width == 1600) + s3->width = 800; + svga->hdisp = 800; + break; + } + } + } + } + break; + } + } else { + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if ((svga->crtc[0x31] & 0x08) && ((svga->gdcreg[5] & 0x60) == 0x00)) { + if (svga->bpp == 8) { + svga->render = svga_render_8bpp_highres; /*Enhanced 4bpp mode, just like the 8bpp mode per spec.*/ + if (svga->hdisp <= 1024) + s3->width = 1024; + } + } + } else { + if (s3->chip <= S3_86C924) + s3->width = 1024; + } + } + } +} + +static void +s3_trio64v_recalctimings(svga_t *svga) +{ + s3_t *s3 = (s3_t *) svga->p; + int clk_sel = (svga->miscout >> 2) & 3; + + if (!svga->scrblank && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + if (svga->crtc[0x3a] & 0x10) /*256+ color register*/ + svga->gdcreg[5] |= 0x40; + } + } + svga->hdisp = svga->hdisp_old; + if (svga->crtc[0x5d] & 0x01) + svga->htotal |= 0x100; + if (svga->crtc[0x5d] & 0x02) { + svga->hdisp_time |= 0x100; + svga->hdisp |= 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + } + if (svga->crtc[0x5e] & 0x01) + svga->vtotal |= 0x400; + if (svga->crtc[0x5e] & 0x02) + svga->dispend |= 0x400; + if (svga->crtc[0x5e] & 0x04) + svga->vblankstart |= 0x400; + if (svga->crtc[0x5e] & 0x10) + svga->vsyncstart |= 0x400; + if (svga->crtc[0x5e] & 0x40) + svga->split |= 0x400; + svga->interlace = svga->crtc[0x42] & 0x20; + + svga->clock = (cpuclock * (double) (1ull << 32)) / svga->getclock(clk_sel, svga->clock_gen); + + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ + { + svga->ma_latch |= (s3->ma_ext << 16); + if (svga->crtc[0x51] & 0x30) + svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) + svga->rowoffset |= 0x100; + if (!svga->rowoffset) + svga->rowoffset = 256; + + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + break; + case 16: + svga->render = svga_render_16bpp_highres; + svga->hdisp >>= 1; + break; + case 24: + svga->render = svga_render_24bpp_highres; + svga->hdisp /= 3; + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } + } else /*Streams mode*/ + { + if (s3->streams.buffer_ctrl & 1) + svga->ma_latch = s3->streams.pri_fb1 >> 2; + else + svga->ma_latch = s3->streams.pri_fb0 >> 2; + + svga->hdisp = s3->streams.pri_w + 1; + if (s3->streams.pri_h < svga->dispend) + svga->dispend = s3->streams.pri_h; + + svga->overlay.x = s3->streams.sec_x - s3->streams.pri_x; + svga->overlay.y = s3->streams.sec_y - s3->streams.pri_y; + svga->overlay.cur_ysize = s3->streams.sec_h; + + if (s3->streams.buffer_ctrl & 2) + svga->overlay.addr = s3->streams.sec_fb1; + else + svga->overlay.addr = s3->streams.sec_fb0; + + svga->overlay.ena = (svga->overlay.x >= 0); + svga->overlay.v_acc = s3->streams.dda_vert_accumulator; + svga->rowoffset = s3->streams.pri_stride >> 3; + + switch ((s3->streams.pri_ctrl >> 24) & 0x7) { + case 0: /*RGB-8 (CLUT)*/ + svga->render = svga_render_8bpp_highres; + break; + case 3: /*KRGB-16 (1.5.5.5)*/ + svga->htotal >>= 1; + svga->render = svga_render_15bpp_highres; + break; + case 5: /*RGB-16 (5.6.5)*/ + svga->htotal >>= 1; + svga->render = svga_render_16bpp_highres; + break; + case 6: /*RGB-24 (8.8.8)*/ + svga->render = svga_render_24bpp_highres; + break; + case 7: /*XRGB-32 (X.8.8.8)*/ + svga->render = svga_render_32bpp_highres; + break; + } + } } static void s3_updatemapping(s3_t *s3) { - svga_t *svga = &s3->svga; + svga_t *svga = &s3->svga; - if (s3->pci && !(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&s3->linear_mapping); - mem_mapping_disable(&s3->mmio_mapping); - mem_mapping_disable(&s3->new_mmio_mapping); - return; - } + if (s3->pci && !(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&s3->linear_mapping); + mem_mapping_disable(&s3->mmio_mapping); + mem_mapping_disable(&s3->new_mmio_mapping); + return; + } - /*Banked framebuffer*/ - if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ - { - /* Enhanced mode forces 64kb at 0xa0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - } - else switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + /*Banked framebuffer*/ + if (svga->crtc[0x31] & 0x08) /*Enhanced mode mappings*/ + { + /* Enhanced mode forces 64kb at 0xa0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } else + switch (svga->gdcreg[6] & 0xc) /*VGA mapping*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } - if (s3->chip >= S3_86C928) { - s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); + if (s3->chip >= S3_86C928) { + s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { - if (s3->vlb) - s3->linear_base &= 0x03ffffff; - else - s3->linear_base &= 0x00ffffff; - } + if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (s3->vlb) + s3->linear_base &= 0x03ffffff; + else + s3->linear_base &= 0x00ffffff; + } - if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) - { - /*Linear framebuffer*/ - mem_mapping_disable(&svga->mapping); + if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { + /*Linear framebuffer*/ + mem_mapping_disable(&svga->mapping); - switch (svga->crtc[0x58] & 3) - { - case 0: /*64k*/ - s3->linear_size = 0x10000; - break; - case 1: /*1mb*/ - s3->linear_size = 0x100000; - break; - case 2: /*2mb*/ - s3->linear_size = 0x200000; - break; - case 3: /*8mb*/ - switch (s3->chip) { /* Not on video cards that don't support 4MB*/ - case S3_TRIO64: - case S3_TRIO64V: - case S3_TRIO64V2: - case S3_86C928: - case S3_86C928PCI: - s3->linear_size = 0x400000; - break; - default: - s3->linear_size = 0x800000; - break; - } - break; - } - s3->linear_base &= ~(s3->linear_size - 1); - if (s3->linear_base == 0xa0000) { - mem_mapping_disable(&s3->linear_mapping); - if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, s3->linear_base, 0x10000); - svga->banked_mask = 0xffff; - } - } else { - if (s3->chip >= S3_TRIO64V) { - s3->linear_base &= 0xfc000000; - } else if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { - s3->linear_base &= 0xfe000000; - } + switch (svga->crtc[0x58] & 3) { + case 0: /*64k*/ + s3->linear_size = 0x10000; + break; + case 1: /*1mb*/ + s3->linear_size = 0x100000; + break; + case 2: /*2mb*/ + s3->linear_size = 0x200000; + break; + case 3: /*8mb*/ + switch (s3->chip) { /* Not on video cards that don't support 4MB*/ + case S3_TRIO64: + case S3_TRIO64V: + case S3_TRIO64V2: + case S3_86C928: + case S3_86C928PCI: + s3->linear_size = 0x400000; + break; + default: + s3->linear_size = 0x800000; + break; + } + break; + } + s3->linear_base &= ~(s3->linear_size - 1); + if (s3->linear_base == 0xa0000) { + mem_mapping_disable(&s3->linear_mapping); + if (!(svga->crtc[0x53] & 0x10)) { + mem_mapping_set_addr(&svga->mapping, s3->linear_base, 0x10000); + svga->banked_mask = 0xffff; + } + } else { + if (s3->chip >= S3_TRIO64V) { + s3->linear_base &= 0xfc000000; + } else if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) { + s3->linear_base &= 0xfe000000; + } - mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); - } - svga->fb_only = 1; - } else { - svga->fb_only = 0; - mem_mapping_disable(&s3->linear_mapping); - } + mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); + } + svga->fb_only = 1; + } else { + svga->fb_only = 0; + mem_mapping_disable(&s3->linear_mapping); + } - /* Memory mapped I/O. */ - if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) { - mem_mapping_disable(&svga->mapping); - if (s3->chip >= S3_TRIO64V) { - if (svga->crtc[0x53] & 0x20) - mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); - else - mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); - } else { - mem_mapping_enable(&s3->mmio_mapping); - } - } else { - mem_mapping_disable(&s3->mmio_mapping); - } + /* Memory mapped I/O. */ + if ((svga->crtc[0x53] & 0x10) || (s3->accel.advfunc_cntl & 0x20)) { + mem_mapping_disable(&svga->mapping); + if (s3->chip >= S3_TRIO64V) { + if (svga->crtc[0x53] & 0x20) + mem_mapping_set_addr(&s3->mmio_mapping, 0xb8000, 0x8000); + else + mem_mapping_set_addr(&s3->mmio_mapping, 0xa0000, 0x10000); + } else { + mem_mapping_enable(&s3->mmio_mapping); + } + } else { + mem_mapping_disable(&s3->mmio_mapping); + } - /* New MMIO. */ - if (svga->crtc[0x53] & 0x08) - mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); - else - mem_mapping_disable(&s3->new_mmio_mapping); - } + /* New MMIO. */ + if (svga->crtc[0x53] & 0x08) + mem_mapping_set_addr(&s3->new_mmio_mapping, s3->linear_base + 0x1000000, 0x20000); + else + mem_mapping_disable(&s3->new_mmio_mapping); + } } static float s3_trio64_getclock(int clock, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - float t; - int m, n1, n2; - if (clock == 0) return 25175000.0; - if (clock == 1) return 28322000.0; - m = svga->seqregs[0x13] + 2; - n1 = (svga->seqregs[0x12] & 0x1f) + 2; - n2 = ((svga->seqregs[0x12] >> 5) & 0x07); - t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - return t; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + float t; + int m, n1, n2; + if (clock == 0) + return 25175000.0; + if (clock == 1) + return 28322000.0; + m = svga->seqregs[0x13] + 2; + n1 = (svga->seqregs[0x12] & 0x1f) + 2; + n2 = ((svga->seqregs[0x12] >> 5) & 0x07); + t = (14318184.0 * ((float) m / (float) n1)) / (float) (1 << n2); + return t; } static void s3_accel_out(uint16_t port, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; - if (port >= 0x8000) { - if (!s3->enable_8514) - return; + if (port >= 0x8000) { + if (!s3->enable_8514) + return; - if (s3_enable_fifo(s3)) - s3_queue(s3, port, val, FIFO_OUT_BYTE); - else - s3_accel_out_fifo(s3, port, val); - } else { - switch (port) - { - case 0x4148: case 0x42e8: - s3->subsys_stat &= ~val; - s3_update_irqs(s3); - break; - case 0x4149: case 0x42e9: - s3->subsys_cntl = val; - s3_update_irqs(s3); - break; - case 0x4548: case 0x46e8: - s3->accel.setup_md = val; - break; - case 0x4948: case 0x4ae8: - s3->accel.advfunc_cntl = val; - if ((s3->chip > S3_86C805) && ((svga->crtc[0x50] & 0xc1) == 0x80)) { - s3->width = (val & 4) ? 1600 : 800; - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } else if (s3->chip <= S3_86C805) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - if (s3->chip > S3_86C924) - s3_updatemapping(s3); - break; - } - } + if (s3_enable_fifo(s3)) + s3_queue(s3, port, val, FIFO_OUT_BYTE); + else + s3_accel_out_fifo(s3, port, val); + } else { + switch (port) { + case 0x4148: + case 0x42e8: + s3->subsys_stat &= ~val; + s3_update_irqs(s3); + break; + case 0x4149: + case 0x42e9: + s3->subsys_cntl = val; + s3_update_irqs(s3); + break; + case 0x4548: + case 0x46e8: + s3->accel.setup_md = val; + break; + case 0x4948: + case 0x4ae8: + s3->accel.advfunc_cntl = val; + if ((s3->chip > S3_86C805) && ((svga->crtc[0x50] & 0xc1) == 0x80)) { + s3->width = (val & 4) ? 1600 : 800; + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } else if (s3->chip <= S3_86C805) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + if (s3->chip > S3_86C924) + s3_updatemapping(s3); + break; + } + } } static void s3_accel_out_w(uint16_t port, uint16_t val, void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; - if (!s3->enable_8514) - return; + if (!s3->enable_8514) + return; - if (s3_enable_fifo(s3)) - s3_queue(s3, port, val, FIFO_OUT_WORD); - else - s3_accel_out_fifo_w(s3, port, val); + if (s3_enable_fifo(s3)) + s3_queue(s3, port, val, FIFO_OUT_WORD); + else + s3_accel_out_fifo_w(s3, port, val); } static void s3_accel_out_l(uint16_t port, uint32_t val, void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; - if (!s3->enable_8514) - return; + if (!s3->enable_8514) + return; - if (s3_enable_fifo(s3)) - s3_queue(s3, port, val, FIFO_OUT_DWORD); - else - s3_accel_out_fifo_l(s3, port, val); + if (s3_enable_fifo(s3)) + s3_queue(s3, port, val, FIFO_OUT_DWORD); + else + s3_accel_out_fifo_l(s3, port, val); } static uint8_t s3_accel_in(uint16_t port, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - int temp; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + int temp; - if (!s3->enable_8514) - return 0xff; + if (!s3->enable_8514) + return 0xff; - switch (port) { - case 0x4148: case 0x42e8: - return s3->subsys_stat; - case 0x4149: case 0x42e9: - return s3->subsys_cntl; + switch (port) { + case 0x4148: + case 0x42e8: + return s3->subsys_stat; + case 0x4149: + case 0x42e9: + return s3->subsys_cntl; - case 0x8148: case 0x82e8: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.cur_y & 0xff; - case 0x8149: case 0x82e9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.cur_y >> 8; + case 0x8148: + case 0x82e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.cur_y & 0xff; + case 0x8149: + case 0x82e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.cur_y >> 8; - case 0x8548: case 0x86e8: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.cur_x & 0xff; - case 0x8549: case 0x86e9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.cur_x >> 8; + case 0x8548: + case 0x86e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.cur_x & 0xff; + case 0x8549: + case 0x86e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.cur_x >> 8; - case 0x8948: case 0x8ae8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.desty_axstp & 0xff; - } - break; - case 0x8949: case 0x8ae9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.desty_axstp >> 8; - } - break; + case 0x8948: + case 0x8ae8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.desty_axstp & 0xff; + } + break; + case 0x8949: + case 0x8ae9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.desty_axstp >> 8; + } + break; - case 0x8d48: case 0x8ee8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.destx_distp & 0xff; - } - break; - case 0x8d49: case 0x8ee9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.destx_distp >> 8; - } - break; + case 0x8d48: + case 0x8ee8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.destx_distp & 0xff; + } + break; + case 0x8d49: + case 0x8ee9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.destx_distp >> 8; + } + break; - case 0x9148: case 0x92e8: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.err_term & 0xff; - case 0x9149: case 0x92e9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.err_term >> 8; + case 0x9148: + case 0x92e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.err_term & 0xff; + case 0x9149: + case 0x92e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.err_term >> 8; - case 0x9548: case 0x96e8: - if (s3->chip >= S3_86C928) { - return s3->accel.maj_axis_pcnt & 0xff; - } - break; - case 0x9549: case 0x96e9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.maj_axis_pcnt >> 8; - } - break; + case 0x9548: + case 0x96e8: + if (s3->chip >= S3_86C928) { + return s3->accel.maj_axis_pcnt & 0xff; + } + break; + case 0x9549: + case 0x96e9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.maj_axis_pcnt >> 8; + } + break; - case 0x8118: - case 0x9948: case 0x9ae8: - temp = 0; /* FIFO empty */ - if (s3_enable_fifo(s3)) { - if (!s3->blitter_busy) - wake_fifo_thread(s3); - if (FIFO_FULL) - temp = 0xff; - } - return temp; - case 0x8119: - case 0x9949: case 0x9ae9: - temp = 0; - if (s3_enable_fifo(s3)) { - if (!s3->blitter_busy) - wake_fifo_thread(s3); - - if (!FIFO_EMPTY || s3->force_busy) - temp |= 0x02; /*Hardware busy*/ - else - temp |= 0x04; /*FIFO empty*/ - s3->force_busy = 0; - - if (s3->chip >= S3_VISION964) { + case 0x8118: + case 0x9948: + case 0x9ae8: + temp = 0; /* FIFO empty */ + if (s3_enable_fifo(s3)) { + if (!s3->blitter_busy) + wake_fifo_thread(s3); if (FIFO_FULL) - temp |= 0xf8; /*FIFO full*/ - } + temp = 0xff; + } + return temp; + case 0x8119: + case 0x9949: + case 0x9ae9: + temp = 0; + if (s3_enable_fifo(s3)) { + if (!s3->blitter_busy) + wake_fifo_thread(s3); - if (s3->data_available) { - temp |= 0x01; /*Read Data available*/ - s3->data_available = 0; - } - } else { - if (s3->force_busy) { - temp |= 0x02; /*Hardware busy*/ - } - s3->force_busy = 0; - if (s3->data_available) { - temp |= 0x01; /*Read Data available*/ - s3->data_available = 0; - } - } - return temp; + if (!FIFO_EMPTY || s3->force_busy) + temp |= 0x02; /*Hardware busy*/ + else + temp |= 0x04; /*FIFO empty*/ + s3->force_busy = 0; - case 0x9d48: case 0x9ee8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.short_stroke & 0xff; - } - break; - case 0x9d49: case 0x9ee9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.short_stroke >> 8; - } - break; + if (s3->chip >= S3_VISION964) { + if (FIFO_FULL) + temp |= 0xf8; /*FIFO full*/ + } - case 0xa148: case 0xa2e8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color & 0xff; - } - break; - case 0xa149: case 0xa2e9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 8; - } - break; - case 0xa14a: case 0xa2ea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 16; - case 0xa14b: case 0xa2eb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 24; + if (s3->data_available) { + temp |= 0x01; /*Read Data available*/ + s3->data_available = 0; + } + } else { + if (s3->force_busy) { + temp |= 0x02; /*Hardware busy*/ + } + s3->force_busy = 0; + if (s3->data_available) { + temp |= 0x01; /*Read Data available*/ + s3->data_available = 0; + } + } + return temp; - case 0xa548: case 0xa6e8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color & 0xff; - } - break; - case 0xa549: case 0xa6e9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 8; - } - break; - case 0xa54a: case 0xa6ea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 16; - case 0xa54b: case 0xa6eb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 24; + case 0x9d48: + case 0x9ee8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.short_stroke & 0xff; + } + break; + case 0x9d49: + case 0x9ee9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.short_stroke >> 8; + } + break; - case 0xa948: case 0xaae8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask & 0xff; - } - break; - case 0xa949: case 0xaae9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 8; - } - break; - case 0xa94a: case 0xaaea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 16; - case 0xa94b: case 0xaaeb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 24; + case 0xa148: + case 0xa2e8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color & 0xff; + } + break; + case 0xa149: + case 0xa2e9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color >> 8; + } + break; + case 0xa14a: + case 0xa2ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color >> 16; + case 0xa14b: + case 0xa2eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_color >> 24; - case 0xad48: case 0xaee8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask & 0xff; - } - break; - case 0xad49: case 0xaee9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 8; - case 0xad4a: case 0xaeea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 16; - case 0xad4b: case 0xaeeb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 24; + case 0xa548: + case 0xa6e8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color & 0xff; + } + break; + case 0xa549: + case 0xa6e9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color >> 8; + } + break; + case 0xa54a: + case 0xa6ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color >> 16; + case 0xa54b: + case 0xa6eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.frgd_color >> 24; - case 0xb148: case 0xb2e8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp & 0xff; - } - break; - case 0xb149: case 0xb2e9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 8; - } - break; - case 0xb14a: case 0xb2ea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 16; - case 0xb14b: case 0xb2eb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 24; + case 0xa948: + case 0xaae8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask & 0xff; + } + break; + case 0xa949: + case 0xaae9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask >> 8; + } + break; + case 0xa94a: + case 0xaaea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask >> 16; + case 0xa94b: + case 0xaaeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.wrt_mask >> 24; - case 0xb548: case 0xb6e8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.bkgd_mix; - } - break; + case 0xad48: + case 0xaee8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask & 0xff; + } + break; + case 0xad49: + case 0xaee9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask >> 8; + case 0xad4a: + case 0xaeea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask >> 16; + case 0xad4b: + case 0xaeeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.rd_mask >> 24; - case 0xb948: case 0xbae8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.frgd_mix; - } - break; + case 0xb148: + case 0xb2e8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp & 0xff; + } + break; + case 0xb149: + case 0xb2e9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp >> 8; + } + break; + case 0xb14a: + case 0xb2ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp >> 16; + case 0xb14b: + case 0xb2eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.color_cmp >> 24; - case 0xbd48: case 0xbee8: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - switch (temp) - { - case 0x0: return s3->accel.multifunc[0x0] & 0xff; - case 0x1: return s3->accel.multifunc[0x1] & 0xff; - case 0x2: return s3->accel.multifunc[0x2] & 0xff; - case 0x3: return s3->accel.multifunc[0x3] & 0xff; - case 0x4: return s3->accel.multifunc[0x4] & 0xff; - case 0x5: return s3->accel.multifunc[0xa] & 0xff; - case 0x6: return s3->accel.multifunc[0xe] & 0xff; - case 0x7: return s3->accel.cmd & 0xff; - case 0x8: return s3->accel.subsys_cntl & 0xff; - case 0x9: return s3->accel.setup_md & 0xff; - case 0xa: return s3->accel.multifunc[0xd] & 0xff; - } - return 0xff; - } - break; - case 0xbd49: case 0xbee9: - if (s3->chip >= S3_86C928) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->accel.multifunc[0xf] & 0xf; - s3->accel.multifunc[0xf]++; - switch (temp) - { - case 0x0: return s3->accel.multifunc[0x0] >> 8; - case 0x1: return s3->accel.multifunc[0x1] >> 8; - case 0x2: return s3->accel.multifunc[0x2] >> 8; - case 0x3: return s3->accel.multifunc[0x3] >> 8; - case 0x4: return s3->accel.multifunc[0x4] >> 8; - case 0x5: return s3->accel.multifunc[0xa] >> 8; - case 0x6: return s3->accel.multifunc[0xe] >> 8; - case 0x7: return s3->accel.cmd >> 8; - case 0x8: return (s3->accel.subsys_cntl >> 8) & ~0xe000; - case 0x9: return (s3->accel.setup_md >> 8) & ~0xf000; - case 0xa: return s3->accel.multifunc[0xd] >> 8; - } - return 0xff; - } - break; + case 0xb548: + case 0xb6e8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.bkgd_mix; + } + break; - case 0xd148: case 0xd2e8: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.ropmix & 0xff; + case 0xb948: + case 0xbae8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.frgd_mix; + } + break; - case 0xd149: case 0xd2e9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.ropmix >> 8; + case 0xbd48: + case 0xbee8: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->accel.multifunc[0xf] & 0xf; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] & 0xff; + case 0x1: + return s3->accel.multifunc[0x1] & 0xff; + case 0x2: + return s3->accel.multifunc[0x2] & 0xff; + case 0x3: + return s3->accel.multifunc[0x3] & 0xff; + case 0x4: + return s3->accel.multifunc[0x4] & 0xff; + case 0x5: + return s3->accel.multifunc[0xa] & 0xff; + case 0x6: + return s3->accel.multifunc[0xe] & 0xff; + case 0x7: + return s3->accel.cmd & 0xff; + case 0x8: + return s3->accel.subsys_cntl & 0xff; + case 0x9: + return s3->accel.setup_md & 0xff; + case 0xa: + return s3->accel.multifunc[0xd] & 0xff; + } + return 0xff; + } + break; + case 0xbd49: + case 0xbee9: + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->accel.multifunc[0xf] & 0xf; + s3->accel.multifunc[0xf]++; + switch (temp) { + case 0x0: + return s3->accel.multifunc[0x0] >> 8; + case 0x1: + return s3->accel.multifunc[0x1] >> 8; + case 0x2: + return s3->accel.multifunc[0x2] >> 8; + case 0x3: + return s3->accel.multifunc[0x3] >> 8; + case 0x4: + return s3->accel.multifunc[0x4] >> 8; + case 0x5: + return s3->accel.multifunc[0xa] >> 8; + case 0x6: + return s3->accel.multifunc[0xe] >> 8; + case 0x7: + return s3->accel.cmd >> 8; + case 0x8: + return (s3->accel.subsys_cntl >> 8) & ~0xe000; + case 0x9: + return (s3->accel.setup_md >> 8) & ~0xf000; + case 0xa: + return s3->accel.multifunc[0xd] >> 8; + } + return 0xff; + } + break; - case 0xe548: case 0xe6e8: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color & 0xff; + case 0xd148: + case 0xd2e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.ropmix & 0xff; - case 0xe549: case 0xe6e9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 8; + case 0xd149: + case 0xd2e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.ropmix >> 8; - case 0xe54a: case 0xe6ea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 16; + case 0xe548: + case 0xe6e8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_bg_color & 0xff; - case 0xe54b: case 0xe6eb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 24; + case 0xe549: + case 0xe6e9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_bg_color >> 8; - case 0xe948: case 0xeae8: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_y & 0xff; + case 0xe54a: + case 0xe6ea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_bg_color >> 16; - case 0xe949: case 0xeae9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_y >> 8; + case 0xe54b: + case 0xe6eb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_bg_color >> 24; - case 0xe94a: case 0xeaea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_x & 0xff; + case 0xe948: + case 0xeae8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_y & 0xff; - case 0xe94b: case 0xeaeb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_x >> 8; + case 0xe949: + case 0xeae9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_y >> 8; - case 0xed48: case 0xeee8: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color & 0xff; + case 0xe94a: + case 0xeaea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_x & 0xff; - case 0xed49: case 0xeee9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 8; + case 0xe94b: + case 0xeaeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_x >> 8; - case 0xed4a: case 0xeeea: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 16; + case 0xed48: + case 0xeee8: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_fg_color & 0xff; - case 0xed4b: case 0xeeeb: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 24; + case 0xed49: + case 0xeee9: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_fg_color >> 8; - case 0xe148: case 0xe2e8: - if (!s3_cpu_dest(s3)) - break; - READ_PIXTRANS_BYTE_IO(0) - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } else { - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); - } - break; - } - } - return s3->accel.pix_trans[0]; + case 0xed4a: + case 0xeeea: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_fg_color >> 16; - case 0xe149: case 0xe2e9: - if (!s3_cpu_dest(s3)) - break; - READ_PIXTRANS_BYTE_IO(1); - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); - else - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - } else { - if (s3->accel.cmd & 0x1000) - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); - } - break; - } - } - return s3->accel.pix_trans[1]; + case 0xed4b: + case 0xeeeb: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.pat_fg_color >> 24; - case 0xe14a: case 0xe2ea: - if (!s3_cpu_dest(s3)) - break; - READ_PIXTRANS_BYTE_IO(2); - return s3->accel.pix_trans[2]; + case 0xe148: + case 0xe2e8: + if (!s3_cpu_dest(s3)) + break; + READ_PIXTRANS_BYTE_IO(0) + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, s3->accel.pix_trans[0], 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(16, 1, s3->accel.pix_trans[0], 0, s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } else { + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0], s3); + } + break; + } + } + return s3->accel.pix_trans[0]; - case 0xe14b: case 0xe2eb: - if (!s3_cpu_dest(s3)) - break; - READ_PIXTRANS_BYTE_IO(3) - if (s3->accel.cmd & 0x100) { - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } else - s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); - else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - } else - s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); - break; - } - } - return s3->accel.pix_trans[3]; + case 0xe149: + case 0xe2e9: + if (!s3_cpu_dest(s3)) + break; + READ_PIXTRANS_BYTE_IO(1); + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + s3_accel_start(16, 1, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), 0, s3); + else + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), 0, s3); + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + } else { + if (s3->accel.cmd & 0x1000) + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[1] | (s3->accel.pix_trans[0] << 8), s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8), s3); + } + break; + } + } + return s3->accel.pix_trans[1]; - case 0xff20: case 0xff21: - temp = s3->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); - if ((s3->serialport & SERIAL_PORT_SCW) && i2c_gpio_get_scl(s3->i2c)) - temp |= SERIAL_PORT_SCR; - if ((s3->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(s3->i2c)) - temp |= SERIAL_PORT_SDR; - return temp; - } + case 0xe14a: + case 0xe2ea: + if (!s3_cpu_dest(s3)) + break; + READ_PIXTRANS_BYTE_IO(2); + return s3->accel.pix_trans[2]; - return 0xff; + case 0xe14b: + case 0xe2eb: + if (!s3_cpu_dest(s3)) + break; + READ_PIXTRANS_BYTE_IO(3) + if (s3->accel.cmd & 0x100) { + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } else + s3_accel_start(1, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(16, 1, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), 0, s3); + else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + } else + s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[1] << 8) | (s3->accel.pix_trans[2] << 16) | (s3->accel.pix_trans[3] << 24), s3); + break; + } + } + return s3->accel.pix_trans[3]; + + case 0xff20: + case 0xff21: + temp = s3->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); + if ((s3->serialport & SERIAL_PORT_SCW) && i2c_gpio_get_scl(s3->i2c)) + temp |= SERIAL_PORT_SCR; + if ((s3->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(s3->i2c)) + temp |= SERIAL_PORT_SDR; + return temp; + } + + return 0xff; } static uint16_t s3_accel_in_w(uint16_t port, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - uint16_t temp = 0x0000; - uint16_t *vram_w = (uint16_t *)svga->vram; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + uint16_t temp = 0x0000; + uint16_t *vram_w = (uint16_t *) svga->vram; - if (!s3->enable_8514) - return 0xffff; + if (!s3->enable_8514) + return 0xffff; - if (port != 0x9ee8 && port != 0x9d48) { - if (s3_cpu_dest(s3)) { - READ_PIXTRANS_WORD + if (port != 0x9ee8 && port != 0x9d48) { + if (s3_cpu_dest(s3)) { + READ_PIXTRANS_WORD - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - temp = (temp >> 8) | (temp << 8); - s3_accel_start(8, 1, temp | (temp << 16), 0, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } - } else { - if (s3->color_16bit) { - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } - } - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - temp = (temp >> 8) | (temp << 8); - s3_accel_start(16, 1, temp | (temp << 16), 0, s3); - } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } else { - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } - break; - } - } - } else { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->accel.short_stroke; - } + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = (temp >> 8) | (temp << 8); + s3_accel_start(8, 1, temp | (temp << 16), 0, s3); + } else { + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } + } else { + if (s3->color_16bit) { + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } else { + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } + } + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = (temp >> 8) | (temp << 8); + s3_accel_start(16, 1, temp | (temp << 16), 0, s3); + } else + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } else { + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } + break; + } + } + } else { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->accel.short_stroke; + } - return temp; + return temp; } static uint32_t s3_accel_in_l(uint16_t port, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - uint32_t temp = 0x00000000; - uint16_t *vram_w = (uint16_t *)svga->vram; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + uint32_t temp = 0x00000000; + uint16_t *vram_w = (uint16_t *) svga->vram; - if (!s3->enable_8514) - return 0xffffffff; + if (!s3->enable_8514) + return 0xffffffff; - if (s3_cpu_dest(s3)) { - READ_PIXTRANS_LONG + if (s3_cpu_dest(s3)) { + READ_PIXTRANS_LONG - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); - s3_accel_start(8, 1, temp, 0, s3); - s3_accel_start(8, 1, temp >> 16, 0, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); - } - } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); - } - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - if (s3->accel.cmd & 0x1000) - temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); - s3_accel_start(16, 1, temp, 0, s3); - s3_accel_start(16, 1, temp >> 16, 0, s3); - } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); - } - } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); - } - break; - } - } + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); + s3_accel_start(8, 1, temp, 0, s3); + s3_accel_start(8, 1, temp >> 16, 0, s3); + } else { + s3_accel_start(1, 1, 0xffffffff, temp, s3); + s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + } + } else { + s3_accel_start(1, 1, 0xffffffff, temp, s3); + s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + } + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + if (s3->accel.cmd & 0x1000) + temp = ((temp & 0xff00ff00) >> 8) | ((temp & 0x00ff00ff) << 8); + s3_accel_start(16, 1, temp, 0, s3); + s3_accel_start(16, 1, temp >> 16, 0, s3); + } else { + s3_accel_start(2, 1, 0xffffffff, temp, s3); + s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + } + } else { + s3_accel_start(2, 1, 0xffffffff, temp, s3); + s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + } + break; + } + } - return temp; + return temp; } - static void s3_accel_write(uint32_t addr, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; svga_t *svga = &s3->svga; - if (!s3->enable_8514) - return; + if (!s3->enable_8514) + return; - if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); - } else - s3_accel_write_fifo(s3, addr & 0xffff, val); + if (s3_enable_fifo(s3)) { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_BYTE); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); + } else + s3_accel_write_fifo(s3, addr & 0xffff, val); } static void s3_accel_write_w(uint32_t addr, uint16_t val, void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; svga_t *svga = &s3->svga; - if (!s3->enable_8514) - return; + if (!s3->enable_8514) + return; - if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); - } else - s3_accel_write_fifo_w(s3, addr & 0xffff, val); + if (s3_enable_fifo(s3)) { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_WORD); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); + } else + s3_accel_write_fifo_w(s3, addr & 0xffff, val); } static void s3_accel_write_l(uint32_t addr, uint32_t val, void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; svga_t *svga = &s3->svga; - if (!s3->enable_8514) - return; + if (!s3->enable_8514) + return; - if (s3_enable_fifo(s3)) { - if (svga->crtc[0x53] & 0x08) - s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD); - else - s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); - } else - s3_accel_write_fifo_l(s3, addr & 0xffff, val); + if (s3_enable_fifo(s3)) { + if (svga->crtc[0x53] & 0x08) + s3_queue(s3, addr & 0x1ffff, val, FIFO_WRITE_DWORD); + else + s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); + } else + s3_accel_write_fifo_l(s3, addr & 0xffff, val); } static uint8_t s3_accel_read(uint32_t addr, void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; svga_t *svga = &s3->svga; uint8_t temp = 0x00; - if (!s3->enable_8514) - return 0xff; + if (!s3->enable_8514) + return 0xff; if (svga->crtc[0x53] & 0x08) { - if ((addr >= 0x08000) && (addr <= 0x0803f)) - return s3_pci_read(0, addr & 0xff, s3); - switch (addr & 0x1ffff) { - case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: - case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: - case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: - case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: - case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: - case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: - case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: - case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: - case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: - case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: - case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: - case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - return s3_in(addr & 0x3ff, s3); - case 0x8504: - return s3->subsys_stat; - case 0x8505: - return s3->subsys_cntl; - default: - return s3_accel_in(addr & 0xffff, p); - } - return 0xff; + if ((addr >= 0x08000) && (addr <= 0x0803f)) + return s3_pci_read(0, addr & 0xff, s3); + switch (addr & 0x1ffff) { + case 0x83b0: + case 0x83b1: + case 0x83b2: + case 0x83b3: + case 0x83b4: + case 0x83b5: + case 0x83b6: + case 0x83b7: + case 0x83b8: + case 0x83b9: + case 0x83ba: + case 0x83bb: + case 0x83bc: + case 0x83bd: + case 0x83be: + case 0x83bf: + case 0x83c0: + case 0x83c1: + case 0x83c2: + case 0x83c3: + case 0x83c4: + case 0x83c5: + case 0x83c6: + case 0x83c7: + case 0x83c8: + case 0x83c9: + case 0x83ca: + case 0x83cb: + case 0x83cc: + case 0x83cd: + case 0x83ce: + case 0x83cf: + case 0x83d0: + case 0x83d1: + case 0x83d2: + case 0x83d3: + case 0x83d4: + case 0x83d5: + case 0x83d6: + case 0x83d7: + case 0x83d8: + case 0x83d9: + case 0x83da: + case 0x83db: + case 0x83dc: + case 0x83dd: + case 0x83de: + case 0x83df: + return s3_in(addr & 0x3ff, s3); + case 0x8504: + return s3->subsys_stat; + case 0x8505: + return s3->subsys_cntl; + default: + return s3_accel_in(addr & 0xffff, p); + } + return 0xff; } else { - if (addr & 0x8000) { - temp = s3_accel_in(addr & 0xffff, p); - } else if (s3_cpu_dest(s3)) { - READ_PIXTRANS_BYTE_MM + if (addr & 0x8000) { + temp = s3_accel_in(addr & 0xffff, p); + } else if (s3_cpu_dest(s3)) { + READ_PIXTRANS_BYTE_MM - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); - } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); - else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); - } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); - break; - } - } + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + } else + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(16, 1, temp | (temp << 8) | (temp << 16) | (temp << 24), 0, s3); + else + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + } else + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 8) | (temp << 16) | (temp << 24), s3); + break; + } + } } return temp; @@ -4244,242 +4515,240 @@ s3_accel_read(uint32_t addr, void *p) static uint16_t s3_accel_read_w(uint32_t addr, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - uint16_t temp = 0x0000; - uint16_t *vram_w = (uint16_t *)svga->vram; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + uint16_t temp = 0x0000; + uint16_t *vram_w = (uint16_t *) svga->vram; - if (!s3->enable_8514) - return 0xffff; + if (!s3->enable_8514) + return 0xffff; if (svga->crtc[0x53] & 0x08) { - switch (addr & 0x1fffe) { - case 0x811c: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.short_stroke; + switch (addr & 0x1fffe) { + case 0x811c: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + return s3->accel.short_stroke; - default: - return s3_accel_read(addr, p) | - s3_accel_read(addr + 1, p) << 8; - } - return 0xffff; + default: + return s3_accel_read(addr, p) | s3_accel_read(addr + 1, p) << 8; + } + return 0xffff; } else { - if (addr & 0x8000) { - if (addr == 0x811c) { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->accel.short_stroke; - } else { - temp = s3_accel_read((addr & 0xfffe), p); - temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; - } - } else if (s3_cpu_dest(s3)) { - READ_PIXTRANS_WORD + if (addr & 0x8000) { + if (addr == 0x811c) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->accel.short_stroke; + } else { + temp = s3_accel_read((addr & 0xfffe), p); + temp |= s3_accel_read((addr & 0xfffe) + 1, p) << 8; + } + } else if (s3_cpu_dest(s3)) { + READ_PIXTRANS_WORD - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(8, 1, temp | (temp << 16), 0, s3); - else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - } else - s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) - s3_accel_start(16, 1, temp | (temp << 16), 0, s3); - else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - } else - s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); - break; - } - } + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(8, 1, temp | (temp << 16), 0, s3); + else + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3_accel_start(1, 1, 0xffffffff, temp | (temp << 16), s3); + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) + s3_accel_start(16, 1, temp | (temp << 16), 0, s3); + else + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + } else + s3_accel_start(2, 1, 0xffffffff, temp | (temp << 16), s3); + break; + } + } } return temp; } - static uint32_t s3_accel_read_l(uint32_t addr, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; - uint32_t temp = 0x00000000; - uint16_t *vram_w = (uint16_t *)svga->vram; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; + uint32_t temp = 0x00000000; + uint16_t *vram_w = (uint16_t *) svga->vram; - if (!s3->enable_8514) - return 0xffffffff; + if (!s3->enable_8514) + return 0xffffffff; if (svga->crtc[0x53] & 0x08) { - switch (addr & 0x1fffc) { - case 0x8180: - temp = s3->streams.pri_ctrl; - break; - case 0x8184: - temp = s3->streams.chroma_ctrl; - break; - case 0x8190: - temp = s3->streams.sec_ctrl; - break; - case 0x8194: - temp = s3->streams.chroma_upper_bound; - break; - case 0x8198: - temp = s3->streams.sec_filter; - break; - case 0x81a0: - temp = s3->streams.blend_ctrl; - break; - case 0x81c0: - temp = s3->streams.pri_fb0; - break; - case 0x81c4: - temp = s3->streams.pri_fb1; - break; - case 0x81c8: - temp = s3->streams.pri_stride; - break; - case 0x81cc: - temp = s3->streams.buffer_ctrl; - break; - case 0x81d0: - temp = s3->streams.sec_fb0; - break; - case 0x81d4: - temp = s3->streams.sec_fb1; - break; - case 0x81d8: - temp = s3->streams.sec_stride; - break; - case 0x81dc: - temp = s3->streams.overlay_ctrl; - break; - case 0x81e0: - temp = s3->streams.k1_vert_scale; - break; - case 0x81e4: - temp = s3->streams.k2_vert_scale; - break; - case 0x81e8: - temp = s3->streams.dda_vert_accumulator; - break; - case 0x81ec: - temp = s3->streams.fifo_ctrl; - break; - case 0x81f0: - temp = s3->streams.pri_start; - break; - case 0x81f4: - temp = s3->streams.pri_size; - break; - case 0x81f8: - temp = s3->streams.sec_start; - break; - case 0x81fc: - temp = s3->streams.sec_size; - break; + switch (addr & 0x1fffc) { + case 0x8180: + temp = s3->streams.pri_ctrl; + break; + case 0x8184: + temp = s3->streams.chroma_ctrl; + break; + case 0x8190: + temp = s3->streams.sec_ctrl; + break; + case 0x8194: + temp = s3->streams.chroma_upper_bound; + break; + case 0x8198: + temp = s3->streams.sec_filter; + break; + case 0x81a0: + temp = s3->streams.blend_ctrl; + break; + case 0x81c0: + temp = s3->streams.pri_fb0; + break; + case 0x81c4: + temp = s3->streams.pri_fb1; + break; + case 0x81c8: + temp = s3->streams.pri_stride; + break; + case 0x81cc: + temp = s3->streams.buffer_ctrl; + break; + case 0x81d0: + temp = s3->streams.sec_fb0; + break; + case 0x81d4: + temp = s3->streams.sec_fb1; + break; + case 0x81d8: + temp = s3->streams.sec_stride; + break; + case 0x81dc: + temp = s3->streams.overlay_ctrl; + break; + case 0x81e0: + temp = s3->streams.k1_vert_scale; + break; + case 0x81e4: + temp = s3->streams.k2_vert_scale; + break; + case 0x81e8: + temp = s3->streams.dda_vert_accumulator; + break; + case 0x81ec: + temp = s3->streams.fifo_ctrl; + break; + case 0x81f0: + temp = s3->streams.pri_start; + break; + case 0x81f4: + temp = s3->streams.pri_size; + break; + case 0x81f8: + temp = s3->streams.sec_start; + break; + case 0x81fc: + temp = s3->streams.sec_size; + break; - case 0x18080: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = 0; - break; - case 0x18088: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->videoengine.cntl; - if (s3->bpp == 1) { /*The actual bpp is decided by the guest when idf is the same as odf*/ - if (s3->videoengine.idf == 0 && s3->videoengine.odf == 0) { - if (svga->bpp == 15) - temp |= 0x600000; - else - temp |= 0x700000; - } - } else if (s3->bpp > 1) { - if (s3->videoengine.idf == 0 && s3->videoengine.odf == 0) - temp |= 0x300000; - } - break; - case 0x1808c: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->videoengine.stretch_filt_const; - break; - case 0x18090: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->videoengine.src_dst_step; - break; - case 0x18094: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->videoengine.crop; - break; - case 0x18098: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->videoengine.src_base; - break; - case 0x1809c: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - temp = s3->videoengine.dest_base; - if (s3->videoengine.busy) { - temp |= (1 << 31); - } else { - temp &= ~(1 << 31); - } - break; + case 0x18080: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = 0; + break; + case 0x18088: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->videoengine.cntl; + if (s3->bpp == 1) { /*The actual bpp is decided by the guest when idf is the same as odf*/ + if (s3->videoengine.idf == 0 && s3->videoengine.odf == 0) { + if (svga->bpp == 15) + temp |= 0x600000; + else + temp |= 0x700000; + } + } else if (s3->bpp > 1) { + if (s3->videoengine.idf == 0 && s3->videoengine.odf == 0) + temp |= 0x300000; + } + break; + case 0x1808c: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->videoengine.stretch_filt_const; + break; + case 0x18090: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->videoengine.src_dst_step; + break; + case 0x18094: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->videoengine.crop; + break; + case 0x18098: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->videoengine.src_base; + break; + case 0x1809c: + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + temp = s3->videoengine.dest_base; + if (s3->videoengine.busy) { + temp |= (1 << 31); + } else { + temp &= ~(1 << 31); + } + break; - default: - temp = s3_accel_read_w(addr, p) | (s3_accel_read_w(addr + 2, p) << 16); - break; - } + default: + temp = s3_accel_read_w(addr, p) | (s3_accel_read_w(addr + 2, p) << 16); + break; + } } else { - if (addr & 0x8000) { - temp = s3_accel_read((addr & 0xfffc), p); - temp |= s3_accel_read((addr & 0xfffc) + 1, p) << 8; - temp |= s3_accel_read((addr & 0xfffc) + 2, p) << 16; - temp |= s3_accel_read((addr & 0xfffc) + 3, p) << 24; - } else if (s3_cpu_dest(s3)) { - READ_PIXTRANS_LONG + if (addr & 0x8000) { + temp = s3_accel_read((addr & 0xfffc), p); + temp |= s3_accel_read((addr & 0xfffc) + 1, p) << 8; + temp |= s3_accel_read((addr & 0xfffc) + 2, p) << 16; + temp |= s3_accel_read((addr & 0xfffc) + 3, p) << 24; + } else if (s3_cpu_dest(s3)) { + READ_PIXTRANS_LONG - switch (s3->accel.cmd & 0x600) { - case 0x000: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(8, 1, temp, 0, s3); - s3_accel_start(8, 1, temp >> 16, 0, s3); - } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); - } - } else { - s3_accel_start(1, 1, 0xffffffff, temp, s3); - s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); - } - break; - case 0x200: - if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { - if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { - s3_accel_start(16, 1, temp, 0, s3); - s3_accel_start(16, 1, temp >> 16, 0, s3); - } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); - } - } else { - s3_accel_start(2, 1, 0xffffffff, temp, s3); - s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); - } - break; - } - } + switch (s3->accel.cmd & 0x600) { + case 0x000: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + s3_accel_start(8, 1, temp, 0, s3); + s3_accel_start(8, 1, temp >> 16, 0, s3); + } else { + s3_accel_start(1, 1, 0xffffffff, temp, s3); + s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + } + } else { + s3_accel_start(1, 1, 0xffffffff, temp, s3); + s3_accel_start(1, 1, 0xffffffff, temp >> 16, s3); + } + break; + case 0x200: + if (((s3->accel.multifunc[0xa] & 0xc0) == 0x80) || (s3->accel.cmd & 2)) { + if (((s3->accel.frgd_mix & 0x60) != 0x40) || ((s3->accel.bkgd_mix & 0x60) != 0x40)) { + s3_accel_start(16, 1, temp, 0, s3); + s3_accel_start(16, 1, temp >> 16, 0, s3); + } else { + s3_accel_start(2, 1, 0xffffffff, temp, s3); + s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + } + } else { + s3_accel_start(2, 1, 0xffffffff, temp, s3); + s3_accel_start(2, 1, 0xffffffff, temp >> 16, s3); + } + break; + } + } } return temp; @@ -4488,372 +4757,908 @@ s3_accel_read_l(uint32_t addr, void *p) static void polygon_setup(s3_t *s3) { - if (s3->accel.point_1_updated) - { - int start_x = s3->accel.poly_cx; - int start_y = s3->accel.poly_cy; - int end_x = s3->accel.destx_distp << 20; - int end_y = s3->accel.desty_axstp; + if (s3->accel.point_1_updated) { + int start_x = s3->accel.poly_cx; + int start_y = s3->accel.poly_cy; + int end_x = s3->accel.destx_distp << 20; + int end_y = s3->accel.desty_axstp; - if (end_y - start_y) - s3->accel.poly_dx1 = (end_x - start_x) / (end_y - start_y); - else - s3->accel.poly_dx1 = 0; + if (end_y - start_y) + s3->accel.poly_dx1 = (end_x - start_x) / (end_y - start_y); + else + s3->accel.poly_dx1 = 0; - s3->accel.point_1_updated = 0; + s3->accel.point_1_updated = 0; - if (end_y == s3->accel.poly_cy) - { - s3->accel.poly_cx = end_x; - s3->accel.poly_x = end_x >> 20; - } - } - if (s3->accel.point_2_updated) - { - int start_x = s3->accel.poly_cx2; - int start_y = s3->accel.poly_cy2; - int end_x = s3->accel.x2 << 20; - int end_y = s3->accel.desty_axstp2; + if (end_y == s3->accel.poly_cy) { + s3->accel.poly_cx = end_x; + s3->accel.poly_x = end_x >> 20; + } + } + if (s3->accel.point_2_updated) { + int start_x = s3->accel.poly_cx2; + int start_y = s3->accel.poly_cy2; + int end_x = s3->accel.x2 << 20; + int end_y = s3->accel.desty_axstp2; - if (end_y - start_y) - s3->accel.poly_dx2 = (end_x - start_x) / (end_y - start_y); - else - s3->accel.poly_dx2 = 0; + if (end_y - start_y) + s3->accel.poly_dx2 = (end_x - start_x) / (end_y - start_y); + else + s3->accel.poly_dx2 = 0; - s3->accel.point_2_updated = 0; + s3->accel.point_2_updated = 0; - if (end_y == s3->accel.poly_cy) - s3->accel.poly_cx2 = end_x; - } + if (end_y == s3->accel.poly_cy) + s3->accel.poly_cx2 = end_x; + } } -#define READ(addr, dat) if (s3->bpp == 0 && !s3->color_16bit) dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else if (s3->bpp == 1 || s3->color_16bit) dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ - else if (s3->bpp == 2) dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else dat = vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)]; +#define READ(addr, dat) \ + if (s3->bpp == 0 && !s3->color_16bit) \ + dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ + else if (s3->bpp == 1 || s3->color_16bit) \ + dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ + else if (s3->bpp == 2) \ + dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ + else \ + dat = vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)]; -#define MIX_READ { \ - switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) \ - { \ - case 0x0: dest_dat = ~dest_dat; break; \ - case 0x1: dest_dat = 0; break; \ - case 0x2: dest_dat = ~0; break; \ - case 0x3: dest_dat = dest_dat; break; \ - case 0x4: dest_dat = ~src_dat; break; \ - case 0x5: dest_dat = src_dat ^ dest_dat; break; \ - case 0x6: dest_dat = ~(src_dat ^ dest_dat); break; \ - case 0x7: dest_dat = src_dat; break; \ - case 0x8: dest_dat = ~(src_dat & dest_dat); break; \ - case 0x9: dest_dat = ~src_dat | dest_dat; break; \ - case 0xa: dest_dat = src_dat | ~dest_dat; break; \ - case 0xb: dest_dat = src_dat | dest_dat; break; \ - case 0xc: dest_dat = src_dat & dest_dat; break; \ - case 0xd: dest_dat = src_dat & ~dest_dat; break; \ - case 0xe: dest_dat = ~src_dat & dest_dat; break; \ - case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ - } \ - } +#define MIX_READ \ + { \ + switch ((mix_dat & mix_mask) ? (s3->accel.frgd_mix & 0xf) : (s3->accel.bkgd_mix & 0xf)) { \ + case 0x0: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x1: \ + dest_dat = 0; \ + break; \ + case 0x2: \ + dest_dat = ~0; \ + break; \ + case 0x3: \ + dest_dat = dest_dat; \ + break; \ + case 0x4: \ + dest_dat = ~src_dat; \ + break; \ + case 0x5: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x6: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x7: \ + dest_dat = src_dat; \ + break; \ + case 0x8: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x9: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0xa: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0xb: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0xc: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0xd: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0xe: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0xf: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + } \ + } +#define MIX \ + { \ + old_dest_dat = dest_dat; \ + MIX_READ \ + dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + } -#define MIX { \ - old_dest_dat = dest_dat; \ - MIX_READ \ - dest_dat = (dest_dat & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ - } +#define ROPMIX_READ(D, P, S) \ + { \ + switch (rop) { \ + case 0x00: \ + out = 0; \ + break; \ + case 0x01: \ + out = ~(D | (P | S)); \ + break; \ + case 0x02: \ + out = D & ~(P | S); \ + break; \ + case 0x03: \ + out = ~(P | S); \ + break; \ + case 0x04: \ + out = S & ~(D | P); \ + break; \ + case 0x05: \ + out = ~(D | P); \ + break; \ + case 0x06: \ + out = ~(P | ~(D ^ S)); \ + break; \ + case 0x07: \ + out = ~(P | (D & S)); \ + break; \ + case 0x08: \ + out = S & (D & ~P); \ + break; \ + case 0x09: \ + out = ~(P | (D ^ S)); \ + break; \ + case 0x0a: \ + out = D & ~P; \ + break; \ + case 0x0b: \ + out = ~(P | (S & ~D)); \ + break; \ + case 0x0c: \ + out = S & ~P; \ + break; \ + case 0x0d: \ + out = ~(P | (D & ~S)); \ + break; \ + case 0x0e: \ + out = ~(P | ~(D | S)); \ + break; \ + case 0x0f: \ + out = ~P; \ + break; \ + case 0x10: \ + out = P & ~(D | S); \ + break; \ + case 0x11: \ + out = ~(D | S); \ + break; \ + case 0x12: \ + out = ~(S | ~(D ^ P)); \ + break; \ + case 0x13: \ + out = ~(S | (D & P)); \ + break; \ + case 0x14: \ + out = ~(D | ~(P ^ S)); \ + break; \ + case 0x15: \ + out = ~(D | (P & S)); \ + break; \ + case 0x16: \ + out = P ^ (S ^ (D & ~(P & S))); \ + break; \ + case 0x17: \ + out = ~(S ^ ((S ^ P) & (D ^ S))); \ + break; \ + case 0x18: \ + out = (S ^ P) & (P ^ D); \ + break; \ + case 0x19: \ + out = ~(S ^ (D & ~(P & S))); \ + break; \ + case 0x1a: \ + out = P ^ (D | (S & P)); \ + break; \ + case 0x1b: \ + out = ~(S ^ (D & (P ^ S))); \ + break; \ + case 0x1c: \ + out = P ^ (S | (D & P)); \ + break; \ + case 0x1d: \ + out = ~(D ^ (S & (P ^ D))); \ + break; \ + case 0x1e: \ + out = P ^ (D | S); \ + break; \ + case 0x1f: \ + out = ~(P & (D | S)); \ + break; \ + case 0x20: \ + out = D & (P & ~S); \ + break; \ + case 0x21: \ + out = ~(S | (D ^ P)); \ + break; \ + case 0x22: \ + out = D & ~S; \ + break; \ + case 0x23: \ + out = ~(S | (P & ~D)); \ + break; \ + case 0x24: \ + out = (S ^ P) & (D ^ S); \ + break; \ + case 0x25: \ + out = ~(P ^ (D & ~(S & P))); \ + break; \ + case 0x26: \ + out = S ^ (D | (P & S)); \ + break; \ + case 0x27: \ + out = S ^ (D | ~(P ^ S)); \ + break; \ + case 0x28: \ + out = D & (P ^ S); \ + break; \ + case 0x29: \ + out = ~(P ^ (S ^ (D | (P & S)))); \ + break; \ + case 0x2a: \ + out = D & ~(P & S); \ + break; \ + case 0x2b: \ + out = ~(S ^ ((S ^ P) & (P ^ D))); \ + break; \ + case 0x2c: \ + out = S ^ (P & (D | S)); \ + break; \ + case 0x2d: \ + out = P ^ (S | ~D); \ + break; \ + case 0x2e: \ + out = P ^ (S | (D ^ P)); \ + break; \ + case 0x2f: \ + out = ~(P & (S | ~D)); \ + break; \ + case 0x30: \ + out = P & ~S; \ + break; \ + case 0x31: \ + out = ~(S | (D & ~P)); \ + break; \ + case 0x32: \ + out = S ^ (D | (P | S)); \ + break; \ + case 0x33: \ + out = ~S; \ + break; \ + case 0x34: \ + out = S ^ (P | (D & S)); \ + break; \ + case 0x35: \ + out = S ^ (P | ~(D ^ S)); \ + break; \ + case 0x36: \ + out = S ^ (D | P); \ + break; \ + case 0x37: \ + out = ~(S & (D | P)); \ + break; \ + case 0x38: \ + out = P ^ (S & (D | P)); \ + break; \ + case 0x39: \ + out = S ^ (P | ~D); \ + break; \ + case 0x3a: \ + out = S ^ (P | (D ^ S)); \ + break; \ + case 0x3b: \ + out = ~(S & (P | ~D)); \ + break; \ + case 0x3c: \ + out = P ^ S; \ + break; \ + case 0x3d: \ + out = S ^ (P | ~(D | S)); \ + break; \ + case 0x3e: \ + out = S ^ (P | (D & ~S)); \ + break; \ + case 0x3f: \ + out = ~(P & S); \ + break; \ + case 0x40: \ + out = P & (S & ~D); \ + break; \ + case 0x41: \ + out = ~(D | (P ^ S)); \ + break; \ + case 0x42: \ + out = (S ^ D) & (P ^ D); \ + break; \ + case 0x43: \ + out = ~(S ^ (P & ~(D & S))); \ + break; \ + case 0x44: \ + out = S & ~D; \ + break; \ + case 0x45: \ + out = ~(D | (P & ~S)); \ + break; \ + case 0x46: \ + out = D ^ (S | (P & D)); \ + break; \ + case 0x47: \ + out = ~(P ^ (S & (D ^ P))); \ + break; \ + case 0x48: \ + out = S & (D ^ P); \ + break; \ + case 0x49: \ + out = ~(P ^ (D ^ (S | (P & D)))); \ + break; \ + case 0x4a: \ + out = D ^ (P & (S | D)); \ + break; \ + case 0x4b: \ + out = P ^ (D | ~S); \ + break; \ + case 0x4c: \ + out = S & ~(D & P); \ + break; \ + case 0x4d: \ + out = ~(S ^ ((S ^ P) | (D ^ S))); \ + break; \ + case 0x4e: \ + out = P ^ (D | (S ^ P)); \ + break; \ + case 0x4f: \ + out = ~(P & (D | ~S)); \ + break; \ + case 0x50: \ + out = P & ~D; \ + break; \ + case 0x51: \ + out = ~(D | (S & ~P)); \ + break; \ + case 0x52: \ + out = D ^ (P | (S & D)); \ + break; \ + case 0x53: \ + out = ~(S ^ (P & (D ^ S))); \ + break; \ + case 0x54: \ + out = ~(D | ~(P | S)); \ + break; \ + case 0x55: \ + out = ~D; \ + break; \ + case 0x56: \ + out = D ^ (P | S); \ + break; \ + case 0x57: \ + out = ~(D & (P | S)); \ + break; \ + case 0x58: \ + out = P ^ (D & (S | P)); \ + break; \ + case 0x59: \ + out = D ^ (P | ~S); \ + break; \ + case 0x5a: \ + out = D ^ P; \ + break; \ + case 0x5b: \ + out = D ^ (P | ~(S | D)); \ + break; \ + case 0x5c: \ + out = D ^ (P | (S ^ D)); \ + break; \ + case 0x5d: \ + out = ~(D & (P | ~S)); \ + break; \ + case 0x5e: \ + out = D ^ (P | (S & ~D)); \ + break; \ + case 0x5f: \ + out = ~(D & P); \ + break; \ + case 0x60: \ + out = P & (D ^ S); \ + break; \ + case 0x61: \ + out = ~(D ^ (S ^ (P | (D & S)))); \ + break; \ + case 0x62: \ + out = D ^ (S & (P | D)); \ + break; \ + case 0x63: \ + out = S ^ (D | ~P); \ + break; \ + case 0x64: \ + out = S ^ (D & (P | S)); \ + break; \ + case 0x65: \ + out = D ^ (S | ~P); \ + break; \ + case 0x66: \ + out = D ^ S; \ + break; \ + case 0x67: \ + out = S ^ (D | ~(P | S)); \ + break; \ + case 0x68: \ + out = ~(D ^ (S ^ (P | ~(D | S)))); \ + break; \ + case 0x69: \ + out = ~(P ^ (D ^ S)); \ + break; \ + case 0x6a: \ + out = D ^ (P & S); \ + break; \ + case 0x6b: \ + out = ~(P ^ (S ^ (D & (P | S)))); \ + break; \ + case 0x6c: \ + out = S ^ (D & P); \ + break; \ + case 0x6d: \ + out = ~(P ^ (D ^ (S & (P | D)))); \ + break; \ + case 0x6e: \ + out = S ^ (D & (P | ~S)); \ + break; \ + case 0x6f: \ + out = ~(P & ~(D ^ S)); \ + break; \ + case 0x70: \ + out = P & ~(D & S); \ + break; \ + case 0x71: \ + out = ~(S ^ ((S ^ D) & (P ^ D))); \ + break; \ + case 0x72: \ + out = S ^ (D | (P ^ S)); \ + break; \ + case 0x73: \ + out = ~(S & (D | ~P)); \ + break; \ + case 0x74: \ + out = D ^ (S | (P ^ D)); \ + break; \ + case 0x75: \ + out = ~(D & (S | ~P)); \ + break; \ + case 0x76: \ + out = S ^ (D | (P & ~S)); \ + break; \ + case 0x77: \ + out = ~(D & S); \ + break; \ + case 0x78: \ + out = P ^ (D & S); \ + break; \ + case 0x79: \ + out = ~(D ^ (S ^ (P & (D | S)))); \ + break; \ + case 0x7a: \ + out = D ^ (P & (S | ~D)); \ + break; \ + case 0x7b: \ + out = ~(S & ~(D ^ P)); \ + break; \ + case 0x7c: \ + out = S ^ (P & (D | ~S)); \ + break; \ + case 0x7d: \ + out = ~(D & ~(P ^ S)); \ + break; \ + case 0x7e: \ + out = (S ^ P) | (D ^ S); \ + break; \ + case 0x7f: \ + out = ~(D & (P & S)); \ + break; \ + case 0x80: \ + out = D & (P & S); \ + break; \ + case 0x81: \ + out = ~((S ^ P) | (D ^ S)); \ + break; \ + case 0x82: \ + out = D & ~(P ^ S); \ + break; \ + case 0x83: \ + out = ~(S ^ (P & (D | ~S))); \ + break; \ + case 0x84: \ + out = S & ~(D ^ P); \ + break; \ + case 0x85: \ + out = ~(P ^ (D & (S | ~P))); \ + break; \ + case 0x86: \ + out = D ^ (S ^ (P & (D | S))); \ + break; \ + case 0x87: \ + out = ~(P ^ (D & S)); \ + break; \ + case 0x88: \ + out = D & S; \ + break; \ + case 0x89: \ + out = ~(S ^ (D | (P & ~S))); \ + break; \ + case 0x8a: \ + out = D & (S | ~P); \ + break; \ + case 0x8b: \ + out = ~(D ^ (S | (P ^ D))); \ + break; \ + case 0x8c: \ + out = S & (D | ~P); \ + break; \ + case 0x8d: \ + out = ~(S ^ (D | (P ^ S))); \ + break; \ + case 0x8e: \ + out = S ^ ((S ^ D) & (P ^ D)); \ + break; \ + case 0x8f: \ + out = ~(P & ~(D & S)); \ + break; \ + case 0x90: \ + out = P & ~(D ^ S); \ + break; \ + case 0x91: \ + out = ~(S ^ (D & (P | ~S))); \ + break; \ + case 0x92: \ + out = D ^ (P ^ (S & (D | P))); \ + break; \ + case 0x93: \ + out = ~(S ^ (P & D)); \ + break; \ + case 0x94: \ + out = P ^ (S ^ (D & (P | S))); \ + break; \ + case 0x95: \ + out = ~(D ^ (P & S)); \ + break; \ + case 0x96: \ + out = D ^ (P ^ S); \ + break; \ + case 0x97: \ + out = P ^ (S ^ (D | ~(P | S))); \ + break; \ + case 0x98: \ + out = ~(S ^ (D | ~(P | S))); \ + break; \ + case 0x99: \ + out = ~(D ^ S); \ + break; \ + case 0x9a: \ + out = D ^ (P & ~S); \ + break; \ + case 0x9b: \ + out = ~(S ^ (D & (P | S))); \ + break; \ + case 0x9c: \ + out = S ^ (P & ~D); \ + break; \ + case 0x9d: \ + out = ~(D ^ (S & (P | D))); \ + break; \ + case 0x9e: \ + out = D ^ (S ^ (P | (D & S))); \ + break; \ + case 0x9f: \ + out = ~(P & (D ^ S)); \ + break; \ + case 0xa0: \ + out = D & P; \ + break; \ + case 0xa1: \ + out = ~(P ^ (D | (S & ~P))); \ + break; \ + case 0xa2: \ + out = D & (P | ~S); \ + break; \ + case 0xa3: \ + out = ~(D ^ (P | (S ^ D))); \ + break; \ + case 0xa4: \ + out = ~(P ^ (D | ~(S | P))); \ + break; \ + case 0xa5: \ + out = ~(P ^ D); \ + break; \ + case 0xa6: \ + out = D ^ (S & ~P); \ + break; \ + case 0xa7: \ + out = ~(P ^ (D & (S | P))); \ + break; \ + case 0xa8: \ + out = D & (P | S); \ + break; \ + case 0xa9: \ + out = ~(D ^ (P | S)); \ + break; \ + case 0xaa: \ + out = D; \ + break; \ + case 0xab: \ + out = D | ~(P | S); \ + break; \ + case 0xac: \ + out = S ^ (P & (D ^ S)); \ + break; \ + case 0xad: \ + out = ~(D ^ (P | (S & D))); \ + break; \ + case 0xae: \ + out = D | (S & ~P); \ + break; \ + case 0xaf: \ + out = D | ~P; \ + break; \ + case 0xb0: \ + out = P & (D | ~S); \ + break; \ + case 0xb1: \ + out = ~(P ^ (D | (S ^ P))); \ + break; \ + case 0xb2: \ + out = S ^ ((S ^ P) | (D ^ S)); \ + break; \ + case 0xb3: \ + out = ~(S & ~(D & P)); \ + break; \ + case 0xb4: \ + out = P ^ (S & ~D); \ + break; \ + case 0xb5: \ + out = ~(D ^ (P & (S | D))); \ + break; \ + case 0xb6: \ + out = D ^ (P ^ (S | (D & P))); \ + break; \ + case 0xb7: \ + out = ~(S & (D ^ P)); \ + break; \ + case 0xb8: \ + out = P ^ (S & (D ^ P)); \ + break; \ + case 0xb9: \ + out = ~(D ^ (S | (P & D))); \ + break; \ + case 0xba: \ + out = D | (P & ~S); \ + break; \ + case 0xbb: \ + out = D | ~S; \ + break; \ + case 0xbc: \ + out = S ^ (P & ~(D & S)); \ + break; \ + case 0xbd: \ + out = ~((S ^ D) & (P ^ D)); \ + break; \ + case 0xbe: \ + out = D | (P ^ S); \ + break; \ + case 0xbf: \ + out = D | ~(P & S); \ + break; \ + case 0xc0: \ + out = P & S; \ + break; \ + case 0xc1: \ + out = ~(S ^ (P | (D & ~S))); \ + break; \ + case 0xc2: \ + out = ~(S ^ (P | ~(D | S))); \ + break; \ + case 0xc3: \ + out = ~(P ^ S); \ + break; \ + case 0xc4: \ + out = S & (P | ~D); \ + break; \ + case 0xc5: \ + out = ~(S ^ (P | (D ^ S))); \ + break; \ + case 0xc6: \ + out = S ^ (D & ~P); \ + break; \ + case 0xc7: \ + out = ~(P ^ (S & (D | P))); \ + break; \ + case 0xc8: \ + out = S & (D | P); \ + break; \ + case 0xc9: \ + out = ~(S ^ (P | D)); \ + break; \ + case 0xca: \ + out = D ^ (P & (S ^ D)); \ + break; \ + case 0xcb: \ + out = ~(S ^ (P | (D & S))); \ + break; \ + case 0xcc: \ + out = S; \ + break; \ + case 0xcd: \ + out = S | ~(D | P); \ + break; \ + case 0xce: \ + out = S | (D & ~P); \ + break; \ + case 0xcf: \ + out = S | ~P; \ + break; \ + case 0xd0: \ + out = P & (S | ~D); \ + break; \ + case 0xd1: \ + out = ~(P ^ (S | (D ^ P))); \ + break; \ + case 0xd2: \ + out = P ^ (D & ~S); \ + break; \ + case 0xd3: \ + out = ~(S ^ (P & (D | S))); \ + break; \ + case 0xd4: \ + out = S ^ ((S ^ P) & (P ^ D)); \ + break; \ + case 0xd5: \ + out = ~(D & ~(P & S)); \ + break; \ + case 0xd6: \ + out = P ^ (S ^ (D | (P & S))); \ + break; \ + case 0xd7: \ + out = ~(D & (P ^ S)); \ + break; \ + case 0xd8: \ + out = P ^ (D & (S ^ P)); \ + break; \ + case 0xd9: \ + out = ~(S ^ (D | (P & S))); \ + break; \ + case 0xda: \ + out = D ^ (P & ~(S & D)); \ + break; \ + case 0xdb: \ + out = ~((S ^ P) & (D ^ S)); \ + break; \ + case 0xdc: \ + out = S | (P & ~D); \ + break; \ + case 0xdd: \ + out = S | ~D; \ + break; \ + case 0xde: \ + out = S | (D ^ P); \ + break; \ + case 0xdf: \ + out = S | ~(D & P); \ + break; \ + case 0xe0: \ + out = P & (D | S); \ + break; \ + case 0xe1: \ + out = ~(P ^ (D | S)); \ + break; \ + case 0xe2: \ + out = D ^ (S & (P ^ D)); \ + break; \ + case 0xe3: \ + out = ~(P ^ (S | (D & P))); \ + break; \ + case 0xe4: \ + out = S ^ (D & (P ^ S)); \ + break; \ + case 0xe5: \ + out = ~(P ^ (D | (S & P))); \ + break; \ + case 0xe6: \ + out = S ^ (D & ~(P & S)); \ + break; \ + case 0xe7: \ + out = ~((S ^ P) & (P ^ D)); \ + break; \ + case 0xe8: \ + out = S ^ ((S ^ P) & (D ^ S)); \ + break; \ + case 0xe9: \ + out = ~(D ^ (S ^ (P & ~(D & S)))); \ + break; \ + case 0xea: \ + out = D | (P & S); \ + break; \ + case 0xeb: \ + out = D | ~(P ^ S); \ + break; \ + case 0xec: \ + out = S | (D & P); \ + break; \ + case 0xed: \ + out = S | ~(D ^ P); \ + break; \ + case 0xee: \ + out = D | S; \ + break; \ + case 0xef: \ + out = S | (D | ~P); \ + break; \ + case 0xf0: \ + out = P; \ + break; \ + case 0xf1: \ + out = P | ~(D | S); \ + break; \ + case 0xf2: \ + out = P | (D & ~S); \ + break; \ + case 0xf3: \ + out = P | ~S; \ + break; \ + case 0xf4: \ + out = P | (S & ~D); \ + break; \ + case 0xf5: \ + out = P | ~D; \ + break; \ + case 0xf6: \ + out = P | (D ^ S); \ + break; \ + case 0xf7: \ + out = P | ~(D & S); \ + break; \ + case 0xf8: \ + out = P | (D & S); \ + break; \ + case 0xf9: \ + out = P | ~(D ^ S); \ + break; \ + case 0xfa: \ + out = D | P; \ + break; \ + case 0xfb: \ + out = D | (P | ~S); \ + break; \ + case 0xfc: \ + out = P | S; \ + break; \ + case 0xfd: \ + out = P | (S | ~D); \ + break; \ + case 0xfe: \ + out = D | (P | S); \ + break; \ + case 0xff: \ + out = ~0; \ + break; \ + } \ + } +#define ROPMIX \ + { \ + old_dest_dat = dest_dat; \ + ROPMIX_READ(dest_dat, pat_dat, src_dat); \ + out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + } - -#define ROPMIX_READ(D, P, S) \ - { \ - switch (rop) { \ - case 0x00: out = 0; break; \ - case 0x01: out = ~(D | (P | S)); break; \ - case 0x02: out = D & ~(P | S); break; \ - case 0x03: out = ~(P | S); break; \ - case 0x04: out = S & ~(D | P); break; \ - case 0x05: out = ~(D | P); break; \ - case 0x06: out = ~(P | ~(D ^ S)); break; \ - case 0x07: out = ~(P | (D & S)); break; \ - case 0x08: out = S & (D & ~P); break; \ - case 0x09: out = ~(P | (D ^ S)); break; \ - case 0x0a: out = D & ~P; break; \ - case 0x0b: out = ~(P | (S & ~D)); break; \ - case 0x0c: out = S & ~P; break; \ - case 0x0d: out = ~(P | (D & ~S)); break; \ - case 0x0e: out = ~(P | ~(D | S)); break; \ - case 0x0f: out = ~P; break; \ - case 0x10: out = P & ~(D | S); break; \ - case 0x11: out = ~(D | S); break; \ - case 0x12: out = ~(S | ~(D ^ P)); break; \ - case 0x13: out = ~(S | (D & P)); break; \ - case 0x14: out = ~(D | ~(P ^ S)); break; \ - case 0x15: out = ~(D | (P & S)); break; \ - case 0x16: out = P ^ (S ^ (D & ~(P & S))); break; \ - case 0x17: out = ~(S ^ ((S ^ P) & (D ^ S))); break; \ - case 0x18: out = (S ^ P) & (P ^ D); break; \ - case 0x19: out = ~(S ^ (D & ~(P & S))); break; \ - case 0x1a: out = P ^ (D | (S & P)); break; \ - case 0x1b: out = ~(S ^ (D & (P ^ S))); break; \ - case 0x1c: out = P ^ (S | (D & P)); break; \ - case 0x1d: out = ~(D ^ (S & (P ^ D))); break; \ - case 0x1e: out = P ^ (D | S); break; \ - case 0x1f: out = ~(P & (D | S)); break; \ - case 0x20: out = D & (P & ~S); break; \ - case 0x21: out = ~(S | (D ^ P)); break; \ - case 0x22: out = D & ~S; break; \ - case 0x23: out = ~(S | (P & ~D)); break; \ - case 0x24: out = (S ^ P) & (D ^ S); break; \ - case 0x25: out = ~(P ^ (D & ~(S & P))); break; \ - case 0x26: out = S ^ (D | (P & S)); break; \ - case 0x27: out = S ^ (D | ~(P ^ S)); break; \ - case 0x28: out = D & (P ^ S); break; \ - case 0x29: out = ~(P ^ (S ^ (D | (P & S)))); break; \ - case 0x2a: out = D & ~(P & S); break; \ - case 0x2b: out = ~(S ^ ((S ^ P) & (P ^ D))); break; \ - case 0x2c: out = S ^ (P & (D | S)); break; \ - case 0x2d: out = P ^ (S | ~D); break; \ - case 0x2e: out = P ^ (S | (D ^ P)); break; \ - case 0x2f: out = ~(P & (S | ~D)); break; \ - case 0x30: out = P & ~S; break; \ - case 0x31: out = ~(S | (D & ~P)); break; \ - case 0x32: out = S ^ (D | (P | S)); break; \ - case 0x33: out = ~S; break; \ - case 0x34: out = S ^ (P | (D & S)); break; \ - case 0x35: out = S ^ (P | ~(D ^ S)); break; \ - case 0x36: out = S ^ (D | P); break; \ - case 0x37: out = ~(S & (D | P)); break; \ - case 0x38: out = P ^ (S & (D | P)); break; \ - case 0x39: out = S ^ (P | ~D); break; \ - case 0x3a: out = S ^ (P | (D ^ S)); break; \ - case 0x3b: out = ~(S & (P | ~D)); break; \ - case 0x3c: out = P ^ S; break; \ - case 0x3d: out = S ^ (P | ~(D | S)); break; \ - case 0x3e: out = S ^ (P | (D & ~S)); break; \ - case 0x3f: out = ~(P & S); break; \ - case 0x40: out = P & (S & ~D); break; \ - case 0x41: out = ~(D | (P ^ S)); break; \ - case 0x42: out = (S ^ D) & (P ^ D); break; \ - case 0x43: out = ~(S ^ (P & ~(D & S))); break; \ - case 0x44: out = S & ~D; break; \ - case 0x45: out = ~(D | (P & ~S)); break; \ - case 0x46: out = D ^ (S | (P & D)); break; \ - case 0x47: out = ~(P ^ (S & (D ^ P))); break; \ - case 0x48: out = S & (D ^ P); break; \ - case 0x49: out = ~(P ^ (D ^ (S | (P & D)))); break; \ - case 0x4a: out = D ^ (P & (S | D)); break; \ - case 0x4b: out = P ^ (D | ~S); break; \ - case 0x4c: out = S & ~(D & P); break; \ - case 0x4d: out = ~(S ^ ((S ^ P) | (D ^ S))); break; \ - case 0x4e: out = P ^ (D | (S ^ P)); break; \ - case 0x4f: out = ~(P & (D | ~S)); break; \ - case 0x50: out = P & ~D; break; \ - case 0x51: out = ~(D | (S & ~P)); break; \ - case 0x52: out = D ^ (P | (S & D)); break; \ - case 0x53: out = ~(S ^ (P & (D ^ S))); break; \ - case 0x54: out = ~(D | ~(P | S)); break; \ - case 0x55: out = ~D; break; \ - case 0x56: out = D ^ (P | S); break; \ - case 0x57: out = ~(D & (P | S)); break; \ - case 0x58: out = P ^ (D & (S | P)); break; \ - case 0x59: out = D ^ (P | ~S); break; \ - case 0x5a: out = D ^ P; break; \ - case 0x5b: out = D ^ (P | ~(S | D)); break; \ - case 0x5c: out = D ^ (P | (S ^ D)); break; \ - case 0x5d: out = ~(D & (P | ~S)); break; \ - case 0x5e: out = D ^ (P | (S & ~D)); break; \ - case 0x5f: out = ~(D & P); break; \ - case 0x60: out = P & (D ^ S); break; \ - case 0x61: out = ~(D ^ (S ^ (P | (D & S)))); break; \ - case 0x62: out = D ^ (S & (P | D)); break; \ - case 0x63: out = S ^ (D | ~P); break; \ - case 0x64: out = S ^ (D & (P | S)); break; \ - case 0x65: out = D ^ (S | ~P); break; \ - case 0x66: out = D ^ S; break; \ - case 0x67: out = S ^ (D | ~(P | S)); break; \ - case 0x68: out = ~(D ^ (S ^ (P | ~(D | S)))); break; \ - case 0x69: out = ~(P ^ (D ^ S)); break; \ - case 0x6a: out = D ^ (P & S); break; \ - case 0x6b: out = ~(P ^ (S ^ (D & (P | S)))); break; \ - case 0x6c: out = S ^ (D & P); break; \ - case 0x6d: out = ~(P ^ (D ^ (S & (P | D)))); break; \ - case 0x6e: out = S ^ (D & (P | ~S)); break; \ - case 0x6f: out = ~(P & ~(D ^ S)); break; \ - case 0x70: out = P & ~(D & S); break; \ - case 0x71: out = ~(S ^ ((S ^ D) & (P ^ D))); break; \ - case 0x72: out = S ^ (D | (P ^ S)); break; \ - case 0x73: out = ~(S & (D | ~P)); break; \ - case 0x74: out = D ^ (S | (P ^ D)); break; \ - case 0x75: out = ~(D & (S | ~P)); break; \ - case 0x76: out = S ^ (D | (P & ~S)); break; \ - case 0x77: out = ~(D & S); break; \ - case 0x78: out = P ^ (D & S); break; \ - case 0x79: out = ~(D ^ (S ^ (P & (D | S)))); break; \ - case 0x7a: out = D ^ (P & (S | ~D)); break; \ - case 0x7b: out = ~(S & ~(D ^ P)); break; \ - case 0x7c: out = S ^ (P & (D | ~S)); break; \ - case 0x7d: out = ~(D & ~(P ^ S)); break; \ - case 0x7e: out = (S ^ P) | (D ^ S); break; \ - case 0x7f: out = ~(D & (P & S)); break; \ - case 0x80: out = D & (P & S); break; \ - case 0x81: out = ~((S ^ P) | (D ^ S)); break; \ - case 0x82: out = D & ~(P ^ S); break; \ - case 0x83: out = ~(S ^ (P & (D | ~S))); break; \ - case 0x84: out = S & ~(D ^ P); break; \ - case 0x85: out = ~(P ^ (D & (S | ~P))); break; \ - case 0x86: out = D ^ (S ^ (P & (D | S))); break; \ - case 0x87: out = ~(P ^ (D & S)); break; \ - case 0x88: out = D & S; break; \ - case 0x89: out = ~(S ^ (D | (P & ~S))); break; \ - case 0x8a: out = D & (S | ~P); break; \ - case 0x8b: out = ~(D ^ (S | (P ^ D))); break; \ - case 0x8c: out = S & (D | ~P); break; \ - case 0x8d: out = ~(S ^ (D | (P ^ S))); break; \ - case 0x8e: out = S ^ ((S ^ D) & (P ^ D)); break; \ - case 0x8f: out = ~(P & ~(D & S)); break; \ - case 0x90: out = P & ~(D ^ S); break; \ - case 0x91: out = ~(S ^ (D & (P | ~S))); break; \ - case 0x92: out = D ^ (P ^ (S & (D | P))); break; \ - case 0x93: out = ~(S ^ (P & D)); break; \ - case 0x94: out = P ^ (S ^ (D & (P | S))); break; \ - case 0x95: out = ~(D ^ (P & S)); break; \ - case 0x96: out = D ^ (P ^ S); break; \ - case 0x97: out = P ^ (S ^ (D | ~(P | S))); break; \ - case 0x98: out = ~(S ^ (D | ~(P | S))); break; \ - case 0x99: out = ~(D ^ S); break; \ - case 0x9a: out = D ^ (P & ~S); break; \ - case 0x9b: out = ~(S ^ (D & (P | S))); break; \ - case 0x9c: out = S ^ (P & ~D); break; \ - case 0x9d: out = ~(D ^ (S & (P | D))); break; \ - case 0x9e: out = D ^ (S ^ (P | (D & S))); break; \ - case 0x9f: out = ~(P & (D ^ S)); break; \ - case 0xa0: out = D & P; break; \ - case 0xa1: out = ~(P ^ (D | (S & ~P))); break; \ - case 0xa2: out = D & (P | ~S); break; \ - case 0xa3: out = ~(D ^ (P | (S ^ D))); break; \ - case 0xa4: out = ~(P ^ (D | ~(S | P))); break; \ - case 0xa5: out = ~(P ^ D); break; \ - case 0xa6: out = D ^ (S & ~P); break; \ - case 0xa7: out = ~(P ^ (D & (S | P))); break; \ - case 0xa8: out = D & (P | S); break; \ - case 0xa9: out = ~(D ^ (P | S)); break; \ - case 0xaa: out = D; break; \ - case 0xab: out = D | ~(P | S); break; \ - case 0xac: out = S ^ (P & (D ^ S)); break; \ - case 0xad: out = ~(D ^ (P | (S & D))); break; \ - case 0xae: out = D | (S & ~P); break; \ - case 0xaf: out = D | ~P; break; \ - case 0xb0: out = P & (D | ~S); break; \ - case 0xb1: out = ~(P ^ (D | (S ^ P))); break; \ - case 0xb2: out = S ^ ((S ^ P) | (D ^ S)); break; \ - case 0xb3: out = ~(S & ~(D & P)); break; \ - case 0xb4: out = P ^ (S & ~D); break; \ - case 0xb5: out = ~(D ^ (P & (S | D))); break; \ - case 0xb6: out = D ^ (P ^ (S | (D & P))); break; \ - case 0xb7: out = ~(S & (D ^ P)); break; \ - case 0xb8: out = P ^ (S & (D ^ P)); break; \ - case 0xb9: out = ~(D ^ (S | (P & D))); break; \ - case 0xba: out = D | (P & ~S); break; \ - case 0xbb: out = D | ~S; break; \ - case 0xbc: out = S ^ (P & ~(D & S)); break; \ - case 0xbd: out = ~((S ^ D) & (P ^ D)); break; \ - case 0xbe: out = D | (P ^ S); break; \ - case 0xbf: out = D | ~(P & S); break; \ - case 0xc0: out = P & S; break; \ - case 0xc1: out = ~(S ^ (P | (D & ~S))); break; \ - case 0xc2: out = ~(S ^ (P | ~(D | S))); break; \ - case 0xc3: out = ~(P ^ S); break; \ - case 0xc4: out = S & (P | ~D); break; \ - case 0xc5: out = ~(S ^ (P | (D ^ S))); break; \ - case 0xc6: out = S ^ (D & ~P); break; \ - case 0xc7: out = ~(P ^ (S & (D | P))); break; \ - case 0xc8: out = S & (D | P); break; \ - case 0xc9: out = ~(S ^ (P | D)); break; \ - case 0xca: out = D ^ (P & (S ^ D)); break; \ - case 0xcb: out = ~(S ^ (P | (D & S))); break; \ - case 0xcc: out = S; break; \ - case 0xcd: out = S | ~(D | P); break; \ - case 0xce: out = S | (D & ~P); break; \ - case 0xcf: out = S | ~P; break; \ - case 0xd0: out = P & (S | ~D); break; \ - case 0xd1: out = ~(P ^ (S | (D ^ P))); break; \ - case 0xd2: out = P ^ (D & ~S); break; \ - case 0xd3: out = ~(S ^ (P & (D | S))); break; \ - case 0xd4: out = S ^ ((S ^ P) & (P ^ D)); break; \ - case 0xd5: out = ~(D & ~(P & S)); break; \ - case 0xd6: out = P ^ (S ^ (D | (P & S))); break; \ - case 0xd7: out = ~(D & (P ^ S)); break; \ - case 0xd8: out = P ^ (D & (S ^ P)); break; \ - case 0xd9: out = ~(S ^ (D | (P & S))); break; \ - case 0xda: out = D ^ (P & ~(S & D)); break; \ - case 0xdb: out = ~((S ^ P) & (D ^ S)); break; \ - case 0xdc: out = S | (P & ~D); break; \ - case 0xdd: out = S | ~D; break; \ - case 0xde: out = S | (D ^ P); break; \ - case 0xdf: out = S | ~(D & P); break; \ - case 0xe0: out = P & (D | S); break; \ - case 0xe1: out = ~(P ^ (D | S)); break; \ - case 0xe2: out = D ^ (S & (P ^ D)); break; \ - case 0xe3: out = ~(P ^ (S | (D & P))); break; \ - case 0xe4: out = S ^ (D & (P ^ S)); break; \ - case 0xe5: out = ~(P ^ (D | (S & P))); break; \ - case 0xe6: out = S ^ (D & ~(P & S)); break; \ - case 0xe7: out = ~((S ^ P) & (P ^ D)); break; \ - case 0xe8: out = S ^ ((S ^ P) & (D ^ S)); break; \ - case 0xe9: out = ~(D ^ (S ^ (P & ~(D & S)))); break; \ - case 0xea: out = D | (P & S); break; \ - case 0xeb: out = D | ~(P ^ S); break; \ - case 0xec: out = S | (D & P); break; \ - case 0xed: out = S | ~(D ^ P); break; \ - case 0xee: out = D | S; break; \ - case 0xef: out = S | (D | ~P); break; \ - case 0xf0: out = P; break; \ - case 0xf1: out = P | ~(D | S); break; \ - case 0xf2: out = P | (D & ~S); break; \ - case 0xf3: out = P | ~S; break; \ - case 0xf4: out = P | (S & ~D); break; \ - case 0xf5: out = P | ~D; break; \ - case 0xf6: out = P | (D ^ S); break; \ - case 0xf7: out = P | ~(D & S); break; \ - case 0xf8: out = P | (D & S); break; \ - case 0xf9: out = P | ~(D ^ S); break; \ - case 0xfa: out = D | P; break; \ - case 0xfb: out = D | (P | ~S); break; \ - case 0xfc: out = P | S; break; \ - case 0xfd: out = P | (S | ~D); break; \ - case 0xfe: out = D | (P | S); break; \ - case 0xff: out = ~0; break; \ - } \ - } - - -#define ROPMIX { \ - old_dest_dat = dest_dat; \ - ROPMIX_READ(dest_dat, pat_dat, src_dat); \ - out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ - } - - -#define WRITE(addr, dat) if (s3->bpp == 0 && !s3->color_16bit) \ - { \ - svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ - svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = changeframecount; \ - } \ - else if (s3->bpp == 1 || s3->color_16bit) \ - { \ - vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ - svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ - } \ - else if (s3->bpp == 2) \ - { \ - svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ - svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = changeframecount; \ - } \ - else \ - { \ - vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)] = dat; \ - svga->changedvram[(dword_remap_l(svga, addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ - } - +#define WRITE(addr, dat) \ + if (s3->bpp == 0 && !s3->color_16bit) { \ + svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ + svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = changeframecount; \ + } else if (s3->bpp == 1 || s3->color_16bit) { \ + vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ + svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = changeframecount; \ + } else if (s3->bpp == 2) { \ + svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ + svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = changeframecount; \ + } else { \ + vram_l[dword_remap_l(svga, addr) & (s3->vram_mask >> 2)] = dat; \ + svga->changedvram[(dword_remap_l(svga, addr) & (s3->vram_mask >> 2)) >> 10] = changeframecount; \ + } static __inline void convert_to_rgb32(int idf, int is_yuv, uint32_t val, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *r2, uint8_t *g2, uint8_t *b2) @@ -4863,73 +5668,73 @@ convert_to_rgb32(int idf, int is_yuv, uint32_t val, uint8_t *r, uint8_t *g, uint static double dU = 0.0, dV = 0.0; switch (idf) { - case 0: /* 8 bpp, RGB 3-3-2 */ - dr = (double) ((val >> 5) & 0x07); - dg = (double) ((val >> 2) & 0x07); - db = (double) (val & 0x03); - dr = (dr / 7.0) * 255.0; - dg = (dg / 7.0) * 255.0; - db = (db / 3.0) * 255.0; - break; - case 3: /* 32bpp, RGB 8-8-8 */ - dr = (double) ((val >> 16) & 0xff); - dg = (double) ((val >> 8) & 0xff); - db = (double) (val & 0xff); - break; - case 4: /* YCbCr */ - if (is_yuv) { - dU = ((double) (val & 0xff)) - 128.0; - dY1 = (double) ((val >> 8) & 0xff); - dY1 = (298.0 * (dY1 - 16.0)) / 256.0; - dV = ((double) ((val >> 16) & 0xff)) - 128.0; - dY2 = (double) ((val >> 24) & 0xff); - dY2 = (298.0 * (dY2 - 16.0)) / 256.0; + case 0: /* 8 bpp, RGB 3-3-2 */ + dr = (double) ((val >> 5) & 0x07); + dg = (double) ((val >> 2) & 0x07); + db = (double) (val & 0x03); + dr = (dr / 7.0) * 255.0; + dg = (dg / 7.0) * 255.0; + db = (db / 3.0) * 255.0; + break; + case 3: /* 32bpp, RGB 8-8-8 */ + dr = (double) ((val >> 16) & 0xff); + dg = (double) ((val >> 8) & 0xff); + db = (double) (val & 0xff); + break; + case 4: /* YCbCr */ + if (is_yuv) { + dU = ((double) (val & 0xff)) - 128.0; + dY1 = (double) ((val >> 8) & 0xff); + dY1 = (298.0 * (dY1 - 16.0)) / 256.0; + dV = ((double) ((val >> 16) & 0xff)) - 128.0; + dY2 = (double) ((val >> 24) & 0xff); + dY2 = (298.0 * (dY2 - 16.0)) / 256.0; - dr = (309.0 * dV) / 256.0; - dg = ((100.0 * dU) + (208.0 * dV)) / 256.0; - db = (516.0 * dU) / 256.0; - } else { - dY1 = (double) (val & 0xff); - dCr = ((double) ((val >> 8) & 0xff)) - 128.0; - dY2 = (double) ((val >> 16) & 0xff); - dCb = ((double) ((val >> 24) & 0xff)) - 128.0; + dr = (309.0 * dV) / 256.0; + dg = ((100.0 * dU) + (208.0 * dV)) / 256.0; + db = (516.0 * dU) / 256.0; + } else { + dY1 = (double) (val & 0xff); + dCr = ((double) ((val >> 8) & 0xff)) - 128.0; + dY2 = (double) ((val >> 16) & 0xff); + dCb = ((double) ((val >> 24) & 0xff)) - 128.0; - dr = (359.0 * dCr) / 256.0; - dg = ((88.0 * dCb) + (183.0 * dCr)) / 2560.0; - db = (453.0 * dCr) / 256.0; - } + dr = (359.0 * dCr) / 256.0; + dg = ((88.0 * dCb) + (183.0 * dCr)) / 2560.0; + db = (453.0 * dCr) / 256.0; + } - *r = (uint8_t) round(dY1 + dr); - CLAMP(*r); - *g = (uint8_t) round(dY1 - dg); - CLAMP(*g); - *b = (uint8_t) round(dY1 + db); - CLAMP(*b); + *r = (uint8_t) round(dY1 + dr); + CLAMP(*r); + *g = (uint8_t) round(dY1 - dg); + CLAMP(*g); + *b = (uint8_t) round(dY1 + db); + CLAMP(*b); - *r2 = (uint8_t) round(dY2 + dr); - CLAMP(*r2); - *g2 = (uint8_t) round(dY2 - dg); - CLAMP(*g2); - *b2 = (uint8_t) round(dY2 + db); - CLAMP(*b2); - return; - case 5: /* 16bpp, raw */ - case 7: /* 16bpp, RGB 5-6-5 */ - dr = (double) ((val >> 11) & 0x1f); - dg = (double) ((val >> 5) & 0x03f); - db = (double) (val & 0x1f); - dr = (dr / 31.0) * 255.0; - dg = (dg / 63.0) * 255.0; - db = (db / 31.0) * 255.0; - break; - case 6: /* 15bpp, RGB 5-5-5 */ - dr = (double) ((val >> 10) & 0x1f); - dg = (double) ((val >> 5) & 0x01f); - db = (double) (val & 0x1f); - dr = (dr / 31.0) * 255.0; - dg = (dg / 31.0) * 255.0; - db = (db / 31.0) * 255.0; - break; + *r2 = (uint8_t) round(dY2 + dr); + CLAMP(*r2); + *g2 = (uint8_t) round(dY2 - dg); + CLAMP(*g2); + *b2 = (uint8_t) round(dY2 + db); + CLAMP(*b2); + return; + case 5: /* 16bpp, raw */ + case 7: /* 16bpp, RGB 5-6-5 */ + dr = (double) ((val >> 11) & 0x1f); + dg = (double) ((val >> 5) & 0x03f); + db = (double) (val & 0x1f); + dr = (dr / 31.0) * 255.0; + dg = (dg / 63.0) * 255.0; + db = (db / 31.0) * 255.0; + break; + case 6: /* 15bpp, RGB 5-5-5 */ + dr = (double) ((val >> 10) & 0x1f); + dg = (double) ((val >> 5) & 0x01f); + db = (double) (val & 0x1f); + dr = (dr / 31.0) * 255.0; + dg = (dg / 31.0) * 255.0; + db = (db / 31.0) * 255.0; + break; } *r = (uint8_t) round(dr); @@ -4937,7 +5742,6 @@ convert_to_rgb32(int idf, int is_yuv, uint32_t val, uint8_t *r, uint8_t *g, uint *b = (uint8_t) round(db); } - static __inline void convert_from_rgb32(int idf, int odf, int is_yuv, uint32_t *val, uint8_t r, uint8_t g, uint8_t b, uint8_t r2, uint8_t g2, uint8_t b2) { @@ -4951,70 +5755,70 @@ convert_from_rgb32(int idf, int odf, int is_yuv, uint32_t *val, uint8_t r, uint8 db = (double) b; switch (odf) { - case 0: /* 8 bpp, RGB 3-3-2 */ - switch (idf) { - case 3: - *val = (((uint32_t) round(dr)) << 16) + (((uint32_t) round(dg)) << 8) + ((uint32_t) round(db)); - break; - case 5: - case 7: - dr = (dr / 255.0) * 31.0; - dg = (dg / 255.0) * 63.0; - db = (db / 255.0) * 31.0; - *val = (((uint32_t) round(dr)) << 11) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); - break; - case 6: - dr = (dr / 255.0) * 31.0; - dg = (dg / 255.0) * 31.0; - db = (db / 255.0) * 31.0; - *val = (((uint32_t) round(dr)) << 10) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); - break; - case 0: - default: - dr = (dr / 255.0) * 7.0; - dg = (dg / 255.0) * 7.0; - db = (db / 255.0) * 3.0; - *val = (((uint32_t) round(dr)) << 5) + (((uint32_t) round(dg)) << 2) + ((uint32_t) round(db)); - break; - } - break; - case 3: /* 32bpp, RGB 8-8-8 */ - *val = (((uint32_t) round(dr)) << 16) + (((uint32_t) round(dg)) << 8) + ((uint32_t) round(db)); - break; - case 4: /* YCbCr */ - dr2 = (double) r2; - dg2 = (double) g2; - db2 = (double) b2; + case 0: /* 8 bpp, RGB 3-3-2 */ + switch (idf) { + case 3: + *val = (((uint32_t) round(dr)) << 16) + (((uint32_t) round(dg)) << 8) + ((uint32_t) round(db)); + break; + case 5: + case 7: + dr = (dr / 255.0) * 31.0; + dg = (dg / 255.0) * 63.0; + db = (db / 255.0) * 31.0; + *val = (((uint32_t) round(dr)) << 11) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); + break; + case 6: + dr = (dr / 255.0) * 31.0; + dg = (dg / 255.0) * 31.0; + db = (db / 255.0) * 31.0; + *val = (((uint32_t) round(dr)) << 10) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); + break; + case 0: + default: + dr = (dr / 255.0) * 7.0; + dg = (dg / 255.0) * 7.0; + db = (db / 255.0) * 3.0; + *val = (((uint32_t) round(dr)) << 5) + (((uint32_t) round(dg)) << 2) + ((uint32_t) round(db)); + break; + } + break; + case 3: /* 32bpp, RGB 8-8-8 */ + *val = (((uint32_t) round(dr)) << 16) + (((uint32_t) round(dg)) << 8) + ((uint32_t) round(db)); + break; + case 4: /* YCbCr */ + dr2 = (double) r2; + dg2 = (double) g2; + db2 = (double) b2; - if (is_yuv) { - dU = ((113046.0 * dg2) - (71552.0 * dr2) - (69488.0 * db2)) / 28509.0; - dV = ((3328.0 * dr2) + (800.0 * db2) - (4128.0 * dg2)) / 663.0; - dY1 = dr - ((309 * dV) / 256.0); - dY2 = dr2 - ((309 * dV) / 256.0); + if (is_yuv) { + dU = ((113046.0 * dg2) - (71552.0 * dr2) - (69488.0 * db2)) / 28509.0; + dV = ((3328.0 * dr2) + (800.0 * db2) - (4128.0 * dg2)) / 663.0; + dY1 = dr - ((309 * dV) / 256.0); + dY2 = dr2 - ((309 * dV) / 256.0); - *val = ((uint32_t) round(dU)) + (((uint32_t) round(dY1)) << 8) + (((uint32_t) round(dV)) << 16) + (((uint32_t) round(dY2)) << 24); - } else { - dCr = ((128.0 * db2) - (128.0 * dr2)) / 47.0; - dCb = ((128.0 * dr2) - (128.0 * dg2) - (271.0 * dCr)) / 44.0; - dY1 = dr - ((359.0 * dCr) / 256.0); - dY2 = dr2 - ((359.0 * dCr) / 256.0); + *val = ((uint32_t) round(dU)) + (((uint32_t) round(dY1)) << 8) + (((uint32_t) round(dV)) << 16) + (((uint32_t) round(dY2)) << 24); + } else { + dCr = ((128.0 * db2) - (128.0 * dr2)) / 47.0; + dCb = ((128.0 * dr2) - (128.0 * dg2) - (271.0 * dCr)) / 44.0; + dY1 = dr - ((359.0 * dCr) / 256.0); + dY2 = dr2 - ((359.0 * dCr) / 256.0); - *val = ((uint32_t) round(dY1)) + (((uint32_t) round(dCr)) << 8) + (((uint32_t) round(dY2)) << 16) + (((uint32_t) round(dCb)) << 24); - } - return; - case 5: /* 16bpp, raw */ - case 7: /* 16bpp, RGB 5-6-5 */ - dr = (dr / 255.0) * 31.0; - dg = (dg / 255.0) * 63.0; - db = (db / 255.0) * 31.0; - *val = (((uint32_t) round(dr)) << 11) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); - break; - case 6: /* 15bpp, RGB 5-5-5 */ - dr = (dr / 255.0) * 31.0; - dg = (dg / 255.0) * 31.0; - db = (db / 255.0) * 31.0; - *val = (((uint32_t) round(dr)) << 10) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); - break; + *val = ((uint32_t) round(dY1)) + (((uint32_t) round(dCr)) << 8) + (((uint32_t) round(dY2)) << 16) + (((uint32_t) round(dCb)) << 24); + } + return; + case 5: /* 16bpp, raw */ + case 7: /* 16bpp, RGB 5-6-5 */ + dr = (dr / 255.0) * 31.0; + dg = (dg / 255.0) * 63.0; + db = (db / 255.0) * 31.0; + *val = (((uint32_t) round(dr)) << 11) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); + break; + case 6: /* 15bpp, RGB 5-5-5 */ + dr = (dr / 255.0) * 31.0; + dg = (dg / 255.0) * 31.0; + db = (db / 255.0) * 31.0; + *val = (((uint32_t) round(dr)) << 10) + (((uint32_t) round(dg)) << 5) + ((uint32_t) round(db)); + break; } } @@ -5022,1643 +5826,1744 @@ convert_from_rgb32(int idf, int odf, int is_yuv, uint32_t *val, uint8_t r, uint8 static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3) { - svga_t *svga = &s3->svga; - int idf, odf, host; - int is_yuv; - uint32_t src, dest = 0x00000000; - uint8_t r = 0x00, g = 0x00, b = 0x00, r2 = 0x00, g2 = 0x00, b2 = 0x00; - uint16_t *vram_w = (uint16_t *)svga->vram; - uint32_t *vram_l = (uint32_t *)svga->vram; - uint32_t k2 = 0, dda = 0, diff = 0; - int count = -1; + svga_t *svga = &s3->svga; + int idf, odf, host; + int is_yuv; + uint32_t src, dest = 0x00000000; + uint8_t r = 0x00, g = 0x00, b = 0x00, r2 = 0x00, g2 = 0x00, b2 = 0x00; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; + uint32_t k2 = 0, dda = 0, diff = 0; + int count = -1; - idf = s3->videoengine.idf; - odf = s3->videoengine.odf; - is_yuv = s3->videoengine.yuv; - host = s3->videoengine.host_data; + idf = s3->videoengine.idf; + odf = s3->videoengine.odf; + is_yuv = s3->videoengine.yuv; + host = s3->videoengine.host_data; - k2 = s3->videoengine.k2 - 0x700; - dda = s3->videoengine.dda_init_accumulator - 0xf00; - diff = 0xff - k2; + k2 = s3->videoengine.k2 - 0x700; + dda = s3->videoengine.dda_init_accumulator - 0xf00; + diff = 0xff - k2; - s3->videoengine.busy = 1; + s3->videoengine.busy = 1; - if (host) { - if (idf == 0 && odf == 0) { - if (s3->bpp == 0) - count = 4; - else if (s3->bpp == 1) - count = 2; - else - count = 1; - } else { - if (idf == 0) - count = 4; - else if (idf == 3) - count = 1; - else - count = 2; - } - } + if (host) { + if (idf == 0 && odf == 0) { + if (s3->bpp == 0) + count = 4; + else if (s3->bpp == 1) + count = 2; + else + count = 1; + } else { + if (idf == 0) + count = 4; + else if (idf == 3) + count = 1; + else + count = 2; + } + } - if (s3->videoengine.input == 1) { - if (s3->videoengine.scale_down) { - if (s3->bpp > 1) { - s3->videoengine.sx = k2 - dda + diff; - s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start; - } else { - s3->videoengine.sx = k2 - dda + diff - 1; - s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start - 1; - } - s3->videoengine.sx_scale_inc = (double)((s3->videoengine.sx_backup >> 1)); - s3->videoengine.sx_scale_inc = s3->videoengine.sx_scale_inc / (double)((s3->videoengine.sx >> 1)); - } else { - s3->videoengine.sx_scale = (double)(s3->videoengine.k1 - 2); - s3->videoengine.sx_scale_dec = (s3->videoengine.sx_scale / (double)(s3->videoengine.len - s3->videoengine.start - 2)); + if (s3->videoengine.input == 1) { + if (s3->videoengine.scale_down) { + if (s3->bpp > 1) { + s3->videoengine.sx = k2 - dda + diff; + s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start; + } else { + s3->videoengine.sx = k2 - dda + diff - 1; + s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start - 1; + } + s3->videoengine.sx_scale_inc = (double) ((s3->videoengine.sx_backup >> 1)); + s3->videoengine.sx_scale_inc = s3->videoengine.sx_scale_inc / (double) ((s3->videoengine.sx >> 1)); + } else { + s3->videoengine.sx_scale = (double) (s3->videoengine.k1 - 2); + s3->videoengine.sx_scale_dec = (s3->videoengine.sx_scale / (double) (s3->videoengine.len - s3->videoengine.start - 2)); - if (s3->videoengine.sx_scale_dec >= 0.5) { - s3->videoengine.sx_scale++; - } - } + if (s3->videoengine.sx_scale_dec >= 0.5) { + s3->videoengine.sx_scale++; + } + } - if (s3->bpp == 0) { - s3->videoengine.dest = s3->videoengine.dest_base + s3->width; - s3->videoengine.src = s3->videoengine.src_base + s3->width; - } else if (s3->bpp == 1) { - s3->videoengine.dest = (s3->videoengine.dest_base >> 1) + s3->width; - s3->videoengine.src = (s3->videoengine.src_base >> 1) + s3->width; - } else { - s3->videoengine.dest = (s3->videoengine.dest_base >> 2) + s3->width; - s3->videoengine.src = (s3->videoengine.src_base >> 2) + s3->width; - } - s3->videoengine.input = 2; - s3->videoengine.cx = 0.0; - s3->videoengine.dx = 0.0; - } + if (s3->bpp == 0) { + s3->videoengine.dest = s3->videoengine.dest_base + s3->width; + s3->videoengine.src = s3->videoengine.src_base + s3->width; + } else if (s3->bpp == 1) { + s3->videoengine.dest = (s3->videoengine.dest_base >> 1) + s3->width; + s3->videoengine.src = (s3->videoengine.src_base >> 1) + s3->width; + } else { + s3->videoengine.dest = (s3->videoengine.dest_base >> 2) + s3->width; + s3->videoengine.src = (s3->videoengine.src_base >> 2) + s3->width; + } + s3->videoengine.input = 2; + s3->videoengine.cx = 0.0; + s3->videoengine.dx = 0.0; + } - while (count) { - if (host) { /*Source data is CPU*/ - src = cpu_dat; - } else { /*Source data is display memory*/ - READ(s3->videoengine.src + lround(s3->videoengine.cx), src); - } + while (count) { + if (host) { /*Source data is CPU*/ + src = cpu_dat; + } else { /*Source data is display memory*/ + READ(s3->videoengine.src + lround(s3->videoengine.cx), src); + } - convert_to_rgb32(idf, is_yuv, src, &r, &g, &b, &r2, &g2, &b2); + convert_to_rgb32(idf, is_yuv, src, &r, &g, &b, &r2, &g2, &b2); - convert_from_rgb32(idf, odf, is_yuv, &dest, r, g, b, r2, g2, b2); + convert_from_rgb32(idf, odf, is_yuv, &dest, r, g, b, r2, g2, b2); - WRITE(s3->videoengine.dest + lround(s3->videoengine.dx), dest); + WRITE(s3->videoengine.dest + lround(s3->videoengine.dx), dest); - if (s3->videoengine.scale_down) { /*Data shrink*/ - s3->videoengine.dx += s3->videoengine.sx_scale_inc; - if (!host) - s3->videoengine.cx += s3->videoengine.sx_scale_inc; + if (s3->videoengine.scale_down) { /*Data shrink*/ + s3->videoengine.dx += s3->videoengine.sx_scale_inc; + if (!host) + s3->videoengine.cx += s3->videoengine.sx_scale_inc; - s3->videoengine.sx--; + s3->videoengine.sx--; - if (host) { - if (s3->bpp == 0) { - cpu_dat >>= 8; - } else { - cpu_dat >>= 16; - } - count--; - } + if (host) { + if (s3->bpp == 0) { + cpu_dat >>= 8; + } else { + cpu_dat >>= 16; + } + count--; + } - if (s3->videoengine.sx < 0) { - if (s3->bpp > 1) { - s3->videoengine.sx = k2 - dda + diff; - s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start; - } else { - s3->videoengine.sx = k2 - dda + diff - 1; - s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start - 1; - } - s3->videoengine.sx_scale_inc = (double)((s3->videoengine.sx_backup >> 1)); - s3->videoengine.sx_scale_inc = s3->videoengine.sx_scale_inc / (double)((s3->videoengine.sx >> 1)); + if (s3->videoengine.sx < 0) { + if (s3->bpp > 1) { + s3->videoengine.sx = k2 - dda + diff; + s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start; + } else { + s3->videoengine.sx = k2 - dda + diff - 1; + s3->videoengine.sx_backup = s3->videoengine.len - s3->videoengine.start - 1; + } + s3->videoengine.sx_scale_inc = (double) ((s3->videoengine.sx_backup >> 1)); + s3->videoengine.sx_scale_inc = s3->videoengine.sx_scale_inc / (double) ((s3->videoengine.sx >> 1)); - s3->videoengine.cx = 0.0; - s3->videoengine.dx = 0.0; + s3->videoengine.cx = 0.0; + s3->videoengine.dx = 0.0; - if (s3->bpp == 0) { - s3->videoengine.dest = s3->videoengine.dest_base + s3->width; - s3->videoengine.src = s3->videoengine.src_base + s3->width; - } else if (s3->bpp == 1) { - s3->videoengine.dest = (s3->videoengine.dest_base >> 1) + s3->width; - s3->videoengine.src = (s3->videoengine.src_base >> 1) + s3->width; - } else { - s3->videoengine.dest = (s3->videoengine.dest_base >> 2) + s3->width; - s3->videoengine.src = (s3->videoengine.src_base >> 2) + s3->width; - } + if (s3->bpp == 0) { + s3->videoengine.dest = s3->videoengine.dest_base + s3->width; + s3->videoengine.src = s3->videoengine.src_base + s3->width; + } else if (s3->bpp == 1) { + s3->videoengine.dest = (s3->videoengine.dest_base >> 1) + s3->width; + s3->videoengine.src = (s3->videoengine.src_base >> 1) + s3->width; + } else { + s3->videoengine.dest = (s3->videoengine.dest_base >> 2) + s3->width; + s3->videoengine.src = (s3->videoengine.src_base >> 2) + s3->width; + } - if (s3->videoengine.input >= 1) { - s3->videoengine.busy = 0; - return; - } - } - } else { /*Data stretch*/ - s3->videoengine.dx++; + if (s3->videoengine.input >= 1) { + s3->videoengine.busy = 0; + return; + } + } + } else { /*Data stretch*/ + s3->videoengine.dx++; - s3->videoengine.sx_scale -= s3->videoengine.sx_scale_dec; - s3->videoengine.sx_scale_backup = (s3->videoengine.sx_scale - s3->videoengine.sx_scale_dec); + s3->videoengine.sx_scale -= s3->videoengine.sx_scale_dec; + s3->videoengine.sx_scale_backup = (s3->videoengine.sx_scale - s3->videoengine.sx_scale_dec); - s3->videoengine.sx = lround(s3->videoengine.sx_scale); - s3->videoengine.sx_scale_int = lround(s3->videoengine.sx_scale_backup); + s3->videoengine.sx = lround(s3->videoengine.sx_scale); + s3->videoengine.sx_scale_int = lround(s3->videoengine.sx_scale_backup); - if (s3->videoengine.sx > s3->videoengine.sx_scale_int) { - if (host) { - if (s3->bpp == 0) - cpu_dat >>= 8; - else - cpu_dat >>= 16; - count--; - } else { - s3->videoengine.cx++; - } - } + if (s3->videoengine.sx > s3->videoengine.sx_scale_int) { + if (host) { + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + count--; + } else { + s3->videoengine.cx++; + } + } - if (s3->videoengine.sx < 0) { - s3->videoengine.sx_scale = (double)(s3->videoengine.k1 - 2); - s3->videoengine.sx_scale_dec = (s3->videoengine.sx_scale / (double)(s3->videoengine.len - s3->videoengine.start - 2)); + if (s3->videoengine.sx < 0) { + s3->videoengine.sx_scale = (double) (s3->videoengine.k1 - 2); + s3->videoengine.sx_scale_dec = (s3->videoengine.sx_scale / (double) (s3->videoengine.len - s3->videoengine.start - 2)); - if (s3->videoengine.sx_scale_dec >= 0.5) { - s3->videoengine.sx_scale++; - } + if (s3->videoengine.sx_scale_dec >= 0.5) { + s3->videoengine.sx_scale++; + } - s3->videoengine.cx = 0.0; - s3->videoengine.dx = 0.0; + s3->videoengine.cx = 0.0; + s3->videoengine.dx = 0.0; - if (s3->bpp == 0) { - s3->videoengine.dest = s3->videoengine.dest_base + s3->width; - s3->videoengine.src = s3->videoengine.src_base + s3->width; - } else if (s3->bpp == 1) { - s3->videoengine.dest = (s3->videoengine.dest_base >> 1) + s3->width; - s3->videoengine.src = (s3->videoengine.src_base >> 1) + s3->width; - } else { - s3->videoengine.dest = (s3->videoengine.dest_base >> 2) + s3->width; - s3->videoengine.src = (s3->videoengine.src_base >> 2) + s3->width; - } + if (s3->bpp == 0) { + s3->videoengine.dest = s3->videoengine.dest_base + s3->width; + s3->videoengine.src = s3->videoengine.src_base + s3->width; + } else if (s3->bpp == 1) { + s3->videoengine.dest = (s3->videoengine.dest_base >> 1) + s3->width; + s3->videoengine.src = (s3->videoengine.src_base >> 1) + s3->width; + } else { + s3->videoengine.dest = (s3->videoengine.dest_base >> 2) + s3->width; + s3->videoengine.src = (s3->videoengine.src_base >> 2) + s3->width; + } - if (s3->videoengine.input >= 1) { - s3->videoengine.busy = 0; - return; - } - } - } - } + if (s3->videoengine.input >= 1) { + s3->videoengine.busy = 0; + return; + } + } + } + } } void s3_short_stroke_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3, uint8_t ssv) { - if (!cpu_input) { - s3->accel.ssv_len = ssv & 0x0f; - s3->accel.ssv_dir = ssv & 0xe0; - s3->accel.ssv_draw = ssv & 0x10; + if (!cpu_input) { + s3->accel.ssv_len = ssv & 0x0f; + s3->accel.ssv_dir = ssv & 0xe0; + s3->accel.ssv_draw = ssv & 0x10; - if (s3_cpu_src(s3)) { - return; /*Wait for data from CPU*/ - } - } + if (s3_cpu_src(s3)) { + return; /*Wait for data from CPU*/ + } + } - s3_accel_start(count, cpu_input, mix_dat, cpu_dat, s3); + s3_accel_start(count, cpu_input, mix_dat, cpu_dat, s3); } void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) { - svga_t *svga = &s3->svga; - uint32_t src_dat = 0, dest_dat, old_dest_dat; - uint32_t out, pat_dat = 0; - int frgd_mix, bkgd_mix; - int clip_t = s3->accel.multifunc[1] & 0xfff; - int clip_l = s3->accel.multifunc[2] & 0xfff; - int clip_b = s3->accel.multifunc[3] & 0xfff; - int clip_r = s3->accel.multifunc[4] & 0xfff; - int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; - uint32_t mix_mask = 0; - uint16_t *vram_w = (uint16_t *)svga->vram; - uint32_t *vram_l = (uint32_t *)svga->vram; - uint32_t compare = s3->accel.color_cmp; - uint8_t rop = s3->accel.ropmix & 0xff; - int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; - uint32_t rd_mask = s3->accel.rd_mask; - int cmd = s3->accel.cmd >> 13; - uint32_t srcbase, dstbase; - - if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) { - cmd |= 8; - } - - // SRC-BASE/DST-BASE - if ((s3->accel.multifunc[0xd] >> 4) & 7) { - srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); - } else { - srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); - } - if ((s3->accel.multifunc[0xd] >> 0) & 7) { - dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); - } else { - dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); - } - if (s3->bpp == 1) { - srcbase >>= 1; - dstbase >>= 1; - } else if (s3->bpp == 3) { - srcbase >>= 2; - dstbase >>= 2; - } - - if ((s3->accel.cmd & 0x100) && ((s3_cpu_src(s3) || (s3_cpu_dest(s3)))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) { - s3->force_busy = 1; - } - - if (!cpu_input) - s3->accel.dat_count = 0; - - if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { - if ((s3->bpp == 3) && count == 2) { - if (s3->accel.dat_count) { - cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; - count = 4; - s3->accel.dat_count = 0; - } else { - s3->accel.dat_buf = cpu_dat & 0xffff; - s3->accel.dat_count = 1; - } - } - if (s3->bpp == 1 || s3->color_16bit) - count >>= 1; - if (s3->bpp == 3) - count >>= 2; - } - - if (s3->bpp == 0 && !s3->color_16bit) - rd_mask &= 0xff; - else if (s3->bpp == 1 || s3->color_16bit) - rd_mask &= 0xffff; - - if (s3->bpp == 0 && !s3->color_16bit) compare &= 0xff; - if (s3->bpp == 1 || s3->color_16bit) compare &= 0xffff; - - switch (s3->accel.cmd & 0x600) - { - case 0x000: mix_mask = 0x80; break; - case 0x200: mix_mask = 0x8000; break; - case 0x400: mix_mask = 0x80000000; break; - case 0x600: mix_mask = (s3->chip == S3_TRIO32 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) ? 0x80 : 0x80000000; break; - } - - /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. - When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on - the NOP command)*/ - switch (cmd) - { - case 0: /*NOP (Short Stroke Vectors)*/ - if (s3->accel.ssv_state == 0) - break; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.cmd & 8) /*Radial*/ - { - while (count-- && s3->accel.ssv_len >= 0) - { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) - { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - if (s3->accel.ssv_draw) { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - if (!s3->accel.ssv_len) - break; - - switch (s3->accel.ssv_dir & 0xe0) - { - case 0x00: s3->accel.cx++; break; - case 0x20: s3->accel.cx++; s3->accel.cy--; break; - case 0x40: s3->accel.cy--; break; - case 0x60: s3->accel.cx--; s3->accel.cy--; break; - case 0x80: s3->accel.cx--; break; - case 0xa0: s3->accel.cx--; s3->accel.cy++; break; - case 0xc0: s3->accel.cy++; break; - case 0xe0: s3->accel.cx++; s3->accel.cy++; break; - } - - s3->accel.ssv_len--; - } - - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - break; - - case 1: /*Draw line*/ - if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; - - s3->accel.sy = s3->accel.maj_axis_pcnt; - - if (s3_cpu_src(s3)) { - return; /*Wait for data from CPU*/ - } - } - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.cmd & 8) /*Radial*/ - { - while (count-- && s3->accel.sy >= 0) - { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) - { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0 && !s3->color_16bit) - cpu_dat >>= 8; - else { - cpu_dat >>= 16; - } - - if (!s3->accel.sy) { - break; - } - - switch (s3->accel.cmd & 0xe0) - { - case 0x00: s3->accel.cx++; break; - case 0x20: s3->accel.cx++; s3->accel.cy--; break; - case 0x40: s3->accel.cy--; break; - case 0x60: s3->accel.cx--; s3->accel.cy--; break; - case 0x80: s3->accel.cx--; break; - case 0xa0: s3->accel.cx--; s3->accel.cy++; break; - case 0xc0: s3->accel.cy++; break; - case 0xe0: s3->accel.cx++; s3->accel.cy++; break; - } - s3->accel.sy--; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - else /*Bresenham*/ - { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ - count = s3->accel.maj_axis_pcnt + 1; - s3->accel.temp_cnt = 16; - } - - while (count-- && s3->accel.sy >= 0) - { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { - mix_dat >>= 16; - s3->accel.temp_cnt = 16; - } - - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) - { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; break; - } - - if ((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) - { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } - } - - if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { - if (s3->accel.temp_cnt > 0) { - s3->accel.temp_cnt--; - mix_dat <<= 1; - mix_dat |= 1; - } - } else { - mix_dat <<= 1; - mix_dat |= 1; - } - if (s3->bpp == 0 && !s3->color_16bit) - cpu_dat >>= 8; - else { - cpu_dat >>= 16; - } - - if (!s3->accel.sy) { - break; - } - - if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { - s3->accel.err_term += s3->accel.destx_distp; - /*Step minor axis*/ - switch (s3->accel.cmd & 0xe0) - { - case 0x00: s3->accel.cy--; break; - case 0x20: s3->accel.cy--; break; - case 0x40: s3->accel.cx--; break; - case 0x60: s3->accel.cx++; break; - case 0x80: s3->accel.cy++; break; - case 0xa0: s3->accel.cy++; break; - case 0xc0: s3->accel.cx--; break; - case 0xe0: s3->accel.cx++; break; - } - } else { - s3->accel.err_term += s3->accel.desty_axstp; - } - - /*Step major axis*/ - switch (s3->accel.cmd & 0xe0) - { - case 0x00: s3->accel.cx--; break; - case 0x20: s3->accel.cx++; break; - case 0x40: s3->accel.cy--; break; - case 0x60: s3->accel.cy--; break; - case 0x80: s3->accel.cx--; break; - case 0xa0: s3->accel.cx++; break; - case 0xc0: s3->accel.cy++; break; - case 0xe0: s3->accel.cy++; break; - } - s3->accel.sy--; - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - break; - - case 2: /*Rectangle fill*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x; - s3->accel.cy = s3->accel.cur_y; - - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bit12) { - if (s3->accel.cy <= 0x7ff) { - s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; - } else { - s3->accel.cy |= ~0xfff; - } - } - - s3->accel.dest = dstbase + s3->accel.cy * s3->width; - - if (s3_cpu_src(s3)) { - s3->data_available = 0; - return; /*Wait for data from CPU*/ - } else if (s3_cpu_dest(s3)) { - s3->data_available = 1; - return; - } - } - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ - count = s3->accel.maj_axis_pcnt + 1; - s3->accel.temp_cnt = 16; - } - - while (count-- && s3->accel.sy >= 0) - { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { - mix_dat >>= 16; - s3->accel.temp_cnt = 16; - } - - if (((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b)) - { - if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (s3_cpu_dest(s3) && vram_mask) { - /* Mix data = current video memory value. */ - READ(s3->accel.dest + s3->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - - if (s3_cpu_dest(s3)) { - READ(s3->accel.dest + s3->accel.cx, src_dat); - if (vram_mask) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; break; - } - - if (((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) - { - READ(s3->accel.dest + s3->accel.cx, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.cx, dest_dat); - } - } - } - - if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { - if (s3->accel.temp_cnt > 0) { - s3->accel.temp_cnt--; - mix_dat <<= 1; - mix_dat |= 1; - } - } else { - mix_dat <<= 1; - mix_dat |= 1; - } - - if (s3->bpp == 0 && !s3->color_16bit) - cpu_dat >>= 8; - else { - cpu_dat >>= 16; - } - - if (s3->accel.cmd & 0x20) - s3->accel.cx++; - else - s3->accel.cx--; - - s3->accel.sx--; - if (s3->accel.sx < 0) - { - if (s3->accel.cmd & 0x20) - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - else - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) - s3->accel.cy++; - else - s3->accel.cy--; - - s3->accel.dest = dstbase + s3->accel.cy * s3->width; - s3->accel.sy--; - - if (cpu_input) { - if (s3->accel.b2e8_pix) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - return; - } - if (s3->accel.sy < 0) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - return; - } - } - } - break; - - - case 3: /*Polygon Fill Solid (Vision868/968 and Trio64 only)*/ - { - int end_y1, end_y2; - - if (s3->chip != S3_TRIO64 && s3->chip != S3_VISION968 && s3->chip != S3_VISION868) - break; - - polygon_setup(s3); - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - end_y1 = s3->accel.desty_axstp; - end_y2 = s3->accel.desty_axstp2; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) - { - int y = s3->accel.poly_cy; - int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - - s3->accel.dest = dstbase + y * s3->width; - - while (x_count-- && count--) - { - if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && - (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) - { - switch (frgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: src_dat = 0; /*Not supported?*/ break; - } - - if (((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) - { - READ(s3->accel.dest + s3->accel.poly_x, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); - } - } - } - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) - s3->accel.poly_x++; - else - s3->accel.poly_x--; - } - - s3->accel.poly_cx += s3->accel.poly_dx1; - s3->accel.poly_cx2 += s3->accel.poly_dx2; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - - s3->accel.poly_cy++; - s3->accel.poly_cy2++; - - if (!count) - break; - } - - s3->accel.cur_x = s3->accel.poly_cx & 0xfff; - s3->accel.cur_y = s3->accel.poly_cy & 0xfff; - s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; - s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; - } - break; - - - case 6: /*BitBlt*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x; - s3->accel.cy = s3->accel.cur_y; - - if (s3->accel.destx_distp >= 0xfffff000) { /* avoid overflow */ - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bitres > 0xfff) - s3->accel.cy = s3->accel.cur_y_bitres; - } else { - if (s3->accel.cur_x_bit12) { - if (s3->accel.cx <= 0x7ff) { /* overlap x */ - s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; - } else { /* x end is negative */ - s3->accel.cx |= ~0xfff; - } - } - if (s3->accel.cur_y_bit12) { - if (s3->accel.cy <= 0x7ff) { /* overlap y */ - s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; - } else { /* y end is negative */ - s3->accel.cy |= ~0xfff; - } - } - } - - s3->accel.src = srcbase + s3->accel.cy * s3->width; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) { - return; /*Wait for data from CPU*/ - } - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && - (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && - (s3->accel.bkgd_mix & 0xf) == 7) - { - while (1) - { - if (((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) - { - READ(s3->accel.src + s3->accel.cx, src_dat); - READ(s3->accel.dest + s3->accel.dx, dest_dat); - - dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); - - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); - } - } - - s3->accel.cx++; - s3->accel.dx++; - s3->accel.sx--; - if (s3->accel.sx < 0) - { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - s3->accel.cy++; - s3->accel.dy++; - - s3->accel.src = srcbase + s3->accel.cy * s3->width; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (s3->accel.sy < 0) { - return; - } - } - } - } - else - { - while (count-- && s3->accel.sy >= 0) - { - /*This is almost required by OS/2's software cursor or we will risk writing/reading garbage around it.*/ - if ((s3->accel.dx) >= clip_l && (s3->accel.dx) <= clip_r && - ((s3->accel.dy) >= clip_t && (s3->accel.dy) <= clip_b)) - { - if (vram_mask && (s3->accel.cmd & 0x10)) - { - READ(s3->accel.src + s3->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: READ(s3->accel.src + s3->accel.cx, src_dat); - if (vram_mask && (s3->accel.cmd & 0x10)) - src_dat = ((src_dat & rd_mask) == rd_mask); - break; - } - - if ((((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2))) - { - READ(s3->accel.dest + s3->accel.dx, dest_dat); - - MIX - - if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) { - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - - if (s3->bpp == 0 && !s3->color_16bit) - cpu_dat >>= 8; - else { - cpu_dat >>= 16; - } - - if (s3->accel.cmd & 0x20) - { - s3->accel.cx++; - s3->accel.dx++; - } - else - { - s3->accel.cx--; - s3->accel.dx--; - } - s3->accel.sx--; - if (s3->accel.sx < 0) - { - if (s3->accel.cmd & 0x20) - { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - else - { - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) - { - s3->accel.cy++; - s3->accel.dy++; - } - else - { - s3->accel.cy--; - s3->accel.dy--; - } - - s3->accel.src = srcbase + s3->accel.cy * s3->width; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (cpu_input) { - return; - } - - if (s3->accel.sy < 0) { - return; - } - } - } - } - break; - - case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; - - /*Align source with destination*/ - s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.cx = s3->accel.dx & 7; - s3->accel.cy = s3->accel.dy & 7; - - s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) { - return; /*Wait for data from CPU*/ - } - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while (count-- && s3->accel.sy >= 0) - { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) - { - if (vram_mask) - { - READ(s3->accel.src + s3->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: READ(s3->accel.src + s3->accel.cx, src_dat); - if (vram_mask) - src_dat = ((src_dat & rd_mask) == rd_mask); - break; - } - - if (((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) - { - READ(s3->accel.dest + s3->accel.dx, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.dx, dest_dat); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) - { - s3->accel.cx = ((s3->accel.cx + 1) & 7) | (s3->accel.cx & ~7); - s3->accel.dx++; - } - else - { - s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); - s3->accel.dx--; - } - s3->accel.sx--; - if (s3->accel.sx < 0) - { - if (s3->accel.cmd & 0x20) - { - s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - else - { - s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) - { - s3->accel.cy = ((s3->accel.cy + 1) & 7) | (s3->accel.cy & ~7); - s3->accel.dy++; - } - else - { - s3->accel.cy = ((s3->accel.cy - 1) & 7) | (s3->accel.cy & ~7); - s3->accel.dy--; - } - - s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); - s3->accel.dest = dstbase + s3->accel.dy * s3->width; - - s3->accel.sy--; - - if (cpu_input) { - return; - } - if (s3->accel.sy < 0) { - return; - } - } - } - break; - - case 9: /*Polyline/2-Point Line (Vision868/968 and Trio64 only)*/ - { - int error; - - if (s3->chip != S3_TRIO64 && s3->chip != S3_VISION968 && s3->chip != S3_VISION868) - break; - - if (!cpu_input) { - s3->accel.dx = ABS(s3->accel.destx_distp - s3->accel.cur_x); - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; - s3->accel.dy = ABS(s3->accel.desty_axstp - s3->accel.cur_y); - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x; - if (s3->accel.cur_x_bit12) - s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y; - if (s3->accel.cur_y_bit12) - s3->accel.cy |= ~0xfff; - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - if (s3->accel.dx > s3->accel.dy) { - error = s3->accel.dx / 2; - while (s3->accel.cx != s3->accel.destx_distp && count--) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) - { - src_dat = s3->accel.frgd_color; - - if (((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2) && (s3->accel.cmd & 0x10)) - { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } - } - } - - error -= s3->accel.dy; - if (error < 0) { - error += s3->accel.dx; - if (s3->accel.desty_axstp > s3->accel.cur_y) - s3->accel.cy++; - else - s3->accel.cy--; - } - - if (s3->accel.destx_distp > s3->accel.cur_x) - s3->accel.cx++; - else - s3->accel.cx--; - } - } else { - error = s3->accel.dy / 2; - while (s3->accel.cy != s3->accel.desty_axstp && count--) { - if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && - (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) - { - src_dat = s3->accel.frgd_color; - - if (((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) - { - READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); - } - } - } - - error -= s3->accel.dx; - if (error < 0) { - error += s3->accel.dy; - if (s3->accel.destx_distp > s3->accel.cur_x) - s3->accel.cx++; - else - s3->accel.cx--; - } - if (s3->accel.desty_axstp > s3->accel.cur_y) - s3->accel.cy++; - else - s3->accel.cy--; - - } - } - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; - } - break; - - - case 11: /*Polygon Fill Pattern (Vision868/968 and Trio64 only)*/ - { - int end_y1, end_y2; - - if (s3->chip != S3_TRIO64 && s3->chip != S3_VISION968 && s3->chip != S3_VISION868) - break; - - polygon_setup(s3); - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - end_y1 = s3->accel.desty_axstp; - end_y2 = s3->accel.desty_axstp2; - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) - { - int y = s3->accel.poly_cy; - int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; - - s3->accel.src = srcbase + s3->accel.pattern + ((y & 7) * s3->width); - s3->accel.dest = dstbase + y * s3->width; - - while (x_count-- && count--) - { - int pat_x = s3->accel.poly_x & 7; - - if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && - (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) - { - if (vram_mask) { - READ(s3->accel.src + pat_x, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: READ(s3->accel.src + pat_x, src_dat); - if (vram_mask) - src_dat = ((src_dat & rd_mask) == rd_mask); - break; - } - - if (((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) - { - READ(s3->accel.dest + s3->accel.poly_x, dest_dat); - - MIX - - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); - } - } - } - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - mix_dat <<= 1; - mix_dat |= 1; - - if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) - s3->accel.poly_x++; - else - s3->accel.poly_x--; - } - - s3->accel.poly_cx += s3->accel.poly_dx1; - s3->accel.poly_cx2 += s3->accel.poly_dx2; - s3->accel.poly_x = s3->accel.poly_cx >> 20; - - s3->accel.poly_cy++; - s3->accel.poly_cy2++; - - if (!count) - break; - } - - s3->accel.cur_x = s3->accel.poly_cx & 0xfff; - s3->accel.cur_y = s3->accel.poly_cy & 0xfff; - s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; - s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; - } - break; - - case 14: /*ROPBlt (Vision868/968 only)*/ - if (s3->chip != S3_VISION968 && s3->chip != S3_VISION868) - break; - - if (!cpu_input) /*!cpu_input is trigger to start operation*/ - { - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - - s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) s3->accel.dx |= ~0xfff; - s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) s3->accel.dy |= ~0xfff; - - s3->accel.cx = s3->accel.cur_x & 0xfff; - if (s3->accel.cur_x_bit12) s3->accel.cx |= ~0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cur_y_bit12) s3->accel.cy |= ~0xfff; - - s3->accel.px = s3->accel.pat_x & 0xfff; - if (s3->accel.pat_x & 0x1000) s3->accel.px |= ~0xfff; - s3->accel.py = s3->accel.pat_y & 0xfff; - if (s3->accel.pat_y & 0x1000) s3->accel.py |= ~0xfff; - - s3->accel.dest = dstbase + (s3->accel.dy * s3->width); - s3->accel.src = srcbase + (s3->accel.cy * s3->width); - s3->accel.pattern = (s3->accel.py * s3->width); - } - - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - - while (count-- && s3->accel.sy >= 0) - { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && - (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) - { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: src_dat = s3->accel.bkgd_color; break; - case 1: src_dat = s3->accel.frgd_color; break; - case 2: src_dat = cpu_dat; break; - case 3: READ(s3->accel.src + s3->accel.cx, src_dat); break; - } - - if (s3->accel.ropmix & 0x100) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: pat_dat = s3->accel.pat_bg_color; break; - case 1: pat_dat = s3->accel.pat_fg_color; break; - case 2: pat_dat = cpu_dat; break; - case 3: READ(s3->accel.pattern + s3->accel.px, pat_dat); break; - } - } else { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) - { - case 0: pat_dat = s3->accel.bkgd_color; break; - case 1: pat_dat = s3->accel.frgd_color; break; - case 2: pat_dat = cpu_dat; break; - case 3: READ(s3->accel.pattern + s3->accel.px, pat_dat); break; - } - } - - if (((compare_mode == 2 && src_dat != compare) || - (compare_mode == 3 && src_dat == compare) || - compare_mode < 2)) - { - READ(s3->accel.dest + s3->accel.dx, dest_dat); - - ROPMIX - - if (s3->accel.cmd & 0x10) { - WRITE(s3->accel.dest + s3->accel.dx, out); - } - } - } - - mix_dat <<= 1; - mix_dat |= 1; - if (s3->bpp == 0) cpu_dat >>= 8; - else cpu_dat >>= 16; - - if (s3->accel.cmd & 0x20) - { - s3->accel.cx++; - s3->accel.dx++; - s3->accel.px++; - } - else - { - s3->accel.cx--; - s3->accel.dx--; - s3->accel.px--; - } - s3->accel.sx--; - if (s3->accel.sx < 0) - { - if (s3->accel.cmd & 0x20) - { - s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.px -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - else - { - s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - s3->accel.px += (s3->accel.maj_axis_pcnt & 0xfff) + 1; - } - s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - - if (s3->accel.cmd & 0x80) - { - s3->accel.cy++; - s3->accel.dy++; - s3->accel.py++; - } - else - { - s3->accel.cy--; - s3->accel.dy--; - s3->accel.py--; - } - - s3->accel.src = srcbase + (s3->accel.cy * s3->width); - s3->accel.dest = dstbase + (s3->accel.dy * s3->width); - s3->accel.pattern = (s3->accel.py * s3->width); - - s3->accel.sy--; - - if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; - if (s3->accel.sy < 0) { - return; - } - } - } - break; - } + svga_t *svga = &s3->svga; + uint32_t src_dat = 0, dest_dat, old_dest_dat; + uint32_t out, pat_dat = 0; + int frgd_mix, bkgd_mix; + int clip_t = s3->accel.multifunc[1] & 0xfff; + int clip_l = s3->accel.multifunc[2] & 0xfff; + int clip_b = s3->accel.multifunc[3] & 0xfff; + int clip_r = s3->accel.multifunc[4] & 0xfff; + int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; + uint32_t mix_mask = 0; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; + uint32_t compare = s3->accel.color_cmp; + uint8_t rop = s3->accel.ropmix & 0xff; + int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; + uint32_t rd_mask = s3->accel.rd_mask; + int cmd = s3->accel.cmd >> 13; + uint32_t srcbase, dstbase; + + if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) { + cmd |= 8; + } + + // SRC-BASE/DST-BASE + if ((s3->accel.multifunc[0xd] >> 4) & 7) { + srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); + } else { + srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); + } + if ((s3->accel.multifunc[0xd] >> 0) & 7) { + dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); + } else { + dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); + } + if (s3->bpp == 1) { + srcbase >>= 1; + dstbase >>= 1; + } else if (s3->bpp == 3) { + srcbase >>= 2; + dstbase >>= 2; + } + + if ((s3->accel.cmd & 0x100) && ((s3_cpu_src(s3) || (s3_cpu_dest(s3)))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) { + s3->force_busy = 1; + } + + if (!cpu_input) + s3->accel.dat_count = 0; + + if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { + if ((s3->bpp == 3) && count == 2) { + if (s3->accel.dat_count) { + cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; + count = 4; + s3->accel.dat_count = 0; + } else { + s3->accel.dat_buf = cpu_dat & 0xffff; + s3->accel.dat_count = 1; + } + } + if (s3->bpp == 1 || s3->color_16bit) + count >>= 1; + if (s3->bpp == 3) + count >>= 2; + } + + if (s3->bpp == 0 && !s3->color_16bit) + rd_mask &= 0xff; + else if (s3->bpp == 1 || s3->color_16bit) + rd_mask &= 0xffff; + + if (s3->bpp == 0 && !s3->color_16bit) + compare &= 0xff; + if (s3->bpp == 1 || s3->color_16bit) + compare &= 0xffff; + + switch (s3->accel.cmd & 0x600) { + case 0x000: + mix_mask = 0x80; + break; + case 0x200: + mix_mask = 0x8000; + break; + case 0x400: + mix_mask = 0x80000000; + break; + case 0x600: + mix_mask = (s3->chip == S3_TRIO32 || s3->chip >= S3_TRIO64V || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) ? 0x80 : 0x80000000; + break; + } + + /*Bit 4 of the Command register is the draw yes bit, which enables writing to memory/reading from memory when enabled. + When this bit is disabled, no writing to memory/reading from memory is allowed. (This bit is almost meaningless on + the NOP command)*/ + switch (cmd) { + case 0: /*NOP (Short Stroke Vectors)*/ + if (s3->accel.ssv_state == 0) + break; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) /*Radial*/ + { + while (count-- && s3->accel.ssv_len >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.ssv_draw) + { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + if (!s3->accel.ssv_len) + break; + + switch (s3->accel.ssv_dir & 0xe0) { + case 0x00: + s3->accel.cx++; + break; + case 0x20: + s3->accel.cx++; + s3->accel.cy--; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cx--; + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx--; + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cx++; + s3->accel.cy++; + break; + } + + s3->accel.ssv_len--; + } + + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + + case 1: /*Draw line*/ + if (!cpu_input) { + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x_bit12) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y_bit12) + s3->accel.cy |= ~0xfff; + + s3->accel.sy = s3->accel.maj_axis_pcnt; + + if (s3_cpu_src(s3)) { + return; /*Wait for data from CPU*/ + } + } + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.cmd & 8) /*Radial*/ + { + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else { + cpu_dat >>= 16; + } + + if (!s3->accel.sy) { + break; + } + + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx++; + break; + case 0x20: + s3->accel.cx++; + s3->accel.cy--; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cx--; + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx--; + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cx++; + s3->accel.cy++; + break; + } + s3->accel.sy--; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } else /*Bresenham*/ + { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + count = s3->accel.maj_axis_pcnt + 1; + s3->accel.temp_cnt = 16; + } + + while (count-- && s3->accel.sy >= 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { + mix_dat >>= 16; + s3->accel.temp_cnt = 16; + } + + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } + + if ((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + + if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { + if (s3->accel.temp_cnt > 0) { + s3->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } else { + mix_dat <<= 1; + mix_dat |= 1; + } + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else { + cpu_dat >>= 16; + } + + if (!s3->accel.sy) { + break; + } + + if (s3->accel.err_term >= s3->accel.maj_axis_pcnt) { + s3->accel.err_term += s3->accel.destx_distp; + /*Step minor axis*/ + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cy--; + break; + case 0x20: + s3->accel.cy--; + break; + case 0x40: + s3->accel.cx--; + break; + case 0x60: + s3->accel.cx++; + break; + case 0x80: + s3->accel.cy++; + break; + case 0xa0: + s3->accel.cy++; + break; + case 0xc0: + s3->accel.cx--; + break; + case 0xe0: + s3->accel.cx++; + break; + } + } else { + s3->accel.err_term += s3->accel.desty_axstp; + } + + /*Step major axis*/ + switch (s3->accel.cmd & 0xe0) { + case 0x00: + s3->accel.cx--; + break; + case 0x20: + s3->accel.cx++; + break; + case 0x40: + s3->accel.cy--; + break; + case 0x60: + s3->accel.cy--; + break; + case 0x80: + s3->accel.cx--; + break; + case 0xa0: + s3->accel.cx++; + break; + case 0xc0: + s3->accel.cy++; + break; + case 0xe0: + s3->accel.cy++; + break; + } + s3->accel.sy--; + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + + case 2: /*Rectangle fill*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + s3->accel.cx = s3->accel.cur_x; + s3->accel.cy = s3->accel.cur_y; + + if (s3->accel.cur_x_bit12) { + if (s3->accel.cx <= 0x7ff) { + s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; + } else { + s3->accel.cx |= ~0xfff; + } + } + if (s3->accel.cur_y_bit12) { + if (s3->accel.cy <= 0x7ff) { + s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; + } else { + s3->accel.cy |= ~0xfff; + } + } + + s3->accel.dest = dstbase + s3->accel.cy * s3->width; + + if (s3_cpu_src(s3)) { + s3->data_available = 0; + return; /*Wait for data from CPU*/ + } else if (s3_cpu_dest(s3)) { + s3->data_available = 1; + return; + } + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + count = s3->accel.maj_axis_pcnt + 1; + s3->accel.temp_cnt = 16; + } + + while (count-- && s3->accel.sy >= 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { + mix_dat >>= 16; + s3->accel.temp_cnt = 16; + } + + if (((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b)) { + if (s3_cpu_dest(s3) && ((s3->accel.multifunc[0xa] & 0xc0) == 0x00)) { + mix_dat = mix_mask; /* Mix data = forced to foreground register. */ + } else if (s3_cpu_dest(s3) && vram_mask) { + /* Mix data = current video memory value. */ + READ(s3->accel.dest + s3->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + + if (s3_cpu_dest(s3)) { + READ(s3->accel.dest + s3->accel.cx, src_dat); + if (vram_mask) + src_dat = ((src_dat & rd_mask) == rd_mask); + } else + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } + + if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + READ(s3->accel.dest + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) + { + WRITE(s3->accel.dest + s3->accel.cx, dest_dat); + } + } + } + + if (s3->accel.b2e8_pix && s3_cpu_src(s3)) { + if (s3->accel.temp_cnt > 0) { + s3->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } else { + mix_dat <<= 1; + mix_dat |= 1; + } + + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else { + cpu_dat >>= 16; + } + + if (s3->accel.cmd & 0x20) + s3->accel.cx++; + else + s3->accel.cx--; + + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + else + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) + s3->accel.cy++; + else + s3->accel.cy--; + + s3->accel.dest = dstbase + s3->accel.cy * s3->width; + s3->accel.sy--; + + if (cpu_input) { + if (s3->accel.b2e8_pix) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + return; + } + if (s3->accel.sy < 0) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + return; + } + } + } + break; + + case 3: /*Polygon Fill Solid (Vision868/968 and Trio64 only)*/ + { + int end_y1, end_y2; + + if (s3->chip != S3_TRIO64 && s3->chip != S3_VISION968 && s3->chip != S3_VISION868) + break; + + polygon_setup(s3); + + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + + end_y1 = s3->accel.desty_axstp; + end_y2 = s3->accel.desty_axstp2; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + + while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { + int y = s3->accel.poly_cy; + int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; + + s3->accel.dest = dstbase + y * s3->width; + + while (x_count-- && count--) { + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { + switch (frgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; /*Not supported?*/ + break; + } + + if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + READ(s3->accel.dest + s3->accel.poly_x, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) + { + WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); + } + } + } + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) + s3->accel.poly_x++; + else + s3->accel.poly_x--; + } + + s3->accel.poly_cx += s3->accel.poly_dx1; + s3->accel.poly_cx2 += s3->accel.poly_dx2; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + + s3->accel.poly_cy++; + s3->accel.poly_cy2++; + + if (!count) + break; + } + + s3->accel.cur_x = s3->accel.poly_cx & 0xfff; + s3->accel.cur_y = s3->accel.poly_cy & 0xfff; + s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; + s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; + } + break; + + case 6: /*BitBlt*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.destx_distp & 0x1000) + s3->accel.dx |= ~0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + if (s3->accel.desty_axstp & 0x1000) + s3->accel.dy |= ~0xfff; + + s3->accel.cx = s3->accel.cur_x; + s3->accel.cy = s3->accel.cur_y; + + if (s3->accel.destx_distp >= 0xfffff000) { /* avoid overflow */ + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.cur_x_bit12) { + if (s3->accel.cx <= 0x7ff) { + s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; + } else { + s3->accel.cx |= ~0xfff; + } + } + if (s3->accel.cur_y_bitres > 0xfff) + s3->accel.cy = s3->accel.cur_y_bitres; + } else { + if (s3->accel.cur_x_bit12) { + if (s3->accel.cx <= 0x7ff) { /* overlap x */ + s3->accel.cx = s3->accel.cur_x_bitres & 0xfff; + } else { /* x end is negative */ + s3->accel.cx |= ~0xfff; + } + } + if (s3->accel.cur_y_bit12) { + if (s3->accel.cy <= 0x7ff) { /* overlap y */ + s3->accel.cy = s3->accel.cur_y_bitres & 0xfff; + } else { /* y end is negative */ + s3->accel.cy |= ~0xfff; + } + } + } + + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + } + + if ((s3->accel.cmd & 0x100) && !cpu_input) { + return; /*Wait for data from CPU*/ + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && (s3->accel.bkgd_mix & 0xf) == 7) { + while (1) { + if (((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b)) { + READ(s3->accel.src + s3->accel.cx, src_dat); + READ(s3->accel.dest + s3->accel.dx, dest_dat); + + dest_dat = (src_dat & s3->accel.wrt_mask) | (dest_dat & ~s3->accel.wrt_mask); + + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } + } + + s3->accel.cx++; + s3->accel.dx++; + s3->accel.sx--; + if (s3->accel.sx < 0) { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + s3->accel.cy++; + s3->accel.dy++; + + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (s3->accel.sy < 0) { + return; + } + } + } + } else { + while (count-- && s3->accel.sy >= 0) { + /*This is almost required by OS/2's software cursor or we will risk writing/reading garbage around it.*/ + if ((s3->accel.dx) >= clip_l && (s3->accel.dx) <= clip_r && ((s3->accel.dy) >= clip_t && (s3->accel.dy) <= clip_b)) { + if (vram_mask && (s3->accel.cmd & 0x10)) { + READ(s3->accel.src + s3->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(s3->accel.src + s3->accel.cx, src_dat); + if (vram_mask && (s3->accel.cmd & 0x10)) + src_dat = ((src_dat & rd_mask) == rd_mask); + break; + } + + if ((((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2))) { + READ(s3->accel.dest + s3->accel.dx, dest_dat); + + MIX + + if ((!(s3->accel.cmd & 0x10) && vram_mask) || (s3->accel.cmd & 0x10)) + { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + + if (s3->bpp == 0 && !s3->color_16bit) + cpu_dat >>= 8; + else { + cpu_dat >>= 16; + } + + if (s3->accel.cmd & 0x20) { + s3->accel.cx++; + s3->accel.dx++; + } else { + s3->accel.cx--; + s3->accel.dx--; + } + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } else { + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } + + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy++; + s3->accel.dy++; + } else { + s3->accel.cy--; + s3->accel.dy--; + } + + s3->accel.src = srcbase + s3->accel.cy * s3->width; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input) { + return; + } + + if (s3->accel.sy < 0) { + return; + } + } + } + } + break; + + case 7: /*Pattern fill - BitBlt but with source limited to 8x8*/ + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.destx_distp & 0x1000) + s3->accel.dx |= ~0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + if (s3->accel.desty_axstp & 0x1000) + s3->accel.dy |= ~0xfff; + + s3->accel.cx = s3->accel.cur_x & 0xfff; + if (s3->accel.cur_x_bit12) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->accel.cur_y_bit12) + s3->accel.cy |= ~0xfff; + + /*Align source with destination*/ + s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.cx = s3->accel.dx & 7; + s3->accel.cy = s3->accel.dy & 7; + + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + } + + if ((s3->accel.cmd & 0x100) && !cpu_input) { + return; /*Wait for data from CPU*/ + } + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + if (vram_mask) { + READ(s3->accel.src + s3->accel.cx, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(s3->accel.src + s3->accel.cx, src_dat); + if (vram_mask) + src_dat = ((src_dat & rd_mask) == rd_mask); + break; + } + + if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + READ(s3->accel.dest + s3->accel.dx, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) + { + WRITE(s3->accel.dest + s3->accel.dx, dest_dat); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx = ((s3->accel.cx + 1) & 7) | (s3->accel.cx & ~7); + s3->accel.dx++; + } else { + s3->accel.cx = ((s3->accel.cx - 1) & 7) | (s3->accel.cx & ~7); + s3->accel.dx--; + } + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) { + s3->accel.cx = ((s3->accel.cx - ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } else { + s3->accel.cx = ((s3->accel.cx + ((s3->accel.maj_axis_pcnt & 0xfff) + 1)) & 7) | (s3->accel.cx & ~7); + s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy = ((s3->accel.cy + 1) & 7) | (s3->accel.cy & ~7); + s3->accel.dy++; + } else { + s3->accel.cy = ((s3->accel.cy - 1) & 7) | (s3->accel.cy & ~7); + s3->accel.dy--; + } + + s3->accel.src = srcbase + s3->accel.pattern + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + s3->accel.dy * s3->width; + + s3->accel.sy--; + + if (cpu_input) { + return; + } + if (s3->accel.sy < 0) { + return; + } + } + } + break; + + case 9: /*Polyline/2-Point Line (Vision868/968 and Trio64 only)*/ + { + int error; + + if (s3->chip != S3_TRIO64 && s3->chip != S3_VISION968 && s3->chip != S3_VISION868) + break; + + if (!cpu_input) { + s3->accel.dx = ABS(s3->accel.destx_distp - s3->accel.cur_x); + if (s3->accel.destx_distp & 0x1000) + s3->accel.dx |= ~0xfff; + s3->accel.dy = ABS(s3->accel.desty_axstp - s3->accel.cur_y); + if (s3->accel.desty_axstp & 0x1000) + s3->accel.dy |= ~0xfff; + + s3->accel.cx = s3->accel.cur_x; + if (s3->accel.cur_x_bit12) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y; + if (s3->accel.cur_y_bit12) + s3->accel.cy |= ~0xfff; + } + + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + + if (s3->accel.dx > s3->accel.dy) { + error = s3->accel.dx / 2; + while (s3->accel.cx != s3->accel.destx_distp && count--) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + src_dat = s3->accel.frgd_color; + + if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2) && (s3->accel.cmd & 0x10)) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) + { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + } + + error -= s3->accel.dy; + if (error < 0) { + error += s3->accel.dx; + if (s3->accel.desty_axstp > s3->accel.cur_y) + s3->accel.cy++; + else + s3->accel.cy--; + } + + if (s3->accel.destx_distp > s3->accel.cur_x) + s3->accel.cx++; + else + s3->accel.cx--; + } + } else { + error = s3->accel.dy / 2; + while (s3->accel.cy != s3->accel.desty_axstp && count--) { + if ((s3->accel.cx & 0xfff) >= clip_l && (s3->accel.cx & 0xfff) <= clip_r && (s3->accel.cy & 0xfff) >= clip_t && (s3->accel.cy & 0xfff) <= clip_b) { + src_dat = s3->accel.frgd_color; + + if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) + { + WRITE((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); + } + } + } + + error -= s3->accel.dx; + if (error < 0) { + error += s3->accel.dy; + if (s3->accel.destx_distp > s3->accel.cur_x) + s3->accel.cx++; + else + s3->accel.cx--; + } + if (s3->accel.desty_axstp > s3->accel.cur_y) + s3->accel.cy++; + else + s3->accel.cy--; + } + } + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; + } + break; + + case 11: /*Polygon Fill Pattern (Vision868/968 and Trio64 only)*/ + { + int end_y1, end_y2; + + if (s3->chip != S3_TRIO64 && s3->chip != S3_VISION968 && s3->chip != S3_VISION868) + break; + + polygon_setup(s3); + + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + + end_y1 = s3->accel.desty_axstp; + end_y2 = s3->accel.desty_axstp2; + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + while ((s3->accel.poly_cy < end_y1) && (s3->accel.poly_cy2 < end_y2)) { + int y = s3->accel.poly_cy; + int x_count = ABS((s3->accel.poly_cx2 >> 20) - s3->accel.poly_x) + 1; + + s3->accel.src = srcbase + s3->accel.pattern + ((y & 7) * s3->width); + s3->accel.dest = dstbase + y * s3->width; + + while (x_count-- && count--) { + int pat_x = s3->accel.poly_x & 7; + + if ((s3->accel.poly_x & 0xfff) >= clip_l && (s3->accel.poly_x & 0xfff) <= clip_r && (s3->accel.poly_cy & 0xfff) >= clip_t && (s3->accel.poly_cy & 0xfff) <= clip_b) { + if (vram_mask) { + READ(s3->accel.src + pat_x, mix_dat); + mix_dat = ((mix_dat & rd_mask) == rd_mask); + mix_dat = mix_dat ? mix_mask : 0; + } + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(s3->accel.src + pat_x, src_dat); + if (vram_mask) + src_dat = ((src_dat & rd_mask) == rd_mask); + break; + } + + if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + READ(s3->accel.dest + s3->accel.poly_x, dest_dat); + + MIX + + if (s3->accel.cmd & 0x10) + { + WRITE(s3->accel.dest + s3->accel.poly_x, dest_dat); + } + } + } + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + mix_dat <<= 1; + mix_dat |= 1; + + if (s3->accel.poly_x < (s3->accel.poly_cx2 >> 20)) + s3->accel.poly_x++; + else + s3->accel.poly_x--; + } + + s3->accel.poly_cx += s3->accel.poly_dx1; + s3->accel.poly_cx2 += s3->accel.poly_dx2; + s3->accel.poly_x = s3->accel.poly_cx >> 20; + + s3->accel.poly_cy++; + s3->accel.poly_cy2++; + + if (!count) + break; + } + + s3->accel.cur_x = s3->accel.poly_cx & 0xfff; + s3->accel.cur_y = s3->accel.poly_cy & 0xfff; + s3->accel.cur_x2 = s3->accel.poly_cx2 & 0xfff; + s3->accel.cur_y2 = s3->accel.poly_cy & 0xfff; + } + break; + + case 14: /*ROPBlt (Vision868/968 only)*/ + if (s3->chip != S3_VISION968 && s3->chip != S3_VISION868) + break; + + if (!cpu_input) /*!cpu_input is trigger to start operation*/ + { + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + s3->accel.sy = s3->accel.multifunc[0] & 0xfff; + + s3->accel.dx = s3->accel.destx_distp & 0xfff; + if (s3->accel.destx_distp & 0x1000) + s3->accel.dx |= ~0xfff; + s3->accel.dy = s3->accel.desty_axstp & 0xfff; + if (s3->accel.desty_axstp & 0x1000) + s3->accel.dy |= ~0xfff; + + s3->accel.cx = s3->accel.cur_x & 0xfff; + if (s3->accel.cur_x_bit12) + s3->accel.cx |= ~0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; + if (s3->accel.cur_y_bit12) + s3->accel.cy |= ~0xfff; + + s3->accel.px = s3->accel.pat_x & 0xfff; + if (s3->accel.pat_x & 0x1000) + s3->accel.px |= ~0xfff; + s3->accel.py = s3->accel.pat_y & 0xfff; + if (s3->accel.pat_y & 0x1000) + s3->accel.py |= ~0xfff; + + s3->accel.dest = dstbase + (s3->accel.dy * s3->width); + s3->accel.src = srcbase + (s3->accel.cy * s3->width); + s3->accel.pattern = (s3->accel.py * s3->width); + } + + if ((s3->accel.cmd & 0x100) && !cpu_input) + return; /*Wait for data from CPU*/ + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + + while (count-- && s3->accel.sy >= 0) { + if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = s3->accel.bkgd_color; + break; + case 1: + src_dat = s3->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(s3->accel.src + s3->accel.cx, src_dat); + break; + } + + if (s3->accel.ropmix & 0x100) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + pat_dat = s3->accel.pat_bg_color; + break; + case 1: + pat_dat = s3->accel.pat_fg_color; + break; + case 2: + pat_dat = cpu_dat; + break; + case 3: + READ(s3->accel.pattern + s3->accel.px, pat_dat); + break; + } + } else { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + pat_dat = s3->accel.bkgd_color; + break; + case 1: + pat_dat = s3->accel.frgd_color; + break; + case 2: + pat_dat = cpu_dat; + break; + case 3: + READ(s3->accel.pattern + s3->accel.px, pat_dat); + break; + } + } + + if (((compare_mode == 2 && src_dat != compare) || (compare_mode == 3 && src_dat == compare) || compare_mode < 2)) { + READ(s3->accel.dest + s3->accel.dx, dest_dat); + + ROPMIX + + if (s3->accel.cmd & 0x10) { + WRITE(s3->accel.dest + s3->accel.dx, out); + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if (s3->bpp == 0) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (s3->accel.cmd & 0x20) { + s3->accel.cx++; + s3->accel.dx++; + s3->accel.px++; + } else { + s3->accel.cx--; + s3->accel.dx--; + s3->accel.px--; + } + s3->accel.sx--; + if (s3->accel.sx < 0) { + if (s3->accel.cmd & 0x20) { + s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.px -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } else { + s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.dx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + s3->accel.px += (s3->accel.maj_axis_pcnt & 0xfff) + 1; + } + s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; + + if (s3->accel.cmd & 0x80) { + s3->accel.cy++; + s3->accel.dy++; + s3->accel.py++; + } else { + s3->accel.cy--; + s3->accel.dy--; + s3->accel.py--; + } + + s3->accel.src = srcbase + (s3->accel.cy * s3->width); + s3->accel.dest = dstbase + (s3->accel.dy * s3->width); + s3->accel.pattern = (s3->accel.py * s3->width); + + s3->accel.sy--; + + if (cpu_input /* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) + return; + if (s3->accel.sy < 0) { + return; + } + } + } + break; + } } static uint8_t s3_pci_read(int func, int addr, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; - switch (addr) - { - case 0x00: return 0x33; /*'S3'*/ - case 0x01: return 0x53; + switch (addr) { + case 0x00: + return 0x33; /*'S3'*/ + case 0x01: + return 0x53; - case 0x02: return s3->id_ext_pci; - case 0x03: return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; + case 0x02: + return s3->id_ext_pci; + case 0x03: + return (s3->chip == S3_TRIO64V2) ? 0x89 : 0x88; - case PCI_REG_COMMAND: - if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - return s3->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ - else - return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - break; + case PCI_REG_COMMAND: + if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) + return s3->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ + else + return s3->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ + break; - case 0x07: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ + case 0x07: + return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x07] & 0x36) : (1 << 1); /*Medium DEVSEL timing*/ - case 0x08: return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ + case 0x08: + return (s3->chip == S3_TRIO64V) ? 0x40 : 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0a: - if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - return 0x00; /*Supports VGA interface*/ - else - return 0x01; - break; - case 0x0b: - if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - return 0x03; - else - return 0x00; - break; + case 0x0a: + if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) + return 0x00; /*Supports VGA interface*/ + else + return 0x01; + break; + case 0x0b: + if (s3->chip >= S3_TRIO32 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) + return 0x03; + else + return 0x00; + break; - case 0x0d: return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00; break; + case 0x0d: + return (s3->chip == S3_TRIO64V2) ? (s3->pci_regs[0x0d] & 0xf8) : 0x00; + break; - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: - if (svga->crtc[0x53] & 0x08) - return 0x00; - else - return (svga->crtc[0x5a] & 0x80); - break; + case 0x10: + return 0x00; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + if (svga->crtc[0x53] & 0x08) + return 0x00; + else + return (svga->crtc[0x5a] & 0x80); + break; - case 0x13: - if (svga->crtc[0x53] & 0x08) { - return (s3->chip >= S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); - } else { - return svga->crtc[0x59]; - } - break; + case 0x13: + if (svga->crtc[0x53] & 0x08) { + return (s3->chip >= S3_TRIO64V) ? (svga->crtc[0x59] & 0xfc) : (svga->crtc[0x59] & 0xfe); + } else { + return svga->crtc[0x59]; + } + break; - case 0x30: return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return s3->has_bios ? s3->pci_regs[0x32] : 0x00; - case 0x33: return s3->has_bios ? s3->pci_regs[0x33] : 0x00; + case 0x30: + return s3->has_bios ? (s3->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return s3->has_bios ? s3->pci_regs[0x32] : 0x00; + case 0x33: + return s3->has_bios ? s3->pci_regs[0x33] : 0x00; - case 0x3c: return s3->int_line; - case 0x3d: return PCI_INTA; + case 0x3c: + return s3->int_line; + case 0x3d: + return PCI_INTA; - case 0x3e: return (s3->chip == S3_TRIO64V2) ? 0x04 : 0x00; break; - case 0x3f: return (s3->chip == S3_TRIO64V2) ? 0xff : 0x00; break; - } - return 0; + case 0x3e: + return (s3->chip == S3_TRIO64V2) ? 0x04 : 0x00; + break; + case 0x3f: + return (s3->chip == S3_TRIO64V2) ? 0xff : 0x00; + break; + } + return 0; } static void s3_pci_write(int func, int addr, uint8_t val, void *p) { - s3_t *s3 = (s3_t *)p; - svga_t *svga = &s3->svga; + s3_t *s3 = (s3_t *) p; + svga_t *svga = &s3->svga; - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x3d: case 0x3e: case 0x3f: - if (s3->chip == S3_TRIO64V2) - return; - break; + switch (addr) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x3d: + case 0x3e: + case 0x3f: + if (s3->chip == S3_TRIO64V2) + return; + break; - case PCI_REG_COMMAND: - if (val & PCI_COMMAND_IO) - s3_io_set(s3); - else - s3_io_remove(s3); - s3->pci_regs[PCI_REG_COMMAND] = (val & 0x23); - s3_updatemapping(s3); - break; + case PCI_REG_COMMAND: + if (val & PCI_COMMAND_IO) + s3_io_set(s3); + else + s3_io_remove(s3); + s3->pci_regs[PCI_REG_COMMAND] = (val & 0x23); + s3_updatemapping(s3); + break; - case 0x07: - if (s3->chip == S3_TRIO64V2) { - s3->pci_regs[0x07] = val & 0x3e; - return; - } - break; + case 0x07: + if (s3->chip == S3_TRIO64V2) { + s3->pci_regs[0x07] = val & 0x3e; + return; + } + break; - case 0x0d: - if (s3->chip == S3_TRIO64V2) { - s3->pci_regs[0x0d] = val & 0xf8; - return; - } - break; + case 0x0d: + if (s3->chip == S3_TRIO64V2) { + s3->pci_regs[0x0d] = val & 0xf8; + return; + } + break; - case 0x12: - if (!(svga->crtc[0x53] & 0x08)) { - svga->crtc[0x5a] = (svga->crtc[0x5a] & 0x7f) | (val & 0x80); - s3_updatemapping(s3); - } - break; + case 0x12: + if (!(svga->crtc[0x53] & 0x08)) { + svga->crtc[0x5a] = (svga->crtc[0x5a] & 0x7f) | (val & 0x80); + s3_updatemapping(s3); + } + break; - case 0x13: - if (svga->crtc[0x53] & 0x08) { - svga->crtc[0x59] = (s3->chip >= S3_TRIO64V) ? (val & 0xfc) : (val & 0xfe); - } else { - svga->crtc[0x59] = val; - } - s3_updatemapping(s3); - break; + case 0x13: + if (svga->crtc[0x53] & 0x08) { + svga->crtc[0x59] = (s3->chip >= S3_TRIO64V) ? (val & 0xfc) : (val & 0xfe); + } else { + svga->crtc[0x59] = val; + } + s3_updatemapping(s3); + break; - case 0x30: case 0x32: case 0x33: - if (!s3->has_bios) - return; - s3->pci_regs[addr] = val; - if (s3->pci_regs[0x30] & 0x01) - { - uint32_t biosaddr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); - mem_mapping_set_addr(&s3->bios_rom.mapping, biosaddr, 0x8000); - } - else - { - mem_mapping_disable(&s3->bios_rom.mapping); - } - return; + case 0x30: + case 0x32: + case 0x33: + if (!s3->has_bios) + return; + s3->pci_regs[addr] = val; + if (s3->pci_regs[0x30] & 0x01) { + uint32_t biosaddr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); + mem_mapping_set_addr(&s3->bios_rom.mapping, biosaddr, 0x8000); + } else { + mem_mapping_disable(&s3->bios_rom.mapping); + } + return; - case 0x3c: - s3->int_line = val; - return; - } + case 0x3c: + s3->int_line = val; + return; + } } static void fifo_thread(void *param) { - s3_t *s3 = (s3_t *)param; - uint64_t start_time, end_time; + s3_t *s3 = (s3_t *) param; + uint64_t start_time, end_time; - while (s3->fifo_thread_run) { - thread_set_event(s3->fifo_not_full_event); - thread_wait_event(s3->wake_fifo_thread, -1); - thread_reset_event(s3->wake_fifo_thread); - s3->blitter_busy = 1; - while (!FIFO_EMPTY) { - start_time = plat_timer_read(); - fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; + while (s3->fifo_thread_run) { + thread_set_event(s3->fifo_not_full_event); + thread_wait_event(s3->wake_fifo_thread, -1); + thread_reset_event(s3->wake_fifo_thread); + s3->blitter_busy = 1; + while (!FIFO_EMPTY) { + start_time = plat_timer_read(); + fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) { - case FIFO_WRITE_BYTE: - s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_WORD: - s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_WRITE_DWORD: - s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_BYTE: - s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_WORD: - s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - case FIFO_OUT_DWORD: - s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); - break; - } + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITE_BYTE: + s3_accel_write_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_WORD: + s3_accel_write_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_WRITE_DWORD: + s3_accel_write_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_BYTE: + s3_accel_out_fifo(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_WORD: + s3_accel_out_fifo_w(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + case FIFO_OUT_DWORD: + s3_accel_out_fifo_l(s3, fifo->addr_type & FIFO_ADDR, fifo->val); + break; + } - s3->fifo_read_idx++; - fifo->addr_type = FIFO_INVALID; + s3->fifo_read_idx++; + fifo->addr_type = FIFO_INVALID; - if (FIFO_ENTRIES > 0xe000) - thread_set_event(s3->fifo_not_full_event); + if (FIFO_ENTRIES > 0xe000) + thread_set_event(s3->fifo_not_full_event); - end_time = plat_timer_read(); - s3->blitter_time += (end_time - start_time); - } - s3->blitter_busy = 0; - s3->subsys_stat |= INT_FIFO_EMP; - s3_update_irqs(s3); - } + end_time = plat_timer_read(); + s3->blitter_time += (end_time - start_time); + } + s3->blitter_busy = 0; + s3->subsys_stat |= INT_FIFO_EMP; + s3_update_irqs(s3); + } } -static int vram_sizes[] = -{ - 7, /*512 kB*/ - 6, /*1 MB*/ - 4, /*2 MB*/ - 0, - 0, /*4 MB*/ - 0, - 0, /*6 MB*/ - 0, - 3 /*8 MB*/ +static int vram_sizes[] = { + 7, /*512 kB*/ + 6, /*1 MB*/ + 4, /*2 MB*/ + 0, + 0, /*4 MB*/ + 0, + 0, /*6 MB*/ + 0, + 3 /*8 MB*/ }; -static void s3_reset(void *priv) +static void +s3_reset(void *priv) { - s3_t *s3 = (s3_t *) priv; + s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; memset(svga->crtc, 0x00, sizeof(svga->crtc)); - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = 1000ull << 32; + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; svga->dispofftime = 1000ull << 32; - svga->bpp = 8; + svga->bpp = 8; - if (s3->pci) - svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4); - else if (s3->vlb) - svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4); - else - svga->crtc[0x36] = 3 | (1 << 4); + if (s3->pci) + svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4); + else if (s3->vlb) + svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4); + else + svga->crtc[0x36] = 3 | (1 << 4); - if (s3->chip >= S3_86C928) - svga->crtc[0x36] |= (vram_sizes[s3->vram] << 5); - else - svga->crtc[0x36] |= ((s3->vram == 1) ? 0x00 : 0x20) | 0x80; + if (s3->chip >= S3_86C928) + svga->crtc[0x36] |= (vram_sizes[s3->vram] << 5); + else + svga->crtc[0x36] |= ((s3->vram == 1) ? 0x00 : 0x20) | 0x80; - svga->crtc[0x37] = 1 | (7 << 5); + svga->crtc[0x37] = 1 | (7 << 5); - if (s3->chip >= S3_86C928) - svga->crtc[0x37] |= 0x04; + if (s3->chip >= S3_86C928) + svga->crtc[0x37] |= 0x04; s3_io_set(s3); @@ -6670,1786 +7575,1757 @@ static void s3_reset(void *priv) s3->pci_regs[0x32] = 0x0c; s3->pci_regs[0x33] = 0x00; - switch(s3->card_type) { - case S3_MIROCRYSTAL8S_805: - case S3_MIROCRYSTAL10SD_805: - svga->crtc[0x5a] = 0x0a; - svga->getclock = sdac_getclock; - break; + switch (s3->card_type) { + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + svga->crtc[0x5a] = 0x0a; + svga->getclock = sdac_getclock; + break; - case S3_SPEA_MIRAGE_86C801: - case S3_SPEA_MIRAGE_86C805: - svga->crtc[0x5a] = 0x0a; - break; + case S3_SPEA_MIRAGE_86C801: + case S3_SPEA_MIRAGE_86C805: + svga->crtc[0x5a] = 0x0a; + break; - case S3_PHOENIX_86C801: - case S3_PHOENIX_86C805: - svga->crtc[0x5a] = 0x0a; - break; + case S3_PHOENIX_86C801: + case S3_PHOENIX_86C805: + svga->crtc[0x5a] = 0x0a; + break; - case S3_METHEUS_86C928: - case S3_SPEA_MERCURY_LITE_PCI: - svga->crtc[0x5a] = 0x0a; - break; + case S3_METHEUS_86C928: + case S3_SPEA_MERCURY_LITE_PCI: + svga->crtc[0x5a] = 0x0a; + break; - case S3_PARADISE_BAHAMAS64: - case S3_PHOENIX_VISION864: - case S3_MIROCRYSTAL20SD_864: - svga->crtc[0x5a] = 0x0a; - break; + case S3_PARADISE_BAHAMAS64: + case S3_PHOENIX_VISION864: + case S3_MIROCRYSTAL20SD_864: + svga->crtc[0x5a] = 0x0a; + break; - case S3_DIAMOND_STEALTH64_964: - case S3_ELSAWIN2KPROX_964: - case S3_MIROCRYSTAL20SV_964: - svga->crtc[0x5a] = 0x0a; - break; + case S3_DIAMOND_STEALTH64_964: + case S3_ELSAWIN2KPROX_964: + case S3_MIROCRYSTAL20SV_964: + svga->crtc[0x5a] = 0x0a; + break; - case S3_ELSAWIN2KPROX: - case S3_SPEA_MERCURY_P64V: - case S3_MIROVIDEO40SV_ERGO_968: - case S3_NUMBER9_9FX_771: - case S3_PHOENIX_VISION968: - if (s3->pci) { - svga->crtc[0x53] = 0x18; - svga->crtc[0x58] = 0x10; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - } else { - svga->crtc[0x53] = 0x00; - svga->crtc[0x59] = 0x00; - svga->crtc[0x5a] = 0x0a; - } - break; + case S3_ELSAWIN2KPROX: + case S3_SPEA_MERCURY_P64V: + case S3_MIROVIDEO40SV_ERGO_968: + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + if (s3->pci) { + svga->crtc[0x53] = 0x18; + svga->crtc[0x58] = 0x10; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + } else { + svga->crtc[0x53] = 0x00; + svga->crtc[0x59] = 0x00; + svga->crtc[0x5a] = 0x0a; + } + break; - case S3_NUMBER9_9FX_531: - case S3_PHOENIX_VISION868: - if (s3->pci) { - svga->crtc[0x53] = 0x18; - svga->crtc[0x58] = 0x10; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - } else { - svga->crtc[0x53] = 0x00; - svga->crtc[0x59] = 0x00; - svga->crtc[0x5a] = 0x0a; - } - break; + case S3_NUMBER9_9FX_531: + case S3_PHOENIX_VISION868: + if (s3->pci) { + svga->crtc[0x53] = 0x18; + svga->crtc[0x58] = 0x10; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + } else { + svga->crtc[0x53] = 0x00; + svga->crtc[0x59] = 0x00; + svga->crtc[0x5a] = 0x0a; + } + break; - case S3_PHOENIX_TRIO64: - case S3_PHOENIX_TRIO64_ONBOARD: - case S3_PHOENIX_TRIO64VPLUS: - case S3_PHOENIX_TRIO64VPLUS_ONBOARD: - case S3_DIAMOND_STEALTH64_764: - case S3_SPEA_MIRAGE_P64: - case S3_NUMBER9_9FX: - if (s3->card_type == S3_PHOENIX_TRIO64VPLUS || s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) - svga->crtc[0x53] = 0x08; - break; + case S3_PHOENIX_TRIO64: + case S3_PHOENIX_TRIO64_ONBOARD: + case S3_PHOENIX_TRIO64VPLUS: + case S3_PHOENIX_TRIO64VPLUS_ONBOARD: + case S3_DIAMOND_STEALTH64_764: + case S3_SPEA_MIRAGE_P64: + case S3_NUMBER9_9FX: + if (s3->card_type == S3_PHOENIX_TRIO64VPLUS || s3->card_type == S3_PHOENIX_TRIO64VPLUS_ONBOARD) + svga->crtc[0x53] = 0x08; + break; - case S3_TRIO64V2_DX: - svga->crtc[0x53] = 0x08; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - s3->pci_regs[0x05] = 0; - s3->pci_regs[0x06] = 0; - s3->pci_regs[0x07] = 2; - s3->pci_regs[0x3d] = 1; - s3->pci_regs[0x3e] = 4; - s3->pci_regs[0x3f] = 0xff; - break; - } + case S3_TRIO64V2_DX: + svga->crtc[0x53] = 0x08; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + s3->pci_regs[0x05] = 0; + s3->pci_regs[0x06] = 0; + s3->pci_regs[0x07] = 2; + s3->pci_regs[0x3d] = 1; + s3->pci_regs[0x3e] = 4; + s3->pci_regs[0x3f] = 0xff; + break; + } - if (s3->has_bios) { - if (s3->pci) - mem_mapping_disable(&s3->bios_rom.mapping); - } + if (s3->has_bios) { + if (s3->pci) + mem_mapping_disable(&s3->bios_rom.mapping); + } - s3_updatemapping(s3); + s3_updatemapping(s3); - mem_mapping_disable(&s3->mmio_mapping); - mem_mapping_disable(&s3->new_mmio_mapping); + mem_mapping_disable(&s3->mmio_mapping); + mem_mapping_disable(&s3->new_mmio_mapping); } - -static void *s3_init(const device_t *info) +static void * +s3_init(const device_t *info) { - const char *bios_fn; - int chip, stepping; - s3_t *s3 = malloc(sizeof(s3_t)); - svga_t *svga = &s3->svga; - int vram; - uint32_t vram_size; + const char *bios_fn; + int chip, stepping; + s3_t *s3 = malloc(sizeof(s3_t)); + svga_t *svga = &s3->svga; + int vram; + uint32_t vram_size; - switch(info->local) { - case S3_ORCHID_86C911: - bios_fn = ROM_ORCHID_86C911; - chip = S3_86C911; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c911); - break; - case S3_DIAMOND_STEALTH_VRAM: - bios_fn = ROM_DIAMOND_STEALTH_VRAM; - chip = S3_86C911; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c911); - break; - case S3_AMI_86C924: - bios_fn = ROM_AMI_86C924; - chip = S3_86C924; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c911); - break; - case S3_SPEA_MIRAGE_86C801: - bios_fn = ROM_SPEA_MIRAGE_86C801; - chip = S3_86C801; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); - break; - case S3_86C805_ONBOARD: - bios_fn = NULL; - chip = S3_86C805; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); - break; - case S3_SPEA_MIRAGE_86C805: - bios_fn = ROM_SPEA_MIRAGE_86C805; - chip = S3_86C805; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); - break; - case S3_MIROCRYSTAL8S_805: - bios_fn = ROM_MIROCRYSTAL8S_805; - chip = S3_86C805; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); - break; - case S3_MIROCRYSTAL10SD_805: - bios_fn = ROM_MIROCRYSTAL10SD_805; - chip = S3_86C805; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); - break; - case S3_PHOENIX_86C801: - bios_fn = ROM_PHOENIX_86C80X; - chip = S3_86C801; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); - break; - case S3_PHOENIX_86C805: - bios_fn = ROM_PHOENIX_86C80X; - chip = S3_86C805; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); - break; - case S3_METHEUS_86C928: - bios_fn = ROM_METHEUS_86C928; - chip = S3_86C928; - if (info->flags & DEVICE_VLB) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); - break; - case S3_SPEA_MERCURY_LITE_PCI: - bios_fn = ROM_SPEA_MERCURY_LITE_PCI; - chip = S3_86C928PCI; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c928pci); - break; - case S3_MIROCRYSTAL20SD_864: - bios_fn = ROM_MIROCRYSTAL20SD_864_VLB; - chip = S3_VISION864; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); - break; - case S3_PARADISE_BAHAMAS64: - bios_fn = ROM_PARADISE_BAHAMAS64; - chip = S3_VISION864; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); - break; - case S3_PHOENIX_VISION864: - bios_fn = ROM_PHOENIX_VISION864; - chip = S3_VISION864; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); - break; - case S3_NUMBER9_9FX_531: - bios_fn = ROM_NUMBER9_9FX_531; - chip = S3_VISION868; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); - break; - case S3_PHOENIX_VISION868: - bios_fn = ROM_PHOENIX_VISION868; - chip = S3_VISION868; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_vlb); - break; - case S3_DIAMOND_STEALTH64_964: - bios_fn = ROM_DIAMOND_STEALTH64_964; - chip = S3_VISION964; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); - break; - case S3_MIROCRYSTAL20SV_964: - chip = S3_VISION964; - if (info->flags & DEVICE_PCI) { - bios_fn = ROM_MIROCRYSTAL20SV_964_PCI; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); - } else { - bios_fn = ROM_MIROCRYSTAL20SV_964_VLB; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); - } - break; - case S3_MIROVIDEO40SV_ERGO_968: - bios_fn = ROM_MIROVIDEO40SV_ERGO_968_PCI; - chip = S3_VISION968; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); - break; - case S3_NUMBER9_9FX_771: - bios_fn = ROM_NUMBER9_9FX_771; - chip = S3_VISION968; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); - break; - case S3_PHOENIX_VISION968: - bios_fn = ROM_PHOENIX_VISION968; - chip = S3_VISION968; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb); - break; - case S3_ELSAWIN2KPROX_964: - bios_fn = ROM_ELSAWIN2KPROX_964; - chip = S3_VISION964; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); - break; - case S3_ELSAWIN2KPROX: - bios_fn = ROM_ELSAWIN2KPROX; - chip = S3_VISION968; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); - break; - case S3_SPEA_MERCURY_P64V: - bios_fn = ROM_SPEA_MERCURY_P64V; - chip = S3_VISION968; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); - break; - case S3_PHOENIX_TRIO32: - bios_fn = ROM_PHOENIX_TRIO32; - chip = S3_TRIO32; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); - break; - case S3_DIAMOND_STEALTH_SE: - bios_fn = ROM_DIAMOND_STEALTH_SE; - chip = S3_TRIO32; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); - break; - case S3_PHOENIX_TRIO64: - bios_fn = ROM_PHOENIX_TRIO64; - chip = S3_TRIO64; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); - break; - case S3_SPEA_MIRAGE_P64: - bios_fn = ROM_SPEA_MIRAGE_P64; - chip = S3_TRIO64; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); - break; - case S3_PHOENIX_TRIO64_ONBOARD: - bios_fn = NULL; - chip = S3_TRIO64; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); - break; - case S3_PHOENIX_TRIO64VPLUS: - bios_fn = ROM_PHOENIX_TRIO64VPLUS; - chip = S3_TRIO64V; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); - break; - case S3_PHOENIX_TRIO64VPLUS_ONBOARD: - bios_fn = NULL; - chip = S3_TRIO64V; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); - break; - case S3_DIAMOND_STEALTH64_764: - bios_fn = ROM_DIAMOND_STEALTH64_764; - chip = S3_TRIO64; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_stealth64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_stealth64_vlb); - break; - case S3_NUMBER9_9FX: - bios_fn = ROM_NUMBER9_9FX; - chip = S3_TRIO64; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); - break; - case S3_TRIO64V2_DX: - bios_fn = ROM_TRIO64V2_DX_VBE20; - chip = S3_TRIO64V2; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); - break; - case S3_TRIO64V2_DX_ONBOARD: - bios_fn = NULL; - chip = S3_TRIO64V2; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); - break; - default: - free(s3); - return NULL; - } + switch (info->local) { + case S3_ORCHID_86C911: + bios_fn = ROM_ORCHID_86C911; + chip = S3_86C911; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c911); + break; + case S3_DIAMOND_STEALTH_VRAM: + bios_fn = ROM_DIAMOND_STEALTH_VRAM; + chip = S3_86C911; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c911); + break; + case S3_AMI_86C924: + bios_fn = ROM_AMI_86C924; + chip = S3_86C924; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c911); + break; + case S3_SPEA_MIRAGE_86C801: + bios_fn = ROM_SPEA_MIRAGE_86C801; + chip = S3_86C801; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; + case S3_86C805_ONBOARD: + bios_fn = NULL; + chip = S3_86C805; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_SPEA_MIRAGE_86C805: + bios_fn = ROM_SPEA_MIRAGE_86C805; + chip = S3_86C805; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_MIROCRYSTAL8S_805: + bios_fn = ROM_MIROCRYSTAL8S_805; + chip = S3_86C805; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_MIROCRYSTAL10SD_805: + bios_fn = ROM_MIROCRYSTAL10SD_805; + chip = S3_86C805; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_PHOENIX_86C801: + bios_fn = ROM_PHOENIX_86C80X; + chip = S3_86C801; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; + case S3_PHOENIX_86C805: + bios_fn = ROM_PHOENIX_86C80X; + chip = S3_86C805; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_METHEUS_86C928: + bios_fn = ROM_METHEUS_86C928; + chip = S3_86C928; + if (info->flags & DEVICE_VLB) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; + case S3_SPEA_MERCURY_LITE_PCI: + bios_fn = ROM_SPEA_MERCURY_LITE_PCI; + chip = S3_86C928PCI; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c928pci); + break; + case S3_MIROCRYSTAL20SD_864: + bios_fn = ROM_MIROCRYSTAL20SD_864_VLB; + chip = S3_VISION864; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); + break; + case S3_PARADISE_BAHAMAS64: + bios_fn = ROM_PARADISE_BAHAMAS64; + chip = S3_VISION864; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); + break; + case S3_PHOENIX_VISION864: + bios_fn = ROM_PHOENIX_VISION864; + chip = S3_VISION864; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision864_vlb); + break; + case S3_NUMBER9_9FX_531: + bios_fn = ROM_NUMBER9_9FX_531; + chip = S3_VISION868; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); + break; + case S3_PHOENIX_VISION868: + bios_fn = ROM_PHOENIX_VISION868; + chip = S3_VISION868; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision868_vlb); + break; + case S3_DIAMOND_STEALTH64_964: + bios_fn = ROM_DIAMOND_STEALTH64_964; + chip = S3_VISION964; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); + break; + case S3_MIROCRYSTAL20SV_964: + chip = S3_VISION964; + if (info->flags & DEVICE_PCI) { + bios_fn = ROM_MIROCRYSTAL20SV_964_PCI; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); + } else { + bios_fn = ROM_MIROCRYSTAL20SV_964_VLB; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_vlb); + } + break; + case S3_MIROVIDEO40SV_ERGO_968: + bios_fn = ROM_MIROVIDEO40SV_ERGO_968_PCI; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; + case S3_NUMBER9_9FX_771: + bios_fn = ROM_NUMBER9_9FX_771; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; + case S3_PHOENIX_VISION968: + bios_fn = ROM_PHOENIX_VISION968; + chip = S3_VISION968; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_vlb); + break; + case S3_ELSAWIN2KPROX_964: + bios_fn = ROM_ELSAWIN2KPROX_964; + chip = S3_VISION964; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision964_pci); + break; + case S3_ELSAWIN2KPROX: + bios_fn = ROM_ELSAWIN2KPROX; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; + case S3_SPEA_MERCURY_P64V: + bios_fn = ROM_SPEA_MERCURY_P64V; + chip = S3_VISION968; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_vision968_pci); + break; + case S3_PHOENIX_TRIO32: + bios_fn = ROM_PHOENIX_TRIO32; + chip = S3_TRIO32; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); + break; + case S3_DIAMOND_STEALTH_SE: + bios_fn = ROM_DIAMOND_STEALTH_SE; + chip = S3_TRIO32; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio32_vlb); + break; + case S3_PHOENIX_TRIO64: + bios_fn = ROM_PHOENIX_TRIO64; + chip = S3_TRIO64; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; + case S3_SPEA_MIRAGE_P64: + bios_fn = ROM_SPEA_MIRAGE_P64; + chip = S3_TRIO64; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; + case S3_PHOENIX_TRIO64_ONBOARD: + bios_fn = NULL; + chip = S3_TRIO64; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; + case S3_PHOENIX_TRIO64VPLUS: + bios_fn = ROM_PHOENIX_TRIO64VPLUS; + chip = S3_TRIO64V; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; + case S3_PHOENIX_TRIO64VPLUS_ONBOARD: + bios_fn = NULL; + chip = S3_TRIO64V; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; + case S3_DIAMOND_STEALTH64_764: + bios_fn = ROM_DIAMOND_STEALTH64_764; + chip = S3_TRIO64; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_stealth64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_stealth64_vlb); + break; + case S3_NUMBER9_9FX: + bios_fn = ROM_NUMBER9_9FX; + chip = S3_TRIO64; + if (info->flags & DEVICE_PCI) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_vlb); + break; + case S3_TRIO64V2_DX: + bios_fn = ROM_TRIO64V2_DX_VBE20; + chip = S3_TRIO64V2; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + break; + case S3_TRIO64V2_DX_ONBOARD: + bios_fn = NULL; + chip = S3_TRIO64V2; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_trio64_pci); + break; + default: + free(s3); + return NULL; + } - memset(s3, 0, sizeof(s3_t)); + memset(s3, 0, sizeof(s3_t)); - vram = device_get_config_int("memory"); + vram = device_get_config_int("memory"); - if (vram) - vram_size = vram << 20; - else - vram_size = 512 << 10; - s3->vram_mask = vram_size - 1; - s3->vram = vram; + if (vram) + vram_size = vram << 20; + else + vram_size = 512 << 10; + s3->vram_mask = vram_size - 1; + s3->vram = vram; - s3->has_bios = (bios_fn != NULL); - if (s3->has_bios) { - rom_init(&s3->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&s3->bios_rom.mapping); - } + s3->has_bios = (bios_fn != NULL); + if (s3->has_bios) { + rom_init(&s3->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (info->flags & DEVICE_PCI) + mem_mapping_disable(&s3->bios_rom.mapping); + } - s3->pci = !!(info->flags & DEVICE_PCI); - s3->vlb = !!(info->flags & DEVICE_VLB); + s3->pci = !!(info->flags & DEVICE_PCI); + s3->vlb = !!(info->flags & DEVICE_VLB); - mem_mapping_add(&s3->linear_mapping, 0, 0, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear, - NULL, MEM_MAPPING_EXTERNAL, &s3->svga); - /*It's hardcoded to 0xa0000 before the Trio64V+ and expects so*/ - if (chip >= S3_TRIO64V) - mem_mapping_add(&s3->mmio_mapping, 0, 0, - s3_accel_read, s3_accel_read_w, s3_accel_read_l, - s3_accel_write, s3_accel_write_w, s3_accel_write_l, - NULL, MEM_MAPPING_EXTERNAL, s3); - else - mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, - s3_accel_read, s3_accel_read_w, s3_accel_read_l, - s3_accel_write, s3_accel_write_w, s3_accel_write_l, - NULL, MEM_MAPPING_EXTERNAL, s3); - mem_mapping_add(&s3->new_mmio_mapping, 0, 0, - s3_accel_read, s3_accel_read_w, s3_accel_read_l, - s3_accel_write, s3_accel_write_w, s3_accel_write_l, - NULL, MEM_MAPPING_EXTERNAL, s3); - mem_mapping_disable(&s3->mmio_mapping); - mem_mapping_disable(&s3->new_mmio_mapping); + mem_mapping_add(&s3->linear_mapping, 0, 0, + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear, + NULL, MEM_MAPPING_EXTERNAL, &s3->svga); + /*It's hardcoded to 0xa0000 before the Trio64V+ and expects so*/ + if (chip >= S3_TRIO64V) + mem_mapping_add(&s3->mmio_mapping, 0, 0, + s3_accel_read, s3_accel_read_w, s3_accel_read_l, + s3_accel_write, s3_accel_write_w, s3_accel_write_l, + NULL, MEM_MAPPING_EXTERNAL, s3); + else + mem_mapping_add(&s3->mmio_mapping, 0xa0000, 0x10000, + s3_accel_read, s3_accel_read_w, s3_accel_read_l, + s3_accel_write, s3_accel_write_w, s3_accel_write_l, + NULL, MEM_MAPPING_EXTERNAL, s3); + mem_mapping_add(&s3->new_mmio_mapping, 0, 0, + s3_accel_read, s3_accel_read_w, s3_accel_read_l, + s3_accel_write, s3_accel_write_w, s3_accel_write_l, + NULL, MEM_MAPPING_EXTERNAL, s3); + mem_mapping_disable(&s3->mmio_mapping); + mem_mapping_disable(&s3->new_mmio_mapping); - if (chip == S3_VISION964 || chip == S3_VISION968) - svga_init(info, &s3->svga, s3, vram_size, - s3_recalctimings, - s3_in, s3_out, - NULL, - NULL); - else { - if (chip >= S3_TRIO64V) { - svga_init(info, svga, s3, vram_size, - s3_trio64v_recalctimings, - s3_in, s3_out, - s3_hwcursor_draw, - s3_trio64v_overlay_draw); - } else { - svga_init(info, svga, s3, vram_size, - s3_recalctimings, - s3_in, s3_out, - s3_hwcursor_draw, - NULL); - } - } + if (chip == S3_VISION964 || chip == S3_VISION968) + svga_init(info, &s3->svga, s3, vram_size, + s3_recalctimings, + s3_in, s3_out, + NULL, + NULL); + else { + if (chip >= S3_TRIO64V) { + svga_init(info, svga, s3, vram_size, + s3_trio64v_recalctimings, + s3_in, s3_out, + s3_hwcursor_draw, + s3_trio64v_overlay_draw); + } else { + svga_init(info, svga, s3, vram_size, + s3_recalctimings, + s3_in, s3_out, + s3_hwcursor_draw, + NULL); + } + } svga->hwcursor.cur_ysize = 64; - if (chip == S3_VISION964 && info->local != S3_ELSAWIN2KPROX_964) - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || (chip == S3_VISION968 && (info->local == S3_ELSAWIN2KPROX || - info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771))) - svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; - else if (chip == S3_VISION968 && (info->local == S3_SPEA_MERCURY_P64V || info->local == S3_MIROVIDEO40SV_ERGO_968)) - svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; + if (chip == S3_VISION964 && info->local != S3_ELSAWIN2KPROX_964) + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + else if ((chip == S3_VISION964 && info->local == S3_ELSAWIN2KPROX_964) || (chip == S3_VISION968 && (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771))) + svga->dac_hwcursor_draw = ibm_rgb528_hwcursor_draw; + else if (chip == S3_VISION968 && (info->local == S3_SPEA_MERCURY_P64V || info->local == S3_MIROVIDEO40SV_ERGO_968)) + svga->dac_hwcursor_draw = tvp3026_hwcursor_draw; - if (chip >= S3_VISION964) { - switch (vram) { - case 0: /* 512 kB */ - svga->vram_mask = (1 << 19) - 1; - svga->vram_max = 2 << 20; - break; - case 1: /* 1 MB */ - /* VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus. + if (chip >= S3_VISION964) { + switch (vram) { + case 0: /* 512 kB */ + svga->vram_mask = (1 << 19) - 1; + svga->vram_max = 2 << 20; + break; + case 1: /* 1 MB */ + /* VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus. - This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, - but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference? */ - svga->vram_mask = (1 << 20) - 1; - svga->vram_max = 2 << 20; - break; - case 2: - default: /*2 MB */ - /* VRAM in first 2 MB, 3rd and 4th MBs are open bus. */ - svga->vram_mask = (2 << 20) - 1; - svga->vram_max = 2 << 20; - break; - case 4: /*4MB*/ - svga->vram_mask = (4 << 20) - 1; - svga->vram_max = 4 << 20; - break; - case 8: /*8MB*/ - svga->vram_mask = (8 << 20) - 1; - svga->vram_max = 8 << 20; - break; - } - } + This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, + but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference? */ + svga->vram_mask = (1 << 20) - 1; + svga->vram_max = 2 << 20; + break; + case 2: + default: /*2 MB */ + /* VRAM in first 2 MB, 3rd and 4th MBs are open bus. */ + svga->vram_mask = (2 << 20) - 1; + svga->vram_max = 2 << 20; + break; + case 4: /*4MB*/ + svga->vram_mask = (4 << 20) - 1; + svga->vram_max = 4 << 20; + break; + case 8: /*8MB*/ + svga->vram_mask = (8 << 20) - 1; + svga->vram_max = 8 << 20; + break; + } + } - if (s3->pci) - svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4); - else if (s3->vlb) - svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4); - else - svga->crtc[0x36] = 3 | (1 << 4); + if (s3->pci) + svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4); + else if (s3->vlb) + svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4); + else + svga->crtc[0x36] = 3 | (1 << 4); - if (chip >= S3_86C928) - svga->crtc[0x36] |= (vram_sizes[vram] << 5); - else { - svga->crtc[0x36] |= ((vram == 1) ? 0x00 : 0x20) | 0x98; - svga->crtc[0x41] = (vram == 1) ? 0x10 : 0x00; - } + if (chip >= S3_86C928) + svga->crtc[0x36] |= (vram_sizes[vram] << 5); + else { + svga->crtc[0x36] |= ((vram == 1) ? 0x00 : 0x20) | 0x98; + svga->crtc[0x41] = (vram == 1) ? 0x10 : 0x00; + } - svga->crtc[0x37] = 1 | (7 << 5); + svga->crtc[0x37] = 1 | (7 << 5); - if (chip >= S3_86C928) - svga->crtc[0x37] |= 0x04; + if (chip >= S3_86C928) + svga->crtc[0x37] |= 0x04; - svga->vblank_start = s3_vblank_start; + svga->vblank_start = s3_vblank_start; - s3_io_set(s3); + s3_io_set(s3); - s3->pci_regs[PCI_REG_COMMAND] = 7; + s3->pci_regs[PCI_REG_COMMAND] = 7; - s3->pci_regs[0x30] = 0x00; - s3->pci_regs[0x32] = 0x0c; - s3->pci_regs[0x33] = 0x00; + s3->pci_regs[0x30] = 0x00; + s3->pci_regs[0x32] = 0x0c; + s3->pci_regs[0x33] = 0x00; - s3->chip = chip; + s3->chip = chip; - s3->int_line = 0; + s3->int_line = 0; - s3->card_type = info->local; + s3->card_type = info->local; - svga->force_old_addr = 1; + svga->force_old_addr = 1; - switch(s3->card_type) { - case S3_ORCHID_86C911: - case S3_DIAMOND_STEALTH_VRAM: - svga->decode_mask = (1 << 20) - 1; - stepping = 0x81; /*86C911*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = 0; - s3->packed_mmio = 0; - s3->width = 1024; + switch (s3->card_type) { + case S3_ORCHID_86C911: + case S3_DIAMOND_STEALTH_VRAM: + svga->decode_mask = (1 << 20) - 1; + stepping = 0x81; /*86C911*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + s3->width = 1024; - svga->ramdac = device_add(&sc11483_ramdac_device); - svga->clock_gen = device_add(&av9194_device); - svga->getclock = av9194_getclock; - break; + svga->ramdac = device_add(&sc11483_ramdac_device); + svga->clock_gen = device_add(&av9194_device); + svga->getclock = av9194_getclock; + break; - case S3_AMI_86C924: - svga->decode_mask = (1 << 20) - 1; - stepping = 0x82; /*86C911A/86C924*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = 0; - s3->packed_mmio = 0; - s3->width = 1024; + case S3_AMI_86C924: + svga->decode_mask = (1 << 20) - 1; + stepping = 0x82; /*86C911A/86C924*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + s3->width = 1024; - svga->ramdac = device_add(&sc11487_ramdac_device); - svga->clock_gen = device_add(&ics2494an_305_device); - svga->getclock = ics2494_getclock; - break; + svga->ramdac = device_add(&sc11487_ramdac_device); + svga->clock_gen = device_add(&ics2494an_305_device); + svga->getclock = ics2494_getclock; + break; - case S3_MIROCRYSTAL8S_805: - case S3_MIROCRYSTAL10SD_805: - svga->decode_mask = (2 << 20) - 1; - stepping = 0xa0; /*86C801/86C805*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = 0; - s3->packed_mmio = 0; - svga->crtc[0x5a] = 0x0a; + case S3_MIROCRYSTAL8S_805: + case S3_MIROCRYSTAL10SD_805: + svga->decode_mask = (2 << 20) - 1; + stepping = 0xa0; /*86C801/86C805*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&gendac_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = sdac_getclock; - break; + svga->ramdac = device_add(&gendac_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = sdac_getclock; + break; - case S3_SPEA_MIRAGE_86C801: - case S3_SPEA_MIRAGE_86C805: - svga->decode_mask = (2 << 20) - 1; - stepping = 0xa0; /*86C801/86C805*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = 0; - s3->packed_mmio = 0; - svga->crtc[0x5a] = 0x0a; + case S3_SPEA_MIRAGE_86C801: + case S3_SPEA_MIRAGE_86C805: + svga->decode_mask = (2 << 20) - 1; + stepping = 0xa0; /*86C801/86C805*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&att490_ramdac_device); - svga->clock_gen = device_add(&av9194_device); - svga->getclock = av9194_getclock; - break; + svga->ramdac = device_add(&att490_ramdac_device); + svga->clock_gen = device_add(&av9194_device); + svga->getclock = av9194_getclock; + break; - case S3_86C805_ONBOARD: - svga->decode_mask = (2 << 20) - 1; - stepping = 0xa0; /*86C801/86C805*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = 0; - s3->packed_mmio = 0; - svga->crtc[0x5a] = 0x0a; + case S3_86C805_ONBOARD: + svga->decode_mask = (2 << 20) - 1; + stepping = 0xa0; /*86C801/86C805*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&att490_ramdac_device); - svga->clock_gen = device_add(&av9194_device); - svga->getclock = av9194_getclock; - break; + svga->ramdac = device_add(&att490_ramdac_device); + svga->clock_gen = device_add(&av9194_device); + svga->getclock = av9194_getclock; + break; - case S3_PHOENIX_86C801: - case S3_PHOENIX_86C805: - svga->decode_mask = (2 << 20) - 1; - stepping = 0xa0; /*86C801/86C805*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = 0; - s3->packed_mmio = 0; - svga->crtc[0x5a] = 0x0a; + case S3_PHOENIX_86C801: + case S3_PHOENIX_86C805: + svga->decode_mask = (2 << 20) - 1; + stepping = 0xa0; /*86C801/86C805*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&att492_ramdac_device); - svga->clock_gen = device_add(&av9194_device); - svga->getclock = av9194_getclock; - break; + svga->ramdac = device_add(&att492_ramdac_device); + svga->clock_gen = device_add(&av9194_device); + svga->getclock = av9194_getclock; + break; - case S3_METHEUS_86C928: - svga->decode_mask = (4 << 20) - 1; - stepping = 0x91; /*86C928*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = 0; - s3->packed_mmio = 0; - svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&bt485_ramdac_device); - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; - break; + case S3_METHEUS_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&bt485_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; - case S3_SPEA_MERCURY_LITE_PCI: - svga->decode_mask = (4 << 20) - 1; - stepping = 0xb0; /*86C928PCI*/ - s3->id = stepping; - s3->id_ext = stepping; - s3->id_ext_pci = stepping; - s3->packed_mmio = 0; - svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&sc1502x_ramdac_device); - svga->clock_gen = device_add(&av9194_device); - svga->getclock = av9194_getclock; - break; + case S3_SPEA_MERCURY_LITE_PCI: + svga->decode_mask = (4 << 20) - 1; + stepping = 0xb0; /*86C928PCI*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = stepping; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + svga->clock_gen = device_add(&av9194_device); + svga->getclock = av9194_getclock; + break; - case S3_PARADISE_BAHAMAS64: - case S3_PHOENIX_VISION864: - case S3_MIROCRYSTAL20SD_864: /*BIOS 3.xx has a SDAC ramdac.*/ - svga->decode_mask = (8 << 20) - 1; - if (info->local == S3_PARADISE_BAHAMAS64 || info->local == S3_MIROCRYSTAL20SD_864) - stepping = 0xc0; /*Vision864*/ - else - stepping = 0xc1; /*Vision864P*/ - s3->id = stepping; - s3->id_ext = s3->id_ext_pci = stepping; - s3->packed_mmio = 0; - svga->crtc[0x5a] = 0x0a; - svga->ramdac = device_add(&sdac_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = sdac_getclock; - break; + case S3_PARADISE_BAHAMAS64: + case S3_PHOENIX_VISION864: + case S3_MIROCRYSTAL20SD_864: /*BIOS 3.xx has a SDAC ramdac.*/ + svga->decode_mask = (8 << 20) - 1; + if (info->local == S3_PARADISE_BAHAMAS64 || info->local == S3_MIROCRYSTAL20SD_864) + stepping = 0xc0; /*Vision864*/ + else + stepping = 0xc1; /*Vision864P*/ + s3->id = stepping; + s3->id_ext = s3->id_ext_pci = stepping; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sdac_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = sdac_getclock; + break; - case S3_DIAMOND_STEALTH64_964: - case S3_ELSAWIN2KPROX_964: - case S3_MIROCRYSTAL20SV_964: - svga->decode_mask = (8 << 20) - 1; - stepping = 0xd0; /*Vision964*/ - s3->id = stepping; - s3->id_ext = s3->id_ext_pci = stepping; - s3->packed_mmio = 1; - svga->crtc[0x5a] = 0x0a; + case S3_DIAMOND_STEALTH64_964: + case S3_ELSAWIN2KPROX_964: + case S3_MIROCRYSTAL20SV_964: + svga->decode_mask = (8 << 20) - 1; + stepping = 0xd0; /*Vision964*/ + s3->id = stepping; + s3->id_ext = s3->id_ext_pci = stepping; + s3->packed_mmio = 1; + svga->crtc[0x5a] = 0x0a; - if (info->local == S3_ELSAWIN2KPROX_964) - svga->ramdac = device_add(&ibm_rgb528_ramdac_device); - else - svga->ramdac = device_add(&bt485_ramdac_device); + if (info->local == S3_ELSAWIN2KPROX_964) + svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + else + svga->ramdac = device_add(&bt485_ramdac_device); - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; - break; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + break; - case S3_ELSAWIN2KPROX: - case S3_SPEA_MERCURY_P64V: - case S3_MIROVIDEO40SV_ERGO_968: - case S3_NUMBER9_9FX_771: - case S3_PHOENIX_VISION968: - svga->decode_mask = (8 << 20) - 1; - s3->id = 0xe1; /*Vision968*/ - s3->id_ext = s3->id_ext_pci = 0xf0; - s3->packed_mmio = 1; - if (s3->pci) { - svga->crtc[0x53] = 0x18; - svga->crtc[0x58] = 0x10; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - } else { - svga->crtc[0x53] = 0x00; - svga->crtc[0x59] = 0x00; - svga->crtc[0x5a] = 0x0a; - } + case S3_ELSAWIN2KPROX: + case S3_SPEA_MERCURY_P64V: + case S3_MIROVIDEO40SV_ERGO_968: + case S3_NUMBER9_9FX_771: + case S3_PHOENIX_VISION968: + svga->decode_mask = (8 << 20) - 1; + s3->id = 0xe1; /*Vision968*/ + s3->id_ext = s3->id_ext_pci = 0xf0; + s3->packed_mmio = 1; + if (s3->pci) { + svga->crtc[0x53] = 0x18; + svga->crtc[0x58] = 0x10; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + } else { + svga->crtc[0x53] = 0x00; + svga->crtc[0x59] = 0x00; + svga->crtc[0x5a] = 0x0a; + } - if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || - info->local == S3_NUMBER9_9FX_771) { - svga->ramdac = device_add(&ibm_rgb528_ramdac_device); - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; - } else { - svga->ramdac = device_add(&tvp3026_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = tvp3026_getclock; - } - break; + if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 || info->local == S3_NUMBER9_9FX_771) { + svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + } else { + svga->ramdac = device_add(&tvp3026_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = tvp3026_getclock; + } + break; - case S3_NUMBER9_9FX_531: - case S3_PHOENIX_VISION868: - svga->decode_mask = (8 << 20) - 1; - s3->id = 0xe1; /*Vision868*/ - s3->id_ext = 0x90; - s3->id_ext_pci = 0x80; - s3->packed_mmio = 1; - if (s3->pci) { - svga->crtc[0x53] = 0x18; - svga->crtc[0x58] = 0x10; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - } else { - svga->crtc[0x53] = 0x00; - svga->crtc[0x59] = 0x00; - svga->crtc[0x5a] = 0x0a; - } + case S3_NUMBER9_9FX_531: + case S3_PHOENIX_VISION868: + svga->decode_mask = (8 << 20) - 1; + s3->id = 0xe1; /*Vision868*/ + s3->id_ext = 0x90; + s3->id_ext_pci = 0x80; + s3->packed_mmio = 1; + if (s3->pci) { + svga->crtc[0x53] = 0x18; + svga->crtc[0x58] = 0x10; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + } else { + svga->crtc[0x53] = 0x00; + svga->crtc[0x59] = 0x00; + svga->crtc[0x5a] = 0x0a; + } - if (info->local == S3_NUMBER9_9FX_531) { - svga->ramdac = device_add(&att498_ramdac_device); - svga->clock_gen = device_add(&icd2061_device); - svga->getclock = icd2061_getclock; - } else { - svga->ramdac = device_add(&sdac_ramdac_device); - svga->clock_gen = svga->ramdac; - svga->getclock = sdac_getclock; - } - break; + if (info->local == S3_NUMBER9_9FX_531) { + svga->ramdac = device_add(&att498_ramdac_device); + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + } else { + svga->ramdac = device_add(&sdac_ramdac_device); + svga->clock_gen = svga->ramdac; + svga->getclock = sdac_getclock; + } + break; - case S3_PHOENIX_TRIO32: - case S3_DIAMOND_STEALTH_SE: - svga->decode_mask = (4 << 20) - 1; - s3->id = 0xe1; /*Trio32*/ - s3->id_ext = 0x10; - s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; + case S3_PHOENIX_TRIO32: + case S3_DIAMOND_STEALTH_SE: + svga->decode_mask = (4 << 20) - 1; + s3->id = 0xe1; /*Trio32*/ + s3->id_ext = 0x10; + s3->id_ext_pci = 0x11; + s3->packed_mmio = 1; - svga->clock_gen = s3; - svga->getclock = s3_trio64_getclock; - break; + svga->clock_gen = s3; + svga->getclock = s3_trio64_getclock; + break; - case S3_PHOENIX_TRIO64: - case S3_PHOENIX_TRIO64_ONBOARD: - case S3_PHOENIX_TRIO64VPLUS: - case S3_PHOENIX_TRIO64VPLUS_ONBOARD: - case S3_DIAMOND_STEALTH64_764: - case S3_SPEA_MIRAGE_P64: - if (device_get_config_int("memory") == 1) - svga->vram_max = 1 << 20; /* Phoenix BIOS does not expect VRAM to be mirrored. */ - /* Fall over. */ + case S3_PHOENIX_TRIO64: + case S3_PHOENIX_TRIO64_ONBOARD: + case S3_PHOENIX_TRIO64VPLUS: + case S3_PHOENIX_TRIO64VPLUS_ONBOARD: + case S3_DIAMOND_STEALTH64_764: + case S3_SPEA_MIRAGE_P64: + if (device_get_config_int("memory") == 1) + svga->vram_max = 1 << 20; /* Phoenix BIOS does not expect VRAM to be mirrored. */ + /* Fall over. */ - case S3_NUMBER9_9FX: - svga->decode_mask = (4 << 20) - 1; - s3->id = 0xe1; /*Trio64*/ - s3->id_ext = s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; + case S3_NUMBER9_9FX: + svga->decode_mask = (4 << 20) - 1; + s3->id = 0xe1; /*Trio64*/ + s3->id_ext = s3->id_ext_pci = 0x11; + s3->packed_mmio = 1; - if (info->local == S3_PHOENIX_TRIO64VPLUS || info->local == S3_PHOENIX_TRIO64VPLUS_ONBOARD) { - svga->crtc[0x53] = 0x08; - } + if (info->local == S3_PHOENIX_TRIO64VPLUS || info->local == S3_PHOENIX_TRIO64VPLUS_ONBOARD) { + svga->crtc[0x53] = 0x08; + } - svga->clock_gen = s3; - svga->getclock = s3_trio64_getclock; - break; + svga->clock_gen = s3; + svga->getclock = s3_trio64_getclock; + break; - case S3_TRIO64V2_DX: - case S3_TRIO64V2_DX_ONBOARD: - svga->decode_mask = (4 << 20) - 1; - s3->id = 0xe1; /*Trio64V2*/ - s3->id_ext = s3->id_ext_pci = 0x01; - s3->packed_mmio = 1; - svga->crtc[0x53] = 0x08; - svga->crtc[0x59] = 0x70; - svga->crtc[0x5a] = 0x00; - svga->crtc[0x6c] = 1; - s3->pci_regs[0x05] = 0; - s3->pci_regs[0x06] = 0; - s3->pci_regs[0x07] = 2; - s3->pci_regs[0x3d] = 1; - s3->pci_regs[0x3e] = 4; - s3->pci_regs[0x3f] = 0xff; + case S3_TRIO64V2_DX: + case S3_TRIO64V2_DX_ONBOARD: + svga->decode_mask = (4 << 20) - 1; + s3->id = 0xe1; /*Trio64V2*/ + s3->id_ext = s3->id_ext_pci = 0x01; + s3->packed_mmio = 1; + svga->crtc[0x53] = 0x08; + svga->crtc[0x59] = 0x70; + svga->crtc[0x5a] = 0x00; + svga->crtc[0x6c] = 1; + s3->pci_regs[0x05] = 0; + s3->pci_regs[0x06] = 0; + s3->pci_regs[0x07] = 2; + s3->pci_regs[0x3d] = 1; + s3->pci_regs[0x3e] = 4; + s3->pci_regs[0x3f] = 0xff; - svga->clock_gen = s3; - svga->getclock = s3_trio64_getclock; - break; + svga->clock_gen = s3; + svga->getclock = s3_trio64_getclock; + break; - default: - return NULL; - } + default: + return NULL; + } - if (s3->pci) - s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); + if (s3->pci) + s3->card = pci_add_card(PCI_ADD_VIDEO, s3_pci_read, s3_pci_write, s3); - s3->i2c = i2c_gpio_init("ddc_s3"); - s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); + s3->i2c = i2c_gpio_init("ddc_s3"); + s3->ddc = ddc_init(i2c_gpio_get_bus(s3->i2c)); - s3->wake_fifo_thread = thread_create_event(); - s3->fifo_not_full_event = thread_create_event(); - s3->fifo_thread_run = 1; - s3->fifo_thread = thread_create(fifo_thread, s3); + s3->wake_fifo_thread = thread_create_event(); + s3->fifo_not_full_event = thread_create_event(); + s3->fifo_thread_run = 1; + s3->fifo_thread = thread_create(fifo_thread, s3); - return s3; + return s3; } -static int s3_orchid_86c911_available(void) +static int +s3_orchid_86c911_available(void) { - return rom_present(ROM_ORCHID_86C911); + return rom_present(ROM_ORCHID_86C911); } -static int s3_diamond_stealth_vram_available(void) +static int +s3_diamond_stealth_vram_available(void) { - return rom_present(ROM_DIAMOND_STEALTH_VRAM); + return rom_present(ROM_DIAMOND_STEALTH_VRAM); } -static int s3_ami_86c924_available(void) +static int +s3_ami_86c924_available(void) { - return rom_present(ROM_AMI_86C924); + return rom_present(ROM_AMI_86C924); } -static int s3_spea_mirage_86c801_available(void) +static int +s3_spea_mirage_86c801_available(void) { - return rom_present(ROM_SPEA_MIRAGE_86C801); + return rom_present(ROM_SPEA_MIRAGE_86C801); } -static int s3_spea_mirage_86c805_available(void) +static int +s3_spea_mirage_86c805_available(void) { - return rom_present(ROM_SPEA_MIRAGE_86C805); + return rom_present(ROM_SPEA_MIRAGE_86C805); } -static int s3_phoenix_86c80x_available(void) +static int +s3_phoenix_86c80x_available(void) { - return rom_present(ROM_PHOENIX_86C80X); + return rom_present(ROM_PHOENIX_86C80X); } -static int s3_mirocrystal_8s_805_available(void) +static int +s3_mirocrystal_8s_805_available(void) { - return rom_present(ROM_MIROCRYSTAL8S_805); + return rom_present(ROM_MIROCRYSTAL8S_805); } -static int s3_mirocrystal_10sd_805_available(void) +static int +s3_mirocrystal_10sd_805_available(void) { - return rom_present(ROM_MIROCRYSTAL10SD_805); + return rom_present(ROM_MIROCRYSTAL10SD_805); } -static int s3_metheus_86c928_available(void) +static int +s3_metheus_86c928_available(void) { - return rom_present(ROM_METHEUS_86C928); + return rom_present(ROM_METHEUS_86C928); } -static int s3_spea_mercury_lite_pci_available(void) +static int +s3_spea_mercury_lite_pci_available(void) { - return rom_present(ROM_SPEA_MERCURY_LITE_PCI); + return rom_present(ROM_SPEA_MERCURY_LITE_PCI); } -static int s3_bahamas64_available(void) +static int +s3_bahamas64_available(void) { - return rom_present(ROM_PARADISE_BAHAMAS64); + return rom_present(ROM_PARADISE_BAHAMAS64); } -static int s3_phoenix_vision864_available(void) +static int +s3_phoenix_vision864_available(void) { - return rom_present(ROM_PHOENIX_VISION864); + return rom_present(ROM_PHOENIX_VISION864); } -static int s3_9fx_531_available(void) +static int +s3_9fx_531_available(void) { - return rom_present(ROM_NUMBER9_9FX_531); + return rom_present(ROM_NUMBER9_9FX_531); } -static int s3_phoenix_vision868_available(void) +static int +s3_phoenix_vision868_available(void) { - return rom_present(ROM_PHOENIX_VISION868); + return rom_present(ROM_PHOENIX_VISION868); } -static int s3_mirocrystal_20sv_964_vlb_available(void) +static int +s3_mirocrystal_20sv_964_vlb_available(void) { - return rom_present(ROM_MIROCRYSTAL20SV_964_VLB); + return rom_present(ROM_MIROCRYSTAL20SV_964_VLB); } -static int s3_mirocrystal_20sv_964_pci_available(void) +static int +s3_mirocrystal_20sv_964_pci_available(void) { - return rom_present(ROM_MIROCRYSTAL20SV_964_PCI); + return rom_present(ROM_MIROCRYSTAL20SV_964_PCI); } -static int s3_diamond_stealth64_964_available(void) +static int +s3_diamond_stealth64_964_available(void) { - return rom_present(ROM_DIAMOND_STEALTH64_964); + return rom_present(ROM_DIAMOND_STEALTH64_964); } -static int s3_mirovideo_40sv_ergo_968_pci_available(void) +static int +s3_mirovideo_40sv_ergo_968_pci_available(void) { - return rom_present(ROM_MIROVIDEO40SV_ERGO_968_PCI); + return rom_present(ROM_MIROVIDEO40SV_ERGO_968_PCI); } -static int s3_9fx_771_available(void) +static int +s3_9fx_771_available(void) { - return rom_present(ROM_NUMBER9_9FX_771); + return rom_present(ROM_NUMBER9_9FX_771); } -static int s3_phoenix_vision968_available(void) +static int +s3_phoenix_vision968_available(void) { - return rom_present(ROM_PHOENIX_VISION968); + return rom_present(ROM_PHOENIX_VISION968); } -static int s3_mirocrystal_20sd_864_vlb_available(void) +static int +s3_mirocrystal_20sd_864_vlb_available(void) { - return rom_present(ROM_MIROCRYSTAL20SD_864_VLB); + return rom_present(ROM_MIROCRYSTAL20SD_864_VLB); } -static int s3_spea_mercury_p64v_pci_available(void) +static int +s3_spea_mercury_p64v_pci_available(void) { - return rom_present(ROM_SPEA_MERCURY_P64V); + return rom_present(ROM_SPEA_MERCURY_P64V); } -static int s3_elsa_winner2000_pro_x_964_available(void) +static int +s3_elsa_winner2000_pro_x_964_available(void) { - return rom_present(ROM_ELSAWIN2KPROX_964); + return rom_present(ROM_ELSAWIN2KPROX_964); } -static int s3_elsa_winner2000_pro_x_available(void) +static int +s3_elsa_winner2000_pro_x_available(void) { - return rom_present(ROM_ELSAWIN2KPROX); + return rom_present(ROM_ELSAWIN2KPROX); } -static int s3_phoenix_trio32_available(void) +static int +s3_phoenix_trio32_available(void) { - return rom_present(ROM_PHOENIX_TRIO32); + return rom_present(ROM_PHOENIX_TRIO32); } -static int s3_diamond_stealth_se_available(void) +static int +s3_diamond_stealth_se_available(void) { - return rom_present(ROM_DIAMOND_STEALTH_SE); + return rom_present(ROM_DIAMOND_STEALTH_SE); } -static int s3_9fx_available(void) +static int +s3_9fx_available(void) { - return rom_present(ROM_NUMBER9_9FX); + return rom_present(ROM_NUMBER9_9FX); } -static int s3_spea_mirage_p64_vlb_available(void) +static int +s3_spea_mirage_p64_vlb_available(void) { - return rom_present(ROM_SPEA_MIRAGE_P64); + return rom_present(ROM_SPEA_MIRAGE_P64); } -static int s3_phoenix_trio64_available(void) +static int +s3_phoenix_trio64_available(void) { - return rom_present(ROM_PHOENIX_TRIO64); + return rom_present(ROM_PHOENIX_TRIO64); } -static int s3_phoenix_trio64vplus_available(void) +static int +s3_phoenix_trio64vplus_available(void) { - return rom_present(ROM_PHOENIX_TRIO64VPLUS); + return rom_present(ROM_PHOENIX_TRIO64VPLUS); } -static int s3_diamond_stealth64_764_available(void) +static int +s3_diamond_stealth64_764_available(void) { - return rom_present(ROM_DIAMOND_STEALTH64_764); + return rom_present(ROM_DIAMOND_STEALTH64_764); } -static int s3_trio64v2_dx_available(void) +static int +s3_trio64v2_dx_available(void) { - return rom_present(ROM_TRIO64V2_DX_VBE20); + return rom_present(ROM_TRIO64V2_DX_VBE20); } -static void s3_close(void *p) +static void +s3_close(void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; - s3->fifo_thread_run = 0; - thread_set_event(s3->wake_fifo_thread); - thread_wait(s3->fifo_thread); - thread_destroy_event(s3->fifo_not_full_event); - thread_destroy_event(s3->wake_fifo_thread); + s3->fifo_thread_run = 0; + thread_set_event(s3->wake_fifo_thread); + thread_wait(s3->fifo_thread); + thread_destroy_event(s3->fifo_not_full_event); + thread_destroy_event(s3->wake_fifo_thread); - svga_close(&s3->svga); + svga_close(&s3->svga); - ddc_close(s3->ddc); - i2c_gpio_close(s3->i2c); + ddc_close(s3->ddc); + i2c_gpio_close(s3->i2c); - free(s3); + free(s3); } -static void s3_speed_changed(void *p) +static void +s3_speed_changed(void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; - svga_recalctimings(&s3->svga); + svga_recalctimings(&s3->svga); } -static void s3_force_redraw(void *p) +static void +s3_force_redraw(void *p) { - s3_t *s3 = (s3_t *)p; + s3_t *s3 = (s3_t *) p; - s3->svga.fullchange = changeframecount; + s3->svga.fullchange = changeframecount; } static const device_config_t s3_orchid_86c911_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 1, - .selection = { - { - .description = "512 KB", - .value = 0 - }, - { - .description = "1 MB", - .value = 1 - }, - { - .description = "" - } - } - }, - { - .type = CONFIG_END - } + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 1, + .selection = { + { .description = "512 KB", + .value = 0 }, + { .description = "1 MB", + .value = 1 }, + { .description = "" } } }, + { .type = CONFIG_END} }; static const device_config_t s3_9fx_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 2, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 2, + .selection = { + { .description = "1 MB", + .value = 1 }, + { .description = "2 MB", + .value = 2 }, /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ { - .description = "" - } - } - }, - { - .type = CONFIG_END - } + .description = "" } } }, + { .type = CONFIG_END} }; static const device_config_t s3_phoenix_trio32_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 2, - .selection = { - { - .description = "512 KB", - .value = 0 - }, - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "" - } - } - }, - { - .type = CONFIG_END - } + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 2, + .selection = { + { .description = "512 KB", + .value = 0 }, + { .description = "1 MB", + .value = 1 }, + { .description = "2 MB", + .value = 2 }, + { .description = "" } } }, + { .type = CONFIG_END} }; static const device_config_t s3_standard_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - } - }, - { - .type = CONFIG_END - } + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 4, + .selection = { + { .description = "1 MB", + .value = 1 }, + { .description = "2 MB", + .value = 2 }, + { .description = "4 MB", + .value = 4 }, + { .description = "" } } }, + { .type = CONFIG_END} }; static const device_config_t s3_968_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .default_int = 4, - .selection = { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - } - }, - { - .type = CONFIG_END - } + {.name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 4, + .selection = { + { .description = "1 MB", + .value = 1 }, + { .description = "2 MB", + .value = 2 }, + { .description = "4 MB", + .value = 4 }, + { .description = "8 MB", + .value = 8 }, + { .description = "" } } }, + { .type = CONFIG_END} }; const device_t s3_orchid_86c911_isa_device = { - .name = "S3 86c911 ISA (Orchid Fahrenheit 1280)", + .name = "S3 86c911 ISA (Orchid Fahrenheit 1280)", .internal_name = "orchid_s3_911", - .flags = DEVICE_AT | DEVICE_ISA, - .local = S3_ORCHID_86C911, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = S3_ORCHID_86C911, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_orchid_86c911_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_orchid_86c911_config + .force_redraw = s3_force_redraw, + .config = s3_orchid_86c911_config }; const device_t s3_diamond_stealth_vram_isa_device = { - .name = "S3 86c911 ISA (Diamond Stealth VRAM)", + .name = "S3 86c911 ISA (Diamond Stealth VRAM)", .internal_name = "stealthvram_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = S3_DIAMOND_STEALTH_VRAM, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = S3_DIAMOND_STEALTH_VRAM, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_diamond_stealth_vram_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_orchid_86c911_config + .force_redraw = s3_force_redraw, + .config = s3_orchid_86c911_config }; const device_t s3_ami_86c924_isa_device = { - .name = "S3 86c924 ISA (AMI)", + .name = "S3 86c924 ISA (AMI)", .internal_name = "ami_s3_924", - .flags = DEVICE_AT | DEVICE_ISA, - .local = S3_AMI_86C924, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = S3_AMI_86C924, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_ami_86c924_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_orchid_86c911_config + .force_redraw = s3_force_redraw, + .config = s3_orchid_86c911_config }; const device_t s3_spea_mirage_86c801_isa_device = { - .name = "S3 86c801 ISA (SPEA Mirage ISA)", + .name = "S3 86c801 ISA (SPEA Mirage ISA)", .internal_name = "px_s3_v7_801_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = S3_SPEA_MIRAGE_86C801, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = S3_SPEA_MIRAGE_86C801, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_spea_mirage_86c801_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_86c805_onboard_vlb_device = { - .name = "S3 86c805 VLB On-Board", + .name = "S3 86c805 VLB On-Board", .internal_name = "px_s3_805_onboard_vlb", - .flags = DEVICE_VLB, - .local = S3_86C805_ONBOARD, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_86C805_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = NULL }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_spea_mirage_86c805_vlb_device = { - .name = "S3 86c805 VLB (SPEA Mirage VL)", + .name = "S3 86c805 VLB (SPEA Mirage VL)", .internal_name = "px_s3_v7_805_vlb", - .flags = DEVICE_VLB, - .local = S3_SPEA_MIRAGE_86C805, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_SPEA_MIRAGE_86C805, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_spea_mirage_86c805_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_mirocrystal_8s_805_vlb_device = { - .name = "S3 86c805 VLB (MiroCRYSTAL 8S)", + .name = "S3 86c805 VLB (MiroCRYSTAL 8S)", .internal_name = "mirocrystal8s_vlb", - .flags = DEVICE_VLB, - .local = S3_MIROCRYSTAL8S_805, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_MIROCRYSTAL8S_805, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_mirocrystal_8s_805_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_mirocrystal_10sd_805_vlb_device = { - .name = "S3 86c805 VLB (MiroCRYSTAL 10SD)", + .name = "S3 86c805 VLB (MiroCRYSTAL 10SD)", .internal_name = "mirocrystal10sd_vlb", - .flags = DEVICE_VLB, - .local = S3_MIROCRYSTAL10SD_805, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_MIROCRYSTAL10SD_805, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_mirocrystal_10sd_805_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_phoenix_86c801_isa_device = { - .name = "S3 86c801 ISA (Phoenix)", + .name = "S3 86c801 ISA (Phoenix)", .internal_name = "px_86c801_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = S3_PHOENIX_86C801, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = S3_PHOENIX_86C801, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_86c80x_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_phoenix_86c805_vlb_device = { - .name = "S3 86c805 VLB (Phoenix)", + .name = "S3 86c805 VLB (Phoenix)", .internal_name = "px_86c805_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_86C805, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_PHOENIX_86C805, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_86c80x_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_metheus_86c928_isa_device = { - .name = "S3 86c928 ISA (Metheus Premier 928)", + .name = "S3 86c928 ISA (Metheus Premier 928)", .internal_name = "metheus928_isa", - .flags = DEVICE_AT | DEVICE_ISA, - .local = S3_METHEUS_86C928, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_AT | DEVICE_ISA, + .local = S3_METHEUS_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_metheus_86c928_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_metheus_86c928_vlb_device = { - .name = "S3 86c928 VLB (Metheus Premier 928)", + .name = "S3 86c928 VLB (Metheus Premier 928)", .internal_name = "metheus928_vlb", - .flags = DEVICE_VLB, - .local = S3_METHEUS_86C928, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_METHEUS_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_metheus_86c928_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_spea_mercury_lite_86c928_pci_device = { - .name = "S3 86c928 PCI (SPEA Mercury Lite)", + .name = "S3 86c928 PCI (SPEA Mercury Lite)", .internal_name = "spea_mercurylite_pci", - .flags = DEVICE_PCI, - .local = S3_SPEA_MERCURY_LITE_PCI, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_SPEA_MERCURY_LITE_PCI, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_spea_mercury_lite_pci_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_mirocrystal_20sd_864_vlb_device = { - .name = "S3 Vision864 VLB (MiroCRYSTAL 20SD)", + .name = "S3 Vision864 VLB (MiroCRYSTAL 20SD)", .internal_name = "mirocrystal20sd_vlb", - .flags = DEVICE_VLB, - .local = S3_MIROCRYSTAL20SD_864, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_MIROCRYSTAL20SD_864, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_mirocrystal_20sd_864_vlb_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_bahamas64_vlb_device = { - .name = "S3 Vision864 VLB (Paradise Bahamas 64)", + .name = "S3 Vision864 VLB (Paradise Bahamas 64)", .internal_name = "bahamas64_vlb", - .flags = DEVICE_VLB, - .local = S3_PARADISE_BAHAMAS64, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_PARADISE_BAHAMAS64, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_bahamas64_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_bahamas64_pci_device = { - .name = "S3 Vision864 PCI (Paradise Bahamas 64)", + .name = "S3 Vision864 PCI (Paradise Bahamas 64)", .internal_name = "bahamas64_pci", - .flags = DEVICE_PCI, - .local = S3_PARADISE_BAHAMAS64, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PARADISE_BAHAMAS64, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_bahamas64_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_mirocrystal_20sv_964_vlb_device = { - .name = "S3 Vision964 VLB (MiroCRYSTAL 20SV)", + .name = "S3 Vision964 VLB (MiroCRYSTAL 20SV)", .internal_name = "mirocrystal20sv_vlb", - .flags = DEVICE_VLB, - .local = S3_MIROCRYSTAL20SV_964, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_MIROCRYSTAL20SV_964, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_mirocrystal_20sv_964_vlb_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_mirocrystal_20sv_964_pci_device = { - .name = "S3 Vision964 PCI (MiroCRYSTAL 20SV)", + .name = "S3 Vision964 PCI (MiroCRYSTAL 20SV)", .internal_name = "mirocrystal20sv_pci", - .flags = DEVICE_PCI, - .local = S3_MIROCRYSTAL20SV_964, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_MIROCRYSTAL20SV_964, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_mirocrystal_20sv_964_pci_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_diamond_stealth64_964_vlb_device = { - .name = "S3 Vision964 VLB (Diamond Stealth64 VRAM)", + .name = "S3 Vision964 VLB (Diamond Stealth64 VRAM)", .internal_name = "stealth64v_vlb", - .flags = DEVICE_VLB, - .local = S3_DIAMOND_STEALTH64_964, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_DIAMOND_STEALTH64_964, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_diamond_stealth64_964_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_diamond_stealth64_964_pci_device = { - .name = "S3 Vision964 PCI (Diamond Stealth64 VRAM)", + .name = "S3 Vision964 PCI (Diamond Stealth64 VRAM)", .internal_name = "stealth64v_pci", - .flags = DEVICE_PCI, - .local = S3_DIAMOND_STEALTH64_964, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH64_964, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_diamond_stealth64_964_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_9fx_771_pci_device = { - .name = "S3 Vision968 PCI (Number 9 9FX 771)", + .name = "S3 Vision968 PCI (Number 9 9FX 771)", .internal_name = "n9_9fx_771_pci", - .flags = DEVICE_PCI, - .local = S3_NUMBER9_9FX_771, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_NUMBER9_9FX_771, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_9fx_771_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_vision968_pci_device = { - .name = "S3 Vision968 PCI (Phoenix)", + .name = "S3 Vision968 PCI (Phoenix)", .internal_name = "px_vision968_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_VISION968, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_VISION968, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_vision968_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_vision968_vlb_device = { - .name = "S3 Vision968 VLB (Phoenix)", + .name = "S3 Vision968 VLB (Phoenix)", .internal_name = "px_vision968_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_VISION968, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_PHOENIX_VISION968, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_vision968_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_mirovideo_40sv_ergo_968_pci_device = { - .name = "S3 Vision968 PCI (MiroVIDEO 40SV Ergo)", + .name = "S3 Vision968 PCI (MiroVIDEO 40SV Ergo)", .internal_name = "mirovideo40sv_pci", - .flags = DEVICE_PCI, - .local = S3_MIROVIDEO40SV_ERGO_968, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_MIROVIDEO40SV_ERGO_968, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_mirovideo_40sv_ergo_968_pci_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_spea_mercury_p64v_pci_device = { - .name = "S3 Vision968 PCI (SPEA Mercury P64V)", + .name = "S3 Vision968 PCI (SPEA Mercury P64V)", .internal_name = "spea_mercury64p_pci", - .flags = DEVICE_PCI, - .local = S3_SPEA_MERCURY_P64V, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_SPEA_MERCURY_P64V, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_spea_mercury_p64v_pci_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_9fx_vlb_device = { - .name = "S3 Trio64 VLB (Number 9 9FX 330)", + .name = "S3 Trio64 VLB (Number 9 9FX 330)", .internal_name = "n9_9fx_vlb", - .flags = DEVICE_VLB, - .local = S3_NUMBER9_9FX, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_NUMBER9_9FX, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_9fx_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_9fx_pci_device = { - .name = "S3 Trio64 PCI (Number 9 9FX 330)", + .name = "S3 Trio64 PCI (Number 9 9FX 330)", .internal_name = "n9_9fx_pci", - .flags = DEVICE_PCI, - .local = S3_NUMBER9_9FX, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_NUMBER9_9FX, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_9fx_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_phoenix_trio32_vlb_device = { - .name = "S3 Trio32 VLB (Phoenix)", + .name = "S3 Trio32 VLB (Phoenix)", .internal_name = "px_trio32_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_TRIO32, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_PHOENIX_TRIO32, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_trio32_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_phoenix_trio32_config + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config }; const device_t s3_phoenix_trio32_pci_device = { - .name = "S3 Trio32 PCI (Phoenix)", + .name = "S3 Trio32 PCI (Phoenix)", .internal_name = "px_trio32_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_TRIO32, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_TRIO32, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_trio32_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_phoenix_trio32_config + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config }; const device_t s3_diamond_stealth_se_vlb_device = { - .name = "S3 Trio32 VLB (Diamond Stealth SE)", + .name = "S3 Trio32 VLB (Diamond Stealth SE)", .internal_name = "stealthse_vlb", - .flags = DEVICE_VLB, - .local = S3_DIAMOND_STEALTH_SE, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_DIAMOND_STEALTH_SE, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_diamond_stealth_se_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_phoenix_trio32_config + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config }; const device_t s3_diamond_stealth_se_pci_device = { - .name = "S3 Trio32 PCI (Diamond Stealth SE)", + .name = "S3 Trio32 PCI (Diamond Stealth SE)", .internal_name = "stealthse_pci", - .flags = DEVICE_PCI, - .local = S3_DIAMOND_STEALTH_SE, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH_SE, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_diamond_stealth_se_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_phoenix_trio32_config + .force_redraw = s3_force_redraw, + .config = s3_phoenix_trio32_config }; const device_t s3_phoenix_trio64_vlb_device = { - .name = "S3 Trio64 VLB (Phoenix)", + .name = "S3 Trio64 VLB (Phoenix)", .internal_name = "px_trio64_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_TRIO64, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_PHOENIX_TRIO64, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_trio64_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_trio64_onboard_pci_device = { - .name = "S3 Trio64 PCI On-Board (Phoenix)", + .name = "S3 Trio64 PCI On-Board (Phoenix)", .internal_name = "px_trio64_onboard_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_TRIO64_ONBOARD, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_TRIO64_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = NULL }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_trio64_pci_device = { - .name = "S3 Trio64 PCI (Phoenix)", + .name = "S3 Trio64 PCI (Phoenix)", .internal_name = "px_trio64_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_TRIO64, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_TRIO64, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_trio64_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_trio64vplus_onboard_pci_device = { - .name = "S3 Trio64V+ PCI On-Board (Phoenix)", + .name = "S3 Trio64V+ PCI On-Board (Phoenix)", .internal_name = "px_trio64vplus_onboard_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_TRIO64VPLUS_ONBOARD, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_TRIO64VPLUS_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = NULL }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_trio64vplus_pci_device = { - .name = "S3 Trio64V+ PCI (Phoenix)", + .name = "S3 Trio64V+ PCI (Phoenix)", .internal_name = "px_trio64vplus_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_TRIO64VPLUS, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_TRIO64VPLUS, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_trio64vplus_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_vision864_vlb_device = { - .name = "S3 Vision864 VLB (Phoenix)", + .name = "S3 Vision864 VLB (Phoenix)", .internal_name = "px_vision864_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_VISION864, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_PHOENIX_VISION864, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_vision864_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_vision864_pci_device = { - .name = "S3 Vision864 PCI (Phoenix)", + .name = "S3 Vision864 PCI (Phoenix)", .internal_name = "px_vision864_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_VISION864, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_VISION864, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_vision864_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_9fx_531_pci_device = { - .name = "S3 Vision868 PCI (Number 9 9FX 531)", + .name = "S3 Vision868 PCI (Number 9 9FX 531)", .internal_name = "n9_9fx_531_pci", - .flags = DEVICE_PCI, - .local = S3_NUMBER9_9FX_531, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_NUMBER9_9FX_531, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_9fx_531_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_phoenix_vision868_vlb_device = { - .name = "S3 Vision868 VLB (Phoenix)", + .name = "S3 Vision868 VLB (Phoenix)", .internal_name = "px_vision868_vlb", - .flags = DEVICE_VLB, - .local = S3_PHOENIX_VISION868, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_PHOENIX_VISION868, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_vision868_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_phoenix_vision868_pci_device = { - .name = "S3 Vision868 PCI (Phoenix)", + .name = "S3 Vision868 PCI (Phoenix)", .internal_name = "px_vision868_pci", - .flags = DEVICE_PCI, - .local = S3_PHOENIX_VISION868, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_PHOENIX_VISION868, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_phoenix_vision868_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_diamond_stealth64_vlb_device = { - .name = "S3 Trio64 VLB (Diamond Stealth64 DRAM)", + .name = "S3 Trio64 VLB (Diamond Stealth64 DRAM)", .internal_name = "stealth64d_vlb", - .flags = DEVICE_VLB, - .local = S3_DIAMOND_STEALTH64_764, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_DIAMOND_STEALTH64_764, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_diamond_stealth64_764_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_diamond_stealth64_pci_device = { - .name = "S3 Trio64 PCI (Diamond Stealth64 DRAM)", + .name = "S3 Trio64 PCI (Diamond Stealth64 DRAM)", .internal_name = "stealth64d_pci", - .flags = DEVICE_PCI, - .local = S3_DIAMOND_STEALTH64_764, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH64_764, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_diamond_stealth64_764_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_spea_mirage_p64_vlb_device = { - .name = "S3 Trio64 VLB (SPEA Mirage P64)", + .name = "S3 Trio64 VLB (SPEA Mirage P64)", .internal_name = "spea_miragep64_vlb", - .flags = DEVICE_VLB, - .local = S3_SPEA_MIRAGE_P64, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_VLB, + .local = S3_SPEA_MIRAGE_P64, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_spea_mirage_p64_vlb_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_9fx_config + .force_redraw = s3_force_redraw, + .config = s3_9fx_config }; const device_t s3_elsa_winner2000_pro_x_964_pci_device = { - .name = "S3 Vision964 PCI (ELSA Winner 2000 Pro/X)", + .name = "S3 Vision964 PCI (ELSA Winner 2000 Pro/X)", .internal_name = "elsawin2kprox_964_pci", - .flags = DEVICE_PCI, - .local = S3_ELSAWIN2KPROX_964, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_ELSAWIN2KPROX_964, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_elsa_winner2000_pro_x_964_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_968_config + .force_redraw = s3_force_redraw, + .config = s3_968_config }; const device_t s3_elsa_winner2000_pro_x_pci_device = { - .name = "S3 Vision968 PCI (ELSA Winner 2000 Pro/X)", + .name = "S3 Vision968 PCI (ELSA Winner 2000 Pro/X)", .internal_name = "elsawin2kprox_pci", - .flags = DEVICE_PCI, - .local = S3_ELSAWIN2KPROX, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_ELSAWIN2KPROX, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_elsa_winner2000_pro_x_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_968_config + .force_redraw = s3_force_redraw, + .config = s3_968_config }; const device_t s3_trio64v2_dx_pci_device = { - .name = "S3 Trio64V2/DX PCI", + .name = "S3 Trio64V2/DX PCI", .internal_name = "trio64v2dx_pci", - .flags = DEVICE_PCI, - .local = S3_TRIO64V2_DX, - .init = s3_init, - .close = s3_close, - .reset = s3_reset, + .flags = DEVICE_PCI, + .local = S3_TRIO64V2_DX, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, { .available = s3_trio64v2_dx_available }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; const device_t s3_trio64v2_dx_onboard_pci_device = { - .name = "S3 Trio64V2/DX On-Board PCI", + .name = "S3 Trio64V2/DX On-Board PCI", .internal_name = "trio64v2dx_onboard_pci", - .flags = DEVICE_PCI, - .local = S3_TRIO64V2_DX_ONBOARD, - .init = s3_init, - .close = s3_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = S3_TRIO64V2_DX_ONBOARD, + .init = s3_init, + .close = s3_close, + .reset = NULL, { .available = NULL }, .speed_changed = s3_speed_changed, - .force_redraw = s3_force_redraw, - .config = s3_standard_config + .force_redraw = s3_force_redraw, + .config = s3_standard_config }; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 475269f93..d8a440f30 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -39,273 +39,266 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> - -static int dither[4][4] = -{ - {0, 4, 1, 5}, - {6, 2, 7, 3}, - {1, 5, 0, 4}, - {7, 3, 6, 2}, +static int dither[4][4] = { + {0, 4, 1, 5}, + { 6, 2, 7, 3}, + { 1, 5, 0, 4}, + { 7, 3, 6, 2}, }; -#define RB_SIZE 256 -#define RB_MASK (RB_SIZE - 1) +#define RB_SIZE 256 +#define RB_MASK (RB_SIZE - 1) -#define RB_ENTRIES (virge->s3d_write_idx - virge->s3d_read_idx) -#define RB_FULL (RB_ENTRIES == RB_SIZE) -#define RB_EMPTY (!RB_ENTRIES) +#define RB_ENTRIES (virge->s3d_write_idx - virge->s3d_read_idx) +#define RB_FULL (RB_ENTRIES == RB_SIZE) +#define RB_EMPTY (!RB_ENTRIES) -#define FIFO_SIZE 65536 -#define FIFO_MASK (FIFO_SIZE - 1) -#define FIFO_ENTRY_SIZE (1 << 31) +#define FIFO_SIZE 65536 +#define FIFO_MASK (FIFO_SIZE - 1) +#define FIFO_ENTRY_SIZE (1 << 31) -#define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) -#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= (FIFO_SIZE - 4)) -#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) +#define FIFO_ENTRIES (virge->fifo_write_idx - virge->fifo_read_idx) +#define FIFO_FULL ((virge->fifo_write_idx - virge->fifo_read_idx) >= (FIFO_SIZE - 4)) +#define FIFO_EMPTY (virge->fifo_read_idx == virge->fifo_write_idx) -#define FIFO_TYPE 0xff000000 -#define FIFO_ADDR 0x00ffffff +#define FIFO_TYPE 0xff000000 +#define FIFO_ADDR 0x00ffffff -#define ROM_VIRGE_325 "roms/video/s3virge/86c325.bin" -#define ROM_DIAMOND_STEALTH3D_2000 "roms/video/s3virge/s3virge.bin" -#define ROM_DIAMOND_STEALTH3D_3000 "roms/video/s3virge/diamondstealth3000.vbi" -#define ROM_STB_VELOCITY_3D "roms/video/s3virge/stb_velocity3d_110.BIN" -#define ROM_VIRGE_DX "roms/video/s3virge/86c375_1.bin" -#define ROM_DIAMOND_STEALTH3D_2000PRO "roms/video/s3virge/virgedxdiamond.vbi" -#define ROM_VIRGE_GX "roms/video/s3virge/86c375_4.bin" -#define ROM_VIRGE_GX2 "roms/video/s3virge/flagpoint.VBI" -#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/86c357.bin" -#define ROM_TRIO3D2X "roms/video/s3virge/TRIO3D2X_8mbsdr.VBI" +#define ROM_VIRGE_325 "roms/video/s3virge/86c325.bin" +#define ROM_DIAMOND_STEALTH3D_2000 "roms/video/s3virge/s3virge.bin" +#define ROM_DIAMOND_STEALTH3D_3000 "roms/video/s3virge/diamondstealth3000.vbi" +#define ROM_STB_VELOCITY_3D "roms/video/s3virge/stb_velocity3d_110.BIN" +#define ROM_VIRGE_DX "roms/video/s3virge/86c375_1.bin" +#define ROM_DIAMOND_STEALTH3D_2000PRO "roms/video/s3virge/virgedxdiamond.vbi" +#define ROM_VIRGE_GX "roms/video/s3virge/86c375_4.bin" +#define ROM_VIRGE_GX2 "roms/video/s3virge/flagpoint.VBI" +#define ROM_DIAMOND_STEALTH3D_4000 "roms/video/s3virge/86c357.bin" +#define ROM_TRIO3D2X "roms/video/s3virge/TRIO3D2X_8mbsdr.VBI" -enum -{ - S3_VIRGE_325, - S3_DIAMOND_STEALTH3D_2000, - S3_DIAMOND_STEALTH3D_3000, - S3_STB_VELOCITY_3D, - S3_VIRGE_DX, - S3_DIAMOND_STEALTH3D_2000PRO, - S3_VIRGE_GX, - S3_VIRGE_GX2, - S3_DIAMOND_STEALTH3D_4000, - S3_TRIO_3D2X +enum { + S3_VIRGE_325, + S3_DIAMOND_STEALTH3D_2000, + S3_DIAMOND_STEALTH3D_3000, + S3_STB_VELOCITY_3D, + S3_VIRGE_DX, + S3_DIAMOND_STEALTH3D_2000PRO, + S3_VIRGE_GX, + S3_VIRGE_GX2, + S3_DIAMOND_STEALTH3D_4000, + S3_TRIO_3D2X }; -enum -{ - S3_VIRGE, - S3_VIRGEVX, - S3_VIRGEDX, - S3_VIRGEGX2, - S3_TRIO3D2X +enum { + S3_VIRGE, + S3_VIRGEVX, + S3_VIRGEDX, + S3_VIRGEGX2, + S3_TRIO3D2X }; -enum -{ - FIFO_INVALID = (0x00 << 24), - FIFO_WRITE_BYTE = (0x01 << 24), - FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24) +enum { + FIFO_INVALID = (0x00 << 24), + FIFO_WRITE_BYTE = (0x01 << 24), + FIFO_WRITE_WORD = (0x02 << 24), + FIFO_WRITE_DWORD = (0x03 << 24) }; typedef struct { - uint32_t addr_type; - uint32_t val; + uint32_t addr_type; + uint32_t val; } fifo_entry_t; -typedef struct s3d_t -{ - uint32_t cmd_set; - int clip_l, clip_r, clip_t, clip_b; +typedef struct s3d_t { + uint32_t cmd_set; + int clip_l, clip_r, clip_t, clip_b; - uint32_t dest_base; - uint32_t dest_str; + uint32_t dest_base; + uint32_t dest_str; - uint32_t z_base; - uint32_t z_str; + uint32_t z_base; + uint32_t z_str; - uint32_t tex_base; - uint32_t tex_bdr_clr; - uint32_t tbv, tbu; - int32_t TdVdX, TdUdX; - int32_t TdVdY, TdUdY; - uint32_t tus, tvs; + uint32_t tex_base; + uint32_t tex_bdr_clr; + uint32_t tbv, tbu; + int32_t TdVdX, TdUdX; + int32_t TdVdY, TdUdY; + uint32_t tus, tvs; - int32_t TdZdX, TdZdY; - uint32_t tzs; + int32_t TdZdX, TdZdY; + uint32_t tzs; - int32_t TdWdX, TdWdY; - uint32_t tws; + int32_t TdWdX, TdWdY; + uint32_t tws; - int32_t TdDdX, TdDdY; - uint32_t tds; + int32_t TdDdX, TdDdY; + uint32_t tds; - int16_t TdGdX, TdBdX, TdRdX, TdAdX; - int16_t TdGdY, TdBdY, TdRdY, TdAdY; - uint32_t tgs, tbs, trs, tas; + int16_t TdGdX, TdBdX, TdRdX, TdAdX; + int16_t TdGdY, TdBdY, TdRdY, TdAdY; + uint32_t tgs, tbs, trs, tas; - uint32_t TdXdY12; - uint32_t txend12; - uint32_t TdXdY01; - uint32_t txend01; - uint32_t TdXdY02; - uint32_t txs; - uint32_t tys; - int ty01, ty12, tlr; + uint32_t TdXdY12; + uint32_t txend12; + uint32_t TdXdY01; + uint32_t txend01; + uint32_t TdXdY02; + uint32_t txs; + uint32_t tys; + int ty01, ty12, tlr; - uint8_t fog_r, fog_g, fog_b; + uint8_t fog_r, fog_g, fog_b; } s3d_t; -typedef struct virge_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t mmio_mapping; - mem_mapping_t new_mmio_mapping; +typedef struct virge_t { + mem_mapping_t linear_mapping; + mem_mapping_t mmio_mapping; + mem_mapping_t new_mmio_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; + svga_t svga; - uint8_t bank; - uint8_t ma_ext; - uint8_t reg6b, lfb_bios; + uint8_t bank; + uint8_t ma_ext; + uint8_t reg6b, lfb_bios; - uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; + uint8_t virge_id, virge_id_high, virge_id_low, virge_rev; - uint8_t int_line; + uint8_t int_line; - uint32_t linear_base, linear_size; + uint32_t linear_base, linear_size; - uint8_t pci_regs[256]; - int card; + uint8_t pci_regs[256]; + int card; - int pci; - int chip; - int is_agp; + int pci; + int chip; + int is_agp; - int bilinear_enabled; - int dithering_enabled; - uint32_t memory_size; - uint32_t vram_mask; + int bilinear_enabled; + int dithering_enabled; + uint32_t memory_size; + uint32_t vram_mask; - thread_t *render_thread; - event_t *wake_render_thread; - event_t *wake_main_thread; - event_t *not_full_event; + thread_t *render_thread; + event_t *wake_render_thread; + event_t *wake_main_thread; + event_t *not_full_event; - uint32_t hwc_fg_col, hwc_bg_col; - int hwc_col_stack_pos; + uint32_t hwc_fg_col, hwc_bg_col; + int hwc_col_stack_pos; - struct - { - uint32_t src_base; - uint32_t dest_base; - int clip_l, clip_r, clip_t, clip_b; - int dest_str, src_str; - uint32_t mono_pat_0; - uint32_t mono_pat_1; - uint32_t pat_bg_clr; - uint32_t pat_fg_clr; - uint32_t src_bg_clr; - uint32_t src_fg_clr; - uint32_t cmd_set; - int r_width, r_height; - int rsrc_x, rsrc_y; - int rdest_x, rdest_y; + struct + { + uint32_t src_base; + uint32_t dest_base; + int clip_l, clip_r, clip_t, clip_b; + int dest_str, src_str; + uint32_t mono_pat_0; + uint32_t mono_pat_1; + uint32_t pat_bg_clr; + uint32_t pat_fg_clr; + uint32_t src_bg_clr; + uint32_t src_fg_clr; + uint32_t cmd_set; + int r_width, r_height; + int rsrc_x, rsrc_y; + int rdest_x, rdest_y; - int lxend0, lxend1; - int32_t ldx; - uint32_t lxstart, lystart; - int lycnt; - int line_dir; + int lxend0, lxend1; + int32_t ldx; + uint32_t lxstart, lystart; + int lycnt; + int line_dir; - int src_x, src_y; - int dest_x, dest_y; - int w, h; - uint8_t rop; + int src_x, src_y; + int dest_x, dest_y; + int w, h; + uint8_t rop; - int data_left_count; - uint32_t data_left; + int data_left_count; + uint32_t data_left; - uint32_t pattern_8[8*8]; - uint32_t pattern_16[8*8]; - uint32_t pattern_24[8*8]; - uint32_t pattern_32[8*8]; + uint32_t pattern_8[8 * 8]; + uint32_t pattern_16[8 * 8]; + uint32_t pattern_24[8 * 8]; + uint32_t pattern_32[8 * 8]; - uint32_t prdx; - uint32_t prxstart; - uint32_t pldx; - uint32_t plxstart; - uint32_t pystart; - uint32_t pycnt; - uint32_t dest_l, dest_r; - } s3d; + uint32_t prdx; + uint32_t prxstart; + uint32_t pldx; + uint32_t plxstart; + uint32_t pystart; + uint32_t pycnt; + uint32_t dest_l, dest_r; + } s3d; - s3d_t s3d_tri; + s3d_t s3d_tri; - s3d_t s3d_buffer[RB_SIZE]; - int s3d_read_idx, s3d_write_idx; - int s3d_busy; - int render_idx; + s3d_t s3d_buffer[RB_SIZE]; + int s3d_read_idx, s3d_write_idx; + int s3d_busy; + int render_idx; - struct - { - uint32_t pri_ctrl; - uint32_t chroma_ctrl; - uint32_t sec_ctrl; - uint32_t chroma_upper_bound; - uint32_t sec_filter; - uint32_t blend_ctrl; - uint32_t pri_fb0, pri_fb1; - uint32_t pri_stride; - uint32_t buffer_ctrl; - uint32_t sec_fb0, sec_fb1; - uint32_t sec_stride; - uint32_t overlay_ctrl; - int32_t k1_vert_scale; - int32_t k2_vert_scale; - int32_t dda_vert_accumulator; - int32_t k1_horiz_scale; - int32_t k2_horiz_scale; - int32_t dda_horiz_accumulator; - uint32_t fifo_ctrl; - uint32_t pri_start; - uint32_t pri_size; - uint32_t sec_start; - uint32_t sec_size; + struct + { + uint32_t pri_ctrl; + uint32_t chroma_ctrl; + uint32_t sec_ctrl; + uint32_t chroma_upper_bound; + uint32_t sec_filter; + uint32_t blend_ctrl; + uint32_t pri_fb0, pri_fb1; + uint32_t pri_stride; + uint32_t buffer_ctrl; + uint32_t sec_fb0, sec_fb1; + uint32_t sec_stride; + uint32_t overlay_ctrl; + int32_t k1_vert_scale; + int32_t k2_vert_scale; + int32_t dda_vert_accumulator; + int32_t k1_horiz_scale; + int32_t k2_horiz_scale; + int32_t dda_horiz_accumulator; + uint32_t fifo_ctrl; + uint32_t pri_start; + uint32_t pri_size; + uint32_t sec_start; + uint32_t sec_size; - int sdif; + int sdif; - int pri_x, pri_y, pri_w, pri_h; - int sec_x, sec_y, sec_w, sec_h; - } streams; + int pri_x, pri_y, pri_w, pri_h; + int sec_x, sec_y, sec_w, sec_h; + } streams; - uint8_t cmd_dma; - uint32_t cmd_dma_base; - uint32_t dma_ptr; - uint64_t blitter_time; - volatile int fifo_slot; + uint8_t cmd_dma; + uint32_t cmd_dma_base; + uint32_t dma_ptr; + uint64_t blitter_time; + volatile int fifo_slot; - pc_timer_t tri_timer; + pc_timer_t tri_timer; - int virge_busy, local; + int virge_busy, local; - uint8_t subsys_stat, subsys_cntl, advfunc_cntl; + uint8_t subsys_stat, subsys_cntl, advfunc_cntl; - uint8_t render_thread_run; + uint8_t render_thread_run; - uint8_t serialport; + uint8_t serialport; - void *i2c, *ddc; + void *i2c, *ddc; - int waiting; + int waiting; } virge_t; -static video_timings_t timing_diamond_stealth3d_2000_pci = {VIDEO_PCI, 2, 2, 3, 28, 28, 45}; -static video_timings_t timing_diamond_stealth3d_3000_pci = {VIDEO_PCI, 2, 2, 4, 26, 26, 42}; -static video_timings_t timing_virge_dx_pci = {VIDEO_PCI, 2, 2, 3, 28, 28, 45}; -static video_timings_t timing_virge_agp = {VIDEO_AGP, 2, 2, 3, 28, 28, 45}; +static video_timings_t timing_diamond_stealth3d_2000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; +static video_timings_t timing_diamond_stealth3d_3000_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 4, .read_b = 26, .read_w = 26, .read_l = 42 }; +static video_timings_t timing_virge_dx_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; +static video_timings_t timing_virge_agp = { .type = VIDEO_AGP, .write_b = 2, .write_w = 2, .write_l = 3, .read_b = 28, .read_w = 28, .read_l = 45 }; static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri); @@ -321,34 +314,33 @@ static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p); static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p); static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p); -enum -{ - CMD_SET_AE = 1, - CMD_SET_HC = (1 << 1), +enum { + CMD_SET_AE = 1, + CMD_SET_HC = (1 << 1), - CMD_SET_FORMAT_MASK = (7 << 2), - CMD_SET_FORMAT_8 = (0 << 2), - CMD_SET_FORMAT_16 = (1 << 2), - CMD_SET_FORMAT_24 = (2 << 2), + CMD_SET_FORMAT_MASK = (7 << 2), + CMD_SET_FORMAT_8 = (0 << 2), + CMD_SET_FORMAT_16 = (1 << 2), + CMD_SET_FORMAT_24 = (2 << 2), - CMD_SET_MS = (1 << 6), - CMD_SET_IDS = (1 << 7), - CMD_SET_MP = (1 << 8), - CMD_SET_TP = (1 << 9), + CMD_SET_MS = (1 << 6), + CMD_SET_IDS = (1 << 7), + CMD_SET_MP = (1 << 8), + CMD_SET_TP = (1 << 9), - CMD_SET_ITA_MASK = (3 << 10), - CMD_SET_ITA_BYTE = (0 << 10), - CMD_SET_ITA_WORD = (1 << 10), - CMD_SET_ITA_DWORD = (2 << 10), + CMD_SET_ITA_MASK = (3 << 10), + CMD_SET_ITA_BYTE = (0 << 10), + CMD_SET_ITA_WORD = (1 << 10), + CMD_SET_ITA_DWORD = (2 << 10), - CMD_SET_ZUP = (1 << 23), + CMD_SET_ZUP = (1 << 23), - CMD_SET_ZB_MODE = (3 << 24), + CMD_SET_ZB_MODE = (3 << 24), - CMD_SET_XP = (1 << 25), - CMD_SET_YP = (1 << 26), + CMD_SET_XP = (1 << 25), + CMD_SET_YP = (1 << 26), - CMD_SET_COMMAND_MASK = (15 << 27) + CMD_SET_COMMAND_MASK = (15 << 27) }; #define CMD_SET_FE (1 << 17) @@ -356,52 +348,48 @@ enum #define CMD_SET_ABC_ENABLE (1 << 19) #define CMD_SET_TWE (1 << 26) -enum -{ - CMD_SET_COMMAND_BITBLT = (0 << 27), - CMD_SET_COMMAND_RECTFILL = (2 << 27), - CMD_SET_COMMAND_LINE = (3 << 27), - CMD_SET_COMMAND_POLY = (5 << 27), - CMD_SET_COMMAND_NOP = (15 << 27) +enum { + CMD_SET_COMMAND_BITBLT = (0 << 27), + CMD_SET_COMMAND_RECTFILL = (2 << 27), + CMD_SET_COMMAND_LINE = (3 << 27), + CMD_SET_COMMAND_POLY = (5 << 27), + CMD_SET_COMMAND_NOP = (15 << 27) }; -#define INT_VSY (1 << 0) -#define INT_S3D_DONE (1 << 1) -#define INT_FIFO_OVF (1 << 2) -#define INT_FIFO_EMP (1 << 3) -#define INT_3DF_EMP (1 << 6) -#define INT_MASK 0xff +#define INT_VSY (1 << 0) +#define INT_S3D_DONE (1 << 1) +#define INT_FIFO_OVF (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_3DF_EMP (1 << 6) +#define INT_MASK 0xff #define SERIAL_PORT_SCW (1 << 0) #define SERIAL_PORT_SDW (1 << 1) #define SERIAL_PORT_SCR (1 << 2) #define SERIAL_PORT_SDR (1 << 3) - #ifdef ENABLE_S3_VIRGE_LOG int s3_virge_do_log = ENABLE_S3_VIRGE_LOG; - static void s3_virge_log(const char *fmt, ...) { va_list ap; if (s3_virge_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define s3_virge_log(fmt, ...) +# define s3_virge_log(fmt, ...) #endif - static void s3_virge_tri_timer(void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *) p; thread_set_event(virge->wake_render_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -409,1893 +397,2052 @@ s3_virge_tri_timer(void *p) static void queue_triangle(virge_t *virge) { - if (RB_FULL) - { - thread_reset_event(virge->not_full_event); - thread_reset_event(virge->wake_main_thread); - if (RB_FULL) { - thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ - thread_wait_event(virge->wake_main_thread, -1); - } - } - virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; - virge->s3d_write_idx++; + if (RB_FULL) { + thread_reset_event(virge->not_full_event); + thread_reset_event(virge->wake_main_thread); + if (RB_FULL) { + thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ + thread_wait_event(virge->wake_main_thread, -1); + } + } + virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; + virge->s3d_write_idx++; - if (!virge->s3d_busy) { - if (!(timer_is_enabled(&virge->tri_timer))) - timer_set_delay_u64(&virge->tri_timer, 100 * TIMER_USEC); - } + if (!virge->s3d_busy) { + if (!(timer_is_enabled(&virge->tri_timer))) + timer_set_delay_u64(&virge->tri_timer, 100 * TIMER_USEC); + } } static void s3_virge_update_irqs(virge_t *virge) { - if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & (virge->subsys_cntl & INT_MASK))) - pci_set_irq(virge->card, PCI_INTA); - else - pci_clear_irq(virge->card, PCI_INTA); + if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & (virge->subsys_cntl & INT_MASK))) + pci_set_irq(virge->card, PCI_INTA); + else + pci_clear_irq(virge->card, PCI_INTA); } - static void render_thread(void *param) { - virge_t *virge = (virge_t *)param; + virge_t *virge = (virge_t *) param; - while (virge->render_thread_run) { - thread_wait_event(virge->wake_render_thread, -1); - thread_reset_event(virge->wake_render_thread); - virge->s3d_busy = 1; - while (!RB_EMPTY) { - s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); - virge->s3d_read_idx++; - if (RB_ENTRIES == RB_MASK) { - thread_set_event(virge->not_full_event); - thread_set_event(virge->wake_main_thread); - } - } - virge->s3d_busy = 0; - virge->subsys_stat |= INT_S3D_DONE; - s3_virge_update_irqs(virge); - } -} - - -static void s3_virge_out(uint16_t addr, uint8_t val, void *p) -{ - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t old; - uint32_t cursoraddr; - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; - - switch (addr) - { - case 0x3c5: - if (svga->seqaddr >= 0x10) - { - svga->seqregs[svga->seqaddr & 0x1f]=val; - svga_recalctimings(svga); - return; - } - if (svga->seqaddr == 4) /*Chain-4 - update banking*/ - { - if (val & 8) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - } else if (svga->seqaddr == 0x08) { - svga->seqregs[svga->seqaddr] = val & 0x0f; - return; - } else if ((svga->seqaddr == 0x0d) && (svga->seqregs[0x08] == 0x06)) { - svga->seqregs[svga->seqaddr] = val; - svga->dpms = (svga->seqregs[0x0d] & 0x50) || (svga->crtc[0x56] & 0x06); - svga_recalctimings(svga); - return; - } - break; - - case 0x3d4: - svga->crtcreg = val; - return; - case 0x3d5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && - (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && - (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) - return; - if ((svga->crtcreg >= 0x40) && ((svga->crtc[0x39] & 0xe0) != 0xa0)) - return; - if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) - return; - if (svga->crtcreg >= 0x80) - return; - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (svga->crtcreg > 0x18) - s3_virge_log("OUTB VGA reg = %02x, val = %02x\n", svga->crtcreg, val); - - switch (svga->crtcreg) - { - case 0x31: - virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); - break; - case 0x32: - s3_virge_update_irqs(virge); - break; - - case 0x69: - virge->ma_ext = val & 0x1f; - break; - - case 0x35: - virge->bank = (virge->bank & 0x70) | (val & 0xf); - if (svga->chain4) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - break; - case 0x51: - virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2); - if (svga->chain4) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2); - break; - case 0x6a: - virge->bank = val; - if (svga->chain4) - svga->write_bank = svga->read_bank = virge->bank << 16; - else - svga->write_bank = svga->read_bank = virge->bank << 14; - break; - - case 0x3a: - if (val & 0x10) - svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ - break; - - case 0x45: - svga->hwcursor.ena = val & 1; - break; - case 0x46: case 0x47: case 0x48: case 0x49: - case 0x4c: case 0x4d: case 0x4e: case 0x4f: - svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; - svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; - svga->hwcursor.xoff = svga->crtc[0x4e] & 0x3f; - svga->hwcursor.yoff = svga->crtc[0x4f] & 0x3f; - cursoraddr = (virge->memory_size == 8) ? 0x1fff : 0x0fff; - svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & cursoraddr) * 1024) + (svga->hwcursor.yoff * 16); - break; - - case 0x4a: - switch (virge->hwc_col_stack_pos) - { - case 0: - virge->hwc_fg_col = (virge->hwc_fg_col & 0xffff00) | val; - break; - case 1: - virge->hwc_fg_col = (virge->hwc_fg_col & 0xff00ff) | (val << 8); - break; - case 2: - virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); - break; - } - virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; - break; - case 0x4b: - switch (virge->hwc_col_stack_pos) - { - case 0: - virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; - break; - case 1: - virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); - break; - case 2: - virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); - break; - } - virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; - break; - - case 0x53: - case 0x58: case 0x59: case 0x5a: - s3_virge_updatemapping(virge); - break; - - case 0x56: - svga->dpms = (svga->seqregs[0x0d] & 0x50) || (svga->crtc[0x56] & 0x06); - old = ~val; /* force recalc */ - break; - - case 0x5c: - if ((val & 0xa0) == 0x80) - i2c_gpio_set(virge->i2c, !!(val & 0x40), !!(val & 0x10)); - break; - - case 0x67: - switch (val >> 4) - { - case 2: case 3: svga->bpp = 15; break; - case 4: case 5: svga->bpp = 16; break; - case 7: svga->bpp = 24; break; - case 13: svga->bpp = (virge->chip == S3_VIRGEVX) ? 24 : 32; break; - default: svga->bpp = 8; break; - } - break; - - case 0xaa: - i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); - break; - } - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - if ((svga->crtc[0x67] & 0xc) != 0xc) - svga->ma_latch |= (virge->ma_ext << 16); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - break; + while (virge->render_thread_run) { + thread_wait_event(virge->wake_render_thread, -1); + thread_reset_event(virge->wake_render_thread); + virge->s3d_busy = 1; + while (!RB_EMPTY) { + s3_virge_triangle(virge, &virge->s3d_buffer[virge->s3d_read_idx & RB_MASK]); + virge->s3d_read_idx++; + if (RB_ENTRIES == RB_MASK) { + thread_set_event(virge->not_full_event); + thread_set_event(virge->wake_main_thread); + } } - svga_out(addr, val, svga); + virge->s3d_busy = 0; + virge->subsys_stat |= INT_S3D_DONE; + s3_virge_update_irqs(virge); + } } -static uint8_t s3_virge_in(uint16_t addr, void *p) +static void +s3_virge_out(uint16_t addr, uint8_t val, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t ret; + virge_t *virge = (virge_t *) p; + svga_t *svga = &virge->svga; + uint8_t old; + uint32_t cursoraddr; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3c1: - if (svga->attraddr > 0x14) - ret = 0xff; + switch (addr) { + case 0x3c5: + if (svga->seqaddr >= 0x10) { + svga->seqregs[svga->seqaddr & 0x1f] = val; + svga_recalctimings(svga); + return; + } + if (svga->seqaddr == 4) /*Chain-4 - update banking*/ + { + if (val & 8) + svga->write_bank = svga->read_bank = virge->bank << 16; else - ret = svga_in(addr, svga); - break; + svga->write_bank = svga->read_bank = virge->bank << 14; + } else if (svga->seqaddr == 0x08) { + svga->seqregs[svga->seqaddr] = val & 0x0f; + return; + } else if ((svga->seqaddr == 0x0d) && (svga->seqregs[0x08] == 0x06)) { + svga->seqregs[svga->seqaddr] = val; + svga->dpms = (svga->seqregs[0x0d] & 0x50) || (svga->crtc[0x56] & 0x06); + svga_recalctimings(svga); + return; + } + break; - case 0x3c5: - if (svga->seqaddr >= 8) - ret = svga->seqregs[svga->seqaddr & 0x1f]; - else if (svga->seqaddr <= 4) - ret = svga_in(addr, svga); - else - ret = 0xff; - break; + case 0x3d4: + svga->crtcreg = val; + return; + case 0x3d5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + if ((svga->crtcreg >= 0x20) && (svga->crtcreg < 0x40) && (svga->crtcreg != 0x36) && (svga->crtcreg != 0x38) && (svga->crtcreg != 0x39) && ((svga->crtc[0x38] & 0xcc) != 0x48)) + return; + if ((svga->crtcreg >= 0x40) && ((svga->crtc[0x39] & 0xe0) != 0xa0)) + return; + if ((svga->crtcreg == 0x36) && (svga->crtc[0x39] != 0xa5)) + return; + if (svga->crtcreg >= 0x80) + return; + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - case 0x3D4: - ret = svga->crtcreg; - break; - case 0x3D5: - switch (svga->crtcreg) - { - case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/ - case 0x2e: ret = virge->virge_id_low; break; /*New chip ID*/ - case 0x2f: ret = virge->virge_rev; break; - case 0x30: ret = virge->virge_id; break; /*Chip ID*/ - case 0x31: ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); break; - case 0x33: ret = (svga->crtc[0x33] | 0x04); break; - case 0x35: ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); break; - case 0x45: virge->hwc_col_stack_pos = 0; ret = svga->crtc[0x45]; break; - case 0x51: ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); break; - case 0x5c: /* General Output Port Register */ - ret = svga->crtc[svga->crtcreg] & 0xa0; - if (((svga->miscout >> 2) & 3) == 3) - ret |= svga->crtc[0x42] & 0x0f; - else - ret |= ((svga->miscout >> 2) & 3); - if ((ret & 0xa0) == 0xa0) { - if ((svga->crtc[0x5c] & 0x40) && i2c_gpio_get_scl(virge->i2c)) - ret |= 0x40; - if ((svga->crtc[0x5c] & 0x10) && i2c_gpio_get_sda(virge->i2c)) - ret |= 0x10; - } - break; - case 0x69: ret = virge->ma_ext; break; - case 0x6a: ret = virge->bank; break; + if (svga->crtcreg > 0x18) + s3_virge_log("OUTB VGA reg = %02x, val = %02x\n", svga->crtcreg, val); - case 0xaa: /* DDC */ - if (virge->chip >= S3_VIRGEGX2) { - ret = svga->crtc[0xaa] & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); - if ((svga->crtc[0xaa] & SERIAL_PORT_SCW) && i2c_gpio_get_scl(virge->i2c)) - ret |= SERIAL_PORT_SCR; - if ((svga->crtc[0xaa] & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) - ret |= SERIAL_PORT_SDR; - break; - } else - ret = svga->crtc[0xaa]; - break; + switch (svga->crtcreg) { + case 0x31: + virge->ma_ext = (virge->ma_ext & 0x1c) | ((val & 0x30) >> 4); + break; + case 0x32: + s3_virge_update_irqs(virge); + break; - default: - ret = svga->crtc[svga->crtcreg]; - break; + case 0x69: + virge->ma_ext = val & 0x1f; + break; + + case 0x35: + virge->bank = (virge->bank & 0x70) | (val & 0xf); + if (svga->chain4) + svga->write_bank = svga->read_bank = virge->bank << 16; + else + svga->write_bank = svga->read_bank = virge->bank << 14; + break; + case 0x51: + virge->bank = (virge->bank & 0x4f) | ((val & 0xc) << 2); + if (svga->chain4) + svga->write_bank = svga->read_bank = virge->bank << 16; + else + svga->write_bank = svga->read_bank = virge->bank << 14; + virge->ma_ext = (virge->ma_ext & ~0xc) | ((val & 3) << 2); + break; + case 0x6a: + virge->bank = val; + if (svga->chain4) + svga->write_bank = svga->read_bank = virge->bank << 16; + else + svga->write_bank = svga->read_bank = virge->bank << 14; + break; + + case 0x3a: + if (val & 0x10) + svga->gdcreg[5] |= 0x40; /*Horrible cheat*/ + break; + + case 0x45: + svga->hwcursor.ena = val & 1; + break; + case 0x46: + case 0x47: + case 0x48: + case 0x49: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + svga->hwcursor.x = ((svga->crtc[0x46] << 8) | svga->crtc[0x47]) & 0x7ff; + svga->hwcursor.y = ((svga->crtc[0x48] << 8) | svga->crtc[0x49]) & 0x7ff; + svga->hwcursor.xoff = svga->crtc[0x4e] & 0x3f; + svga->hwcursor.yoff = svga->crtc[0x4f] & 0x3f; + cursoraddr = (virge->memory_size == 8) ? 0x1fff : 0x0fff; + svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & cursoraddr) * 1024) + (svga->hwcursor.yoff * 16); + break; + + case 0x4a: + switch (virge->hwc_col_stack_pos) { + case 0: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_fg_col = (virge->hwc_fg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_fg_col = (virge->hwc_fg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; + break; + case 0x4b: + switch (virge->hwc_col_stack_pos) { + case 0: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xffff00) | val; + break; + case 1: + virge->hwc_bg_col = (virge->hwc_bg_col & 0xff00ff) | (val << 8); + break; + case 2: + virge->hwc_bg_col = (virge->hwc_bg_col & 0x00ffff) | (val << 16); + break; + } + virge->hwc_col_stack_pos = (virge->hwc_col_stack_pos + 1) & 3; + break; + + case 0x53: + case 0x58: + case 0x59: + case 0x5a: + s3_virge_updatemapping(virge); + break; + + case 0x56: + svga->dpms = (svga->seqregs[0x0d] & 0x50) || (svga->crtc[0x56] & 0x06); + old = ~val; /* force recalc */ + break; + + case 0x5c: + if ((val & 0xa0) == 0x80) + i2c_gpio_set(virge->i2c, !!(val & 0x40), !!(val & 0x10)); + break; + + case 0x67: + switch (val >> 4) { + case 2: + case 3: + svga->bpp = 15; + break; + case 4: + case 5: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; + case 13: + svga->bpp = (virge->chip == S3_VIRGEVX) ? 24 : 32; + break; + default: + svga->bpp = 8; + break; + } + break; + + case 0xaa: + i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); + break; + } + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + if ((svga->crtc[0x67] & 0xc) != 0xc) + svga->ma_latch |= (virge->ma_ext << 16); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } - break; + } + break; + } + svga_out(addr, val, svga); +} + +static uint8_t +s3_virge_in(uint16_t addr, void *p) +{ + virge_t *virge = (virge_t *) p; + svga_t *svga = &virge->svga; + uint8_t ret; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3c1: + if (svga->attraddr > 0x14) + ret = 0xff; + else + ret = svga_in(addr, svga); + break; + + case 0x3c5: + if (svga->seqaddr >= 8) + ret = svga->seqregs[svga->seqaddr & 0x1f]; + else if (svga->seqaddr <= 4) + ret = svga_in(addr, svga); + else + ret = 0xff; + break; + + case 0x3D4: + ret = svga->crtcreg; + break; + case 0x3D5: + switch (svga->crtcreg) { + case 0x2d: + ret = virge->virge_id_high; + break; /*Extended chip ID*/ + case 0x2e: + ret = virge->virge_id_low; + break; /*New chip ID*/ + case 0x2f: + ret = virge->virge_rev; + break; + case 0x30: + ret = virge->virge_id; + break; /*Chip ID*/ + case 0x31: + ret = (svga->crtc[0x31] & 0xcf) | ((virge->ma_ext & 3) << 4); + break; + case 0x33: + ret = (svga->crtc[0x33] | 0x04); + break; + case 0x35: + ret = (svga->crtc[0x35] & 0xf0) | (virge->bank & 0xf); + break; + case 0x45: + virge->hwc_col_stack_pos = 0; + ret = svga->crtc[0x45]; + break; + case 0x51: + ret = (svga->crtc[0x51] & 0xf0) | ((virge->bank >> 2) & 0xc) | ((virge->ma_ext >> 2) & 3); + break; + case 0x5c: /* General Output Port Register */ + ret = svga->crtc[svga->crtcreg] & 0xa0; + if (((svga->miscout >> 2) & 3) == 3) + ret |= svga->crtc[0x42] & 0x0f; + else + ret |= ((svga->miscout >> 2) & 3); + if ((ret & 0xa0) == 0xa0) { + if ((svga->crtc[0x5c] & 0x40) && i2c_gpio_get_scl(virge->i2c)) + ret |= 0x40; + if ((svga->crtc[0x5c] & 0x10) && i2c_gpio_get_sda(virge->i2c)) + ret |= 0x10; + } + break; + case 0x69: + ret = virge->ma_ext; + break; + case 0x6a: + ret = virge->bank; + break; + + case 0xaa: /* DDC */ + if (virge->chip >= S3_VIRGEGX2) { + ret = svga->crtc[0xaa] & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); + if ((svga->crtc[0xaa] & SERIAL_PORT_SCW) && i2c_gpio_get_scl(virge->i2c)) + ret |= SERIAL_PORT_SCR; + if ((svga->crtc[0xaa] & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) + ret |= SERIAL_PORT_SDR; + break; + } else + ret = svga->crtc[0xaa]; + break; default: - ret = svga_in(addr, svga); + ret = svga->crtc[svga->crtcreg]; + break; + } + break; + + default: + ret = svga_in(addr, svga); + break; + } + return ret; +} + +static void +s3_virge_recalctimings(svga_t *svga) +{ + virge_t *virge = (virge_t *) svga->p; + + svga->hdisp = svga->hdisp_old; + + if (svga->crtc[0x5d] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x5d] & 0x02) { + svga->hdisp_time += 0x100; + svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); + } + if (svga->crtc[0x5e] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x5e] & 0x02) + svga->dispend += 0x400; + if (svga->crtc[0x5e] & 0x04) + svga->vblankstart += 0x400; + if (svga->crtc[0x5e] & 0x10) + svga->vsyncstart += 0x400; + if (svga->crtc[0x5e] & 0x40) + svga->split += 0x400; + svga->interlace = svga->crtc[0x42] & 0x20; + + if (((svga->miscout >> 2) & 3) == 3) { + int n = svga->seqregs[0x12] & 0x1f; + int r = (svga->seqregs[0x12] >> 5); + + if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) + r &= 7; + else if (virge->chip >= S3_VIRGEGX2) + r &= 10; + else + r &= 3; + + int m = svga->seqregs[0x13] & 0x7f; + double freq = (((double) m + 2) / (((double) n + 2) * (double) (1 << r))) * 14318184.0; + + svga->clock = (cpuclock * (float) (1ull << 32)) / freq; + } + + if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ + { + svga->ma_latch |= (virge->ma_ext << 16); + if (svga->crtc[0x51] & 0x30) + svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; + else if (svga->crtc[0x43] & 0x04) + svga->rowoffset += 0x100; + if (!svga->rowoffset) + svga->rowoffset = 256; + + svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); + if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { + svga->htotal >>= 1; + svga->hdisp >>= 1; + } + break; + case 16: + svga->render = svga_render_16bpp_highres; + if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) { + svga->htotal >>= 1; + svga->hdisp >>= 1; + } + break; + case 24: + svga->render = svga_render_24bpp_highres; + if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) + svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ + break; + case 32: + svga->render = svga_render_32bpp_highres; + break; + } + } + svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; + s3_virge_log("VGA mode\n"); + } else /*Streams mode*/ + { + if (virge->streams.buffer_ctrl & 1) + svga->ma_latch = virge->streams.pri_fb1 >> 2; + else + svga->ma_latch = virge->streams.pri_fb0 >> 2; + + svga->hdisp = virge->streams.pri_w + 1; + if (virge->streams.pri_h < svga->dispend) + svga->dispend = virge->streams.pri_h; + + svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; + svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; + svga->overlay.cur_ysize = virge->streams.sec_h; + + if (virge->streams.buffer_ctrl & 2) + svga->overlay.addr = virge->streams.sec_fb1; + else + svga->overlay.addr = virge->streams.sec_fb0; + + svga->overlay.ena = (svga->overlay.x >= 0); + svga->overlay.v_acc = virge->streams.dda_vert_accumulator; + svga->rowoffset = virge->streams.pri_stride >> 3; + + switch ((virge->streams.pri_ctrl >> 24) & 0x7) { + case 0: /*RGB-8 (CLUT)*/ + svga->render = svga_render_8bpp_highres; + break; + case 3: /*KRGB-16 (1.5.5.5)*/ + svga->htotal >>= 1; + svga->render = svga_render_15bpp_highres; + break; + case 5: /*RGB-16 (5.6.5)*/ + svga->htotal >>= 1; + svga->render = svga_render_16bpp_highres; + break; + case 6: /*RGB-24 (8.8.8)*/ + svga->render = svga_render_24bpp_highres; + break; + case 7: /*XRGB-32 (X.8.8.8)*/ + svga->render = svga_render_32bpp_highres; break; } - return ret; + svga->vram_display_mask = virge->vram_mask; + } } -static void s3_virge_recalctimings(svga_t *svga) +static void +s3_virge_updatemapping(virge_t *virge) { - virge_t *virge = (virge_t *)svga->p; + svga_t *svga = &virge->svga; - svga->hdisp = svga->hdisp_old; + if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&virge->linear_mapping); + mem_mapping_disable(&virge->mmio_mapping); + mem_mapping_disable(&virge->new_mmio_mapping); + return; + } - if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; - if (svga->crtc[0x5d] & 0x02) { - svga->hdisp_time += 0x100; - svga->hdisp += 0x100 * ((svga->seqregs[1] & 8) ? 16 : 8); - } - if (svga->crtc[0x5e] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x5e] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x5e] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x5e] & 0x10) svga->vsyncstart += 0x400; - if (svga->crtc[0x5e] & 0x40) svga->split += 0x400; - svga->interlace = svga->crtc[0x42] & 0x20; + s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + /*Banked framebuffer*/ + switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } - if (((svga->miscout >> 2) & 3) == 3) { - int n = svga->seqregs[0x12] & 0x1f; - int r = (svga->seqregs[0x12] >> 5); + virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - if (virge->chip == S3_VIRGEVX || virge->chip == S3_VIRGEDX) - r &= 7; - else if (virge->chip >= S3_VIRGEGX2) - r &= 10; - else - r &= 3; - - int m = svga->seqregs[0x13] & 0x7f; - double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; - - svga->clock = (cpuclock * (float)(1ull << 32)) / freq; - } - - - if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ - { - svga->ma_latch |= (virge->ma_ext << 16); - if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; - else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; - if (!svga->rowoffset) svga->rowoffset = 256; - - svga->lowres = !((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)); - if ((svga->gdcreg[5] & 0x40) && (svga->crtc[0x3a] & 0x10)) { - switch (svga->bpp) { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) - { - svga->htotal >>= 1; - svga->hdisp >>= 1; - } - break; - case 16: - svga->render = svga_render_16bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) - { - svga->htotal >>= 1; - svga->hdisp >>= 1; - } - break; - case 24: - svga->render = svga_render_24bpp_highres; - if (virge->chip != S3_VIRGEVX && virge->chip < S3_VIRGEGX2) - svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ - break; - case 32: - svga->render = svga_render_32bpp_highres; - break; - } - } - svga->vram_display_mask = (!(svga->crtc[0x31] & 0x08) && (svga->crtc[0x32] & 0x40)) ? 0x3ffff : virge->vram_mask; - s3_virge_log("VGA mode\n"); - } - else /*Streams mode*/ - { - if (virge->streams.buffer_ctrl & 1) - svga->ma_latch = virge->streams.pri_fb1 >> 2; + s3_virge_log("Linear framebuffer %02X, linear base = %08x, display mask = %08x\n", svga->crtc[0x58] & 0x17, virge->linear_base, svga->vram_display_mask); + if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/ + switch (svga->crtc[0x58] & 7) { + case 0: /*64k*/ + virge->linear_size = 0x10000; + break; + case 1: /*1mb*/ + virge->linear_size = 0x100000; + break; + case 2: /*2mb*/ + virge->linear_size = 0x200000; + break; + case 3: /*4mb on other than ViRGE/VX, 8mb on ViRGE/VX*/ + if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) + virge->linear_size = 0x800000; else - svga->ma_latch = virge->streams.pri_fb0 >> 2; - - svga->hdisp = virge->streams.pri_w + 1; - if (virge->streams.pri_h < svga->dispend) - svga->dispend = virge->streams.pri_h; - - svga->overlay.x = virge->streams.sec_x - virge->streams.pri_x; - svga->overlay.y = virge->streams.sec_y - virge->streams.pri_y; - svga->overlay.cur_ysize = virge->streams.sec_h; - - if (virge->streams.buffer_ctrl & 2) - svga->overlay.addr = virge->streams.sec_fb1; - else - svga->overlay.addr = virge->streams.sec_fb0; - - svga->overlay.ena = (svga->overlay.x >= 0); - svga->overlay.v_acc = virge->streams.dda_vert_accumulator; - svga->rowoffset = virge->streams.pri_stride >> 3; - - switch ((virge->streams.pri_ctrl >> 24) & 0x7) - { - case 0: /*RGB-8 (CLUT)*/ - svga->render = svga_render_8bpp_highres; - break; - case 3: /*KRGB-16 (1.5.5.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_15bpp_highres; - break; - case 5: /*RGB-16 (5.6.5)*/ - svga->htotal >>= 1; - svga->render = svga_render_16bpp_highres; - break; - case 6: /*RGB-24 (8.8.8)*/ - svga->render = svga_render_24bpp_highres; - break; - case 7: /*XRGB-32 (X.8.8.8)*/ - svga->render = svga_render_32bpp_highres; - break; - } - svga->vram_display_mask = virge->vram_mask; + virge->linear_size = 0x400000; + break; + case 7: + virge->linear_size = 0x800000; + break; } -} - -static void s3_virge_updatemapping(virge_t *virge) -{ - svga_t *svga = &virge->svga; - - if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&virge->linear_mapping); - mem_mapping_disable(&virge->mmio_mapping); - mem_mapping_disable(&virge->new_mmio_mapping); - return; - } - - s3_virge_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - /*Banked framebuffer*/ - switch (svga->gdcreg[6] & 0xc) { /*VGA mapping*/ - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - - virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - - s3_virge_log("Linear framebuffer %02X, linear base = %08x, display mask = %08x\n", svga->crtc[0x58] & 0x17, virge->linear_base, svga->vram_display_mask); - if ((svga->crtc[0x58] & 0x10) || (virge->advfunc_cntl & 0x10)) { /*Linear framebuffer*/ - switch (svga->crtc[0x58] & 7) { - case 0: /*64k*/ - virge->linear_size = 0x10000; - break; - case 1: /*1mb*/ - virge->linear_size = 0x100000; - break; - case 2: /*2mb*/ - virge->linear_size = 0x200000; - break; - case 3: /*4mb on other than ViRGE/VX, 8mb on ViRGE/VX*/ - if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) - virge->linear_size = 0x800000; - else - virge->linear_size = 0x400000; - break; - case 7: - virge->linear_size = 0x800000; - break; - } - virge->linear_base &= ~(virge->linear_size - 1); - s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); - if (virge->linear_base == 0xa0000) { - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - mem_mapping_disable(&virge->linear_mapping); - } else { - if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) { - virge->linear_base &= 0xfe000000; - } else { - virge->linear_base &= 0xfc000000; - } - - mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); - } - svga->fb_only = 1; + virge->linear_base &= ~(virge->linear_size - 1); + s3_virge_log("Linear framebuffer at %08X size %08X, mask = %08x, CRTC58 sel = %02x\n", virge->linear_base, virge->linear_size, virge->vram_mask, svga->crtc[0x58] & 7); + if (virge->linear_base == 0xa0000) { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + mem_mapping_disable(&virge->linear_mapping); } else { - mem_mapping_disable(&virge->linear_mapping); - svga->fb_only = 0; + if (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) { + virge->linear_base &= 0xfe000000; + } else { + virge->linear_base &= 0xfc000000; + } + + mem_mapping_set_addr(&virge->linear_mapping, virge->linear_base, virge->linear_size); } + svga->fb_only = 1; + } else { + mem_mapping_disable(&virge->linear_mapping); + svga->fb_only = 0; + } - s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x38); + s3_virge_log("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x38); - /* Memory mapped I/O. */ - /* Old MMIO. */ - if ((svga->crtc[0x53] & 0x10) || (virge->advfunc_cntl & 0x20)) { - if (svga->crtc[0x53] & 0x20) - mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); - else - mem_mapping_set_addr(&virge->mmio_mapping, 0xa0000, 0x10000); - } else - mem_mapping_disable(&virge->mmio_mapping); + /* Memory mapped I/O. */ + /* Old MMIO. */ + if ((svga->crtc[0x53] & 0x10) || (virge->advfunc_cntl & 0x20)) { + if (svga->crtc[0x53] & 0x20) + mem_mapping_set_addr(&virge->mmio_mapping, 0xb8000, 0x8000); + else + mem_mapping_set_addr(&virge->mmio_mapping, 0xa0000, 0x10000); + } else + mem_mapping_disable(&virge->mmio_mapping); - /* New MMIO. */ - if (svga->crtc[0x53] & 0x08) - mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); - else - mem_mapping_disable(&virge->new_mmio_mapping); + /* New MMIO. */ + if (svga->crtc[0x53] & 0x08) + mem_mapping_set_addr(&virge->new_mmio_mapping, virge->linear_base + 0x1000000, 0x10000); + else + mem_mapping_disable(&virge->new_mmio_mapping); } static void s3_virge_vblank_start(svga_t *svga) { - virge_t *virge = (virge_t *)svga->p; + virge_t *virge = (virge_t *) svga->p; - virge->subsys_stat |= INT_VSY; - s3_virge_update_irqs(virge); + virge->subsys_stat |= INT_VSY; + s3_virge_update_irqs(virge); } - static void s3_virge_mmio_fifo_write(uint32_t addr, uint8_t val, virge_t *virge) { - if ((addr & 0xffff) < 0x8000) { - s3_virge_bitblt(virge, 8, val); - } else { - switch (addr & 0xffff) { - case 0x859c: - virge->cmd_dma = val; - break; - } - } + if ((addr & 0xffff) < 0x8000) { + s3_virge_bitblt(virge, 8, val); + } else { + switch (addr & 0xffff) { + case 0x859c: + virge->cmd_dma = val; + break; + } + } } static void s3_virge_mmio_fifo_write_w(uint32_t addr, uint16_t val, virge_t *virge) { - if ((addr & 0xfffe) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - else - s3_virge_bitblt(virge, 16, val); - } else { - if ((addr & 0xfffe) == 0x859c) - virge->cmd_dma = val; - } + if ((addr & 0xfffe) < 0x8000) { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); + else + s3_virge_bitblt(virge, 16, val); + } else { + if ((addr & 0xfffe) == 0x859c) + virge->cmd_dma = val; + } } static void s3_virge_mmio_fifo_write_l(uint32_t addr, uint32_t val, virge_t *virge) { - if ((addr & 0xfffc) < 0x8000) { - if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); + if ((addr & 0xfffc) < 0x8000) { + if (virge->s3d.cmd_set & CMD_SET_MS) + s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + else + s3_virge_bitblt(virge, 32, val); } else { - virge->fifo_slot++; - switch (addr & 0xfffc) { - case 0x8590: - virge->cmd_dma_base = val; - break; + virge->fifo_slot++; + switch (addr & 0xfffc) { + case 0x8590: + virge->cmd_dma_base = val; + break; - case 0x8594: - virge->dma_ptr = val; - break; + case 0x8594: + virge->dma_ptr = val; + break; - case 0x8598: - break; + case 0x8598: + break; - case 0x859c: - virge->cmd_dma = val; - break; + case 0x859c: + virge->cmd_dma = val; + break; - case 0xa000: case 0xa004: case 0xa008: case 0xa00c: - case 0xa010: case 0xa014: case 0xa018: case 0xa01c: - case 0xa020: case 0xa024: case 0xa028: case 0xa02c: - case 0xa030: case 0xa034: case 0xa038: case 0xa03c: - case 0xa040: case 0xa044: case 0xa048: case 0xa04c: - case 0xa050: case 0xa054: case 0xa058: case 0xa05c: - case 0xa060: case 0xa064: case 0xa068: case 0xa06c: - case 0xa070: case 0xa074: case 0xa078: case 0xa07c: - case 0xa080: case 0xa084: case 0xa088: case 0xa08c: - case 0xa090: case 0xa094: case 0xa098: case 0xa09c: - case 0xa0a0: case 0xa0a4: case 0xa0a8: case 0xa0ac: - case 0xa0b0: case 0xa0b4: case 0xa0b8: case 0xa0bc: - case 0xa0c0: case 0xa0c4: case 0xa0c8: case 0xa0cc: - case 0xa0d0: case 0xa0d4: case 0xa0d8: case 0xa0dc: - case 0xa0e0: case 0xa0e4: case 0xa0e8: case 0xa0ec: - case 0xa0f0: case 0xa0f4: case 0xa0f8: case 0xa0fc: - case 0xa100: case 0xa104: case 0xa108: case 0xa10c: - case 0xa110: case 0xa114: case 0xa118: case 0xa11c: - case 0xa120: case 0xa124: case 0xa128: case 0xa12c: - case 0xa130: case 0xa134: case 0xa138: case 0xa13c: - case 0xa140: case 0xa144: case 0xa148: case 0xa14c: - case 0xa150: case 0xa154: case 0xa158: case 0xa15c: - case 0xa160: case 0xa164: case 0xa168: case 0xa16c: - case 0xa170: case 0xa174: case 0xa178: case 0xa17c: - case 0xa180: case 0xa184: case 0xa188: case 0xa18c: - case 0xa190: case 0xa194: case 0xa198: case 0xa19c: - case 0xa1a0: case 0xa1a4: case 0xa1a8: case 0xa1ac: - case 0xa1b0: case 0xa1b4: case 0xa1b8: case 0xa1bc: - case 0xa1c0: case 0xa1c4: case 0xa1c8: case 0xa1cc: - case 0xa1d0: case 0xa1d4: case 0xa1d8: case 0xa1dc: - case 0xa1e0: case 0xa1e4: case 0xa1e8: case 0xa1ec: - case 0xa1f0: case 0xa1f4: case 0xa1f8: case 0xa1fc: - { - int x = addr & 4; - int y = (addr >> 3) & 7; - int color, xx; - int byte; - virge->s3d.pattern_8[y*8 + x] = val & 0xff; - virge->s3d.pattern_8[y*8 + x + 1] = val >> 8; - virge->s3d.pattern_8[y*8 + x + 2] = val >> 16; - virge->s3d.pattern_8[y*8 + x + 3] = val >> 24; + case 0xa000: + case 0xa004: + case 0xa008: + case 0xa00c: + case 0xa010: + case 0xa014: + case 0xa018: + case 0xa01c: + case 0xa020: + case 0xa024: + case 0xa028: + case 0xa02c: + case 0xa030: + case 0xa034: + case 0xa038: + case 0xa03c: + case 0xa040: + case 0xa044: + case 0xa048: + case 0xa04c: + case 0xa050: + case 0xa054: + case 0xa058: + case 0xa05c: + case 0xa060: + case 0xa064: + case 0xa068: + case 0xa06c: + case 0xa070: + case 0xa074: + case 0xa078: + case 0xa07c: + case 0xa080: + case 0xa084: + case 0xa088: + case 0xa08c: + case 0xa090: + case 0xa094: + case 0xa098: + case 0xa09c: + case 0xa0a0: + case 0xa0a4: + case 0xa0a8: + case 0xa0ac: + case 0xa0b0: + case 0xa0b4: + case 0xa0b8: + case 0xa0bc: + case 0xa0c0: + case 0xa0c4: + case 0xa0c8: + case 0xa0cc: + case 0xa0d0: + case 0xa0d4: + case 0xa0d8: + case 0xa0dc: + case 0xa0e0: + case 0xa0e4: + case 0xa0e8: + case 0xa0ec: + case 0xa0f0: + case 0xa0f4: + case 0xa0f8: + case 0xa0fc: + case 0xa100: + case 0xa104: + case 0xa108: + case 0xa10c: + case 0xa110: + case 0xa114: + case 0xa118: + case 0xa11c: + case 0xa120: + case 0xa124: + case 0xa128: + case 0xa12c: + case 0xa130: + case 0xa134: + case 0xa138: + case 0xa13c: + case 0xa140: + case 0xa144: + case 0xa148: + case 0xa14c: + case 0xa150: + case 0xa154: + case 0xa158: + case 0xa15c: + case 0xa160: + case 0xa164: + case 0xa168: + case 0xa16c: + case 0xa170: + case 0xa174: + case 0xa178: + case 0xa17c: + case 0xa180: + case 0xa184: + case 0xa188: + case 0xa18c: + case 0xa190: + case 0xa194: + case 0xa198: + case 0xa19c: + case 0xa1a0: + case 0xa1a4: + case 0xa1a8: + case 0xa1ac: + case 0xa1b0: + case 0xa1b4: + case 0xa1b8: + case 0xa1bc: + case 0xa1c0: + case 0xa1c4: + case 0xa1c8: + case 0xa1cc: + case 0xa1d0: + case 0xa1d4: + case 0xa1d8: + case 0xa1dc: + case 0xa1e0: + case 0xa1e4: + case 0xa1e8: + case 0xa1ec: + case 0xa1f0: + case 0xa1f4: + case 0xa1f8: + case 0xa1fc: + { + int x = addr & 4; + int y = (addr >> 3) & 7; + int color, xx; + int byte; + virge->s3d.pattern_8[y * 8 + x] = val & 0xff; + virge->s3d.pattern_8[y * 8 + x + 1] = val >> 8; + virge->s3d.pattern_8[y * 8 + x + 2] = val >> 16; + virge->s3d.pattern_8[y * 8 + x + 3] = val >> 24; - x = (addr >> 1) & 6; - y = (addr >> 4) & 7; - virge->s3d.pattern_16[y*8 + x] = val & 0xffff; - virge->s3d.pattern_16[y*8 + x + 1] = val >> 16; + x = (addr >> 1) & 6; + y = (addr >> 4) & 7; + virge->s3d.pattern_16[y * 8 + x] = val & 0xffff; + virge->s3d.pattern_16[y * 8 + x + 1] = val >> 16; - addr &= 0x00ff; - for (xx = 0; xx < 4; xx++) { - x = ((addr + xx) / 3) % 8; - y = ((addr + xx) / 24) % 8; - color = ((addr + xx) % 3) << 3; - byte = (xx << 3); - virge->s3d.pattern_24[y*8 + x] &= ~(0xff << color); - virge->s3d.pattern_24[y*8 + x] |= ((val >> byte) & 0xff) << color; - } + addr &= 0x00ff; + for (xx = 0; xx < 4; xx++) { + x = ((addr + xx) / 3) % 8; + y = ((addr + xx) / 24) % 8; + color = ((addr + xx) % 3) << 3; + byte = (xx << 3); + virge->s3d.pattern_24[y * 8 + x] &= ~(0xff << color); + virge->s3d.pattern_24[y * 8 + x] |= ((val >> byte) & 0xff) << color; + } - x = (addr >> 2) & 7; - y = (addr >> 5) & 7; - virge->s3d.pattern_32[y*8 + x] = val & 0xffffff; - } - break; + x = (addr >> 2) & 7; + y = (addr >> 5) & 7; + virge->s3d.pattern_32[y * 8 + x] = val & 0xffffff; + } + break; - case 0xa4d4: case 0xa8d4: - virge->s3d.src_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - s3_virge_log("PortWrite = %04x, SRC Base = %08x, memsize = %i\n", addr & 0xfffc, val, virge->memory_size); - break; - case 0xa4d8: case 0xa8d8: - virge->s3d.dest_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - s3_virge_log("PortWrite = %04x, DST Base = %08x, memsize = %i\n", addr & 0xfffc, val, virge->memory_size); - break; - case 0xa4dc: case 0xa8dc: - virge->s3d.clip_l = (val >> 16) & 0x7ff; - virge->s3d.clip_r = val & 0x7ff; - break; - case 0xa4e0: case 0xa8e0: - virge->s3d.clip_t = (val >> 16) & 0x7ff; - virge->s3d.clip_b = val & 0x7ff; - break; - case 0xa4e4: case 0xa8e4: - virge->s3d.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xa4e8: case 0xace8: - virge->s3d.mono_pat_0 = val; - break; - case 0xa4ec: case 0xacec: - virge->s3d.mono_pat_1 = val; - break; - case 0xa4f0: case 0xacf0: - virge->s3d.pat_bg_clr = val; - break; - case 0xa4f4: case 0xa8f4: case 0xacf4: - virge->s3d.pat_fg_clr = val; - break; - case 0xa4f8: - virge->s3d.src_bg_clr = val; - break; - case 0xa4fc: - virge->s3d.src_fg_clr = val; - break; - case 0xa500: case 0xa900: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) { - s3_virge_bitblt(virge, -1, 0); - } - break; - case 0xa504: - virge->s3d.r_width = (val >> 16) & 0x7ff; - virge->s3d.r_height = val & 0x7ff; - break; - case 0xa508: - virge->s3d.rsrc_x = (val >> 16) & 0x7ff; - virge->s3d.rsrc_y = val & 0x7ff; - break; - case 0xa50c: - virge->s3d.rdest_x = (val >> 16) & 0x7ff; - virge->s3d.rdest_y = val & 0x7ff; - if (virge->s3d.cmd_set & CMD_SET_AE) { - s3_virge_bitblt(virge, -1, 0); - } - break; - case 0xa96c: - virge->s3d.lxend0 = (val >> 16) & 0x7ff; - virge->s3d.lxend1 = val & 0x7ff; - break; - case 0xa970: - virge->s3d.ldx = (int32_t)val; - break; - case 0xa974: - virge->s3d.lxstart = val; - break; - case 0xa978: - virge->s3d.lystart = val & 0x7ff; - break; - case 0xa97c: - virge->s3d.lycnt = val & 0x7ff; - virge->s3d.line_dir = val >> 31; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; + case 0xa4d4: + case 0xa8d4: + virge->s3d.src_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); + s3_virge_log("PortWrite = %04x, SRC Base = %08x, memsize = %i\n", addr & 0xfffc, val, virge->memory_size); + break; + case 0xa4d8: + case 0xa8d8: + virge->s3d.dest_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); + s3_virge_log("PortWrite = %04x, DST Base = %08x, memsize = %i\n", addr & 0xfffc, val, virge->memory_size); + break; + case 0xa4dc: + case 0xa8dc: + virge->s3d.clip_l = (val >> 16) & 0x7ff; + virge->s3d.clip_r = val & 0x7ff; + break; + case 0xa4e0: + case 0xa8e0: + virge->s3d.clip_t = (val >> 16) & 0x7ff; + virge->s3d.clip_b = val & 0x7ff; + break; + case 0xa4e4: + case 0xa8e4: + virge->s3d.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xa4e8: + case 0xace8: + virge->s3d.mono_pat_0 = val; + break; + case 0xa4ec: + case 0xacec: + virge->s3d.mono_pat_1 = val; + break; + case 0xa4f0: + case 0xacf0: + virge->s3d.pat_bg_clr = val; + break; + case 0xa4f4: + case 0xa8f4: + case 0xacf4: + virge->s3d.pat_fg_clr = val; + break; + case 0xa4f8: + virge->s3d.src_bg_clr = val; + break; + case 0xa4fc: + virge->s3d.src_fg_clr = val; + break; + case 0xa500: + case 0xa900: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) { + s3_virge_bitblt(virge, -1, 0); + } + break; + case 0xa504: + virge->s3d.r_width = (val >> 16) & 0x7ff; + virge->s3d.r_height = val & 0x7ff; + break; + case 0xa508: + virge->s3d.rsrc_x = (val >> 16) & 0x7ff; + virge->s3d.rsrc_y = val & 0x7ff; + break; + case 0xa50c: + virge->s3d.rdest_x = (val >> 16) & 0x7ff; + virge->s3d.rdest_y = val & 0x7ff; + if (virge->s3d.cmd_set & CMD_SET_AE) { + s3_virge_bitblt(virge, -1, 0); + } + break; + case 0xa96c: + virge->s3d.lxend0 = (val >> 16) & 0x7ff; + virge->s3d.lxend1 = val & 0x7ff; + break; + case 0xa970: + virge->s3d.ldx = (int32_t) val; + break; + case 0xa974: + virge->s3d.lxstart = val; + break; + case 0xa978: + virge->s3d.lystart = val & 0x7ff; + break; + case 0xa97c: + virge->s3d.lycnt = val & 0x7ff; + virge->s3d.line_dir = val >> 31; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; - case 0xad00: - virge->s3d.cmd_set = val; - if (!(val & CMD_SET_AE)) - s3_virge_bitblt(virge, -1, 0); - break; - case 0xad68: - virge->s3d.prdx = val; - break; - case 0xad6c: - virge->s3d.prxstart = val; - break; - case 0xad70: - virge->s3d.pldx = val; - break; - case 0xad74: - virge->s3d.plxstart = val; - break; - case 0xad78: - virge->s3d.pystart = val & 0x7ff; - break; - case 0xad7c: - virge->s3d.pycnt = val & 0x300007ff; - if (virge->s3d.cmd_set & CMD_SET_AE) - s3_virge_bitblt(virge, -1, 0); - break; + case 0xad00: + virge->s3d.cmd_set = val; + if (!(val & CMD_SET_AE)) + s3_virge_bitblt(virge, -1, 0); + break; + case 0xad68: + virge->s3d.prdx = val; + break; + case 0xad6c: + virge->s3d.prxstart = val; + break; + case 0xad70: + virge->s3d.pldx = val; + break; + case 0xad74: + virge->s3d.plxstart = val; + break; + case 0xad78: + virge->s3d.pystart = val & 0x7ff; + break; + case 0xad7c: + virge->s3d.pycnt = val & 0x300007ff; + if (virge->s3d.cmd_set & CMD_SET_AE) + s3_virge_bitblt(virge, -1, 0); + break; - case 0xb0f4: case 0xb4f4: - virge->s3d_tri.fog_b = val & 0xff; - virge->s3d_tri.fog_g = (val >> 8) & 0xff; - virge->s3d_tri.fog_r = (val >> 16) & 0xff; - break; - case 0xb4d4: - virge->s3d_tri.z_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - break; - case 0xb4d8: - virge->s3d_tri.dest_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - break; - case 0xb4dc: - virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_r = val & 0x7ff; - break; - case 0xb4e0: - virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; - virge->s3d_tri.clip_b = val & 0x7ff; - break; - case 0xb4e4: - virge->s3d_tri.dest_str = (val >> 16) & 0xff8; - virge->s3d.src_str = val & 0xff8; - break; - case 0xb4e8: - virge->s3d_tri.z_str = val & 0xff8; - break; - case 0xb4ec: - virge->s3d_tri.tex_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); - break; - case 0xb4f0: - virge->s3d_tri.tex_bdr_clr = val & 0xffffff; - break; - case 0xb500: - virge->s3d_tri.cmd_set = val; - if (!(val & CMD_SET_AE)) - queue_triangle(virge); - break; - case 0xb504: - virge->s3d_tri.tbv = val & 0xfffff; - break; - case 0xb508: - virge->s3d_tri.tbu = val & 0xfffff; - break; - case 0xb50c: - virge->s3d_tri.TdWdX = val; - break; - case 0xb510: - virge->s3d_tri.TdWdY = val; - break; - case 0xb514: - virge->s3d_tri.tws = val; - break; - case 0xb518: - virge->s3d_tri.TdDdX = val; - break; - case 0xb51c: - virge->s3d_tri.TdVdX = val; - break; - case 0xb520: - virge->s3d_tri.TdUdX = val; - break; - case 0xb524: - virge->s3d_tri.TdDdY = val; - break; - case 0xb528: - virge->s3d_tri.TdVdY = val; - break; - case 0xb52c: - virge->s3d_tri.TdUdY = val; - break; - case 0xb530: - virge->s3d_tri.tds = val; - break; - case 0xb534: - virge->s3d_tri.tvs = val; - break; - case 0xb538: - virge->s3d_tri.tus = val; - break; - case 0xb53c: - virge->s3d_tri.TdGdX = val >> 16; - virge->s3d_tri.TdBdX = val & 0xffff; - break; - case 0xb540: - virge->s3d_tri.TdAdX = val >> 16; - virge->s3d_tri.TdRdX = val & 0xffff; - break; - case 0xb544: - virge->s3d_tri.TdGdY = val >> 16; - virge->s3d_tri.TdBdY = val & 0xffff; - break; - case 0xb548: - virge->s3d_tri.TdAdY = val >> 16; - virge->s3d_tri.TdRdY = val & 0xffff; - break; - case 0xb54c: - virge->s3d_tri.tgs = (val >> 16) & 0xffff; - virge->s3d_tri.tbs = val & 0xffff; - break; - case 0xb550: - virge->s3d_tri.tas = (val >> 16) & 0xffff; - virge->s3d_tri.trs = val & 0xffff; - break; + case 0xb0f4: + case 0xb4f4: + virge->s3d_tri.fog_b = val & 0xff; + virge->s3d_tri.fog_g = (val >> 8) & 0xff; + virge->s3d_tri.fog_r = (val >> 16) & 0xff; + break; + case 0xb4d4: + virge->s3d_tri.z_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); + break; + case 0xb4d8: + virge->s3d_tri.dest_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); + break; + case 0xb4dc: + virge->s3d_tri.clip_l = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_r = val & 0x7ff; + break; + case 0xb4e0: + virge->s3d_tri.clip_t = (val >> 16) & 0x7ff; + virge->s3d_tri.clip_b = val & 0x7ff; + break; + case 0xb4e4: + virge->s3d_tri.dest_str = (val >> 16) & 0xff8; + virge->s3d.src_str = val & 0xff8; + break; + case 0xb4e8: + virge->s3d_tri.z_str = val & 0xff8; + break; + case 0xb4ec: + virge->s3d_tri.tex_base = (virge->memory_size == 8) ? (val & 0x7ffff8) : (val & 0x3ffff8); + break; + case 0xb4f0: + virge->s3d_tri.tex_bdr_clr = val & 0xffffff; + break; + case 0xb500: + virge->s3d_tri.cmd_set = val; + if (!(val & CMD_SET_AE)) + queue_triangle(virge); + break; + case 0xb504: + virge->s3d_tri.tbv = val & 0xfffff; + break; + case 0xb508: + virge->s3d_tri.tbu = val & 0xfffff; + break; + case 0xb50c: + virge->s3d_tri.TdWdX = val; + break; + case 0xb510: + virge->s3d_tri.TdWdY = val; + break; + case 0xb514: + virge->s3d_tri.tws = val; + break; + case 0xb518: + virge->s3d_tri.TdDdX = val; + break; + case 0xb51c: + virge->s3d_tri.TdVdX = val; + break; + case 0xb520: + virge->s3d_tri.TdUdX = val; + break; + case 0xb524: + virge->s3d_tri.TdDdY = val; + break; + case 0xb528: + virge->s3d_tri.TdVdY = val; + break; + case 0xb52c: + virge->s3d_tri.TdUdY = val; + break; + case 0xb530: + virge->s3d_tri.tds = val; + break; + case 0xb534: + virge->s3d_tri.tvs = val; + break; + case 0xb538: + virge->s3d_tri.tus = val; + break; + case 0xb53c: + virge->s3d_tri.TdGdX = val >> 16; + virge->s3d_tri.TdBdX = val & 0xffff; + break; + case 0xb540: + virge->s3d_tri.TdAdX = val >> 16; + virge->s3d_tri.TdRdX = val & 0xffff; + break; + case 0xb544: + virge->s3d_tri.TdGdY = val >> 16; + virge->s3d_tri.TdBdY = val & 0xffff; + break; + case 0xb548: + virge->s3d_tri.TdAdY = val >> 16; + virge->s3d_tri.TdRdY = val & 0xffff; + break; + case 0xb54c: + virge->s3d_tri.tgs = (val >> 16) & 0xffff; + virge->s3d_tri.tbs = val & 0xffff; + break; + case 0xb550: + virge->s3d_tri.tas = (val >> 16) & 0xffff; + virge->s3d_tri.trs = val & 0xffff; + break; - case 0xb554: - virge->s3d_tri.TdZdX = val; - break; - case 0xb558: - virge->s3d_tri.TdZdY = val; - break; - case 0xb55c: - virge->s3d_tri.tzs = val; - break; - case 0xb560: - virge->s3d_tri.TdXdY12 = val; - break; - case 0xb564: - virge->s3d_tri.txend12 = val; - break; - case 0xb568: - virge->s3d_tri.TdXdY01 = val; - break; - case 0xb56c: - virge->s3d_tri.txend01 = val; - break; - case 0xb570: - virge->s3d_tri.TdXdY02 = val; - break; - case 0xb574: - virge->s3d_tri.txs = val; - break; - case 0xb578: - virge->s3d_tri.tys = val; - break; - case 0xb57c: - virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; - virge->s3d_tri.ty12 = val & 0x7ff; - virge->s3d_tri.tlr = val >> 31; - if (virge->s3d_tri.cmd_set & CMD_SET_AE) { - queue_triangle(virge); - } - break; - } - } + case 0xb554: + virge->s3d_tri.TdZdX = val; + break; + case 0xb558: + virge->s3d_tri.TdZdY = val; + break; + case 0xb55c: + virge->s3d_tri.tzs = val; + break; + case 0xb560: + virge->s3d_tri.TdXdY12 = val; + break; + case 0xb564: + virge->s3d_tri.txend12 = val; + break; + case 0xb568: + virge->s3d_tri.TdXdY01 = val; + break; + case 0xb56c: + virge->s3d_tri.txend01 = val; + break; + case 0xb570: + virge->s3d_tri.TdXdY02 = val; + break; + case 0xb574: + virge->s3d_tri.txs = val; + break; + case 0xb578: + virge->s3d_tri.tys = val; + break; + case 0xb57c: + virge->s3d_tri.ty01 = (val >> 16) & 0x7ff; + virge->s3d_tri.ty12 = val & 0x7ff; + virge->s3d_tri.tlr = val >> 31; + if (virge->s3d_tri.cmd_set & CMD_SET_AE) { + queue_triangle(virge); + } + break; + } + } } static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) { - virge_t *virge = (virge_t *)p; - uint8_t ret = 0xff; + virge_t *virge = (virge_t *) p; + uint8_t ret = 0xff; - s3_virge_log("[%04X:%08X]: MMIO ReadB addr = %04x\n", CS, cpu_state.pc, addr & 0xffff); + s3_virge_log("[%04X:%08X]: MMIO ReadB addr = %04x\n", CS, cpu_state.pc, addr & 0xffff); - switch (addr & 0xffff) - { - case 0x8505: - ret = 0; - if (virge->s3d_busy || virge->fifo_slot) { - ret = 0x10; - } else { - ret = 0x30; - } - if (virge->fifo_slot) - virge->fifo_slot--; - return ret; + switch (addr & 0xffff) { + case 0x8505: + ret = 0; + if (virge->s3d_busy || virge->fifo_slot) { + ret = 0x10; + } else { + ret = 0x30; + } + if (virge->fifo_slot) + virge->fifo_slot--; + return ret; - case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: - case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: - case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: - case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: - case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: - case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: - case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: - case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: - case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: - case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: - case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: - case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - return s3_virge_in(addr & 0x3ff, virge); + case 0x83b0: + case 0x83b1: + case 0x83b2: + case 0x83b3: + case 0x83b4: + case 0x83b5: + case 0x83b6: + case 0x83b7: + case 0x83b8: + case 0x83b9: + case 0x83ba: + case 0x83bb: + case 0x83bc: + case 0x83bd: + case 0x83be: + case 0x83bf: + case 0x83c0: + case 0x83c1: + case 0x83c2: + case 0x83c3: + case 0x83c4: + case 0x83c5: + case 0x83c6: + case 0x83c7: + case 0x83c8: + case 0x83c9: + case 0x83ca: + case 0x83cb: + case 0x83cc: + case 0x83cd: + case 0x83ce: + case 0x83cf: + case 0x83d0: + case 0x83d1: + case 0x83d2: + case 0x83d3: + case 0x83d4: + case 0x83d5: + case 0x83d6: + case 0x83d7: + case 0x83d8: + case 0x83d9: + case 0x83da: + case 0x83db: + case 0x83dc: + case 0x83dd: + case 0x83de: + case 0x83df: + return s3_virge_in(addr & 0x3ff, virge); - case 0x859c: - return virge->cmd_dma; + case 0x859c: + return virge->cmd_dma; - case 0xff20: case 0xff21: - ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); - if ((virge->serialport & SERIAL_PORT_SCW) && i2c_gpio_get_scl(virge->i2c)) - ret |= SERIAL_PORT_SCR; - if ((virge->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) - ret |= SERIAL_PORT_SDR; - return ret; - } - return 0xff; + case 0xff20: + case 0xff21: + ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR); + if ((virge->serialport & SERIAL_PORT_SCW) && i2c_gpio_get_scl(virge->i2c)) + ret |= SERIAL_PORT_SCR; + if ((virge->serialport & SERIAL_PORT_SDW) && i2c_gpio_get_sda(virge->i2c)) + ret |= SERIAL_PORT_SDR; + return ret; + } + return 0xff; } static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) { - virge_t *virge = (virge_t *)p; - uint16_t ret = 0xffff; + virge_t *virge = (virge_t *) p; + uint16_t ret = 0xffff; - s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe); + s3_virge_log("[%04X:%08X]: MMIO ReadW addr = %04x\n", CS, cpu_state.pc, addr & 0xfffe); - switch (addr & 0xfffe) { - case 0x8504: - if (!virge->fifo_slot) - virge->subsys_stat |= INT_FIFO_EMP; - ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; - ret |= 0x30; /*A bit of a workaround at the moment.*/ - s3_virge_update_irqs(virge); - return ret; + switch (addr & 0xfffe) { + case 0x8504: + if (!virge->fifo_slot) + virge->subsys_stat |= INT_FIFO_EMP; + ret |= virge->subsys_stat; + if (virge->fifo_slot) + virge->fifo_slot--; + ret |= 0x30; /*A bit of a workaround at the moment.*/ + s3_virge_update_irqs(virge); + return ret; - case 0x859c: - return virge->cmd_dma; + case 0x859c: + return virge->cmd_dma; - default: - return s3_virge_mmio_read(addr, virge) | - (s3_virge_mmio_read(addr + 1, virge) << 8); - } + default: + return s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8); + } - return 0xffff; + return 0xffff; } static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) { - virge_t *virge = (virge_t *)p; - uint32_t ret = 0xffffffff; + virge_t *virge = (virge_t *) p; + uint32_t ret = 0xffffffff; - s3_virge_log("[%04X:%08X]: MMIO ReadL addr = %04x\n", CS, cpu_state.pc, addr & 0xfffc); + s3_virge_log("[%04X:%08X]: MMIO ReadL addr = %04x\n", CS, cpu_state.pc, addr & 0xfffc); - switch (addr & 0xfffc) { - case 0x8180: - ret = virge->streams.pri_ctrl; - break; - case 0x8184: - ret = virge->streams.chroma_ctrl; - break; - case 0x8190: - ret = virge->streams.sec_ctrl; - break; - case 0x8194: - ret = virge->streams.chroma_upper_bound; - break; - case 0x8198: - ret = virge->streams.sec_filter; - break; - case 0x81a0: - ret = virge->streams.blend_ctrl; - break; - case 0x81c0: - ret = virge->streams.pri_fb0; - break; - case 0x81c4: - ret = virge->streams.pri_fb1; - break; - case 0x81c8: - ret = virge->streams.pri_stride; - break; - case 0x81cc: - ret = virge->streams.buffer_ctrl; - break; - case 0x81d0: - ret = virge->streams.sec_fb0; - break; - case 0x81d4: - ret = virge->streams.sec_fb1; - break; - case 0x81d8: - ret = virge->streams.sec_stride; - break; - case 0x81dc: - ret = virge->streams.overlay_ctrl; - break; - case 0x81e0: - ret = virge->streams.k1_vert_scale; - break; - case 0x81e4: - ret = virge->streams.k2_vert_scale; - break; - case 0x81e8: - ret = virge->streams.dda_vert_accumulator; - break; - case 0x81ec: - ret = virge->streams.fifo_ctrl; - break; - case 0x81f0: - ret = virge->streams.pri_start; - break; - case 0x81f4: - ret = virge->streams.pri_size; - break; - case 0x81f8: - ret = virge->streams.sec_start; - break; - case 0x81fc: - ret = virge->streams.sec_size; - break; + switch (addr & 0xfffc) { + case 0x8180: + ret = virge->streams.pri_ctrl; + break; + case 0x8184: + ret = virge->streams.chroma_ctrl; + break; + case 0x8190: + ret = virge->streams.sec_ctrl; + break; + case 0x8194: + ret = virge->streams.chroma_upper_bound; + break; + case 0x8198: + ret = virge->streams.sec_filter; + break; + case 0x81a0: + ret = virge->streams.blend_ctrl; + break; + case 0x81c0: + ret = virge->streams.pri_fb0; + break; + case 0x81c4: + ret = virge->streams.pri_fb1; + break; + case 0x81c8: + ret = virge->streams.pri_stride; + break; + case 0x81cc: + ret = virge->streams.buffer_ctrl; + break; + case 0x81d0: + ret = virge->streams.sec_fb0; + break; + case 0x81d4: + ret = virge->streams.sec_fb1; + break; + case 0x81d8: + ret = virge->streams.sec_stride; + break; + case 0x81dc: + ret = virge->streams.overlay_ctrl; + break; + case 0x81e0: + ret = virge->streams.k1_vert_scale; + break; + case 0x81e4: + ret = virge->streams.k2_vert_scale; + break; + case 0x81e8: + ret = virge->streams.dda_vert_accumulator; + break; + case 0x81ec: + ret = virge->streams.fifo_ctrl; + break; + case 0x81f0: + ret = virge->streams.pri_start; + break; + case 0x81f4: + ret = virge->streams.pri_size; + break; + case 0x81f8: + ret = virge->streams.sec_start; + break; + case 0x81fc: + ret = virge->streams.sec_size; + break; - case 0x8504: - if (virge->s3d_busy || virge->fifo_slot) { - ret = (0x10 << 8); - } else { - ret = (0x10 << 8) | (1 << 13); - if (!virge->s3d_busy) - virge->subsys_stat |= INT_3DF_EMP; - if (!virge->fifo_slot) - virge->subsys_stat |= INT_FIFO_EMP; - } - ret |= virge->subsys_stat; - if (virge->fifo_slot) - virge->fifo_slot--; - s3_virge_update_irqs(virge); - break; + case 0x8504: + if (virge->s3d_busy || virge->fifo_slot) { + ret = (0x10 << 8); + } else { + ret = (0x10 << 8) | (1 << 13); + if (!virge->s3d_busy) + virge->subsys_stat |= INT_3DF_EMP; + if (!virge->fifo_slot) + virge->subsys_stat |= INT_FIFO_EMP; + } + ret |= virge->subsys_stat; + if (virge->fifo_slot) + virge->fifo_slot--; + s3_virge_update_irqs(virge); + break; - case 0x8590: - ret = virge->cmd_dma_base; - break; - case 0x8594: - break; - case 0x8598: - ret = virge->dma_ptr; - break; - case 0x859c: - ret = virge->cmd_dma; - break; + case 0x8590: + ret = virge->cmd_dma_base; + break; + case 0x8594: + break; + case 0x8598: + ret = virge->dma_ptr; + break; + case 0x859c: + ret = virge->cmd_dma; + break; - case 0xa4d4: - ret = virge->s3d.src_base; - break; - case 0xa4d8: - ret = virge->s3d.dest_base; - break; - case 0xa4dc: - ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; - break; - case 0xa4e0: - ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; - break; - case 0xa4e4: - ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; - break; - case 0xa4e8: case 0xace8: - ret = virge->s3d.mono_pat_0; - break; - case 0xa4ec: case 0xacec: - ret = virge->s3d.mono_pat_1; - break; - case 0xa4f0: - ret = virge->s3d.pat_bg_clr; - break; - case 0xa4f4: - ret = virge->s3d.pat_fg_clr; - break; - case 0xa4f8: - ret = virge->s3d.src_bg_clr; - break; - case 0xa4fc: - ret = virge->s3d.src_fg_clr; - break; - case 0xa500: - ret = virge->s3d.cmd_set; - break; - case 0xa504: - ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; - break; - case 0xa508: - ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; - break; - case 0xa50c: - ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; - break; + case 0xa4d4: + ret = virge->s3d.src_base; + break; + case 0xa4d8: + ret = virge->s3d.dest_base; + break; + case 0xa4dc: + ret = (virge->s3d.clip_l << 16) | virge->s3d.clip_r; + break; + case 0xa4e0: + ret = (virge->s3d.clip_t << 16) | virge->s3d.clip_b; + break; + case 0xa4e4: + ret = (virge->s3d.dest_str << 16) | virge->s3d.src_str; + break; + case 0xa4e8: + case 0xace8: + ret = virge->s3d.mono_pat_0; + break; + case 0xa4ec: + case 0xacec: + ret = virge->s3d.mono_pat_1; + break; + case 0xa4f0: + ret = virge->s3d.pat_bg_clr; + break; + case 0xa4f4: + ret = virge->s3d.pat_fg_clr; + break; + case 0xa4f8: + ret = virge->s3d.src_bg_clr; + break; + case 0xa4fc: + ret = virge->s3d.src_fg_clr; + break; + case 0xa500: + ret = virge->s3d.cmd_set; + break; + case 0xa504: + ret = (virge->s3d.r_width << 16) | virge->s3d.r_height; + break; + case 0xa508: + ret = (virge->s3d.rsrc_x << 16) | virge->s3d.rsrc_y; + break; + case 0xa50c: + ret = (virge->s3d.rdest_x << 16) | virge->s3d.rdest_y; + break; - default: - ret = s3_virge_mmio_read(addr, virge) | - (s3_virge_mmio_read(addr + 1, virge) << 8) | - (s3_virge_mmio_read(addr + 2, virge) << 16) | - (s3_virge_mmio_read(addr + 3, virge) << 24); - break; - } + default: + ret = s3_virge_mmio_read(addr, virge) | (s3_virge_mmio_read(addr + 1, virge) << 8) | (s3_virge_mmio_read(addr + 2, virge) << 16) | (s3_virge_mmio_read(addr + 3, virge) << 24); + break; + } - s3_virge_log("MMIO ReadL addr = %04x, val = %08x\n", addr & 0xfffc, ret); - return ret; + s3_virge_log("MMIO ReadL addr = %04x, val = %08x\n", addr & 0xfffc, ret); + return ret; } static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) { - virge_t *virge = (virge_t *)p; - s3_virge_log("MMIO WriteB addr = %04x, val = %02x\n", addr & 0xffff, val); - if (((addr & 0xffff) >= 0x8590) || ((addr & 0xffff) < 0x8000)) { - if ((addr & 0xffff) == 0xff20) { - virge->serialport = val; - i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); - } else - s3_virge_mmio_fifo_write(addr, val, virge); - } else { - switch (addr & 0xffff) { - case 0x83b0: case 0x83b1: case 0x83b2: case 0x83b3: - case 0x83b4: case 0x83b5: case 0x83b6: case 0x83b7: - case 0x83b8: case 0x83b9: case 0x83ba: case 0x83bb: - case 0x83bc: case 0x83bd: case 0x83be: case 0x83bf: - case 0x83c0: case 0x83c1: case 0x83c2: case 0x83c3: - case 0x83c4: case 0x83c5: case 0x83c6: case 0x83c7: - case 0x83c8: case 0x83c9: case 0x83ca: case 0x83cb: - case 0x83cc: case 0x83cd: case 0x83ce: case 0x83cf: - case 0x83d0: case 0x83d1: case 0x83d2: case 0x83d3: - case 0x83d4: case 0x83d5: case 0x83d6: case 0x83d7: - case 0x83d8: case 0x83d9: case 0x83da: case 0x83db: - case 0x83dc: case 0x83dd: case 0x83de: case 0x83df: - s3_virge_out(addr & 0x3ff, val, virge); - break; - } - } + virge_t *virge = (virge_t *) p; + s3_virge_log("MMIO WriteB addr = %04x, val = %02x\n", addr & 0xffff, val); + if (((addr & 0xffff) >= 0x8590) || ((addr & 0xffff) < 0x8000)) { + if ((addr & 0xffff) == 0xff20) { + virge->serialport = val; + i2c_gpio_set(virge->i2c, !!(val & SERIAL_PORT_SCW), !!(val & SERIAL_PORT_SDW)); + } else + s3_virge_mmio_fifo_write(addr, val, virge); + } else { + switch (addr & 0xffff) { + case 0x83b0: + case 0x83b1: + case 0x83b2: + case 0x83b3: + case 0x83b4: + case 0x83b5: + case 0x83b6: + case 0x83b7: + case 0x83b8: + case 0x83b9: + case 0x83ba: + case 0x83bb: + case 0x83bc: + case 0x83bd: + case 0x83be: + case 0x83bf: + case 0x83c0: + case 0x83c1: + case 0x83c2: + case 0x83c3: + case 0x83c4: + case 0x83c5: + case 0x83c6: + case 0x83c7: + case 0x83c8: + case 0x83c9: + case 0x83ca: + case 0x83cb: + case 0x83cc: + case 0x83cd: + case 0x83ce: + case 0x83cf: + case 0x83d0: + case 0x83d1: + case 0x83d2: + case 0x83d3: + case 0x83d4: + case 0x83d5: + case 0x83d6: + case 0x83d7: + case 0x83d8: + case 0x83d9: + case 0x83da: + case 0x83db: + case 0x83dc: + case 0x83dd: + case 0x83de: + case 0x83df: + s3_virge_out(addr & 0x3ff, val, virge); + break; + } + } } static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { - virge_t *virge = (virge_t *)p; - s3_virge_log("[%04X:%08X]: MMIO WriteW addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffe, val); - if (((addr & 0xfffe) >= 0x8590) || ((addr & 0xfffe) < 0x8000)) - if ((addr & 0xfffe) == 0xff20) - s3_virge_mmio_write(addr, val, virge); - else - s3_virge_mmio_fifo_write_w(addr, val, virge); - else { - if ((addr & 0xfffe) == 0x83d4) { - s3_virge_mmio_write(addr, val, virge); - s3_virge_mmio_write(addr + 1, val >> 8, virge); - } - } + virge_t *virge = (virge_t *) p; + s3_virge_log("[%04X:%08X]: MMIO WriteW addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffe, val); + if (((addr & 0xfffe) >= 0x8590) || ((addr & 0xfffe) < 0x8000)) + if ((addr & 0xfffe) == 0xff20) + s3_virge_mmio_write(addr, val, virge); + else + s3_virge_mmio_fifo_write_w(addr, val, virge); + else { + if ((addr & 0xfffe) == 0x83d4) { + s3_virge_mmio_write(addr, val, virge); + s3_virge_mmio_write(addr + 1, val >> 8, virge); + } + } } static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; + virge_t *virge = (virge_t *) p; + svga_t *svga = &virge->svga; - s3_virge_log("[%04X:%08X]: MMIO WriteL addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffc, val); - if (((addr & 0xfffc) >= 0x8590) || ((addr & 0xfffc) < 0x8000)) - if ((addr & 0xfffc) == 0xff20) - s3_virge_mmio_write(addr, val, virge); - else { - s3_virge_mmio_fifo_write_l(addr, val, virge); - } - else { - switch (addr & 0xfffc) { - case 0x8180: - virge->streams.pri_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x8184: - virge->streams.chroma_ctrl = val; - break; - case 0x8190: - virge->streams.sec_ctrl = val; - virge->streams.dda_horiz_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_horiz_accumulator |= 0xfffff800; - virge->streams.sdif = (val >> 24) & 7; - break; - case 0x8194: - virge->streams.chroma_upper_bound = val; - break; - case 0x8198: - virge->streams.sec_filter = val; - virge->streams.k1_horiz_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_horiz_scale |= 0xfffff800; - virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff; - if ((val >> 16) & (1 << 10)) - virge->streams.k2_horiz_scale |= 0xfffff800; - break; - case 0x81a0: - virge->streams.blend_ctrl = val; - break; - case 0x81c0: - virge->streams.pri_fb0 = val & 0x7fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c4: - virge->streams.pri_fb1 = val & 0x7fffff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81c8: - virge->streams.pri_stride = val & 0xfff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81cc: - virge->streams.buffer_ctrl = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d0: - virge->streams.sec_fb0 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d4: - virge->streams.sec_fb1 = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81d8: - virge->streams.sec_stride = val; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81dc: - virge->streams.overlay_ctrl = val; - break; - case 0x81e0: - virge->streams.k1_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k1_vert_scale |= 0xfffff800; - break; - case 0x81e4: - virge->streams.k2_vert_scale = val & 0x7ff; - if (val & (1 << 10)) - virge->streams.k2_vert_scale |= 0xfffff800; - break; - case 0x81e8: - virge->streams.dda_vert_accumulator = val & 0xfff; - if (val & (1 << 11)) - virge->streams.dda_vert_accumulator |= 0xfffff800; - break; - case 0x81ec: - virge->streams.fifo_ctrl = val; - break; - case 0x81f0: - virge->streams.pri_start = val; - virge->streams.pri_x = (val >> 16) & 0x7ff; - virge->streams.pri_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f4: - virge->streams.pri_size = val; - virge->streams.pri_w = (val >> 16) & 0x7ff; - virge->streams.pri_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81f8: - virge->streams.sec_start = val; - virge->streams.sec_x = (val >> 16) & 0x7ff; - virge->streams.sec_y = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; - case 0x81fc: - virge->streams.sec_size = val; - virge->streams.sec_w = (val >> 16) & 0x7ff; - virge->streams.sec_h = val & 0x7ff; - svga_recalctimings(svga); - svga->fullchange = changeframecount; - break; + s3_virge_log("[%04X:%08X]: MMIO WriteL addr = %04x, val = %04x\n", CS, cpu_state.pc, addr & 0xfffc, val); + if (((addr & 0xfffc) >= 0x8590) || ((addr & 0xfffc) < 0x8000)) + if ((addr & 0xfffc) == 0xff20) + s3_virge_mmio_write(addr, val, virge); + else { + s3_virge_mmio_fifo_write_l(addr, val, virge); + } + else { + switch (addr & 0xfffc) { + case 0x8180: + virge->streams.pri_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x8184: + virge->streams.chroma_ctrl = val; + break; + case 0x8190: + virge->streams.sec_ctrl = val; + virge->streams.dda_horiz_accumulator = val & 0xfff; + if (val & (1 << 11)) + virge->streams.dda_horiz_accumulator |= 0xfffff800; + virge->streams.sdif = (val >> 24) & 7; + break; + case 0x8194: + virge->streams.chroma_upper_bound = val; + break; + case 0x8198: + virge->streams.sec_filter = val; + virge->streams.k1_horiz_scale = val & 0x7ff; + if (val & (1 << 10)) + virge->streams.k1_horiz_scale |= 0xfffff800; + virge->streams.k2_horiz_scale = (val >> 16) & 0x7ff; + if ((val >> 16) & (1 << 10)) + virge->streams.k2_horiz_scale |= 0xfffff800; + break; + case 0x81a0: + virge->streams.blend_ctrl = val; + break; + case 0x81c0: + virge->streams.pri_fb0 = val & 0x7fffff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81c4: + virge->streams.pri_fb1 = val & 0x7fffff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81c8: + virge->streams.pri_stride = val & 0xfff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81cc: + virge->streams.buffer_ctrl = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d0: + virge->streams.sec_fb0 = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d4: + virge->streams.sec_fb1 = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81d8: + virge->streams.sec_stride = val; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81dc: + virge->streams.overlay_ctrl = val; + break; + case 0x81e0: + virge->streams.k1_vert_scale = val & 0x7ff; + if (val & (1 << 10)) + virge->streams.k1_vert_scale |= 0xfffff800; + break; + case 0x81e4: + virge->streams.k2_vert_scale = val & 0x7ff; + if (val & (1 << 10)) + virge->streams.k2_vert_scale |= 0xfffff800; + break; + case 0x81e8: + virge->streams.dda_vert_accumulator = val & 0xfff; + if (val & (1 << 11)) + virge->streams.dda_vert_accumulator |= 0xfffff800; + break; + case 0x81ec: + virge->streams.fifo_ctrl = val; + break; + case 0x81f0: + virge->streams.pri_start = val; + virge->streams.pri_x = (val >> 16) & 0x7ff; + virge->streams.pri_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81f4: + virge->streams.pri_size = val; + virge->streams.pri_w = (val >> 16) & 0x7ff; + virge->streams.pri_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81f8: + virge->streams.sec_start = val; + virge->streams.sec_x = (val >> 16) & 0x7ff; + virge->streams.sec_y = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; + case 0x81fc: + virge->streams.sec_size = val; + virge->streams.sec_w = (val >> 16) & 0x7ff; + virge->streams.sec_h = val & 0x7ff; + svga_recalctimings(svga); + svga->fullchange = changeframecount; + break; - case 0x8504: - virge->subsys_stat &= ~(val & 0xff); - virge->subsys_cntl = (val >> 8); - s3_virge_update_irqs(virge); - break; + case 0x8504: + virge->subsys_stat &= ~(val & 0xff); + virge->subsys_cntl = (val >> 8); + s3_virge_update_irqs(virge); + break; - case 0x850c: - virge->advfunc_cntl = val & 0xff; - s3_virge_updatemapping(virge); - break; - } - } + case 0x850c: + virge->advfunc_cntl = val & 0xff; + s3_virge_updatemapping(virge); + break; + } + } } -#define READ(addr, val) \ - { \ - switch (bpp) \ - { \ - case 0: /*8 bpp*/ \ - val = vram[addr & virge->vram_mask]; \ - break; \ - case 1: /*16 bpp*/ \ - val = *(uint16_t *)&vram[addr & virge->vram_mask]; \ - break; \ - case 2: /*24 bpp*/ \ - val = (*(uint32_t *)&vram[addr & virge->vram_mask]) & 0xffffff; \ - break; \ - } \ - } +#define READ(addr, val) \ + { \ + switch (bpp) { \ + case 0: /*8 bpp*/ \ + val = vram[addr & virge->vram_mask]; \ + break; \ + case 1: /*16 bpp*/ \ + val = *(uint16_t *) &vram[addr & virge->vram_mask]; \ + break; \ + case 2: /*24 bpp*/ \ + val = (*(uint32_t *) &vram[addr & virge->vram_mask]) & 0xffffff; \ + break; \ + } \ + } -#define CLIP(x, y) \ - { \ - if ((virge->s3d.cmd_set & CMD_SET_HC) && \ - (x < virge->s3d.clip_l || \ - x > virge->s3d.clip_r || \ - y < virge->s3d.clip_t || \ - y > virge->s3d.clip_b)) \ - update = 0; \ - } +#define CLIP(x, y) \ + { \ + if ((virge->s3d.cmd_set & CMD_SET_HC) && (x < virge->s3d.clip_l || x > virge->s3d.clip_r || y < virge->s3d.clip_t || y > virge->s3d.clip_b)) \ + update = 0; \ + } -#define CLIP_3D(x, y) \ - { \ - if ((s3d_tri->cmd_set & CMD_SET_HC) && \ - (x < s3d_tri->clip_l || \ - x > s3d_tri->clip_r || \ - y < s3d_tri->clip_t || \ - y > s3d_tri->clip_b)) \ - update = 0; \ - } +#define CLIP_3D(x, y) \ + { \ + if ((s3d_tri->cmd_set & CMD_SET_HC) && (x < s3d_tri->clip_l || x > s3d_tri->clip_r || y < s3d_tri->clip_t || y > s3d_tri->clip_b)) \ + update = 0; \ + } +#define MIX() \ + { \ + int c; \ + for (c = 0; c < 24; c++) { \ + int d = (dest & (1 << c)) ? 1 : 0; \ + if (source & (1 << c)) \ + d |= 2; \ + if (pattern & (1 << c)) \ + d |= 4; \ + if (virge->s3d.rop & (1 << d)) \ + out |= (1 << c); \ + } \ + } -#define MIX() \ - { \ - int c; \ - for (c = 0; c < 24; c++) \ - { \ - int d = (dest & (1 << c)) ? 1 : 0; \ - if (source & (1 << c)) d |= 2; \ - if (pattern & (1 << c)) d |= 4; \ - if (virge->s3d.rop & (1 << d)) out |= (1 << c); \ - } \ - } +#define WRITE(addr, val) \ + { \ + switch (bpp) { \ + case 0: /*8 bpp*/ \ + vram[addr & virge->vram_mask] = val; \ + svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ + break; \ + case 1: /*16 bpp*/ \ + *(uint16_t *) &vram[addr & virge->vram_mask] = val; \ + svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ + break; \ + case 2: /*24 bpp*/ \ + *(uint32_t *) &vram[addr & virge->vram_mask] = (val & 0xffffff) | (vram[(addr + 3) & virge->vram_mask] << 24); \ + svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ + break; \ + } \ + } -#define WRITE(addr, val) \ - { \ - switch (bpp) \ - { \ - case 0: /*8 bpp*/ \ - vram[addr & virge->vram_mask] = val; \ - svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ - break; \ - case 1: /*16 bpp*/ \ - *(uint16_t *)&vram[addr & virge->vram_mask] = val; \ - svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ - break; \ - case 2: /*24 bpp*/ \ - *(uint32_t *)&vram[addr & virge->vram_mask] = (val & 0xffffff) | \ - (vram[(addr + 3) & virge->vram_mask] << 24); \ - svga->changedvram[(addr & virge->vram_mask) >> 12] = changeframecount; \ - break; \ - } \ - } - -static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) +static void +s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { - svga_t *svga = &virge->svga; - uint8_t *vram = virge->svga.vram; - uint32_t mono_pattern[64]; - int count_mask; - int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; - int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; - int bpp; - int x_mul; - int cpu_dat_shift; - uint32_t *pattern_data; - uint32_t src_fg_clr, src_bg_clr; - uint32_t src_addr; - uint32_t dest_addr; - uint32_t source = 0, dest = 0, pattern; - uint32_t out = 0; - int update; + svga_t *svga = &virge->svga; + uint8_t *vram = virge->svga.vram; + uint32_t mono_pattern[64]; + int count_mask; + int x_inc = (virge->s3d.cmd_set & CMD_SET_XP) ? 1 : -1; + int y_inc = (virge->s3d.cmd_set & CMD_SET_YP) ? 1 : -1; + int bpp; + int x_mul; + int cpu_dat_shift; + uint32_t *pattern_data; + uint32_t src_fg_clr, src_bg_clr; + uint32_t src_addr; + uint32_t dest_addr; + uint32_t source = 0, dest = 0, pattern; + uint32_t out = 0; + int update; - switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) - { - case CMD_SET_FORMAT_8: - bpp = 0; - x_mul = 1; - cpu_dat_shift = 8; - pattern_data = virge->s3d.pattern_8; - src_fg_clr = virge->s3d.src_fg_clr & 0xff; - src_bg_clr = virge->s3d.src_bg_clr & 0xff; - break; - case CMD_SET_FORMAT_16: - bpp = 1; - x_mul = 2; - cpu_dat_shift = 16; - pattern_data = virge->s3d.pattern_16; - src_fg_clr = virge->s3d.src_fg_clr & 0xffff; - src_bg_clr = virge->s3d.src_bg_clr & 0xffff; - break; - case CMD_SET_FORMAT_24: - default: - bpp = 2; - x_mul = 3; - cpu_dat_shift = 24; - pattern_data = virge->s3d.pattern_24; - src_fg_clr = virge->s3d.src_fg_clr; - src_bg_clr = virge->s3d.src_bg_clr; - break; + switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { + case CMD_SET_FORMAT_8: + bpp = 0; + x_mul = 1; + cpu_dat_shift = 8; + pattern_data = virge->s3d.pattern_8; + src_fg_clr = virge->s3d.src_fg_clr & 0xff; + src_bg_clr = virge->s3d.src_bg_clr & 0xff; + break; + case CMD_SET_FORMAT_16: + bpp = 1; + x_mul = 2; + cpu_dat_shift = 16; + pattern_data = virge->s3d.pattern_16; + src_fg_clr = virge->s3d.src_fg_clr & 0xffff; + src_bg_clr = virge->s3d.src_bg_clr & 0xffff; + break; + case CMD_SET_FORMAT_24: + default: + bpp = 2; + x_mul = 3; + cpu_dat_shift = 24; + pattern_data = virge->s3d.pattern_24; + src_fg_clr = virge->s3d.src_fg_clr; + src_bg_clr = virge->s3d.src_bg_clr; + break; + } + if (virge->s3d.cmd_set & CMD_SET_MP) + pattern_data = mono_pattern; + + switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) { + case CMD_SET_ITA_BYTE: + count_mask = ~0x7; + break; + case CMD_SET_ITA_WORD: + count_mask = ~0xf; + break; + case CMD_SET_ITA_DWORD: + default: + count_mask = ~0x1f; + break; + } + if (virge->s3d.cmd_set & CMD_SET_MP) { + int x, y; + for (y = 0; y < 4; y++) { + for (x = 0; x < 8; x++) { + if (virge->s3d.mono_pat_0 & (1 << (x + y * 8))) + mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_fg_clr; + else + mono_pattern[y * 8 + (7 - x)] = virge->s3d.pat_bg_clr; + if (virge->s3d.mono_pat_1 & (1 << (x + y * 8))) + mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_fg_clr; + else + mono_pattern[(y + 4) * 8 + (7 - x)] = virge->s3d.pat_bg_clr; + } } - if (virge->s3d.cmd_set & CMD_SET_MP) - pattern_data = mono_pattern; + } + switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK) { + case CMD_SET_COMMAND_BITBLT: + if (count == -1) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.dest_y = virge->s3d.rdest_y; + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + virge->s3d.data_left_count = 0; - switch (virge->s3d.cmd_set & CMD_SET_ITA_MASK) - { - case CMD_SET_ITA_BYTE: - count_mask = ~0x7; - break; - case CMD_SET_ITA_WORD: - count_mask = ~0xf; - break; - case CMD_SET_ITA_DWORD: - default: - count_mask = ~0x1f; - break; - } - if (virge->s3d.cmd_set & CMD_SET_MP) - { - int x, y; - for (y = 0; y < 4; y++) - { - for (x = 0; x < 8; x++) - { - if (virge->s3d.mono_pat_0 & (1 << (x + y*8))) - mono_pattern[y*8 + (7 - x)] = virge->s3d.pat_fg_clr; - else - mono_pattern[y*8 + (7 - x)] = virge->s3d.pat_bg_clr; - if (virge->s3d.mono_pat_1 & (1 << (x + y*8))) - mono_pattern[(y+4)*8 + (7 - x)] = virge->s3d.pat_fg_clr; - else - mono_pattern[(y+4)*8 + (7 - x)] = virge->s3d.pat_bg_clr; + s3_virge_log("BitBlt start src_x=%i,src_y=%i,dest_x=%i,dest_y=%i,w=%i,h=%i,rop=%02X,src_base=%x,dest_base=%x\n", + virge->s3d.src_x, + virge->s3d.src_y, + virge->s3d.dest_x, + virge->s3d.dest_y, + virge->s3d.w, + virge->s3d.h, + virge->s3d.rop, + virge->s3d.src_base, + virge->s3d.dest_base); + + if (virge->s3d.cmd_set & CMD_SET_IDS) + return; + } + if (!virge->s3d.h) + return; + while (count) { + src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); + dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + out = 0; + update = 1; + + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { + case 0: + case CMD_SET_MS: + READ(src_addr, source); + if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) + update = 0; + break; + case CMD_SET_IDS: + if (virge->s3d.data_left_count) { + /*Handle shifting for 24-bit data*/ + source = virge->s3d.data_left; + source |= ((cpu_dat << virge->s3d.data_left_count) & ~0xff000000); + cpu_dat >>= (cpu_dat_shift - virge->s3d.data_left_count); + count -= (cpu_dat_shift - virge->s3d.data_left_count); + virge->s3d.data_left_count = 0; + if (count < cpu_dat_shift) { + virge->s3d.data_left = cpu_dat; + virge->s3d.data_left_count = count; + count = 0; + } + } else { + source = cpu_dat; + cpu_dat >>= cpu_dat_shift; + count -= cpu_dat_shift; + if (count < cpu_dat_shift) { + virge->s3d.data_left = cpu_dat; + virge->s3d.data_left_count = count; + count = 0; + } } - } - } - switch (virge->s3d.cmd_set & CMD_SET_COMMAND_MASK) - { - case CMD_SET_COMMAND_BITBLT: - if (count == -1) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - virge->s3d.data_left_count = 0; - - s3_virge_log("BitBlt start src_x=%i,src_y=%i,dest_x=%i,dest_y=%i,w=%i,h=%i,rop=%02X,src_base=%x,dest_base=%x\n", - virge->s3d.src_x, - virge->s3d.src_y, - virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, - virge->s3d.src_base, - virge->s3d.dest_base); - - if (virge->s3d.cmd_set & CMD_SET_IDS) - return; - } - if (!virge->s3d.h) - return; - while (count) - { - src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); - dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - out = 0; - update = 1; - - switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) - { - case 0: - case CMD_SET_MS: - READ(src_addr, source); - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) - update = 0; - break; - case CMD_SET_IDS: - if (virge->s3d.data_left_count) - { - /*Handle shifting for 24-bit data*/ - source = virge->s3d.data_left; - source |= ((cpu_dat << virge->s3d.data_left_count) & ~0xff000000); - cpu_dat >>= (cpu_dat_shift - virge->s3d.data_left_count); - count -= (cpu_dat_shift - virge->s3d.data_left_count); - virge->s3d.data_left_count = 0; - if (count < cpu_dat_shift) - { - virge->s3d.data_left = cpu_dat; - virge->s3d.data_left_count = count; - count = 0; - } - } - else - { - source = cpu_dat; - cpu_dat >>= cpu_dat_shift; - count -= cpu_dat_shift; - if (count < cpu_dat_shift) - { - virge->s3d.data_left = cpu_dat; - virge->s3d.data_left_count = count; - count = 0; - } - } - if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) - update = 0; - break; - case CMD_SET_IDS | CMD_SET_MS: - source = (cpu_dat & (1 << 31)) ? src_fg_clr : src_bg_clr; - if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31))) - update = 0; - cpu_dat <<= 1; - count--; - break; - } - - CLIP(virge->s3d.dest_x, virge->s3d.dest_y); - - if (update) - { - READ(dest_addr, dest); - pattern = pattern_data[(virge->s3d.dest_y & 7)*8 + (virge->s3d.dest_x & 7)]; - MIX(); - - WRITE(dest_addr, out); - } - - virge->s3d.src_x += x_inc; - virge->s3d.src_x &= 0x7ff; - virge->s3d.dest_x += x_inc; - virge->s3d.dest_x &= 0x7ff; - if (!virge->s3d.w) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; - - virge->s3d.src_y += y_inc; - virge->s3d.dest_y += y_inc; - virge->s3d.h--; - - switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) - { - case CMD_SET_IDS: - cpu_dat >>= (count - (count & count_mask)); - count &= count_mask; - virge->s3d.data_left_count = 0; - break; - - case CMD_SET_IDS | CMD_SET_MS: - cpu_dat <<= (count - (count & count_mask)); - count &= count_mask; - break; - } - if (!virge->s3d.h) - { - return; - } - } - else - virge->s3d.w--; - } - break; - - case CMD_SET_COMMAND_RECTFILL: - /*No source, pattern = pat_fg_clr*/ - if (count == -1) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.src_y = virge->s3d.rsrc_y; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.dest_y = virge->s3d.rdest_y; - virge->s3d.w = virge->s3d.r_width; - virge->s3d.h = virge->s3d.r_height; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - - s3_virge_log("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, - virge->s3d.dest_y, - virge->s3d.w, - virge->s3d.h, - virge->s3d.rop, virge->s3d.dest_base); - } - - while (count && virge->s3d.h) - { - source = virge->s3d.pat_fg_clr; - dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - pattern = virge->s3d.pat_fg_clr; - out = 0; - update = 1; - - CLIP(virge->s3d.dest_x, virge->s3d.dest_y); - - if (update) - { - READ(dest_addr, dest); - - MIX(); - - WRITE(dest_addr, out); - } - - virge->s3d.src_x += x_inc; - virge->s3d.src_x &= 0x7ff; - virge->s3d.dest_x += x_inc; - virge->s3d.dest_x &= 0x7ff; - if (!virge->s3d.w) - { - virge->s3d.src_x = virge->s3d.rsrc_x; - virge->s3d.dest_x = virge->s3d.rdest_x; - virge->s3d.w = virge->s3d.r_width; - - virge->s3d.src_y += y_inc; - virge->s3d.dest_y += y_inc; - virge->s3d.h--; - if (!virge->s3d.h) - { - return; - } - } - else - virge->s3d.w--; + if ((virge->s3d.cmd_set & CMD_SET_TP) && source == src_fg_clr) + update = 0; + break; + case CMD_SET_IDS | CMD_SET_MS: + source = (cpu_dat & (1 << 31)) ? src_fg_clr : src_bg_clr; + if ((virge->s3d.cmd_set & CMD_SET_TP) && !(cpu_dat & (1 << 31))) + update = 0; + cpu_dat <<= 1; count--; + break; } - break; - case CMD_SET_COMMAND_LINE: - if (count == -1) - { - virge->s3d.dest_x = virge->s3d.lxstart; - virge->s3d.dest_y = virge->s3d.lystart; - virge->s3d.h = virge->s3d.lycnt; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + CLIP(virge->s3d.dest_x, virge->s3d.dest_y); + + if (update) { + READ(dest_addr, dest); + pattern = pattern_data[(virge->s3d.dest_y & 7) * 8 + (virge->s3d.dest_x & 7)]; + MIX(); + + WRITE(dest_addr, out); } - while (virge->s3d.h) - { - int x; - int new_x; - int first_pixel = 1; - x = virge->s3d.dest_x >> 20; + virge->s3d.src_x += x_inc; + virge->s3d.src_x &= 0x7ff; + virge->s3d.dest_x += x_inc; + virge->s3d.dest_x &= 0x7ff; + if (!virge->s3d.w) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.w = virge->s3d.r_width; - if (virge->s3d.h == virge->s3d.lycnt && - ((virge->s3d.line_dir && x > virge->s3d.lxend0) || - (!virge->s3d.line_dir && x < virge->s3d.lxend0))) - x = virge->s3d.lxend0; + virge->s3d.src_y += y_inc; + virge->s3d.dest_y += y_inc; + virge->s3d.h--; - if (virge->s3d.h == 1) - new_x = virge->s3d.lxend1 + (virge->s3d.line_dir ? 1 : -1); - else - new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; + switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { + case CMD_SET_IDS: + cpu_dat >>= (count - (count & count_mask)); + count &= count_mask; + virge->s3d.data_left_count = 0; + break; + case CMD_SET_IDS | CMD_SET_MS: + cpu_dat <<= (count - (count & count_mask)); + count &= count_mask; + break; + } + if (!virge->s3d.h) { + return; + } + } else + virge->s3d.w--; + } + break; - if ((virge->s3d.line_dir && x > new_x) || - (!virge->s3d.line_dir && x < new_x)) - goto skip_line; + case CMD_SET_COMMAND_RECTFILL: + /*No source, pattern = pat_fg_clr*/ + if (count == -1) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.src_y = virge->s3d.rsrc_y; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.dest_y = virge->s3d.rdest_y; + virge->s3d.w = virge->s3d.r_width; + virge->s3d.h = virge->s3d.r_height; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - do - { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source = 0, dest = 0, pattern; - uint32_t out = 0; - int update = 1; + s3_virge_log("RctFll start %i,%i %i,%i %02X %08x\n", virge->s3d.dest_x, + virge->s3d.dest_y, + virge->s3d.w, + virge->s3d.h, + virge->s3d.rop, virge->s3d.dest_base); + } - if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) && - ((virge->s3d.line_dir && x < virge->s3d.lxend0) || - (!virge->s3d.line_dir && x > virge->s3d.lxend0))) - update = 0; + while (count && virge->s3d.h) { + source = virge->s3d.pat_fg_clr; + dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + pattern = virge->s3d.pat_fg_clr; + out = 0; + update = 1; - if ((virge->s3d.h == 1 || !first_pixel) && - ((virge->s3d.line_dir && x > virge->s3d.lxend1) || - (!virge->s3d.line_dir && x < virge->s3d.lxend1))) - update = 0; + CLIP(virge->s3d.dest_x, virge->s3d.dest_y); - CLIP(x, virge->s3d.dest_y); + if (update) { + READ(dest_addr, dest); - if (update) - { - READ(dest_addr, dest); - pattern = virge->s3d.pat_fg_clr; + MIX(); - MIX(); + WRITE(dest_addr, out); + } - WRITE(dest_addr, out); - } + virge->s3d.src_x += x_inc; + virge->s3d.src_x &= 0x7ff; + virge->s3d.dest_x += x_inc; + virge->s3d.dest_x &= 0x7ff; + if (!virge->s3d.w) { + virge->s3d.src_x = virge->s3d.rsrc_x; + virge->s3d.dest_x = virge->s3d.rdest_x; + virge->s3d.w = virge->s3d.r_width; - if (x < new_x) - x++; - else if (x > new_x) - x--; - first_pixel = 0; - } while (x != new_x); + virge->s3d.src_y += y_inc; + virge->s3d.dest_y += y_inc; + virge->s3d.h--; + if (!virge->s3d.h) { + return; + } + } else + virge->s3d.w--; + count--; + } + break; + + case CMD_SET_COMMAND_LINE: + if (count == -1) { + virge->s3d.dest_x = virge->s3d.lxstart; + virge->s3d.dest_y = virge->s3d.lystart; + virge->s3d.h = virge->s3d.lycnt; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + } + while (virge->s3d.h) { + int x; + int new_x; + int first_pixel = 1; + + x = virge->s3d.dest_x >> 20; + + if (virge->s3d.h == virge->s3d.lycnt && ((virge->s3d.line_dir && x > virge->s3d.lxend0) || (!virge->s3d.line_dir && x < virge->s3d.lxend0))) + x = virge->s3d.lxend0; + + if (virge->s3d.h == 1) + new_x = virge->s3d.lxend1 + (virge->s3d.line_dir ? 1 : -1); + else + new_x = (virge->s3d.dest_x + virge->s3d.ldx) >> 20; + + if ((virge->s3d.line_dir && x > new_x) || (!virge->s3d.line_dir && x < new_x)) + goto skip_line; + + do { + uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + uint32_t source = 0, dest = 0, pattern; + uint32_t out = 0; + int update = 1; + + if ((virge->s3d.h == virge->s3d.lycnt || !first_pixel) && ((virge->s3d.line_dir && x < virge->s3d.lxend0) || (!virge->s3d.line_dir && x > virge->s3d.lxend0))) + update = 0; + + if ((virge->s3d.h == 1 || !first_pixel) && ((virge->s3d.line_dir && x > virge->s3d.lxend1) || (!virge->s3d.line_dir && x < virge->s3d.lxend1))) + update = 0; + + CLIP(x, virge->s3d.dest_y); + + if (update) { + READ(dest_addr, dest); + pattern = virge->s3d.pat_fg_clr; + + MIX(); + + WRITE(dest_addr, out); + } + + if (x < new_x) + x++; + else if (x > new_x) + x--; + first_pixel = 0; + } while (x != new_x); skip_line: - virge->s3d.dest_x += virge->s3d.ldx; - virge->s3d.dest_y--; - virge->s3d.h--; - } - break; + virge->s3d.dest_x += virge->s3d.ldx; + virge->s3d.dest_y--; + virge->s3d.h--; + } + break; - case CMD_SET_COMMAND_POLY: - /*No source*/ - if (virge->s3d.pycnt & (1 << 28)) - virge->s3d.dest_r = virge->s3d.prxstart; - if (virge->s3d.pycnt & (1 << 29)) - virge->s3d.dest_l = virge->s3d.plxstart; - virge->s3d.h = virge->s3d.pycnt & 0x7ff; - virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - while (virge->s3d.h) - { - int x = virge->s3d.dest_l >> 20; - int xend = virge->s3d.dest_r >> 20; - int y = virge->s3d.pystart & 0x7ff; - int xdir = (x < xend) ? 1 : -1; - do - { - uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); - uint32_t source = 0, dest = 0, pattern; - uint32_t out = 0; - int update = 1; + case CMD_SET_COMMAND_POLY: + /*No source*/ + if (virge->s3d.pycnt & (1 << 28)) + virge->s3d.dest_r = virge->s3d.prxstart; + if (virge->s3d.pycnt & (1 << 29)) + virge->s3d.dest_l = virge->s3d.plxstart; + virge->s3d.h = virge->s3d.pycnt & 0x7ff; + virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; + while (virge->s3d.h) { + int x = virge->s3d.dest_l >> 20; + int xend = virge->s3d.dest_r >> 20; + int y = virge->s3d.pystart & 0x7ff; + int xdir = (x < xend) ? 1 : -1; + do { + uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); + uint32_t source = 0, dest = 0, pattern; + uint32_t out = 0; + int update = 1; - CLIP(x, y); + CLIP(x, y); - if (update) - { - READ(dest_addr, dest); - pattern = pattern_data[(y & 7)*8 + (x & 7)]; - MIX(); + if (update) { + READ(dest_addr, dest); + pattern = pattern_data[(y & 7) * 8 + (x & 7)]; + MIX(); - WRITE(dest_addr, out); - } + WRITE(dest_addr, out); + } - x = (x + xdir) & 0x7ff; - } - while (x != (xend + xdir)); + x = (x + xdir) & 0x7ff; + } while (x != (xend + xdir)); - virge->s3d.dest_l += virge->s3d.pldx; - virge->s3d.dest_r += virge->s3d.prdx; - virge->s3d.h--; - virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff; - } - break; + virge->s3d.dest_l += virge->s3d.pldx; + virge->s3d.dest_r += virge->s3d.prdx; + virge->s3d.h--; + virge->s3d.pystart = (virge->s3d.pystart - 1) & 0x7ff; + } + break; - case CMD_SET_COMMAND_NOP: - break; - } + case CMD_SET_COMMAND_NOP: + break; + } } -#define RGB15_TO_24(val, r, g, b) b = ((val & 0x001f) << 3) | ((val & 0x001f) >> 2); \ - g = ((val & 0x03e0) >> 2) | ((val & 0x03e0) >> 7); \ - r = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12); +#define RGB15_TO_24(val, r, g, b) \ + b = ((val & 0x001f) << 3) | ((val & 0x001f) >> 2); \ + g = ((val & 0x03e0) >> 2) | ((val & 0x03e0) >> 7); \ + r = ((val & 0x7c00) >> 7) | ((val & 0x7c00) >> 12); -#define RGB24_TO_24(val, r, g, b) b = val & 0xff; \ - g = (val & 0xff00) >> 8; \ - r = (val & 0xff0000) >> 16 +#define RGB24_TO_24(val, r, g, b) \ + b = val & 0xff; \ + g = (val & 0xff00) >> 8; \ + r = (val & 0xff0000) >> 16 -#define RGB15(r, g, b, dest) \ - if (virge->dithering_enabled) \ - { \ - int add = dither[_y & 3][_x & 3]; \ - int _r = (r > 248) ? 248 : r+add; \ - int _g = (g > 248) ? 248 : g+add; \ - int _b = (b > 248) ? 248 : b+add; \ - dest = ((_b >> 3) & 0x1f) | (((_g >> 3) & 0x1f) << 5) | (((_r >> 3) & 0x1f) << 10); \ - } \ - else \ - dest = ((b >> 3) & 0x1f) | (((g >> 3) & 0x1f) << 5) | (((r >> 3) & 0x1f) << 10) +#define RGB15(r, g, b, dest) \ + if (virge->dithering_enabled) { \ + int add = dither[_y & 3][_x & 3]; \ + int _r = (r > 248) ? 248 : r + add; \ + int _g = (g > 248) ? 248 : g + add; \ + int _b = (b > 248) ? 248 : b + add; \ + dest = ((_b >> 3) & 0x1f) | (((_g >> 3) & 0x1f) << 5) | (((_r >> 3) & 0x1f) << 10); \ + } else \ + dest = ((b >> 3) & 0x1f) | (((g >> 3) & 0x1f) << 5) | (((r >> 3) & 0x1f) << 10) #define RGB24(r, g, b) ((b) | ((g) << 8) | ((r) << 16)) -typedef struct rgba_t -{ - int r, g, b, a; +typedef struct rgba_t { + int r, g, b, a; } rgba_t; -typedef struct s3d_state_t -{ - int32_t r, g, b, a, u, v, d, w; +typedef struct s3d_state_t { + int32_t r, g, b, a, u, v, d, w; - int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; + int32_t base_r, base_g, base_b, base_a, base_u, base_v, base_d, base_w; - uint32_t base_z; + uint32_t base_z; - uint32_t tbu, tbv; + uint32_t tbu, tbv; - uint32_t cmd_set; - int max_d; + uint32_t cmd_set; + int max_d; - uint16_t *texture[10]; + uint16_t *texture[10]; - uint32_t tex_bdr_clr; + uint32_t tex_bdr_clr; - int32_t x1, x2; - int y; + int32_t x1, x2; + int y; - rgba_t dest_rgba; + rgba_t dest_rgba; } s3d_state_t; -typedef struct s3d_texture_state_t -{ - int level; - int texture_shift; +typedef struct s3d_texture_state_t { + int level; + int texture_shift; - int32_t u, v; + int32_t u, v; } s3d_texture_state_t; static void (*tex_read)(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out); @@ -2307,1915 +2454,2003 @@ static void (*dest_pixel)(s3d_state_t *state); static int _x, _y; -static void tex_ARGB1555(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) +static void +tex_ARGB1555(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); - out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); - out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); - out->a = (val & 0x8000) ? 0xff : 0; + out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); + out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); + out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); + out->a = (val & 0x8000) ? 0xff : 0; } -static void tex_ARGB1555_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) +static void +tex_ARGB1555_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; + if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) + val = state->tex_bdr_clr; - out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); - out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); - out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); - out->a = (val & 0x8000) ? 0xff : 0; + out->r = ((val & 0x7c00) >> 7) | ((val & 0x7000) >> 12); + out->g = ((val & 0x03e0) >> 2) | ((val & 0x0380) >> 7); + out->b = ((val & 0x001f) << 3) | ((val & 0x001c) >> 2); + out->a = (val & 0x8000) ? 0xff : 0; } -static void tex_ARGB4444(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) +static void +tex_ARGB4444(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); - out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); - out->b = ((val & 0x000f) << 4) | (val & 0x000f); - out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); + out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); + out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); + out->b = ((val & 0x000f) << 4) | (val & 0x000f); + out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); } -static void tex_ARGB4444_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) +static void +tex_ARGB4444_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint16_t val = state->texture[texture_state->level][offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint16_t val = state->texture[texture_state->level][offset]; - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; + if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) + val = state->tex_bdr_clr; - out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); - out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); - out->b = ((val & 0x000f) << 4) | (val & 0x000f); - out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); + out->r = ((val & 0x0f00) >> 4) | ((val & 0x0f00) >> 8); + out->g = (val & 0x00f0) | ((val & 0x00f0) >> 4); + out->b = ((val & 0x000f) << 4) | (val & 0x000f); + out->a = ((val & 0xf000) >> 8) | ((val & 0xf000) >> 12); } -static void tex_ARGB8888(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) +static void +tex_ARGB8888(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint32_t val = ((uint32_t *) state->texture[texture_state->level])[offset]; - out->r = (val >> 16) & 0xff; - out->g = (val >> 8) & 0xff; - out->b = val & 0xff; - out->a = (val >> 24) & 0xff; + out->r = (val >> 16) & 0xff; + out->g = (val >> 8) & 0xff; + out->b = val & 0xff; + out->a = (val >> 24) & 0xff; } -static void tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) +static void +tex_ARGB8888_nowrap(s3d_state_t *state, s3d_texture_state_t *texture_state, rgba_t *out) { - int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + - (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); - uint32_t val = ((uint32_t *)state->texture[texture_state->level])[offset]; + int offset = ((texture_state->u & 0x7fc0000) >> texture_state->texture_shift) + (((texture_state->v & 0x7fc0000) >> texture_state->texture_shift) << texture_state->level); + uint32_t val = ((uint32_t *) state->texture[texture_state->level])[offset]; - if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) - val = state->tex_bdr_clr; + if (((texture_state->u | texture_state->v) & 0xf8000000) == 0xf8000000) + val = state->tex_bdr_clr; - out->r = (val >> 16) & 0xff; - out->g = (val >> 8) & 0xff; - out->b = val & 0xff; - out->a = (val >> 24) & 0xff; + out->r = (val >> 16) & 0xff; + out->g = (val >> 8) & 0xff; + out->b = val & 0xff; + out->a = (val >> 24) & 0xff; } -static void tex_sample_normal(s3d_state_t *state) +static void +tex_sample_normal(s3d_state_t *state) { - s3d_texture_state_t texture_state; + s3d_texture_state_t texture_state; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } -static void tex_sample_normal_filter(s3d_state_t *state) +static void +tex_sample_normal_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[0]); - du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[0]); + du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } -static void tex_sample_mipmap(s3d_state_t *state) +static void +tex_sample_mipmap(s3d_state_t *state) { - s3d_texture_state_t texture_state; + s3d_texture_state_t texture_state; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } -static void tex_sample_mipmap_filter(s3d_state_t *state) +static void +tex_sample_mipmap_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[0]); - du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[0]); + du = (texture_state.u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (texture_state.v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = state->u + state->tbu; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = state->u + state->tbu; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = state->u + state->tbu + tex_offset; - texture_state.v = state->v + state->tbv + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = state->u + state->tbu + tex_offset; + texture_state.v = state->v + state->tbv + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } -static void tex_sample_persp_normal(s3d_state_t *state) +static void +tex_sample_persp_normal(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; + texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } -static void tex_sample_persp_normal_filter(s3d_state_t *state) +static void +tex_sample_persp_normal_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; + v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } -static void tex_sample_persp_normal_375(s3d_state_t *state) +static void +tex_sample_persp_normal_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; + texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } -static void tex_sample_persp_normal_filter_375(s3d_state_t *state) +static void +tex_sample_persp_normal_filter_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; + v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; - texture_state.level = state->max_d; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = state->max_d; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } - -static void tex_sample_persp_mipmap(s3d_state_t *state) +static void +tex_sample_persp_mipmap(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; + texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } -static void tex_sample_persp_mipmap_filter(s3d_state_t *state) +static void +tex_sample_persp_mipmap_filter(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (12 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (12 + state->max_d)) + state->tbv; + u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (12 + state->max_d)) + state->tbu; + v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (12 + state->max_d)) + state->tbv; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } -static void tex_sample_persp_mipmap_375(s3d_state_t *state) +static void +tex_sample_persp_mipmap_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0; + s3d_texture_state_t texture_state; + int32_t w = 0; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - texture_state.u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - texture_state.v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + texture_state.u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; + texture_state.v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; - tex_read(state, &texture_state, &state->dest_rgba); + tex_read(state, &texture_state, &state->dest_rgba); } -static void tex_sample_persp_mipmap_filter_375(s3d_state_t *state) +static void +tex_sample_persp_mipmap_filter_375(s3d_state_t *state) { - s3d_texture_state_t texture_state; - int32_t w = 0, u, v; - int tex_offset; - rgba_t tex_samples[4]; - int du, dv; - int d[4]; + s3d_texture_state_t texture_state; + int32_t w = 0, u, v; + int tex_offset; + rgba_t tex_samples[4]; + int du, dv; + int d[4]; - if (state->w) - w = (int32_t)(((1ULL << 27) << 19) / (int64_t)state->w); + if (state->w) + w = (int32_t) (((1ULL << 27) << 19) / (int64_t) state->w); - u = (int32_t)(((int64_t)state->u * (int64_t)w) >> (8 + state->max_d)) + state->tbu; - v = (int32_t)(((int64_t)state->v * (int64_t)w) >> (8 + state->max_d)) + state->tbv; + u = (int32_t) (((int64_t) state->u * (int64_t) w) >> (8 + state->max_d)) + state->tbu; + v = (int32_t) (((int64_t) state->v * (int64_t) w) >> (8 + state->max_d)) + state->tbv; - texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); - if (texture_state.level < 0) - texture_state.level = 0; - texture_state.texture_shift = 18 + (9 - texture_state.level); - tex_offset = 1 << texture_state.texture_shift; + texture_state.level = (state->d < 0) ? state->max_d : state->max_d - ((state->d >> 27) & 0xf); + if (texture_state.level < 0) + texture_state.level = 0; + texture_state.texture_shift = 18 + (9 - texture_state.level); + tex_offset = 1 << texture_state.texture_shift; - texture_state.u = u; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[0]); - du = (u >> (texture_state.texture_shift - 8)) & 0xff; - dv = (v >> (texture_state.texture_shift - 8)) & 0xff; + texture_state.u = u; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[0]); + du = (u >> (texture_state.texture_shift - 8)) & 0xff; + dv = (v >> (texture_state.texture_shift - 8)) & 0xff; - texture_state.u = u + tex_offset; - texture_state.v = v; - tex_read(state, &texture_state, &tex_samples[1]); + texture_state.u = u + tex_offset; + texture_state.v = v; + tex_read(state, &texture_state, &tex_samples[1]); - texture_state.u = u; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[2]); + texture_state.u = u; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[2]); - texture_state.u = u + tex_offset; - texture_state.v = v + tex_offset; - tex_read(state, &texture_state, &tex_samples[3]); + texture_state.u = u + tex_offset; + texture_state.v = v + tex_offset; + tex_read(state, &texture_state, &tex_samples[3]); - d[0] = (256 - du) * (256 - dv); - d[1] = du * (256 - dv); - d[2] = (256 - du) * dv; - d[3] = du * dv; + d[0] = (256 - du) * (256 - dv); + d[1] = du * (256 - dv); + d[2] = (256 - du) * dv; + d[3] = du * dv; - state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; - state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; - state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; - state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; + state->dest_rgba.r = (tex_samples[0].r * d[0] + tex_samples[1].r * d[1] + tex_samples[2].r * d[2] + tex_samples[3].r * d[3]) >> 16; + state->dest_rgba.g = (tex_samples[0].g * d[0] + tex_samples[1].g * d[1] + tex_samples[2].g * d[2] + tex_samples[3].g * d[3]) >> 16; + state->dest_rgba.b = (tex_samples[0].b * d[0] + tex_samples[1].b * d[1] + tex_samples[2].b * d[2] + tex_samples[3].b * d[3]) >> 16; + state->dest_rgba.a = (tex_samples[0].a * d[0] + tex_samples[1].a * d[1] + tex_samples[2].a * d[2] + tex_samples[3].a * d[3]) >> 16; } +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) +#define CLAMP_RGBA(r, g, b, a) \ + if ((r) & ~0xff) \ + r = ((r) < 0) ? 0 : 0xff; \ + if ((g) & ~0xff) \ + g = ((g) < 0) ? 0 : 0xff; \ + if ((b) & ~0xff) \ + b = ((b) < 0) ? 0 : 0xff; \ + if ((a) & ~0xff) \ + a = ((a) < 0) ? 0 : 0xff; -#define CLAMP_RGBA(r, g, b, a) \ - if ((r) & ~0xff) \ - r = ((r) < 0) ? 0 : 0xff; \ - if ((g) & ~0xff) \ - g = ((g) < 0) ? 0 : 0xff; \ - if ((b) & ~0xff) \ - b = ((b) < 0) ? 0 : 0xff; \ - if ((a) & ~0xff) \ - a = ((a) < 0) ? 0 : 0xff; +#define CLAMP_RGB(r, g, b) \ + do { \ + if ((r) < 0) \ + r = 0; \ + if ((r) > 0xff) \ + r = 0xff; \ + if ((g) < 0) \ + g = 0; \ + if ((g) > 0xff) \ + g = 0xff; \ + if ((b) < 0) \ + b = 0; \ + if ((b) > 0xff) \ + b = 0xff; \ + } while (0) -#define CLAMP_RGB(r, g, b) do \ - { \ - if ((r) < 0) \ - r = 0; \ - if ((r) > 0xff) \ - r = 0xff; \ - if ((g) < 0) \ - g = 0; \ - if ((g) > 0xff) \ - g = 0xff; \ - if ((b) < 0) \ - b = 0; \ - if ((b) > 0xff) \ - b = 0xff; \ - } \ - while (0) - -static void dest_pixel_gouraud_shaded_triangle(s3d_state_t *state) +static void +dest_pixel_gouraud_shaded_triangle(s3d_state_t *state) { - state->dest_rgba.r = state->r >> 7; - CLAMP(state->dest_rgba.r); + state->dest_rgba.r = state->r >> 7; + CLAMP(state->dest_rgba.r); - state->dest_rgba.g = state->g >> 7; - CLAMP(state->dest_rgba.g); + state->dest_rgba.g = state->g >> 7; + CLAMP(state->dest_rgba.g); - state->dest_rgba.b = state->b >> 7; - CLAMP(state->dest_rgba.b); + state->dest_rgba.b = state->b >> 7; + CLAMP(state->dest_rgba.b); + state->dest_rgba.a = state->a >> 7; + CLAMP(state->dest_rgba.a); +} + +static void +dest_pixel_unlit_texture_triangle(s3d_state_t *state) +{ + tex_sample(state); + + if (state->cmd_set & CMD_SET_ABC_SRC) state->dest_rgba.a = state->a >> 7; - CLAMP(state->dest_rgba.a); } -static void dest_pixel_unlit_texture_triangle(s3d_state_t *state) +static void +dest_pixel_lit_texture_decal(s3d_state_t *state) { - tex_sample(state); + tex_sample(state); - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = state->a >> 7; + if (state->cmd_set & CMD_SET_ABC_SRC) + state->dest_rgba.a = state->a >> 7; } -static void dest_pixel_lit_texture_decal(s3d_state_t *state) +static void +dest_pixel_lit_texture_reflection(s3d_state_t *state) { - tex_sample(state); + tex_sample(state); - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = state->a >> 7; + state->dest_rgba.r += (state->r >> 7); + state->dest_rgba.g += (state->g >> 7); + state->dest_rgba.b += (state->b >> 7); + if (state->cmd_set & CMD_SET_ABC_SRC) + state->dest_rgba.a += (state->a >> 7); + + CLAMP_RGBA(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, state->dest_rgba.a); } -static void dest_pixel_lit_texture_reflection(s3d_state_t *state) +static void +dest_pixel_lit_texture_modulate(s3d_state_t *state) { - tex_sample(state); + int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; - state->dest_rgba.r += (state->r >> 7); - state->dest_rgba.g += (state->g >> 7); - state->dest_rgba.b += (state->b >> 7); - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a += (state->a >> 7); + tex_sample(state); - CLAMP_RGBA(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, state->dest_rgba.a); + CLAMP_RGBA(r, g, b, a); + + state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; + state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; + state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; + + if (state->cmd_set & CMD_SET_ABC_SRC) + state->dest_rgba.a = a; } -static void dest_pixel_lit_texture_modulate(s3d_state_t *state) +static void +tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) { - int r = state->r >> 7, g = state->g >> 7, b = state->b >> 7, a = state->a >> 7; + svga_t *svga = &virge->svga; + uint8_t *vram = (uint8_t *) svga->vram; - tex_sample(state); + int x_dir = s3d_tri->tlr ? 1 : -1; - CLAMP_RGBA(r, g, b, a); + int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); - state->dest_rgba.r = ((state->dest_rgba.r) * r) >> 8; - state->dest_rgba.g = ((state->dest_rgba.g) * g) >> 8; - state->dest_rgba.b = ((state->dest_rgba.b) * b) >> 8; + int y_count = yc; - if (state->cmd_set & CMD_SET_ABC_SRC) - state->dest_rgba.a = a; -} + int bpp = (s3d_tri->cmd_set >> 2) & 7; -static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int32_t dx1, int32_t dx2) -{ - svga_t *svga = &virge->svga; - uint8_t *vram = (uint8_t *)svga->vram; + uint32_t dest_offset = 0, z_offset = 0; - int x_dir = s3d_tri->tlr ? 1 : -1; + uint32_t src_col; + int src_r = 0, src_g = 0, src_b = 0; - int use_z = !(s3d_tri->cmd_set & CMD_SET_ZB_MODE); + int x; + int xe; + uint32_t z; - int y_count = yc; + uint32_t dest_addr; + uint32_t z_addr; + int dx; + int x_offset; + int xz_offset; - int bpp = (s3d_tri->cmd_set >> 2) & 7; + int update; + uint16_t src_z = 0; - uint32_t dest_offset = 0, z_offset = 0; + if (s3d_tri->cmd_set & CMD_SET_HC) { + if (state->y < s3d_tri->clip_t) + return; + if (state->y > s3d_tri->clip_b) { + int diff_y = state->y - s3d_tri->clip_b; - uint32_t src_col; - int src_r = 0, src_g = 0, src_b = 0; + if (diff_y > y_count) + diff_y = y_count; - int x; - int xe; - uint32_t z; + state->base_u += (s3d_tri->TdUdY * diff_y); + state->base_v += (s3d_tri->TdVdY * diff_y); + state->base_z += (s3d_tri->TdZdY * diff_y); + state->base_r += (s3d_tri->TdRdY * diff_y); + state->base_g += (s3d_tri->TdGdY * diff_y); + state->base_b += (s3d_tri->TdBdY * diff_y); + state->base_a += (s3d_tri->TdAdY * diff_y); + state->base_d += (s3d_tri->TdDdY * diff_y); + state->base_w += (s3d_tri->TdWdY * diff_y); + state->x1 += (dx1 * diff_y); + state->x2 += (dx2 * diff_y); + state->y -= diff_y; + dest_offset -= s3d_tri->dest_str * diff_y; + z_offset -= s3d_tri->z_str; + y_count -= diff_y; + } + if ((state->y - y_count) < s3d_tri->clip_t) + y_count = (state->y - s3d_tri->clip_t) + 1; + } - uint32_t dest_addr; - uint32_t z_addr; - int dx; - int x_offset; - int xz_offset; + dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); + z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); - int update; - uint16_t src_z = 0; - - if (s3d_tri->cmd_set & CMD_SET_HC) - { - if (state->y < s3d_tri->clip_t) - return; - if (state->y > s3d_tri->clip_b) - { - int diff_y = state->y - s3d_tri->clip_b; - - if (diff_y > y_count) - diff_y = y_count; - - state->base_u += (s3d_tri->TdUdY * diff_y); - state->base_v += (s3d_tri->TdVdY * diff_y); - state->base_z += (s3d_tri->TdZdY * diff_y); - state->base_r += (s3d_tri->TdRdY * diff_y); - state->base_g += (s3d_tri->TdGdY * diff_y); - state->base_b += (s3d_tri->TdBdY * diff_y); - state->base_a += (s3d_tri->TdAdY * diff_y); - state->base_d += (s3d_tri->TdDdY * diff_y); - state->base_w += (s3d_tri->TdWdY * diff_y); - state->x1 += (dx1 * diff_y); - state->x2 += (dx2 * diff_y); - state->y -= diff_y; - dest_offset -= s3d_tri->dest_str * diff_y; - z_offset -= s3d_tri->z_str; - y_count -= diff_y; - } - if ((state->y - y_count) < s3d_tri->clip_t) - y_count = (state->y - s3d_tri->clip_t) + 1; + while (y_count > 0) { + x = (state->x1 + ((1 << 20) - 1)) >> 20; + xe = (state->x2 + ((1 << 20) - 1)) >> 20; + z = (state->base_z > 0) ? (state->base_z << 1) : 0; + if (x_dir < 0) { + x--; + xe--; } - dest_offset = s3d_tri->dest_base + (state->y * s3d_tri->dest_str); - z_offset = s3d_tri->z_base + (state->y * s3d_tri->z_str); + if (((x != xe) && ((x_dir > 0) && (x < xe))) || ((x_dir < 0) && (x > xe))) { + dx = (x_dir > 0) ? ((31 - ((state->x1 - 1) >> 15)) & 0x1f) : (((state->x1 - 1) >> 15) & 0x1f); + x_offset = x_dir * (bpp + 1); + xz_offset = x_dir << 1; + if (x_dir > 0) + dx += 1; + state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); + state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); + state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); + state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); + state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); + state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); + state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); + state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); + z += ((s3d_tri->TdZdX * dx) >> 5); - while (y_count > 0) - { - x = (state->x1 + ((1 << 20) - 1)) >> 20; - xe = (state->x2 + ((1 << 20) - 1)) >> 20; - z = (state->base_z > 0) ? (state->base_z << 1) : 0; - if (x_dir < 0) - { - x--; - xe--; + if (s3d_tri->cmd_set & CMD_SET_HC) { + if (x_dir > 0) { + if (x > s3d_tri->clip_r) + goto tri_skip_line; + if (xe < s3d_tri->clip_l) + goto tri_skip_line; + if (xe > s3d_tri->clip_r) + xe = s3d_tri->clip_r + 1; + if (x < s3d_tri->clip_l) { + int diff_x = s3d_tri->clip_l - x; + + z += (s3d_tri->TdZdX * diff_x); + state->u += (s3d_tri->TdUdX * diff_x); + state->v += (s3d_tri->TdVdX * diff_x); + state->r += (s3d_tri->TdRdX * diff_x); + state->g += (s3d_tri->TdGdX * diff_x); + state->b += (s3d_tri->TdBdX * diff_x); + state->a += (s3d_tri->TdAdX * diff_x); + state->d += (s3d_tri->TdDdX * diff_x); + state->w += (s3d_tri->TdWdX * diff_x); + + x = s3d_tri->clip_l; + } + } else { + if (x < s3d_tri->clip_l) + goto tri_skip_line; + if (xe > s3d_tri->clip_r) + goto tri_skip_line; + if (xe < s3d_tri->clip_l) + xe = s3d_tri->clip_l - 1; + if (x > s3d_tri->clip_r) { + int diff_x = x - s3d_tri->clip_r; + + z += (s3d_tri->TdZdX * diff_x); + state->u += (s3d_tri->TdUdX * diff_x); + state->v += (s3d_tri->TdVdX * diff_x); + state->r += (s3d_tri->TdRdX * diff_x); + state->g += (s3d_tri->TdGdX * diff_x); + state->b += (s3d_tri->TdBdX * diff_x); + state->a += (s3d_tri->TdAdX * diff_x); + state->d += (s3d_tri->TdDdX * diff_x); + state->w += (s3d_tri->TdWdX * diff_x); + + x = s3d_tri->clip_r; + } + } + } + + svga->changedvram[(dest_offset & virge->vram_mask) >> 12] = changeframecount; + + dest_addr = dest_offset + (x * (bpp + 1)); + z_addr = z_offset + (x << 1); + + x &= 0xfff; + xe &= 0xfff; + + while (x != xe) { + update = 1; + _x = x; + _y = state->y; + + if (use_z) { + src_z = *(uint16_t *) &vram[z_addr & virge->vram_mask]; + switch ((s3d_tri->cmd_set >> 20) & 7) { + case 0: + update = 0; + break; + case 1: + if ((z >> 16) > src_z) { + src_z = (z >> 16); + } else + update = 0; + break; + case 2: + if ((z >> 16) == src_z) { + src_z = (z >> 16); + } else + update = 0; + break; + case 3: + if ((z >> 16) >= src_z) { + src_z = (z >> 16); + } else + update = 0; + break; + case 4: + if ((z >> 16) < src_z) { + src_z = (z >> 16); + } else + update = 0; + break; + case 5: + if ((z >> 16) != src_z) { + src_z = (z >> 16); + } else + update = 0; + break; + case 6: + if ((z >> 16) <= src_z) { + src_z = (z >> 16); + } else + update = 0; + break; + case 7: + src_z = (z >> 16); + break; + } } - if (((x != xe) && ((x_dir > 0) && (x < xe))) || ((x_dir < 0) && (x > xe))) - { - dx = (x_dir > 0) ? ((31 - ((state->x1-1) >> 15)) & 0x1f) : (((state->x1-1) >> 15) & 0x1f); - x_offset = x_dir * (bpp + 1); - xz_offset = x_dir << 1; - if (x_dir > 0) - dx += 1; - state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); - state->g = state->base_g + ((s3d_tri->TdGdX * dx) >> 5); - state->b = state->base_b + ((s3d_tri->TdBdX * dx) >> 5); - state->a = state->base_a + ((s3d_tri->TdAdX * dx) >> 5); - state->u = state->base_u + ((s3d_tri->TdUdX * dx) >> 5); - state->v = state->base_v + ((s3d_tri->TdVdX * dx) >> 5); - state->w = state->base_w + ((s3d_tri->TdWdX * dx) >> 5); - state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); - z += ((s3d_tri->TdZdX * dx) >> 5); + if (update) { + uint32_t dest_col; - if (s3d_tri->cmd_set & CMD_SET_HC) - { - if (x_dir > 0) - { - if (x > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - xe = s3d_tri->clip_r + 1; - if (x < s3d_tri->clip_l) - { - int diff_x = s3d_tri->clip_l - x; + dest_pixel(state); - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); + if (s3d_tri->cmd_set & CMD_SET_FE) { + int a = state->a >> 7; + state->dest_rgba.r = ((state->dest_rgba.r * a) + (s3d_tri->fog_r * (255 - a))) / 255; + state->dest_rgba.g = ((state->dest_rgba.g * a) + (s3d_tri->fog_g * (255 - a))) / 255; + state->dest_rgba.b = ((state->dest_rgba.b * a) + (s3d_tri->fog_b * (255 - a))) / 255; + } - x = s3d_tri->clip_l; - } - } - else - { - if (x < s3d_tri->clip_l) - goto tri_skip_line; - if (xe > s3d_tri->clip_r) - goto tri_skip_line; - if (xe < s3d_tri->clip_l) - xe = s3d_tri->clip_l - 1; - if (x > s3d_tri->clip_r) - { - int diff_x = x - s3d_tri->clip_r; - - z += (s3d_tri->TdZdX * diff_x); - state->u += (s3d_tri->TdUdX * diff_x); - state->v += (s3d_tri->TdVdX * diff_x); - state->r += (s3d_tri->TdRdX * diff_x); - state->g += (s3d_tri->TdGdX * diff_x); - state->b += (s3d_tri->TdBdX * diff_x); - state->a += (s3d_tri->TdAdX * diff_x); - state->d += (s3d_tri->TdDdX * diff_x); - state->w += (s3d_tri->TdWdX * diff_x); - - x = s3d_tri->clip_r; - } - } + if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) { + switch (bpp) { + case 0: /*8 bpp*/ + /*Not implemented yet*/ + break; + case 1: /*16 bpp*/ + src_col = *(uint16_t *) &vram[dest_addr & virge->vram_mask]; + RGB15_TO_24(src_col, src_r, src_g, src_b); + break; + case 2: /*24 bpp*/ + src_col = (*(uint32_t *) &vram[dest_addr & virge->vram_mask]) & 0xffffff; + RGB24_TO_24(src_col, src_r, src_g, src_b); + break; } - svga->changedvram[(dest_offset & virge->vram_mask) >> 12] = changeframecount; + state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + (src_r * (255 - state->dest_rgba.a))) / 255; + state->dest_rgba.g = ((state->dest_rgba.g * state->dest_rgba.a) + (src_g * (255 - state->dest_rgba.a))) / 255; + state->dest_rgba.b = ((state->dest_rgba.b * state->dest_rgba.a) + (src_b * (255 - state->dest_rgba.a))) / 255; + } - dest_addr = dest_offset + (x * (bpp + 1)); - z_addr = z_offset + (x << 1); - - x &= 0xfff; - xe &= 0xfff; - - while (x != xe) { - update = 1; - _x = x; _y = state->y; - - if (use_z) - { - src_z = *(uint16_t *)&vram[z_addr & virge->vram_mask]; - switch ((s3d_tri->cmd_set >> 20) & 7) { - case 0: - update = 0; - break; - case 1: - if ((z >> 16) > src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 2: - if ((z >> 16) == src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 3: - if ((z >> 16) >= src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 4: - if ((z >> 16) < src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 5: - if ((z >> 16) != src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 6: - if ((z >> 16) <= src_z) { - src_z = (z >> 16); - } else - update = 0; - break; - case 7: - src_z = (z >> 16); - break; - } - } - - if (update) - { - uint32_t dest_col; - - dest_pixel(state); - - if (s3d_tri->cmd_set & CMD_SET_FE) - { - int a = state->a >> 7; - state->dest_rgba.r = ((state->dest_rgba.r * a) + (s3d_tri->fog_r * (255 - a))) / 255; - state->dest_rgba.g = ((state->dest_rgba.g * a) + (s3d_tri->fog_g * (255 - a))) / 255; - state->dest_rgba.b = ((state->dest_rgba.b * a) + (s3d_tri->fog_b * (255 - a))) / 255; - } - - if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) - { - switch (bpp) - { - case 0: /*8 bpp*/ - /*Not implemented yet*/ - break; - case 1: /*16 bpp*/ - src_col = *(uint16_t *)&vram[dest_addr & virge->vram_mask]; - RGB15_TO_24(src_col, src_r, src_g, src_b); - break; - case 2: /*24 bpp*/ - src_col = (*(uint32_t *)&vram[dest_addr & virge->vram_mask]) & 0xffffff; - RGB24_TO_24(src_col, src_r, src_g, src_b); - break; - } - - state->dest_rgba.r = ((state->dest_rgba.r * state->dest_rgba.a) + (src_r * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.g = ((state->dest_rgba.g * state->dest_rgba.a) + (src_g * (255 - state->dest_rgba.a))) / 255; - state->dest_rgba.b = ((state->dest_rgba.b * state->dest_rgba.a) + (src_b * (255 - state->dest_rgba.a))) / 255; - } - - switch (bpp) - { - case 0: /*8 bpp*/ - /*Not implemented yet*/ - break; - case 1: /*16 bpp*/ - RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); - *(uint16_t *)&vram[dest_addr & virge->vram_mask] = dest_col; - svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount; - break; - case 2: /*24 bpp*/ - dest_col = RGB24(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b); - *(uint8_t *)&vram[dest_addr & virge->vram_mask] = dest_col & 0xff; - *(uint8_t *)&vram[(dest_addr + 1) & virge->vram_mask] = (dest_col >> 8) & 0xff; - *(uint8_t *)&vram[(dest_addr + 2) & virge->vram_mask] = (dest_col >> 16) & 0xff; - svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount; - break; - } - } - - if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) { - *(uint16_t *)&vram[z_addr & virge->vram_mask] = src_z; - svga->changedvram[(z_addr & virge->vram_mask) >> 12] = changeframecount; - } - - z += s3d_tri->TdZdX; - state->u += s3d_tri->TdUdX; - state->v += s3d_tri->TdVdX; - state->r += s3d_tri->TdRdX; - state->g += s3d_tri->TdGdX; - state->b += s3d_tri->TdBdX; - state->a += s3d_tri->TdAdX; - state->d += s3d_tri->TdDdX; - state->w += s3d_tri->TdWdX; - dest_addr += x_offset; - z_addr += xz_offset; - - x = (x + x_dir) & 0xfff; - } + switch (bpp) { + case 0: /*8 bpp*/ + /*Not implemented yet*/ + break; + case 1: /*16 bpp*/ + RGB15(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b, dest_col); + *(uint16_t *) &vram[dest_addr & virge->vram_mask] = dest_col; + svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount; + break; + case 2: /*24 bpp*/ + dest_col = RGB24(state->dest_rgba.r, state->dest_rgba.g, state->dest_rgba.b); + *(uint8_t *) &vram[dest_addr & virge->vram_mask] = dest_col & 0xff; + *(uint8_t *) &vram[(dest_addr + 1) & virge->vram_mask] = (dest_col >> 8) & 0xff; + *(uint8_t *) &vram[(dest_addr + 2) & virge->vram_mask] = (dest_col >> 16) & 0xff; + svga->changedvram[(dest_addr & virge->vram_mask) >> 12] = changeframecount; + break; + } } - y_count--; + if (use_z && (s3d_tri->cmd_set & CMD_SET_ZUP)) { + *(uint16_t *) &vram[z_addr & virge->vram_mask] = src_z; + svga->changedvram[(z_addr & virge->vram_mask) >> 12] = changeframecount; + } + + z += s3d_tri->TdZdX; + state->u += s3d_tri->TdUdX; + state->v += s3d_tri->TdVdX; + state->r += s3d_tri->TdRdX; + state->g += s3d_tri->TdGdX; + state->b += s3d_tri->TdBdX; + state->a += s3d_tri->TdAdX; + state->d += s3d_tri->TdDdX; + state->w += s3d_tri->TdWdX; + dest_addr += x_offset; + z_addr += xz_offset; + + x = (x + x_dir) & 0xfff; + } + } + + y_count--; tri_skip_line: - state->x1 += dx1; - state->x2 += dx2; - state->base_u += s3d_tri->TdUdY; - state->base_v += s3d_tri->TdVdY; - state->base_z += s3d_tri->TdZdY; - state->base_r += s3d_tri->TdRdY; - state->base_g += s3d_tri->TdGdY; - state->base_b += s3d_tri->TdBdY; - state->base_a += s3d_tri->TdAdY; - state->base_d += s3d_tri->TdDdY; - state->base_w += s3d_tri->TdWdY; - state->y--; - dest_offset -= s3d_tri->dest_str; - z_offset -= s3d_tri->z_str; - } + state->x1 += dx1; + state->x2 += dx2; + state->base_u += s3d_tri->TdUdY; + state->base_v += s3d_tri->TdVdY; + state->base_z += s3d_tri->TdZdY; + state->base_r += s3d_tri->TdRdY; + state->base_g += s3d_tri->TdGdY; + state->base_b += s3d_tri->TdBdY; + state->base_a += s3d_tri->TdAdY; + state->base_d += s3d_tri->TdDdY; + state->base_w += s3d_tri->TdWdY; + state->y--; + dest_offset -= s3d_tri->dest_str; + z_offset -= s3d_tri->z_str; + } } -static int tex_size[8] = -{ - 4*2, - 2*2, - 2*2, - 1*2, - 2/1, - 2/1, - 1*2, - 1*2 +static int tex_size[8] = { + 4 * 2, + 2 * 2, + 2 * 2, + 1 * 2, + 2 / 1, + 2 / 1, + 1 * 2, + 1 * 2 }; -static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) +static void +s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) { - s3d_state_t state; + s3d_state_t state; - uint32_t tex_base; - int c; + uint32_t tex_base; + int c; - uint64_t start_time = plat_timer_read(); - uint64_t end_time; + uint64_t start_time = plat_timer_read(); + uint64_t end_time; - state.tbu = s3d_tri->tbu << 11; - state.tbv = s3d_tri->tbv << 11; + state.tbu = s3d_tri->tbu << 11; + state.tbv = s3d_tri->tbv << 11; - state.max_d = (s3d_tri->cmd_set >> 8) & 15; + state.max_d = (s3d_tri->cmd_set >> 8) & 15; - state.tex_bdr_clr = s3d_tri->tex_bdr_clr; + state.tex_bdr_clr = s3d_tri->tex_bdr_clr; - state.cmd_set = s3d_tri->cmd_set; + state.cmd_set = s3d_tri->cmd_set; - state.base_u = s3d_tri->tus; - state.base_v = s3d_tri->tvs; - state.base_z = s3d_tri->tzs; - state.base_r = (int32_t)s3d_tri->trs; - state.base_g = (int32_t)s3d_tri->tgs; - state.base_b = (int32_t)s3d_tri->tbs; - state.base_a = (int32_t)s3d_tri->tas; - state.base_d = s3d_tri->tds; - state.base_w = s3d_tri->tws; + state.base_u = s3d_tri->tus; + state.base_v = s3d_tri->tvs; + state.base_z = s3d_tri->tzs; + state.base_r = (int32_t) s3d_tri->trs; + state.base_g = (int32_t) s3d_tri->tgs; + state.base_b = (int32_t) s3d_tri->tbs; + state.base_a = (int32_t) s3d_tri->tas; + state.base_d = s3d_tri->tds; + state.base_w = s3d_tri->tws; - tex_base = s3d_tri->tex_base; - for (c = 9; c >= 0; c--) - { - state.texture[c] = (uint16_t *)&virge->svga.vram[tex_base]; - if (c <= state.max_d) - tex_base += ((1 << (c*2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; - } + tex_base = s3d_tri->tex_base; + for (c = 9; c >= 0; c--) { + state.texture[c] = (uint16_t *) &virge->svga.vram[tex_base]; + if (c <= state.max_d) + tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; + } - switch ((s3d_tri->cmd_set >> 27) & 0xf) - { + switch ((s3d_tri->cmd_set >> 27) & 0xf) { + case 0: + dest_pixel = dest_pixel_gouraud_shaded_triangle; + break; + case 1: + case 5: + switch ((s3d_tri->cmd_set >> 15) & 0x3) { case 0: - dest_pixel = dest_pixel_gouraud_shaded_triangle; - break; + dest_pixel = dest_pixel_lit_texture_reflection; + break; case 1: - case 5: - switch ((s3d_tri->cmd_set >> 15) & 0x3) - { - case 0: - dest_pixel = dest_pixel_lit_texture_reflection; - break; - case 1: - dest_pixel = dest_pixel_lit_texture_modulate; - break; - case 2: - dest_pixel = dest_pixel_lit_texture_decal; - break; - default: - s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); - return; - } - break; + dest_pixel = dest_pixel_lit_texture_modulate; + break; case 2: - case 6: - dest_pixel = dest_pixel_unlit_texture_triangle; - break; + dest_pixel = dest_pixel_lit_texture_decal; + break; default: - s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); - return; - } + s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); + return; + } + break; + case 2: + case 6: + dest_pixel = dest_pixel_unlit_texture_triangle; + break; + default: + s3_virge_log("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); + return; + } - switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) - { - case 0: case 1: - tex_sample = tex_sample_mipmap; - break; - case 2: case 3: - tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap; - break; - case 4: case 5: - tex_sample = tex_sample_normal; - break; - case 6: case 7: - tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; - break; - case (0 | 8): case (1 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) - tex_sample = tex_sample_persp_mipmap_375; - else - tex_sample = tex_sample_persp_mipmap; - break; - case (2 | 8): case (3 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; - else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; - break; - case (4 | 8): case (5 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) - tex_sample = tex_sample_persp_normal_375; - else - tex_sample = tex_sample_persp_normal; - break; - case (6 | 8): case (7 | 8): - if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; - else - tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; - break; - } + switch (((s3d_tri->cmd_set >> 12) & 7) | ((s3d_tri->cmd_set & (1 << 29)) ? 8 : 0)) { + case 0: + case 1: + tex_sample = tex_sample_mipmap; + break; + case 2: + case 3: + tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap; + break; + case 4: + case 5: + tex_sample = tex_sample_normal; + break; + case 6: + case 7: + tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; + break; + case (0 | 8): + case (1 | 8): + if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) + tex_sample = tex_sample_persp_mipmap_375; + else + tex_sample = tex_sample_persp_mipmap; + break; + case (2 | 8): + case (3 | 8): + if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; + else + tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; + break; + case (4 | 8): + case (5 | 8): + if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) + tex_sample = tex_sample_persp_normal_375; + else + tex_sample = tex_sample_persp_normal; + break; + case (6 | 8): + case (7 | 8): + if (virge->chip == S3_VIRGEDX || virge->chip >= S3_VIRGEGX2) + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; + else + tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; + break; + } - switch ((s3d_tri->cmd_set >> 5) & 7) - { - case 0: - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB8888 : tex_ARGB8888_nowrap; - break; - case 1: - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; - break; - case 2: - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; - break; - default: - s3_virge_log("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); - tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; - break; - } + switch ((s3d_tri->cmd_set >> 5) & 7) { + case 0: + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB8888 : tex_ARGB8888_nowrap; + break; + case 1: + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; + break; + case 2: + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; + break; + default: + s3_virge_log("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); + tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; + break; + } - state.y = s3d_tri->tys; - state.x1 = s3d_tri->txs; - state.x2 = s3d_tri->txend01; - tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); - state.x2 = s3d_tri->txend12; - tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); + state.y = s3d_tri->tys; + state.x1 = s3d_tri->txs; + state.x2 = s3d_tri->txend01; + tri(virge, s3d_tri, &state, s3d_tri->ty01, s3d_tri->TdXdY02, s3d_tri->TdXdY01); + state.x2 = s3d_tri->txend12; + tri(virge, s3d_tri, &state, s3d_tri->ty12, s3d_tri->TdXdY02, s3d_tri->TdXdY12); - end_time = plat_timer_read(); + end_time = plat_timer_read(); - virge->blitter_time += end_time - start_time; + virge->blitter_time += end_time - start_time; } -static void s3_virge_hwcursor_draw(svga_t *svga, int displine) +static void +s3_virge_hwcursor_draw(svga_t *svga, int displine) { - virge_t *virge = (virge_t *)svga->p; - int x; - uint16_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - uint32_t fg, bg; - uint32_t vram_mask = virge->vram_mask; + virge_t *virge = (virge_t *) svga->p; + int x; + uint16_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t fg, bg; + uint32_t vram_mask = virge->vram_mask; - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; - switch (svga->bpp) - { - case 15: - fg = video_15to32[virge->hwc_fg_col & 0xffff]; - bg = video_15to32[virge->hwc_bg_col & 0xffff]; - break; + switch (svga->bpp) { + case 15: + fg = video_15to32[virge->hwc_fg_col & 0xffff]; + bg = video_15to32[virge->hwc_bg_col & 0xffff]; + break; - case 16: - fg = video_16to32[virge->hwc_fg_col & 0xffff]; - bg = video_16to32[virge->hwc_bg_col & 0xffff]; - break; + case 16: + fg = video_16to32[virge->hwc_fg_col & 0xffff]; + bg = video_16to32[virge->hwc_bg_col & 0xffff]; + break; - case 24: case 32: - fg = virge->hwc_fg_col; - bg = virge->hwc_bg_col; - break; + case 24: + case 32: + fg = virge->hwc_fg_col; + bg = virge->hwc_bg_col; + break; - default: - fg = svga->pallook[virge->hwc_fg_col & 0xff]; - bg = svga->pallook[virge->hwc_bg_col & 0xff]; - break; - } + default: + fg = svga->pallook[virge->hwc_fg_col & 0xff]; + bg = svga->pallook[virge->hwc_bg_col & 0xff]; + break; + } - for (x = 0; x < 64; x += 16) - { - dat[0] = (svga->vram[svga->hwcursor_latch.addr & vram_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & vram_mask]; - dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & vram_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & vram_mask]; - if (svga->crtc[0x55] & 0x10) - { - /*X11*/ - for (xx = 0; xx < 16; xx++) - { - if (offset >= 0) - { - if (dat[0] & 0x8000) - buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } + for (x = 0; x < 64; x += 16) { + dat[0] = (svga->vram[svga->hwcursor_latch.addr & vram_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 1) & vram_mask]; + dat[1] = (svga->vram[(svga->hwcursor_latch.addr + 2) & vram_mask] << 8) | svga->vram[(svga->hwcursor_latch.addr + 3) & vram_mask]; + if (svga->crtc[0x55] & 0x10) { + /*X11*/ + for (xx = 0; xx < 16; xx++) { + if (offset >= 0) { + if (dat[0] & 0x8000) + buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; } - else - { - /*Windows*/ - for (xx = 0; xx < 16; xx++) - { - if (offset >= 0) - { - if (!(dat[0] & 0x8000)) - buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; - else if (dat[1] & 0x8000) - buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; - } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + } else { + /*Windows*/ + for (xx = 0; xx < 16; xx++) { + if (offset >= 0) { + if (!(dat[0] & 0x8000)) + buffer32->line[displine][offset + svga->x_add] = (dat[1] & 0x8000) ? fg : bg; + else if (dat[1] & 0x8000) + buffer32->line[displine][offset + svga->x_add] ^= 0xffffff; } - svga->hwcursor_latch.addr += 4; + + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += 16; + svga->hwcursor_latch.addr += 4; + } + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; } -#define DECODE_YCbCr() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - \ - y1 = src[0]; \ - Cr = src[1] - 0x80; \ - y2 = src[2]; \ - Cb = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) +#define DECODE_YCbCr() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) /*Both YUV formats are untested*/ -#define DECODE_YUV211() \ - do \ - { \ - uint8_t y1, y2, y3, y4; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - y2 = (298 * (src[2] - 16)) >> 8; \ - V = src[3] - 0x80; \ - y3 = (298 * (src[4] - 16)) >> 8; \ - y4 = (298 * (src[5] - 16)) >> 8; \ - src += 6; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - r[x_write+2] = y3 + dR; \ - CLAMP(r[x_write+2]); \ - g[x_write+2] = y3 - dG; \ - CLAMP(g[x_write+2]); \ - b[x_write+2] = y3 + dB; \ - CLAMP(b[x_write+2]); \ - \ - r[x_write+3] = y4 + dR; \ - CLAMP(r[x_write+3]); \ - g[x_write+3] = y4 - dG; \ - CLAMP(g[x_write+3]); \ - b[x_write+3] = y4 + dB; \ - CLAMP(b[x_write+3]); \ - \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_YUV211() \ + do { \ + uint8_t y1, y2, y3, y4; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + y2 = (298 * (src[2] - 16)) >> 8; \ + V = src[3] - 0x80; \ + y3 = (298 * (src[4] - 16)) >> 8; \ + y4 = (298 * (src[5] - 16)) >> 8; \ + src += 6; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + r[x_write + 2] = y3 + dR; \ + CLAMP(r[x_write + 2]); \ + g[x_write + 2] = y3 - dG; \ + CLAMP(g[x_write + 2]); \ + b[x_write + 2] = y3 + dB; \ + CLAMP(b[x_write + 2]); \ + \ + r[x_write + 3] = y4 + dR; \ + CLAMP(r[x_write + 3]); \ + g[x_write + 3] = y4 - dG; \ + CLAMP(g[x_write + 3]); \ + b[x_write + 3] = y4 + dB; \ + CLAMP(b[x_write + 3]); \ + \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_YUV422() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 2; c++) \ - { \ - uint8_t y1, y2; \ - int8_t U, V; \ - int dR, dG, dB; \ - \ - U = src[0] - 0x80; \ - y1 = (298 * (src[1] - 16)) >> 8; \ - V = src[2] - 0x80; \ - y2 = (298 * (src[3] - 16)) >> 8; \ - src += 4; \ - \ - dR = (309*V) >> 8; \ - dG = (100*U + 208*V) >> 8; \ - dB = (516*U) >> 8; \ - \ - r[x_write] = y1 + dR; \ - CLAMP(r[x_write]); \ - g[x_write] = y1 - dG; \ - CLAMP(g[x_write]); \ - b[x_write] = y1 + dB; \ - CLAMP(b[x_write]); \ - \ - r[x_write+1] = y2 + dR; \ - CLAMP(r[x_write+1]); \ - g[x_write+1] = y2 - dG; \ - CLAMP(g[x_write+1]); \ - b[x_write+1] = y2 + dB; \ - CLAMP(b[x_write+1]); \ - \ - x_write = (x_write + 2) & 7; \ - } \ - } while (0) +#define DECODE_YUV422() \ + do { \ + int c; \ + \ + for (c = 0; c < 2; c++) { \ + uint8_t y1, y2; \ + int8_t U, V; \ + int dR, dG, dB; \ + \ + U = src[0] - 0x80; \ + y1 = (298 * (src[1] - 16)) >> 8; \ + V = src[2] - 0x80; \ + y2 = (298 * (src[3] - 16)) >> 8; \ + src += 4; \ + \ + dR = (309 * V) >> 8; \ + dG = (100 * U + 208 * V) >> 8; \ + dB = (516 * U) >> 8; \ + \ + r[x_write] = y1 + dR; \ + CLAMP(r[x_write]); \ + g[x_write] = y1 - dG; \ + CLAMP(g[x_write]); \ + b[x_write] = y1 + dB; \ + CLAMP(b[x_write]); \ + \ + r[x_write + 1] = y2 + dR; \ + CLAMP(r[x_write + 1]); \ + g[x_write + 1] = y2 - dG; \ + CLAMP(g[x_write + 1]); \ + b[x_write + 1] = y2 + dB; \ + CLAMP(b[x_write + 1]); \ + \ + x_write = (x_write + 2) & 7; \ + } \ + } while (0) -#define DECODE_RGB555() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ - b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB555() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *) src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x03e0) >> 2) | ((dat & 0x03e0) >> 7); \ + b[x_write + c] = ((dat & 0x7c00) >> 7) | ((dat & 0x7c00) >> 12); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_RGB565() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - uint16_t dat; \ - \ - dat = *(uint16_t *)src; \ - src += 2; \ - \ - r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ - g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ - b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB565() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + uint16_t dat; \ + \ + dat = *(uint16_t *) src; \ + src += 2; \ + \ + r[x_write + c] = ((dat & 0x001f) << 3) | ((dat & 0x001f) >> 2); \ + g[x_write + c] = ((dat & 0x07e0) >> 3) | ((dat & 0x07e0) >> 9); \ + b[x_write + c] = ((dat & 0xf800) >> 8) | ((dat & 0xf800) >> 13); \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_RGB888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 3; \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_RGB888() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 3; \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define DECODE_XRGB8888() \ - do \ - { \ - int c; \ - \ - for (c = 0; c < 4; c++) \ - { \ - r[x_write + c] = src[0]; \ - g[x_write + c] = src[1]; \ - b[x_write + c] = src[2]; \ - src += 4; \ - } \ - x_write = (x_write + 4) & 7; \ - } while (0) +#define DECODE_XRGB8888() \ + do { \ + int c; \ + \ + for (c = 0; c < 4; c++) { \ + r[x_write + c] = src[0]; \ + g[x_write + c] = src[1]; \ + b[x_write + c] = src[2]; \ + src += 4; \ + } \ + x_write = (x_write + 4) & 7; \ + } while (0) -#define OVERLAY_SAMPLE() \ - do \ - { \ - switch (virge->streams.sdif) \ - { \ - case 1: \ - DECODE_YCbCr(); \ - break; \ - case 2: \ - DECODE_YUV422(); \ - break; \ - case 3: \ - DECODE_RGB555(); \ - break; \ - case 4: \ - DECODE_YUV211(); \ - break; \ - case 5: \ - DECODE_RGB565(); \ - break; \ - case 6: \ - DECODE_RGB888(); \ - break; \ - case 7: \ - default: \ - DECODE_XRGB8888(); \ - break; \ - } \ - } while (0) +#define OVERLAY_SAMPLE() \ + do { \ + switch (virge->streams.sdif) { \ + case 1: \ + DECODE_YCbCr(); \ + break; \ + case 2: \ + DECODE_YUV422(); \ + break; \ + case 3: \ + DECODE_RGB555(); \ + break; \ + case 4: \ + DECODE_YUV211(); \ + break; \ + case 5: \ + DECODE_RGB565(); \ + break; \ + case 6: \ + DECODE_RGB888(); \ + break; \ + case 7: \ + default: \ + DECODE_XRGB8888(); \ + break; \ + } \ + } while (0) -static void s3_virge_overlay_draw(svga_t *svga, int displine) +static void +s3_virge_overlay_draw(svga_t *svga, int displine) { - virge_t *virge = (virge_t *)svga->p; - int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; - int h_acc = virge->streams.dda_horiz_accumulator; - int r[8], g[8], b[8]; - int x_size, x_read = 4, x_write = 4; - int x; - uint32_t *p; - uint8_t *src = &svga->vram[svga->overlay_latch.addr]; + virge_t *virge = (virge_t *) svga->p; + int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; + int h_acc = virge->streams.dda_horiz_accumulator; + int r[8], g[8], b[8]; + int x_size, x_read = 4, x_write = 4; + int x; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay_latch.addr]; - p = &(buffer32->line[displine][offset + svga->x_add]); + p = &(buffer32->line[displine][offset + svga->x_add]); - if ((offset + virge->streams.sec_w) > virge->streams.pri_w) - x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; - else - x_size = virge->streams.sec_w + 1; + if ((offset + virge->streams.sec_w) > virge->streams.pri_w) + x_size = (virge->streams.pri_w - virge->streams.sec_x) + 1; + else + x_size = virge->streams.sec_w + 1; - OVERLAY_SAMPLE(); + OVERLAY_SAMPLE(); - for (x = 0; x < x_size; x++) - { - *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); + for (x = 0; x < x_size; x++) { + *p++ = r[x_read] | (g[x_read] << 8) | (b[x_read] << 16); - h_acc += virge->streams.k1_horiz_scale; - if (h_acc >= 0) - { - if ((x_read ^ (x_read + 1)) & ~3) - OVERLAY_SAMPLE(); - x_read = (x_read + 1) & 7; + h_acc += virge->streams.k1_horiz_scale; + if (h_acc >= 0) { + if ((x_read ^ (x_read + 1)) & ~3) + OVERLAY_SAMPLE(); + x_read = (x_read + 1) & 7; - h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale); - } + h_acc += (virge->streams.k2_horiz_scale - virge->streams.k1_horiz_scale); } + } - svga->overlay_latch.v_acc += virge->streams.k1_vert_scale; - if (svga->overlay_latch.v_acc >= 0) - { - svga->overlay_latch.v_acc += (virge->streams.k2_vert_scale - virge->streams.k1_vert_scale); - svga->overlay_latch.addr += virge->streams.sec_stride; - } + svga->overlay_latch.v_acc += virge->streams.k1_vert_scale; + if (svga->overlay_latch.v_acc >= 0) { + svga->overlay_latch.v_acc += (virge->streams.k2_vert_scale - virge->streams.k1_vert_scale); + svga->overlay_latch.addr += virge->streams.sec_stride; + } } -static uint8_t s3_virge_pci_read(int func, int addr, void *p) +static uint8_t +s3_virge_pci_read(int func, int addr, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - uint8_t ret = 0; + virge_t *virge = (virge_t *) p; + svga_t *svga = &virge->svga; + uint8_t ret = 0; - switch (addr) { - case 0x00: ret = 0x33; break; /*'S3'*/ - case 0x01: ret = 0x53; break; + switch (addr) { + case 0x00: + ret = 0x33; + break; /*'S3'*/ + case 0x01: + ret = 0x53; + break; - case 0x02: ret = virge->virge_id_low; break; - case 0x03: ret = virge->virge_id_high; break; + case 0x02: + ret = virge->virge_id_low; + break; + case 0x03: + ret = virge->virge_id_high; + break; - case PCI_REG_COMMAND: ret = virge->pci_regs[PCI_REG_COMMAND] & 0x27; break; + case PCI_REG_COMMAND: + ret = virge->pci_regs[PCI_REG_COMMAND] & 0x27; + break; - case 0x07: ret = virge->pci_regs[0x07] & 0x36; break; + case 0x07: + ret = virge->pci_regs[0x07] & 0x36; + break; - case 0x08: ret = virge->virge_rev; break; /*Revision ID*/ - case 0x09: ret = 0; break; /*Programming interface*/ + case 0x08: + ret = virge->virge_rev; + break; /*Revision ID*/ + case 0x09: + ret = 0; + break; /*Programming interface*/ - case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ - case 0x0b: ret = 0x03; break; + case 0x0a: + ret = 0x00; + break; /*Supports VGA interface*/ + case 0x0b: + ret = 0x03; + break; - case 0x0d: ret = virge->pci_regs[0x0d] & 0xf8; break; + case 0x0d: + ret = virge->pci_regs[0x0d] & 0xf8; + break; - case 0x10: ret = 0x00; break;/*Linear frame buffer address*/ - case 0x11: ret = 0x00; break; - case 0x12: ret = 0x00; break; - case 0x13: ret = (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) ? (svga->crtc[0x59] & 0xfe) : (svga->crtc[0x59] & 0xfc); break; + case 0x10: + ret = 0x00; + break; /*Linear frame buffer address*/ + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = 0x00; + break; + case 0x13: + ret = (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) ? (svga->crtc[0x59] & 0xfe) : (svga->crtc[0x59] & 0xfc); + break; - case 0x2c: ret = 0x33; break; /* Subsystem vendor ID */ - case 0x2d: ret = 0x53; break; - case 0x2e: ret = virge->virge_id_low; break; - case 0x2f: ret = virge->virge_id_high; break; + case 0x2c: + ret = 0x33; + break; /* Subsystem vendor ID */ + case 0x2d: + ret = 0x53; + break; + case 0x2e: + ret = virge->virge_id_low; + break; + case 0x2f: + ret = virge->virge_id_high; + break; - case 0x30: ret = virge->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ - case 0x31: ret = 0x00; break; - case 0x32: ret = virge->pci_regs[0x32]; break; - case 0x33: ret = virge->pci_regs[0x33]; break; + case 0x30: + ret = virge->pci_regs[0x30] & 0x01; + break; /*BIOS ROM address*/ + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = virge->pci_regs[0x32]; + break; + case 0x33: + ret = virge->pci_regs[0x33]; + break; - case 0x34: ret = (virge->chip >= S3_VIRGEGX2) ? 0xdc : 0x00; break; + case 0x34: + ret = (virge->chip >= S3_VIRGEGX2) ? 0xdc : 0x00; + break; - case 0x3c: ret = virge->pci_regs[0x3c]; break; + case 0x3c: + ret = virge->pci_regs[0x3c]; + break; - case 0x3d: ret = PCI_INTA; break; /*INTA*/ + case 0x3d: + ret = PCI_INTA; + break; /*INTA*/ - case 0x3e: ret = 0x04; break; - case 0x3f: ret = 0xff; break; + case 0x3e: + ret = 0x04; + break; + case 0x3f: + ret = 0xff; + break; - case 0x80: ret = 0x02; break; /* AGP capability */ - case 0x81: ret = 0x00; break; - case 0x82: ret = 0x10; break; /* assumed AGP 1.0 */ + case 0x80: + ret = 0x02; + break; /* AGP capability */ + case 0x81: + ret = 0x00; + break; + case 0x82: + ret = 0x10; + break; /* assumed AGP 1.0 */ - case 0x84: ret = (virge->chip >= S3_TRIO3D2X) ? 0x03 : 0x01; break; - case 0x87: ret = 0x1f; break; + case 0x84: + ret = (virge->chip >= S3_TRIO3D2X) ? 0x03 : 0x01; + break; + case 0x87: + ret = 0x1f; + break; - case 0x88: ret = virge->pci_regs[0x88]; break; - case 0x89: ret = virge->pci_regs[0x89]; break; - case 0x8a: ret = virge->pci_regs[0x8a]; break; - case 0x8b: ret = virge->pci_regs[0x8b]; break; + case 0x88: + ret = virge->pci_regs[0x88]; + break; + case 0x89: + ret = virge->pci_regs[0x89]; + break; + case 0x8a: + ret = virge->pci_regs[0x8a]; + break; + case 0x8b: + ret = virge->pci_regs[0x8b]; + break; - case 0xdc: ret = 0x01; break; /* PCI Power Management capability */ - case 0xdd: ret = virge->is_agp ? 0x80 : 0x00; break; - case 0xde: ret = 0x21; break; + case 0xdc: + ret = 0x01; + break; /* PCI Power Management capability */ + case 0xdd: + ret = virge->is_agp ? 0x80 : 0x00; + break; + case 0xde: + ret = 0x21; + break; - case 0xe0: ret = virge->pci_regs[0xe0]; break; - case 0xe1: ret = virge->pci_regs[0xe1]; break; - case 0xe2: ret = virge->pci_regs[0xe2]; break; - case 0xe3: ret = virge->pci_regs[0xe3]; break; - } - return ret; + case 0xe0: + ret = virge->pci_regs[0xe0]; + break; + case 0xe1: + ret = virge->pci_regs[0xe1]; + break; + case 0xe2: + ret = virge->pci_regs[0xe2]; + break; + case 0xe3: + ret = virge->pci_regs[0xe3]; + break; + } + return ret; } -static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) +static void +s3_virge_pci_write(int func, int addr, uint8_t val, void *p) { - virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x3d: case 0x3e: case 0x3f: - return; + virge_t *virge = (virge_t *) p; + svga_t *svga = &virge->svga; + switch (addr) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x3d: + case 0x3e: + case 0x3f: + return; - case PCI_REG_COMMAND: - if (val & PCI_COMMAND_IO) - { - io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - } + case PCI_REG_COMMAND: + if (val & PCI_COMMAND_IO) { + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + } else + io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; + s3_virge_updatemapping(virge); + return; + case 0x07: + virge->pci_regs[0x07] = val & 0x3e; + return; + case 0x0d: + virge->pci_regs[0x0d] = val & 0xf8; + return; + + case 0x13: + svga->crtc[0x59] = (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) ? (val & 0xfe) : (val & 0xfc); + s3_virge_updatemapping(virge); + return; + + case 0x30: + case 0x32: + case 0x33: + virge->pci_regs[addr] = val; + if (virge->pci_regs[0x30] & 0x01) { + uint32_t biosaddr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); + if (virge->chip == S3_VIRGEGX2) + mem_mapping_set_addr(&virge->bios_rom.mapping, biosaddr, 0x10000); else - io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[PCI_REG_COMMAND] = val & 0x27; - s3_virge_updatemapping(virge); - return; - case 0x07: - virge->pci_regs[0x07] = val & 0x3e; - return; - case 0x0d: - virge->pci_regs[0x0d] = val & 0xf8; - return; + mem_mapping_set_addr(&virge->bios_rom.mapping, biosaddr, 0x8000); + } else { + mem_mapping_disable(&virge->bios_rom.mapping); + } + return; + case 0x3c: + virge->pci_regs[0x3c] = val; + return; - case 0x13: - svga->crtc[0x59] = (virge->chip == S3_VIRGEVX || virge->chip == S3_TRIO3D2X) ? (val & 0xfe) : (val & 0xfc); - s3_virge_updatemapping(virge); - return; + case 0x88: + virge->pci_regs[0x88] = val & 0x27; + return; - case 0x30: case 0x32: case 0x33: - virge->pci_regs[addr] = val; - if (virge->pci_regs[0x30] & 0x01) - { - uint32_t biosaddr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); - if (virge->chip == S3_VIRGEGX2) - mem_mapping_set_addr(&virge->bios_rom.mapping, biosaddr, 0x10000); - else - mem_mapping_set_addr(&virge->bios_rom.mapping, biosaddr, 0x8000); - } - else - { - mem_mapping_disable(&virge->bios_rom.mapping); - } - return; - case 0x3c: - virge->pci_regs[0x3c] = val; - return; + case 0x89: + virge->pci_regs[0x89] = val & 0x03; + return; - case 0x88: - virge->pci_regs[0x88] = val & 0x27; - return; + case 0x8b: + case 0xe1: + case 0xe3: + virge->pci_regs[addr] = val; + return; - case 0x89: - virge->pci_regs[0x89] = val & 0x03; - return; + case 0xe0: + virge->pci_regs[0xe0] = val & 0x03; + return; - case 0x8b: case 0xe1: case 0xe3: - virge->pci_regs[addr] = val; - return; - - case 0xe0: - virge->pci_regs[0xe0] = val & 0x03; - return; - - case 0xe2: - virge->pci_regs[0xe2] = val & 0xc0; - return; - } + case 0xe2: + virge->pci_regs[0xe2] = val & 0xc0; + return; + } } -static void s3_virge_reset(void *priv) +static void +s3_virge_reset(void *priv) { - virge_t *virge = (virge_t *) priv; - svga_t *svga = &virge->svga; + virge_t *virge = (virge_t *) priv; + svga_t *svga = &virge->svga; memset(svga->crtc, 0x00, sizeof(svga->crtc)); - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = 1000ull << 32; + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; svga->dispofftime = 1000ull << 32; - svga->bpp = 8; + svga->bpp = 8; io_removehandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); memset(virge->pci_regs, 0x00, 256); - virge->pci_regs[PCI_REG_COMMAND] = 3; - virge->pci_regs[0x05] = 0; - virge->pci_regs[0x06] = 0; - virge->pci_regs[0x07] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; + virge->pci_regs[PCI_REG_COMMAND] = 3; + virge->pci_regs[0x05] = 0; + virge->pci_regs[0x06] = 0; + virge->pci_regs[0x07] = 2; + virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3e] = 4; + virge->pci_regs[0x3f] = 0xff; - switch(virge->local) { - case S3_VIRGE_325: - case S3_DIAMOND_STEALTH3D_2000: - virge->svga.crtc[0x59] = 0x70; - break; - case S3_DIAMOND_STEALTH3D_3000: - case S3_STB_VELOCITY_3D: - virge->svga.crtc[0x59] = 0x70; - break; - case S3_VIRGE_GX2: - case S3_DIAMOND_STEALTH3D_4000: - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - break; + switch (virge->local) { + case S3_VIRGE_325: + case S3_DIAMOND_STEALTH3D_2000: + virge->svga.crtc[0x59] = 0x70; + break; + case S3_DIAMOND_STEALTH3D_3000: + case S3_STB_VELOCITY_3D: + virge->svga.crtc[0x59] = 0x70; + break; + case S3_VIRGE_GX2: + case S3_DIAMOND_STEALTH3D_4000: + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + break; - case S3_TRIO_3D2X: - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - break; + case S3_TRIO_3D2X: + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + break; - default: - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - break; - } + default: + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + break; + } - if (virge->chip == S3_VIRGEGX2) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (1 << 5); - else { - switch (virge->memory_size) { - case 2: - if (virge->chip == S3_VIRGEVX) { - virge->svga.crtc[0x36] = (0 << 5); - } else - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 8: - if (virge->chip == S3_TRIO3D2X) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5); - else - virge->svga.crtc[0x36] = (3 << 5); - break; - case 4: - if (virge->chip == S3_VIRGEVX) - virge->svga.crtc[0x36] = (1 << 5); - else if (virge->chip == S3_TRIO3D2X) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (2 << 5); - else - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - } - if (virge->local == S3_VIRGE_GX) - virge->svga.crtc[0x36] |= (1 << 2); - } + if (virge->chip == S3_VIRGEGX2) + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (1 << 5); + else { + switch (virge->memory_size) { + case 2: + if (virge->chip == S3_VIRGEVX) { + virge->svga.crtc[0x36] = (0 << 5); + } else + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); + break; + case 8: + if (virge->chip == S3_TRIO3D2X) + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5); + else + virge->svga.crtc[0x36] = (3 << 5); + break; + case 4: + if (virge->chip == S3_VIRGEVX) + virge->svga.crtc[0x36] = (1 << 5); + else if (virge->chip == S3_TRIO3D2X) + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (2 << 5); + else + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + break; + } + if (virge->local == S3_VIRGE_GX) + virge->svga.crtc[0x36] |= (1 << 2); + } - virge->svga.crtc[0x37] = 1 | (7 << 5); - virge->svga.crtc[0x53] = 8; + virge->svga.crtc[0x37] = 1 | (7 << 5); + virge->svga.crtc[0x53] = 8; mem_mapping_disable(&virge->bios_rom.mapping); s3_virge_updatemapping(virge); - mem_mapping_disable(&virge->mmio_mapping); - mem_mapping_disable(&virge->new_mmio_mapping); + mem_mapping_disable(&virge->mmio_mapping); + mem_mapping_disable(&virge->new_mmio_mapping); } -static void *s3_virge_init(const device_t *info) +static void * +s3_virge_init(const device_t *info) { - const char *bios_fn; - virge_t *virge = malloc(sizeof(virge_t)); + const char *bios_fn; + virge_t *virge = malloc(sizeof(virge_t)); - memset(virge, 0, sizeof(virge_t)); + memset(virge, 0, sizeof(virge_t)); - virge->bilinear_enabled = device_get_config_int("bilinear"); - virge->dithering_enabled = device_get_config_int("dithering"); - if (info->local >= S3_VIRGE_GX2) - virge->memory_size = 4; - else - virge->memory_size = device_get_config_int("memory"); + virge->bilinear_enabled = device_get_config_int("bilinear"); + virge->dithering_enabled = device_get_config_int("dithering"); + if (info->local >= S3_VIRGE_GX2) + virge->memory_size = 4; + else + virge->memory_size = device_get_config_int("memory"); + switch (info->local) { + case S3_VIRGE_325: + bios_fn = ROM_VIRGE_325; + break; + case S3_DIAMOND_STEALTH3D_2000: + bios_fn = ROM_DIAMOND_STEALTH3D_2000; + break; + case S3_DIAMOND_STEALTH3D_3000: + bios_fn = ROM_DIAMOND_STEALTH3D_3000; + break; + case S3_STB_VELOCITY_3D: + bios_fn = ROM_STB_VELOCITY_3D; + break; + case S3_VIRGE_DX: + bios_fn = ROM_VIRGE_DX; + break; + case S3_DIAMOND_STEALTH3D_2000PRO: + bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO; + break; + case S3_VIRGE_GX: + bios_fn = ROM_VIRGE_GX; + break; + case S3_VIRGE_GX2: + bios_fn = ROM_VIRGE_GX2; + break; + case S3_DIAMOND_STEALTH3D_4000: + bios_fn = ROM_DIAMOND_STEALTH3D_4000; + break; + case S3_TRIO_3D2X: + bios_fn = ROM_TRIO3D2X; + break; + default: + free(virge); + return NULL; + } - switch(info->local) { - case S3_VIRGE_325: - bios_fn = ROM_VIRGE_325; - break; - case S3_DIAMOND_STEALTH3D_2000: - bios_fn = ROM_DIAMOND_STEALTH3D_2000; - break; - case S3_DIAMOND_STEALTH3D_3000: - bios_fn = ROM_DIAMOND_STEALTH3D_3000; - break; - case S3_STB_VELOCITY_3D: - bios_fn = ROM_STB_VELOCITY_3D; - break; - case S3_VIRGE_DX: - bios_fn = ROM_VIRGE_DX; - break; - case S3_DIAMOND_STEALTH3D_2000PRO: - bios_fn = ROM_DIAMOND_STEALTH3D_2000PRO; - break; - case S3_VIRGE_GX: - bios_fn = ROM_VIRGE_GX; - break; - case S3_VIRGE_GX2: - bios_fn = ROM_VIRGE_GX2; - break; - case S3_DIAMOND_STEALTH3D_4000: - bios_fn = ROM_DIAMOND_STEALTH3D_4000; - break; - case S3_TRIO_3D2X: - bios_fn = ROM_TRIO3D2X; - break; - default: - free(virge); - return NULL; - } - - svga_init(info, &virge->svga, virge, virge->memory_size << 20, - s3_virge_recalctimings, - s3_virge_in, s3_virge_out, - s3_virge_hwcursor_draw, - s3_virge_overlay_draw); + svga_init(info, &virge->svga, virge, virge->memory_size << 20, + s3_virge_recalctimings, + s3_virge_in, s3_virge_out, + s3_virge_hwcursor_draw, + s3_virge_overlay_draw); virge->svga.hwcursor.cur_ysize = 64; - if (info->local == S3_VIRGE_GX2) - rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - else - rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (info->local == S3_VIRGE_GX2) + rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + else + rom_init(&virge->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&virge->bios_rom.mapping); + mem_mapping_disable(&virge->bios_rom.mapping); - mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - MEM_MAPPING_EXTERNAL, - &virge->svga); - mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - MEM_MAPPING_EXTERNAL, - virge); - mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, - s3_virge_mmio_read_w, - s3_virge_mmio_read_l, - s3_virge_mmio_write, - s3_virge_mmio_write_w, - s3_virge_mmio_write_l, - NULL, - MEM_MAPPING_EXTERNAL, - virge); + mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, + svga_readw_linear, + svga_readl_linear, + svga_write_linear, + svga_writew_linear, + svga_writel_linear, + NULL, + MEM_MAPPING_EXTERNAL, + &virge->svga); + mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, + s3_virge_mmio_read_w, + s3_virge_mmio_read_l, + s3_virge_mmio_write, + s3_virge_mmio_write_w, + s3_virge_mmio_write_l, + NULL, + MEM_MAPPING_EXTERNAL, + virge); + mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, + s3_virge_mmio_read_w, + s3_virge_mmio_read_l, + s3_virge_mmio_write, + s3_virge_mmio_write_w, + s3_virge_mmio_write_l, + NULL, + MEM_MAPPING_EXTERNAL, + virge); - io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); - virge->pci_regs[PCI_REG_COMMAND] = 3; - virge->pci_regs[0x05] = 0; - virge->pci_regs[0x06] = 0; - virge->pci_regs[0x07] = 2; - virge->pci_regs[0x32] = 0x0c; - virge->pci_regs[0x3d] = 1; - virge->pci_regs[0x3e] = 4; - virge->pci_regs[0x3f] = 0xff; + virge->pci_regs[PCI_REG_COMMAND] = 3; + virge->pci_regs[0x05] = 0; + virge->pci_regs[0x06] = 0; + virge->pci_regs[0x07] = 2; + virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3e] = 4; + virge->pci_regs[0x3f] = 0xff; - virge->virge_rev = 0; - virge->virge_id = 0xe1; - virge->is_agp = !!(info->flags & DEVICE_AGP); + virge->virge_rev = 0; + virge->virge_id = 0xe1; + virge->is_agp = !!(info->flags & DEVICE_AGP); - switch(info->local) { - case S3_VIRGE_325: - case S3_DIAMOND_STEALTH3D_2000: - virge->svga.decode_mask = (4 << 20) - 1; - virge->virge_id_high = 0x56; - virge->virge_id_low = 0x31; - virge->svga.crtc[0x59] = 0x70; - virge->chip = S3_VIRGE; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_2000_pci); - break; - case S3_DIAMOND_STEALTH3D_3000: - case S3_STB_VELOCITY_3D: - virge->svga.decode_mask = (8 << 20) - 1; - virge->virge_id_high = 0x88; - virge->virge_id_low = 0x3d; - virge->svga.crtc[0x59] = 0x70; - virge->chip = S3_VIRGEVX; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_3000_pci); - break; - case S3_VIRGE_GX2: - case S3_DIAMOND_STEALTH3D_4000: - virge->svga.decode_mask = (4 << 20) - 1; - virge->virge_id_high = 0x8a; - virge->virge_id_low = 0x10; - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - virge->svga.vblank_start = s3_virge_vblank_start; - virge->chip = S3_VIRGEGX2; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci); - break; + switch (info->local) { + case S3_VIRGE_325: + case S3_DIAMOND_STEALTH3D_2000: + virge->svga.decode_mask = (4 << 20) - 1; + virge->virge_id_high = 0x56; + virge->virge_id_low = 0x31; + virge->svga.crtc[0x59] = 0x70; + virge->chip = S3_VIRGE; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_2000_pci); + break; + case S3_DIAMOND_STEALTH3D_3000: + case S3_STB_VELOCITY_3D: + virge->svga.decode_mask = (8 << 20) - 1; + virge->virge_id_high = 0x88; + virge->virge_id_low = 0x3d; + virge->svga.crtc[0x59] = 0x70; + virge->chip = S3_VIRGEVX; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_diamond_stealth3d_3000_pci); + break; + case S3_VIRGE_GX2: + case S3_DIAMOND_STEALTH3D_4000: + virge->svga.decode_mask = (4 << 20) - 1; + virge->virge_id_high = 0x8a; + virge->virge_id_low = 0x10; + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + virge->svga.vblank_start = s3_virge_vblank_start; + virge->chip = S3_VIRGEGX2; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci); + break; - case S3_TRIO_3D2X: - virge->svga.decode_mask = (8 << 20) - 1; - virge->virge_id_high = 0x8a; - virge->virge_id_low = 0x13; - virge->virge_rev = 0x01; - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - virge->svga.vblank_start = s3_virge_vblank_start; - virge->chip = S3_TRIO3D2X; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci); - break; + case S3_TRIO_3D2X: + virge->svga.decode_mask = (8 << 20) - 1; + virge->virge_id_high = 0x8a; + virge->virge_id_low = 0x13; + virge->virge_rev = 0x01; + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + virge->svga.vblank_start = s3_virge_vblank_start; + virge->chip = S3_TRIO3D2X; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, virge->is_agp ? &timing_virge_agp : &timing_virge_dx_pci); + break; - case S3_VIRGE_GX: - virge->virge_rev = 0x01; - /*FALLTHROUGH*/ - default: - virge->svga.decode_mask = (4 << 20) - 1; - virge->virge_id_high = 0x8a; - virge->virge_id_low = 0x01; - virge->svga.crtc[0x6c] = 1; - virge->svga.crtc[0x59] = 0x70; - virge->svga.vblank_start = s3_virge_vblank_start; - virge->chip = S3_VIRGEDX; - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_virge_dx_pci); - break; - } + case S3_VIRGE_GX: + virge->virge_rev = 0x01; + /*FALLTHROUGH*/ + default: + virge->svga.decode_mask = (4 << 20) - 1; + virge->virge_id_high = 0x8a; + virge->virge_id_low = 0x01; + virge->svga.crtc[0x6c] = 1; + virge->svga.crtc[0x59] = 0x70; + virge->svga.vblank_start = s3_virge_vblank_start; + virge->chip = S3_VIRGEDX; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_virge_dx_pci); + break; + } - if (virge->chip == S3_VIRGEGX2) { - virge->vram_mask = (4 << 20) - 1; - virge->svga.vram_mask = (4 << 20) - 1; - virge->svga.vram_max = 4 << 20; - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (1 << 5); - } else { - switch (virge->memory_size) { - case 2: - virge->vram_mask = (2 << 20) - 1; - virge->svga.vram_mask = (2 << 20) - 1; - virge->svga.vram_max = 2 << 20; - if (virge->chip == S3_VIRGEVX) { - virge->svga.crtc[0x36] = (0 << 5); - } else - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); - break; - case 8: - virge->vram_mask = (8 << 20) - 1; - virge->svga.vram_mask = (8 << 20) - 1; - virge->svga.vram_max = 8 << 20; - if (virge->chip == S3_TRIO3D2X) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5); - else - virge->svga.crtc[0x36] = (3 << 5); - break; - case 4: - virge->vram_mask = (4 << 20) - 1; - virge->svga.vram_mask = (4 << 20) - 1; - virge->svga.vram_max = 4 << 20; - if (virge->chip == S3_VIRGEVX) - virge->svga.crtc[0x36] = (1 << 5); - else if (virge->chip == S3_TRIO3D2X) - virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (2 << 5); - else - virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); - break; - } - if (info->local == S3_VIRGE_GX) - virge->svga.crtc[0x36] |= (1 << 2); - } + if (virge->chip == S3_VIRGEGX2) { + virge->vram_mask = (4 << 20) - 1; + virge->svga.vram_mask = (4 << 20) - 1; + virge->svga.vram_max = 4 << 20; + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (1 << 5); + } else { + switch (virge->memory_size) { + case 2: + virge->vram_mask = (2 << 20) - 1; + virge->svga.vram_mask = (2 << 20) - 1; + virge->svga.vram_max = 2 << 20; + if (virge->chip == S3_VIRGEVX) { + virge->svga.crtc[0x36] = (0 << 5); + } else + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); + break; + case 8: + virge->vram_mask = (8 << 20) - 1; + virge->svga.vram_mask = (8 << 20) - 1; + virge->svga.vram_max = 8 << 20; + if (virge->chip == S3_TRIO3D2X) + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (0 << 5); + else + virge->svga.crtc[0x36] = (3 << 5); + break; + case 4: + virge->vram_mask = (4 << 20) - 1; + virge->svga.vram_mask = (4 << 20) - 1; + virge->svga.vram_max = 4 << 20; + if (virge->chip == S3_VIRGEVX) + virge->svga.crtc[0x36] = (1 << 5); + else if (virge->chip == S3_TRIO3D2X) + virge->svga.crtc[0x36] = 2 | (2 << 2) | (1 << 4) | (2 << 5); + else + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + break; + } + if (info->local == S3_VIRGE_GX) + virge->svga.crtc[0x36] |= (1 << 2); + } - virge->svga.crtc[0x37] = 1 | (7 << 5); - virge->svga.crtc[0x53] = 8; + virge->svga.crtc[0x37] = 1 | (7 << 5); + virge->svga.crtc[0x53] = 8; - virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add_card(virge->is_agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, s3_virge_pci_read, s3_virge_pci_write, virge); - virge->i2c = i2c_gpio_init("ddc_s3_virge"); - virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); + virge->i2c = i2c_gpio_init("ddc_s3_virge"); + virge->ddc = ddc_init(i2c_gpio_get_bus(virge->i2c)); - virge->svga.force_old_addr = 1; + virge->svga.force_old_addr = 1; - virge->wake_render_thread = thread_create_event(); - virge->wake_main_thread = thread_create_event(); - virge->not_full_event = thread_create_event(); - virge->render_thread_run = 1; - virge->render_thread = thread_create(render_thread, virge); + virge->wake_render_thread = thread_create_event(); + virge->wake_main_thread = thread_create_event(); + virge->not_full_event = thread_create_event(); + virge->render_thread_run = 1; + virge->render_thread = thread_create(render_thread, virge); - timer_add(&virge->tri_timer, s3_virge_tri_timer, virge, 0); + timer_add(&virge->tri_timer, s3_virge_tri_timer, virge, 0); - virge->local = info->local; + virge->local = info->local; - return virge; + return virge; } -static void s3_virge_close(void *p) +static void +s3_virge_close(void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *) p; - virge->render_thread_run = 0; - thread_set_event(virge->wake_render_thread); - thread_wait(virge->render_thread); - thread_destroy_event(virge->not_full_event); - thread_destroy_event(virge->wake_main_thread); - thread_destroy_event(virge->wake_render_thread); + virge->render_thread_run = 0; + thread_set_event(virge->wake_render_thread); + thread_wait(virge->render_thread); + thread_destroy_event(virge->not_full_event); + thread_destroy_event(virge->wake_main_thread); + thread_destroy_event(virge->wake_render_thread); - svga_close(&virge->svga); + svga_close(&virge->svga); - ddc_close(virge->ddc); - i2c_gpio_close(virge->i2c); + ddc_close(virge->ddc); + i2c_gpio_close(virge->i2c); - free(virge); + free(virge); } -static int s3_virge_325_diamond_available(void) +static int +s3_virge_325_diamond_available(void) { - return rom_present(ROM_DIAMOND_STEALTH3D_2000); + return rom_present(ROM_DIAMOND_STEALTH3D_2000); } -static int s3_virge_325_available(void) +static int +s3_virge_325_available(void) { - return rom_present(ROM_VIRGE_325); + return rom_present(ROM_VIRGE_325); } -static int s3_virge_988_diamond_available(void) +static int +s3_virge_988_diamond_available(void) { - return rom_present(ROM_DIAMOND_STEALTH3D_3000); + return rom_present(ROM_DIAMOND_STEALTH3D_3000); } -static int s3_virge_988_stb_available(void) +static int +s3_virge_988_stb_available(void) { - return rom_present(ROM_STB_VELOCITY_3D); + return rom_present(ROM_STB_VELOCITY_3D); } -static int s3_virge_375_available(void) +static int +s3_virge_375_available(void) { - return rom_present(ROM_VIRGE_DX); + return rom_present(ROM_VIRGE_DX); } -static int s3_virge_375_diamond_available(void) +static int +s3_virge_375_diamond_available(void) { - return rom_present(ROM_DIAMOND_STEALTH3D_2000PRO); + return rom_present(ROM_DIAMOND_STEALTH3D_2000PRO); } -static int s3_virge_385_available(void) +static int +s3_virge_385_available(void) { - return rom_present(ROM_VIRGE_GX); + return rom_present(ROM_VIRGE_GX); } -static int s3_virge_357_available(void) +static int +s3_virge_357_available(void) { - return rom_present(ROM_VIRGE_GX2); + return rom_present(ROM_VIRGE_GX2); } -static int s3_virge_357_diamond_available(void) +static int +s3_virge_357_diamond_available(void) { - return rom_present(ROM_DIAMOND_STEALTH3D_4000); + return rom_present(ROM_DIAMOND_STEALTH3D_4000); } -static int s3_trio3d2x_available(void) +static int +s3_trio3d2x_available(void) { - return rom_present(ROM_TRIO3D2X); + return rom_present(ROM_TRIO3D2X); } -static void s3_virge_speed_changed(void *p) +static void +s3_virge_speed_changed(void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *) p; - svga_recalctimings(&virge->svga); + svga_recalctimings(&virge->svga); } -static void s3_virge_force_redraw(void *p) +static void +s3_virge_force_redraw(void *p) { - virge_t *virge = (virge_t *)p; + virge_t *virge = (virge_t *) p; - virge->svga.fullchange = changeframecount; + virge->svga.fullchange = changeframecount; } static const device_config_t s3_virge_config[] = { + // clang-format off { .name = "memory", .description = "Memory size", @@ -4250,9 +4485,11 @@ static const device_config_t s3_virge_config[] = { { .type = CONFIG_END } + // clang-format on }; static const device_config_t s3_virge_stb_config[] = { + // clang-format off { .name = "memory", .description = "Memory size", @@ -4291,9 +4528,11 @@ static const device_config_t s3_virge_stb_config[] = { { .type = CONFIG_END } + // clang-format on }; static const device_config_t s3_virge_357_config[] = { + // clang-format off { .name = "bilinear", .description = "Bilinear filtering", @@ -4309,9 +4548,11 @@ static const device_config_t s3_virge_357_config[] = { { .type = CONFIG_END } + // clang-format on }; static const device_config_t s3_trio3d2x_config[] = { + // clang-format off { .name = "memory", .description = "Memory size", @@ -4346,186 +4587,187 @@ static const device_config_t s3_trio3d2x_config[] = { { .type = CONFIG_END } +// clang-format on }; const device_t s3_virge_325_pci_device = { - .name = "S3 ViRGE (325) PCI", + .name = "S3 ViRGE (325) PCI", .internal_name = "virge325_pci", - .flags = DEVICE_PCI, - .local = S3_VIRGE_325, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_VIRGE_325, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_325_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config }; const device_t s3_diamond_stealth_2000_pci_device = { - .name = "S3 ViRGE (Diamond Stealth 3D 2000) PCI", + .name = "S3 ViRGE (Diamond Stealth 3D 2000) PCI", .internal_name = "stealth3d_2000_pci", - .flags = DEVICE_PCI, - .local = S3_DIAMOND_STEALTH3D_2000, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH3D_2000, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_325_diamond_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config }; const device_t s3_diamond_stealth_3000_pci_device = { - .name = "S3 ViRGE/VX (Diamond Stealth 3D 3000) PCI", + .name = "S3 ViRGE/VX (Diamond Stealth 3D 3000) PCI", .internal_name = "stealth3d_3000_pci", - .flags = DEVICE_PCI, - .local = S3_DIAMOND_STEALTH3D_3000, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH3D_3000, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_988_diamond_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_stb_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_stb_config }; const device_t s3_stb_velocity_3d_pci_device = { - .name = "S3 ViRGE/VX (STB Velocity 3D) PCI", + .name = "S3 ViRGE/VX (STB Velocity 3D) PCI", .internal_name = "stb_velocity3d_pci", - .flags = DEVICE_PCI, - .local = S3_STB_VELOCITY_3D, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_STB_VELOCITY_3D, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_988_stb_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_stb_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_stb_config }; const device_t s3_virge_375_pci_device = { - .name = "S3 ViRGE/DX (375) PCI", + .name = "S3 ViRGE/DX (375) PCI", .internal_name = "virge375_pci", - .flags = DEVICE_PCI, - .local = S3_VIRGE_DX, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_VIRGE_DX, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_375_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config }; const device_t s3_diamond_stealth_2000pro_pci_device = { - .name = "S3 ViRGE/DX (Diamond Stealth 3D 2000 Pro) PCI", + .name = "S3 ViRGE/DX (Diamond Stealth 3D 2000 Pro) PCI", .internal_name = "stealth3d_2000pro_pci", - .flags = DEVICE_PCI, - .local = S3_DIAMOND_STEALTH3D_2000PRO, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH3D_2000PRO, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_375_diamond_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config }; const device_t s3_virge_385_pci_device = { - .name = "S3 ViRGE/GX (385) PCI", + .name = "S3 ViRGE/GX (385) PCI", .internal_name = "virge385_pci", - .flags = DEVICE_PCI, - .local = S3_VIRGE_GX, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_VIRGE_GX, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_385_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_config }; const device_t s3_virge_357_pci_device = { - .name = "S3 ViRGE/GX2 (357) PCI", + .name = "S3 ViRGE/GX2 (357) PCI", .internal_name = "virge357_pci", - .flags = DEVICE_PCI, - .local = S3_VIRGE_GX2, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_VIRGE_GX2, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_357_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_357_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_357_config }; const device_t s3_virge_357_agp_device = { - .name = "S3 ViRGE/GX2 (357) AGP", + .name = "S3 ViRGE/GX2 (357) AGP", .internal_name = "virge357_agp", - .flags = DEVICE_AGP, - .local = S3_VIRGE_GX2, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_AGP, + .local = S3_VIRGE_GX2, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_357_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_357_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_357_config }; const device_t s3_diamond_stealth_4000_pci_device = { - .name = "S3 ViRGE/GX2 (Diamond Stealth 3D 4000) PCI", + .name = "S3 ViRGE/GX2 (Diamond Stealth 3D 4000) PCI", .internal_name = "stealth3d_4000_pci", - .flags = DEVICE_PCI, - .local = S3_DIAMOND_STEALTH3D_4000, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_DIAMOND_STEALTH3D_4000, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_357_diamond_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_357_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_357_config }; const device_t s3_diamond_stealth_4000_agp_device = { - .name = "S3 ViRGE/GX2 (Diamond Stealth 3D 4000) AGP", + .name = "S3 ViRGE/GX2 (Diamond Stealth 3D 4000) AGP", .internal_name = "stealth3d_4000_agp", - .flags = DEVICE_AGP, - .local = S3_DIAMOND_STEALTH3D_4000, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_AGP, + .local = S3_DIAMOND_STEALTH3D_4000, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_virge_357_diamond_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_virge_357_config + .force_redraw = s3_virge_force_redraw, + .config = s3_virge_357_config }; const device_t s3_trio3d2x_pci_device = { - .name = "S3 Trio3D/2X (362) PCI", + .name = "S3 Trio3D/2X (362) PCI", .internal_name = "trio3d2x", - .flags = DEVICE_PCI, - .local = S3_TRIO_3D2X, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_PCI, + .local = S3_TRIO_3D2X, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_trio3d2x_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_trio3d2x_config + .force_redraw = s3_virge_force_redraw, + .config = s3_trio3d2x_config }; const device_t s3_trio3d2x_agp_device = { - .name = "S3 Trio3D/2X (362) AGP", + .name = "S3 Trio3D/2X (362) AGP", .internal_name = "trio3d2x_agp", - .flags = DEVICE_AGP, - .local = S3_TRIO_3D2X, - .init = s3_virge_init, - .close = s3_virge_close, - .reset = s3_virge_reset, + .flags = DEVICE_AGP, + .local = S3_TRIO_3D2X, + .init = s3_virge_init, + .close = s3_virge_close, + .reset = s3_virge_reset, { .available = s3_trio3d2x_available }, .speed_changed = s3_virge_speed_changed, - .force_redraw = s3_virge_force_redraw, - .config = s3_trio3d2x_config + .force_redraw = s3_virge_force_redraw, + .config = s3_trio3d2x_config }; diff --git a/src/video/vid_sc1148x_ramdac.c b/src/video/vid_sc1148x_ramdac.c index 202147d14..936ff308d 100644 --- a/src/video/vid_sc1148x_ramdac.c +++ b/src/video/vid_sc1148x_ramdac.c @@ -28,104 +28,103 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef struct { - int type; - int state; - int rs2; + int type; + int state; + int rs2; uint8_t ctrl; } sc1148x_ramdac_t; - void sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; - uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); - int oldbpp = 0; + uint8_t rs = (addr & 0x03) | ((!!rs2) << 2); + int oldbpp = 0; switch (rs) { - case 2: case 6: - switch (ramdac->state) { - case 4: - ramdac->state = 0; - if (val == 0xff) - break; - ramdac->ctrl = val; - ramdac->ctrl = (ramdac->ctrl & ~1) | ((((val >> 2) ^ val) & (val & 0x20)) >> 5); - oldbpp = svga->bpp; - switch (ramdac->type) { - case 0: /* Sierra Mark 2 (11483)*/ - case 2: /* Sierra Mark 2 (11484)*/ - case 3: /* Sierra Mark 1 (11486)*/ - if (val & 0xa0) { - svga->bpp = 15; - } else if (val == 0x00) - svga->bpp = 8; - break; - case 1: /* Sierra Mark 3 (11487)*/ - if (val & 0xa0) { - if (val & 0x40) - svga->bpp = 16; - else - svga->bpp = 15; - } else if (val == 0x00) - svga->bpp = 8; - break; - } - if (oldbpp != svga->bpp) - svga_recalctimings(svga); - return; - default: - svga_out(addr, val, svga); - break; - } - break; + case 2: + case 6: + switch (ramdac->state) { + case 4: + ramdac->state = 0; + if (val == 0xff) + break; + ramdac->ctrl = val; + ramdac->ctrl = (ramdac->ctrl & ~1) | ((((val >> 2) ^ val) & (val & 0x20)) >> 5); + oldbpp = svga->bpp; + switch (ramdac->type) { + case 0: /* Sierra Mark 2 (11483)*/ + case 2: /* Sierra Mark 2 (11484)*/ + case 3: /* Sierra Mark 1 (11486)*/ + if (val & 0xa0) { + svga->bpp = 15; + } else if (val == 0x00) + svga->bpp = 8; + break; + case 1: /* Sierra Mark 3 (11487)*/ + if (val & 0xa0) { + if (val & 0x40) + svga->bpp = 16; + else + svga->bpp = 15; + } else if (val == 0x00) + svga->bpp = 8; + break; + } + if (oldbpp != svga->bpp) + svga_recalctimings(svga); + return; + default: + svga_out(addr, val, svga); + break; + } + break; - default: - ramdac->state = 0; - svga_out(addr, val, svga); - break; + default: + ramdac->state = 0; + svga_out(addr, val, svga); + break; } } - uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p; - uint8_t ret = 0xff, rs = (addr & 0x03) | ((!!rs2) << 2); + uint8_t ret = 0xff, rs = (addr & 0x03) | ((!!rs2) << 2); switch (rs) { - case 2: case 6: - switch (ramdac->state) { - case 1: - case 2: case 3: - ret = 0x00; - ramdac->state++; - break; - case 4: - ret = ramdac->ctrl; - ret = (ret & ~0x18) | (svga->dac_mask & 0x18); - break; - default: - ret = svga_in(addr, svga); - ramdac->state++; - break; - } - break; + case 2: + case 6: + switch (ramdac->state) { + case 1: + case 2: + case 3: + ret = 0x00; + ramdac->state++; + break; + case 4: + ret = ramdac->ctrl; + ret = (ret & ~0x18) | (svga->dac_mask & 0x18); + break; + default: + ret = svga_in(addr, svga); + ramdac->state++; + break; + } + break; - default: - ret = svga_in(addr, svga); - ramdac->state = 0; - break; + default: + ret = svga_in(addr, svga); + ramdac->state = 0; + break; } return ret; } - static void * sc1148x_ramdac_init(const device_t *info) { @@ -137,68 +136,67 @@ sc1148x_ramdac_init(const device_t *info) return ramdac; } - static void sc1148x_ramdac_close(void *priv) { sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t sc11483_ramdac_device = { - .name = "Sierra SC11483 RAMDAC", + .name = "Sierra SC11483 RAMDAC", .internal_name = "sc11483_ramdac", - .flags = 0, - .local = 0, - .init = sc1148x_ramdac_init, - .close = sc1148x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = sc1148x_ramdac_init, + .close = sc1148x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t sc11487_ramdac_device = { - .name = "Sierra SC11487 RAMDAC", + .name = "Sierra SC11487 RAMDAC", .internal_name = "sc11487_ramdac", - .flags = 0, - .local = 1, - .init = sc1148x_ramdac_init, - .close = sc1148x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 1, + .init = sc1148x_ramdac_init, + .close = sc1148x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t sc11484_nors2_ramdac_device = { - .name = "Sierra SC11484 RAMDAC (no RS2 signal)", + .name = "Sierra SC11484 RAMDAC (no RS2 signal)", .internal_name = "sc11484_nors2_ramdac", - .flags = 0, - .local = 2, - .init = sc1148x_ramdac_init, - .close = sc1148x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 2, + .init = sc1148x_ramdac_init, + .close = sc1148x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t sc11486_ramdac_device = { - .name = "Sierra SC11486 RAMDAC", + .name = "Sierra SC11486 RAMDAC", .internal_name = "sc11486_ramdac", - .flags = 0, - .local = 3, - .init = sc1148x_ramdac_init, - .close = sc1148x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 3, + .init = sc1148x_ramdac_init, + .close = sc1148x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_sc1502x_ramdac.c b/src/video/vid_sc1502x_ramdac.c index 10b4594e4..202091449 100644 --- a/src/video/vid_sc1502x_ramdac.c +++ b/src/video/vid_sc1502x_ramdac.c @@ -30,110 +30,106 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef struct { - int state; + int state; uint8_t ctrl; } sc1502x_ramdac_t; - void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; - int oldbpp = 0; + int oldbpp = 0; switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - ramdac->state = 0; - if (val == 0xFF) - break; - ramdac->ctrl = val; - oldbpp = svga->bpp; - switch ((val & 1) | ((val & 0xc0) >> 5)) { - case 0: - svga->bpp = 8; - break; - case 2: - case 3: - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - } - break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 16; - break; - case 7: - if (val & 4) { - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - } - break; - } else { - svga->bpp = 16; - break; - } - break; - } - if (oldbpp != svga->bpp) - svga_recalctimings(svga); - return; - } - ramdac->state = 0; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9: - ramdac->state = 0; - break; + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + if (val == 0xFF) + break; + ramdac->ctrl = val; + oldbpp = svga->bpp; + switch ((val & 1) | ((val & 0xc0) >> 5)) { + case 0: + svga->bpp = 8; + break; + case 2: + case 3: + switch (val & 0x20) { + case 0x00: + svga->bpp = 32; + break; + case 0x20: + svga->bpp = 24; + break; + } + break; + case 4: + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + if (val & 4) { + switch (val & 0x20) { + case 0x00: + svga->bpp = 32; + break; + case 0x20: + svga->bpp = 24; + break; + } + break; + } else { + svga->bpp = 16; + break; + } + break; + } + if (oldbpp != svga->bpp) + svga_recalctimings(svga); + return; + } + ramdac->state = 0; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; } svga_out(addr, val, svga); } - uint8_t sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p; - uint8_t temp = svga_in(addr, svga); + uint8_t temp = svga_in(addr, svga); switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; - break; - } - ramdac->state++; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9: - ramdac->state = 0; - break; + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + temp = ramdac->ctrl; + break; + } + ramdac->state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; } return temp; } - static void * sc1502x_ramdac_init(const device_t *info) { @@ -143,26 +139,25 @@ sc1502x_ramdac_init(const device_t *info) return ramdac; } - static void sc1502x_ramdac_close(void *priv) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t sc1502x_ramdac_device = { - .name = "Sierra SC1502x RAMDAC", + .name = "Sierra SC1502x RAMDAC", .internal_name = "sc1502x_ramdac", - .flags = 0, - .local = 0, - .init = sc1502x_ramdac_init, - .close = sc1502x_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = sc1502x_ramdac_init, + .close = sc1502x_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_sdac_ramdac.c b/src/video/vid_sdac_ramdac.c index f127572ac..58d6b164c 100644 --- a/src/video/vid_sdac_ramdac.c +++ b/src/video/vid_sdac_ramdac.c @@ -28,9 +28,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> - -enum -{ +enum { ICS_5300 = 0, ICS_5301, ICS_5340, @@ -38,247 +36,238 @@ enum ICS_5342 }; +#define ICS_S3_MASK 7 +#define ICS_S3 8 -#define ICS_S3_MASK 7 -#define ICS_S3 8 +#define S3_86C708 (ICS_5300 | ICS_S3) +#define S3_86C716 (ICS_5342 | ICS_S3) -#define S3_86C708 (ICS_5300 | ICS_S3) -#define S3_86C716 (ICS_5342 | ICS_S3) - - -typedef struct sdac_ramdac_t -{ +typedef struct sdac_ramdac_t { uint16_t regs[256]; - int magic_count, - windex, rindex, - reg_ff, rs2; + int magic_count, + windex, rindex, + reg_ff, rs2; uint8_t type, command; } sdac_ramdac_t; - static void sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val) { ramdac->command = val; switch (ramdac->type & ICS_S3_MASK) { - case ICS_5300: - case ICS_5301: - switch (val >> 5) { - case 0x00: - default: - svga->bpp = 8; - break; - case 0x01: - case 0x04: - case 0x05: - svga->bpp = 15; - break; - case 0x03: - case 0x06: - svga->bpp = 16; - break; - case 0x02: - case 0x07: - svga->bpp = 24; - break; - } - break; - case ICS_5340: - case ICS_5341: - case ICS_5342: - switch (val >> 4) { - case 0x00: - case 0x01: /* This is actually 8bpp with two pixels read at a time. */ - default: - svga->bpp = 8; - break; - case 0x02: - case 0x03: - case 0x08: - case 0x0a: - svga->bpp = 15; - break; - case 0x05: - case 0x06: - case 0x0c: - svga->bpp = 16; - break; - case 0x04: - case 0x09: - case 0x0e: - svga->bpp = 24; - break; - case 0x07: - svga->bpp = 32; - break; - } - break; + case ICS_5300: + case ICS_5301: + switch (val >> 5) { + case 0x00: + default: + svga->bpp = 8; + break; + case 0x01: + case 0x04: + case 0x05: + svga->bpp = 15; + break; + case 0x03: + case 0x06: + svga->bpp = 16; + break; + case 0x02: + case 0x07: + svga->bpp = 24; + break; + } + break; + case ICS_5340: + case ICS_5341: + case ICS_5342: + switch (val >> 4) { + case 0x00: + case 0x01: /* This is actually 8bpp with two pixels read at a time. */ + default: + svga->bpp = 8; + break; + case 0x02: + case 0x03: + case 0x08: + case 0x0a: + svga->bpp = 15; + break; + case 0x05: + case 0x06: + case 0x0c: + svga->bpp = 16; + break; + case 0x04: + case 0x09: + case 0x0e: + svga->bpp = 24; + break; + case 0x07: + svga->bpp = 32; + break; + } + break; } svga_recalctimings(svga); } - static void sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val) { if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) { - if (!ramdac->reg_ff) - ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; - else - ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); + if (!ramdac->reg_ff) + ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val; + else + ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8); } ramdac->reg_ff = !ramdac->reg_ff; if (!ramdac->reg_ff) - ramdac->windex++; + ramdac->windex++; } - static uint8_t sdac_reg_read(sdac_ramdac_t *ramdac, int reg) { uint8_t temp; if (!ramdac->reg_ff) - temp = ramdac->regs[reg] & 0xff; + temp = ramdac->regs[reg] & 0xff; else - temp = ramdac->regs[reg] >> 8; + temp = ramdac->regs[reg] >> 8; ramdac->reg_ff = !ramdac->reg_ff; if (!ramdac->reg_ff) - ramdac->rindex++; + ramdac->rindex++; return temp; } - void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga) { sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; - uint8_t rs = (addr & 0x03); + uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); if (rs != 0x02) - ramdac->magic_count = 0; + ramdac->magic_count = 0; switch (rs) { - case 0x02: - switch (ramdac->magic_count) { - case 4: - sdac_control_write(ramdac, svga, val); - ramdac->magic_count = 0; - break; - default: - svga_out(addr, val, svga); - break; - } - break; - case 0x00: - case 0x01: - case 0x03: - svga_out(addr, val, svga); - break; - case 0x04: - ramdac->windex = val; - ramdac->reg_ff = 0; - break; - case 0x05: - sdac_reg_write(ramdac, ramdac->windex & 0xff, val); - break; - case 0x06: - sdac_control_write(ramdac, svga, val); - break; - case 0x07: - ramdac->rindex = val; - ramdac->reg_ff = 0; - break; + case 0x02: + switch (ramdac->magic_count) { + case 4: + sdac_control_write(ramdac, svga, val); + ramdac->magic_count = 0; + break; + default: + svga_out(addr, val, svga); + break; + } + break; + case 0x00: + case 0x01: + case 0x03: + svga_out(addr, val, svga); + break; + case 0x04: + ramdac->windex = val; + ramdac->reg_ff = 0; + break; + case 0x05: + sdac_reg_write(ramdac, ramdac->windex & 0xff, val); + break; + case 0x06: + sdac_control_write(ramdac, svga, val); + break; + case 0x07: + ramdac->rindex = val; + ramdac->reg_ff = 0; + break; } } - uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga) { sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; - uint8_t temp = 0xff; - uint8_t rs = (addr & 0x03); + uint8_t temp = 0xff; + uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); if (rs != 0x02) - ramdac->magic_count = 0; + ramdac->magic_count = 0; switch (rs) { - case 0x02: - switch (ramdac->magic_count) { - case 1: case 2: - temp = 0x00; - ramdac->magic_count++; - break; - case 3: - temp = (ramdac->type & ICS_S3) ? 0x70 : 0x00; - ramdac->magic_count++; - break; - case 4: - temp = ramdac->command; - ramdac->magic_count = 0; - break; - default: - temp = svga_in(addr, svga); - ramdac->magic_count++; - break; - } - break; - case 0x00: - case 0x01: - case 0x03: - temp = svga_in(addr, svga); - break; - case 0x04: - temp = ramdac->windex; - break; - case 0x05: - temp = sdac_reg_read(ramdac, ramdac->rindex & 0xff); - break; - case 0x06: - temp = ramdac->command; - break; - case 0x07: - temp = ramdac->rindex; - break; + case 0x02: + switch (ramdac->magic_count) { + case 1: + case 2: + temp = 0x00; + ramdac->magic_count++; + break; + case 3: + temp = (ramdac->type & ICS_S3) ? 0x70 : 0x00; + ramdac->magic_count++; + break; + case 4: + temp = ramdac->command; + ramdac->magic_count = 0; + break; + default: + temp = svga_in(addr, svga); + ramdac->magic_count++; + break; + } + break; + case 0x00: + case 0x01: + case 0x03: + temp = svga_in(addr, svga); + break; + case 0x04: + temp = ramdac->windex; + break; + case 0x05: + temp = sdac_reg_read(ramdac, ramdac->rindex & 0xff); + break; + case 0x06: + temp = ramdac->command; + break; + case 0x07: + temp = ramdac->rindex; + break; } return temp; } - float sdac_getclock(int clock, void *p) { - sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; - float t; - int m, n1, n2; + sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p; + float t; + int m, n1, n2; if (ramdac->regs[0xe] & (1 << 5)) - clock = ramdac->regs[0xe] & 7; + clock = ramdac->regs[0xe] & 7; clock &= 7; if (clock == 0) - return 25175000.0; + return 25175000.0; if (clock == 1) - return 28322000.0; + return 28322000.0; - m = (ramdac->regs[clock] & 0x7f) + 2; - n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; + m = (ramdac->regs[clock] & 0x7f) + 2; + n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; n2 = ((ramdac->regs[clock] >> 13) & 0x07); n2 = (1 << n2); - t = (14318184.0f * (float)m) / (float)(n1 * n2); + t = (14318184.0f * (float) m) / (float) (n1 * n2); return t; } - void * sdac_ramdac_init(const device_t *info) { @@ -293,68 +282,67 @@ sdac_ramdac_init(const device_t *info) return ramdac; } - static void sdac_ramdac_close(void *priv) { sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t gendac_ramdac_device = { - .name = "S3 GENDAC 86c708 RAMDAC", + .name = "S3 GENDAC 86c708 RAMDAC", .internal_name = "gendac_ramdac", - .flags = 0, - .local = S3_86C708, - .init = sdac_ramdac_init, - .close = sdac_ramdac_close, - .reset = NULL, + .flags = 0, + .local = S3_86C708, + .init = sdac_ramdac_init, + .close = sdac_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t tseng_ics5301_ramdac_device = { - .name = "Tseng ICS5301 GENDAC RAMDAC", + .name = "Tseng ICS5301 GENDAC RAMDAC", .internal_name = "tseng_ics5301_ramdac", - .flags = 0, - .local = ICS_5301, - .init = sdac_ramdac_init, - .close = sdac_ramdac_close, - .reset = NULL, + .flags = 0, + .local = ICS_5301, + .init = sdac_ramdac_init, + .close = sdac_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t tseng_ics5341_ramdac_device = { - .name = "Tseng ICS5341 GENDAC RAMDAC", + .name = "Tseng ICS5341 GENDAC RAMDAC", .internal_name = "tseng_ics5341_ramdac", - .flags = 0, - .local = ICS_5341, - .init = sdac_ramdac_init, - .close = sdac_ramdac_close, - .reset = NULL, + .flags = 0, + .local = ICS_5341, + .init = sdac_ramdac_init, + .close = sdac_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t sdac_ramdac_device = { - .name = "S3 SDAC 86c716 RAMDAC", + .name = "S3 SDAC 86c716 RAMDAC", .internal_name = "sdac_ramdac", - .flags = 0, - .local = S3_86C716, - .init = sdac_ramdac_init, - .close = sdac_ramdac_close, - .reset = NULL, + .flags = 0, + .local = S3_86C716, + .init = sdac_ramdac_init, + .close = sdac_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 73a9363e8..bf6524439 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -30,9 +30,8 @@ #include <86box/device.h> #include <86box/video.h> - -#define ROM_SIGMA_FONT "roms/video/sigma/sigma400_font.rom" -#define ROM_SIGMA_BIOS "roms/video/sigma/sigma400_bios.rom" +#define ROM_SIGMA_FONT "roms/video/sigma/sigma400_font.rom" +#define ROM_SIGMA_BIOS "roms/video/sigma/sigma400_bios.rom" /* The Sigma Designs Color 400 is a video card from 1985, presumably intended * as an EGA competitor. @@ -74,20 +73,20 @@ * Graphics 640x400: 0x7F * * I have assumed this is a bitmap with the following meaning: */ -#define MODE_80COLS 0x01 /* For text modes, 80 columns across */ -#define MODE_GRAPHICS 0x02 /* Graphics mode */ -#define MODE_NOBLINK 0x04 /* Disable blink? */ -#define MODE_ENABLE 0x08 /* Enable display */ -#define MODE_HRGFX 0x10 /* For graphics modes, 640 pixels across */ -#define MODE_640x400 0x40 /* 400-line graphics mode */ -#define MODE_FONT16 0x80 /* Use 16-pixel high font */ +#define MODE_80COLS 0x01 /* For text modes, 80 columns across */ +#define MODE_GRAPHICS 0x02 /* Graphics mode */ +#define MODE_NOBLINK 0x04 /* Disable blink? */ +#define MODE_ENABLE 0x08 /* Enable display */ +#define MODE_HRGFX 0x10 /* For graphics modes, 640 pixels across */ +#define MODE_640x400 0x40 /* 400-line graphics mode */ +#define MODE_FONT16 0x80 /* Use 16-pixel high font */ /* * 0x2D9: Control register, with the following bits: */ -#define CTL_CURSOR 0x80 /* Low bit of cursor position */ -#define CTL_NMI 0x20 /* Writes to 0x3D0-0x3DF trigger NMI */ -#define CTL_CLEAR_LPEN 0x08 /* Strobe 0 to clear lightpen latch */ -#define CTL_SET_LPEN 0x04 /* Strobe 0 to set lightpen latch */ -#define CTL_PALETTE 0x01 /* 0x2DE writes to palette (1) or plane (0) */ +#define CTL_CURSOR 0x80 /* Low bit of cursor position */ +#define CTL_NMI 0x20 /* Writes to 0x3D0-0x3DF trigger NMI */ +#define CTL_CLEAR_LPEN 0x08 /* Strobe 0 to clear lightpen latch */ +#define CTL_SET_LPEN 0x04 /* Strobe 0 to set lightpen latch */ +#define CTL_PALETTE 0x01 /* 0x2DE writes to palette (1) or plane (0) */ /* * The card BIOS seems to support two variants of the hardware: One where * bits 2 and 3 are normally 1 and are set to 0 to set/clear the latch, and @@ -96,12 +95,12 @@ * * 0x2DA: Status register. */ -#define STATUS_CURSOR 0x80 /* Last value written to bit 7 of 0x2D9 */ -#define STATUS_NMI 0x20 /* Last value written to bit 5 of 0x2D9 */ -#define STATUS_RETR_V 0x10 /* Vertical retrace */ -#define STATUS_LPEN_T 0x04 /* Lightpen switch is off */ -#define STATUS_LPEN_A 0x02 /* Edge from lightpen has set trigger */ -#define STATUS_RETR_H 0x01 /* Horizontal retrace */ +#define STATUS_CURSOR 0x80 /* Last value written to bit 7 of 0x2D9 */ +#define STATUS_NMI 0x20 /* Last value written to bit 5 of 0x2D9 */ +#define STATUS_RETR_V 0x10 /* Vertical retrace */ +#define STATUS_LPEN_T 0x04 /* Lightpen switch is off */ +#define STATUS_LPEN_A 0x02 /* Edge from lightpen has set trigger */ +#define STATUS_RETR_H 0x01 /* Horizontal retrace */ /* * 0x2DB: On read: Byte written to the card that triggered NMI * 0x2DB: On write: Resets the 'card raised NMI' flag. @@ -126,36 +125,34 @@ * plane 0-3 */ - -typedef struct sigma_t -{ +typedef struct sigma_t { mem_mapping_t mapping, bios_ram; - rom_t bios_rom; + rom_t bios_rom; - uint8_t crtc[32]; /* CRTC: Real values */ + uint8_t crtc[32]; /* CRTC: Real values */ - uint8_t lastport; /* Last I/O port written */ - uint8_t lastwrite; /* Value written to that port */ - uint8_t sigma_ctl; /* Controls register: - * Bit 7 is low bit of cursor position - * Bit 5 set if writes to CGA ports trigger NMI - * Bit 3 clears lightpen latch - * Bit 2 sets lightpen latch - * Bit 1 controls meaning of port 2DE - */ - uint8_t enable_nmi; /* Enable the NMI mechanism for CGA emulation?*/ - uint8_t rom_paged; /* Is ROM paged in at 0xC1800? */ + uint8_t lastport; /* Last I/O port written */ + uint8_t lastwrite; /* Value written to that port */ + uint8_t sigma_ctl; /* Controls register: + * Bit 7 is low bit of cursor position + * Bit 5 set if writes to CGA ports trigger NMI + * Bit 3 clears lightpen latch + * Bit 2 sets lightpen latch + * Bit 1 controls meaning of port 2DE + */ + uint8_t enable_nmi; /* Enable the NMI mechanism for CGA emulation?*/ + uint8_t rom_paged; /* Is ROM paged in at 0xC1800? */ - uint8_t crtc_value; /* Value to return from a CRTC register read */ + uint8_t crtc_value; /* Value to return from a CRTC register read */ - uint8_t sigmastat, /* Status register [0x2DA] */ - fake_stat; /* see sigma_in() for comment */ + uint8_t sigmastat, /* Status register [0x2DA] */ + fake_stat; /* see sigma_in() for comment */ - uint8_t sigmamode; /* Mode control register [0x2D8] */ + uint8_t sigmamode; /* Mode control register [0x2D8] */ uint16_t ma, maback; - int crtcreg; /* CRTC: Real selected register */ + int crtcreg; /* CRTC: Real selected register */ int linepos, displine; int sc, vc; @@ -173,7 +170,7 @@ typedef struct sigma_t pc_timer_t timer; uint8_t *vram; - uint8_t bram[2048]; + uint8_t bram[2048]; uint8_t palette[16]; @@ -185,210 +182,202 @@ typedef struct sigma_t #define COMPOSITE_OLD 0 #define COMPOSITE_NEW 1 -static uint8_t crtcmask[32] = -{ - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +static uint8_t crtcmask[32] = { + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static video_timings_t timing_sigma = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +static video_timings_t timing_sigma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; - -static void sigma_recalctimings(sigma_t *cga); +static void sigma_recalctimings(sigma_t *cga); static void sigma_out(uint16_t addr, uint8_t val, void *p) { - sigma_t *sigma = (sigma_t *)p; - uint8_t old; + sigma_t *sigma = (sigma_t *) p; + uint8_t old; if (addr >= 0x3D0 && addr < 0x3E0) { - sigma->lastport = addr & 0x0F; - sigma->lastwrite = val; - /* If set to NMI on video I/O... */ - if (sigma->enable_nmi && (sigma->sigma_ctl & CTL_NMI)) { - sigma->lastport |= 0x80; /* Card raised NMI */ - nmi_raise(); - } - /* For CRTC emulation, the card BIOS sets the value to be - * read from port 0x3D1 like this */ - if (addr == 0x3D1) - sigma->crtc_value = val; - } else switch (addr) { - case 0x2D0: - case 0x2D2: - case 0x2D4: - case 0x2D6: - sigma->crtcreg = val & 31; - return; - case 0x2D1: - case 0x2D3: - case 0x2D5: - case 0x2D7: - old = sigma->crtc[sigma->crtcreg]; - sigma->crtc[sigma->crtcreg] = val & crtcmask[sigma->crtcreg]; - if (old != val) { - if (sigma->crtcreg < 0xe || sigma->crtcreg > 0x10) { - sigma->fullchange = changeframecount; - sigma_recalctimings(sigma); - } - } - return; + sigma->lastport = addr & 0x0F; + sigma->lastwrite = val; + /* If set to NMI on video I/O... */ + if (sigma->enable_nmi && (sigma->sigma_ctl & CTL_NMI)) { + sigma->lastport |= 0x80; /* Card raised NMI */ + nmi_raise(); + } + /* For CRTC emulation, the card BIOS sets the value to be + * read from port 0x3D1 like this */ + if (addr == 0x3D1) + sigma->crtc_value = val; + } else + switch (addr) { + case 0x2D0: + case 0x2D2: + case 0x2D4: + case 0x2D6: + sigma->crtcreg = val & 31; + return; + case 0x2D1: + case 0x2D3: + case 0x2D5: + case 0x2D7: + old = sigma->crtc[sigma->crtcreg]; + sigma->crtc[sigma->crtcreg] = val & crtcmask[sigma->crtcreg]; + if (old != val) { + if (sigma->crtcreg < 0xe || sigma->crtcreg > 0x10) { + sigma->fullchange = changeframecount; + sigma_recalctimings(sigma); + } + } + return; - case 0x2D8: - sigma->sigmamode = val; - return; - case 0x2D9: - sigma->sigma_ctl = val; - return; - case 0x2DB: - sigma->lastport &= 0x7F; - return; - case 0x2DC: /* Reset NMI */ - nmi = 0; - sigma->lastport &= 0x7F; - return; - case 0x2DD: /* Page in RAM at 0xC1800 */ - if (sigma->rom_paged != 0) - mmu_invalidate(0xC0000); - sigma->rom_paged = 0x00; - return; + case 0x2D8: + sigma->sigmamode = val; + return; + case 0x2D9: + sigma->sigma_ctl = val; + return; + case 0x2DB: + sigma->lastport &= 0x7F; + return; + case 0x2DC: /* Reset NMI */ + nmi = 0; + sigma->lastport &= 0x7F; + return; + case 0x2DD: /* Page in RAM at 0xC1800 */ + if (sigma->rom_paged != 0) + mmu_invalidate(0xC0000); + sigma->rom_paged = 0x00; + return; - case 0x2DE: - if (sigma->sigma_ctl & CTL_PALETTE) - sigma->palette[val >> 4] = (val & 0x0F) ^ 0x0F; - else - sigma->plane = val & 3; - return; - } + case 0x2DE: + if (sigma->sigma_ctl & CTL_PALETTE) + sigma->palette[val >> 4] = (val & 0x0F) ^ 0x0F; + else + sigma->plane = val & 3; + return; + } } - static uint8_t sigma_in(uint16_t addr, void *p) { - uint8_t result = 0xFF; - sigma_t *sigma = (sigma_t *)p; + uint8_t result = 0xFF; + sigma_t *sigma = (sigma_t *) p; switch (addr) { - case 0x2D0: - case 0x2D2: - case 0x2D4: - case 0x2D6: - result = sigma->crtcreg; - break; - case 0x2D1: - case 0x2D3: - case 0x2D5: - case 0x2D7: - result = sigma->crtc[sigma->crtcreg & 0x1F]; - break; - case 0x2DA: - result = (sigma->sigma_ctl & 0xE0) | - (sigma->sigmastat & 0x1F); - break; - case 0x2DB: - result = sigma->lastwrite; /* Value that triggered NMI */ - break; - case 0x2DC: - result = sigma->lastport; /* Port that triggered NMI */ - break; - case 0x2DD: /* Page in ROM at 0xC1800 */ - result = (sigma->rom_paged ? 0x80 : 0); - if (sigma->rom_paged != 0x80) - mmu_invalidate(0xC0000); - sigma->rom_paged = 0x80; - break; - case 0x3D1: - case 0x3D3: - case 0x3D5: - case 0x3D7: - result = sigma->crtc_value; - break; - /* For CGA compatibility we have to return something palatable on this port. - On a real card this functionality can be turned on or off with SW1/6 */ - case 0x3DA: - if (sigma->sigmamode & MODE_ENABLE) { - result = sigma->sigmastat & 0x07; - if (sigma->sigmastat & STATUS_RETR_V) - result |= 0x08; - } else { - /* - * The card is not running yet, and someone - * (probably the system BIOS) is trying to - * read our status in CGA mode. - * - * One of the systems that do this, is the - * DTK XT (PIM-10TB-Z board) with ERSO 2.42 - * BIOS. If this test fails (i.e. it doesnt - * see valid HS and VS bits alternate) it - * will generate lots of annoying beeps.. - * - * So, the trick here is to just send it - * some alternating bits, making it think - * the CGA circuitry is operational. - */ - sigma->fake_stat ^= (0x08 | 0x01); - result = sigma->fake_stat; - } - break; + case 0x2D0: + case 0x2D2: + case 0x2D4: + case 0x2D6: + result = sigma->crtcreg; + break; + case 0x2D1: + case 0x2D3: + case 0x2D5: + case 0x2D7: + result = sigma->crtc[sigma->crtcreg & 0x1F]; + break; + case 0x2DA: + result = (sigma->sigma_ctl & 0xE0) | (sigma->sigmastat & 0x1F); + break; + case 0x2DB: + result = sigma->lastwrite; /* Value that triggered NMI */ + break; + case 0x2DC: + result = sigma->lastport; /* Port that triggered NMI */ + break; + case 0x2DD: /* Page in ROM at 0xC1800 */ + result = (sigma->rom_paged ? 0x80 : 0); + if (sigma->rom_paged != 0x80) + mmu_invalidate(0xC0000); + sigma->rom_paged = 0x80; + break; + case 0x3D1: + case 0x3D3: + case 0x3D5: + case 0x3D7: + result = sigma->crtc_value; + break; + /* For CGA compatibility we have to return something palatable on this port. + On a real card this functionality can be turned on or off with SW1/6 */ + case 0x3DA: + if (sigma->sigmamode & MODE_ENABLE) { + result = sigma->sigmastat & 0x07; + if (sigma->sigmastat & STATUS_RETR_V) + result |= 0x08; + } else { + /* + * The card is not running yet, and someone + * (probably the system BIOS) is trying to + * read our status in CGA mode. + * + * One of the systems that do this, is the + * DTK XT (PIM-10TB-Z board) with ERSO 2.42 + * BIOS. If this test fails (i.e. it doesnt + * see valid HS and VS bits alternate) it + * will generate lots of annoying beeps.. + * + * So, the trick here is to just send it + * some alternating bits, making it think + * the CGA circuitry is operational. + */ + sigma->fake_stat ^= (0x08 | 0x01); + result = sigma->fake_stat; + } + break; } return result; } - static void sigma_write(uint32_t addr, uint8_t val, void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *) p; sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)] = val; cycles -= 4; } - static uint8_t sigma_read(uint32_t addr, void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *) p; cycles -= 4; return sigma->vram[sigma->plane * 0x8000 + (addr & 0x7fff)]; } - static void sigma_bwrite(uint32_t addr, uint8_t val, void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *) p; addr &= 0x3FFF; if ((addr < 0x1800) || sigma->rom_paged || (addr >= 0x2000)) - ; + ; else - sigma->bram[addr & 0x7FF] = val; + sigma->bram[addr & 0x7FF] = val; } - static uint8_t sigma_bread(uint32_t addr, void *p) { - sigma_t *sigma = (sigma_t *)p; - uint8_t result; + sigma_t *sigma = (sigma_t *) p; + uint8_t result; addr &= 0x3FFF; if (addr >= 0x2000) - return 0xFF; + return 0xFF; if (addr < 0x1800 || sigma->rom_paged) - result = sigma->bios_rom.rom[addr & 0x1FFF]; + result = sigma->bios_rom.rom[addr & 0x1FFF]; else - result = sigma->bram[addr & 0x7FF]; + result = sigma->bram[addr & 0x7FF]; return result; } - static void sigma_recalctimings(sigma_t *sigma) { @@ -396,154 +385,146 @@ sigma_recalctimings(sigma_t *sigma) double _dispontime, _dispofftime; if (sigma->sigmamode & MODE_80COLS) { - disptime = (sigma->crtc[0] + 1) << 1; - _dispontime = (sigma->crtc[1]) << 1; + disptime = (sigma->crtc[0] + 1) << 1; + _dispontime = (sigma->crtc[1]) << 1; } else { - disptime = (sigma->crtc[0] + 1) << 2; - _dispontime = sigma->crtc[1] << 2; + disptime = (sigma->crtc[0] + 1) << 2; + _dispontime = sigma->crtc[1] << 2; } _dispofftime = disptime - _dispontime; _dispontime *= CGACONST; _dispofftime *= CGACONST; - sigma->dispontime = (uint64_t)(_dispontime); - sigma->dispofftime = (uint64_t)(_dispofftime); + sigma->dispontime = (uint64_t) (_dispontime); + sigma->dispofftime = (uint64_t) (_dispofftime); } - /* Render a line in 80-column text mode */ -static void sigma_text80(sigma_t *sigma) +static void +sigma_text80(sigma_t *sigma) { - int x, c; - uint8_t chr, attr; + int x, c; + uint8_t chr, attr; uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); uint16_t ma = ((sigma->ma & 0x3FFF) << 1); - int drawcursor; + int drawcursor; uint32_t cols[4]; uint8_t *vram = sigma->vram + (ma << 1); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) - ++ca; + ++ca; ca &= 0x3fff; /* The Sigma 400 seems to use screen widths stated in words (40 for 80-column, 20 for 40-column) */ for (x = 0; x < (sigma->crtc[1] << 1); x++) { - chr = vram[x << 1]; - attr = vram[(x << 1) + 1]; - drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + chr = vram[x << 1]; + attr = vram[(x << 1) + 1]; + drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); - if (!(sigma->sigmamode & MODE_NOBLINK)) { - cols[1] = (attr & 15) | 16; - cols[0] = ((attr >> 4) & 7) | 16; - if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) - cols[1] = cols[0]; - } else { /* No blink */ - cols[1] = (attr & 15) | 16; - cols[0] = (attr >> 4) | 16; - } + if (!(sigma->sigmamode & MODE_NOBLINK)) { + cols[1] = (attr & 15) | 16; + cols[0] = ((attr >> 4) & 7) | 16; + if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) + cols[1] = cols[0]; + } else { /* No blink */ + cols[1] = (attr & 15) | 16; + cols[0] = (attr >> 4) | 16; + } - if (drawcursor) { - for (c = 0; c < 8; c++) { - if (sigma->sigmamode & MODE_FONT16) - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; - else - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; - } - } else { - for (c = 0; c < 8; c++) { - if (sigma->sigmamode & MODE_FONT16) - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - else - buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; + if (drawcursor) { + for (c = 0; c < 8; c++) { + if (sigma->sigmamode & MODE_FONT16) + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; + else + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; + } + } else { + for (c = 0; c < 8; c++) { + if (sigma->sigmamode & MODE_FONT16) + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + else + buffer32->line[sigma->displine][(x << 3) + c + 8] = cols[(fontdat[chr][sigma->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ++ma; } sigma->ma += sigma->crtc[1]; } - /* Render a line in 40-column text mode */ static void sigma_text40(sigma_t *sigma) { - int x, c; - uint8_t chr, attr; + int x, c; + uint8_t chr, attr; uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); uint16_t ma = ((sigma->ma & 0x3FFF) << 1); - int drawcursor; + int drawcursor; uint32_t cols[4]; uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) - ++ca; + ++ca; ca &= 0x3fff; /* The Sigma 400 seems to use screen widths stated in words (40 for 80-column, 20 for 40-column) */ for (x = 0; x < (sigma->crtc[1] << 1); x++) { - chr = vram[x << 1]; - attr = vram[(x << 1) + 1]; - drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); + chr = vram[x << 1]; + attr = vram[(x << 1) + 1]; + drawcursor = ((ma == ca) && sigma->con && sigma->cursoron); - if (!(sigma->sigmamode & MODE_NOBLINK)) { - cols[1] = (attr & 15) | 16; - cols[0] = ((attr >> 4) & 7) | 16; - if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) - cols[1] = cols[0]; - } else { /* No blink */ - cols[1] = (attr & 15) | 16; - cols[0] = (attr >> 4) | 16; - } + if (!(sigma->sigmamode & MODE_NOBLINK)) { + cols[1] = (attr & 15) | 16; + cols[0] = ((attr >> 4) & 7) | 16; + if ((sigma->cgablink & 8) && (attr & 0x80) && !sigma->drawcursor) + cols[1] = cols[0]; + } else { /* No blink */ + cols[1] = (attr & 15) | 16; + cols[0] = (attr >> 4) | 16; + } - if (drawcursor) { - for (c = 0; c < 8; c++) { - buffer32->line[sigma->displine][(x << 4) + 2*c + 8] = - buffer32->line[sigma->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; - } - } else { - for (c = 0; c < 8; c++) { - buffer32->line[sigma->displine][(x << 4) + 2*c + 8] = - buffer32->line[sigma->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ma++; + if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[sigma->displine][(x << 4) + 2 * c + 8] = buffer32->line[sigma->displine][(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0xf; + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[sigma->displine][(x << 4) + 2 * c + 8] = buffer32->line[sigma->displine][(x << 4) + 2 * c + 9] = cols[(fontdatm[chr][sigma->sc & 15] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ma++; } sigma->ma += sigma->crtc[1]; } - /* Draw a line in the 640x400 graphics mode */ static void sigma_gfx400(sigma_t *sigma) { - int x; - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + - (sigma->sc & 3) * 0x2000]; - uint8_t plane[4]; - uint8_t mask, col, c; + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 3) * 0x2000]; + uint8_t plane[4]; + uint8_t mask, col, c; for (x = 0; x < (sigma->crtc[1] << 1); x++) { - plane[0] = vram[x]; - plane[1] = vram[0x8000 + x]; - plane[2] = vram[0x10000 + x]; - plane[3] = vram[0x18000 + x]; + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; - for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { - col = ((plane[3] & mask) ? 8 : 0) | - ((plane[2] & mask) ? 4 : 0) | - ((plane[1] & mask) ? 2 : 0) | - ((plane[0] & mask) ? 1 : 0); - col |= 16; - buffer32->line[sigma->displine][(x << 3) + c + 8] = col; - } - if (x & 1) - ++sigma->ma; + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { + col = ((plane[3] & mask) ? 8 : 0) | ((plane[2] & mask) ? 4 : 0) | ((plane[1] & mask) ? 2 : 0) | ((plane[0] & mask) ? 1 : 0); + col |= 16; + buffer32->line[sigma->displine][(x << 3) + c + 8] = col; + } + if (x & 1) + ++sigma->ma; } } @@ -555,257 +536,245 @@ sigma_gfx400(sigma_t *sigma) static void sigma_gfx200(sigma_t *sigma) { - int x; - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + - (sigma->sc & 2) * 0x1000]; - uint8_t plane[4]; - uint8_t mask, col, c; + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + uint8_t plane[4]; + uint8_t mask, col, c; for (x = 0; x < (sigma->crtc[1] << 1); x++) { - plane[0] = vram[x]; - plane[1] = vram[0x8000 + x]; - plane[2] = vram[0x10000 + x]; - plane[3] = vram[0x18000 + x]; + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; - for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { - col = ((plane[3] & mask) ? 8 : 0) | - ((plane[2] & mask) ? 4 : 0) | - ((plane[1] & mask) ? 2 : 0) | - ((plane[0] & mask) ? 1 : 0); - col |= 16; - buffer32->line[sigma->displine][(x << 3) + c + 8] = col; - } + for (c = 0, mask = 0x80; c < 8; c++, mask >>= 1) { + col = ((plane[3] & mask) ? 8 : 0) | ((plane[2] & mask) ? 4 : 0) | ((plane[1] & mask) ? 2 : 0) | ((plane[0] & mask) ? 1 : 0); + col |= 16; + buffer32->line[sigma->displine][(x << 3) + c + 8] = col; + } - if (x & 1) - ++sigma->ma; + if (x & 1) + ++sigma->ma; } } - /* Draw a line in the 320x200 graphics mode */ static void sigma_gfx4col(sigma_t *sigma) { - int x; - unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + - (sigma->sc & 2) * 0x1000]; - uint8_t plane[4]; - uint8_t mask, col, c; + int x; + unsigned char *vram = &sigma->vram[((sigma->ma << 1) & 0x1FFF) + (sigma->sc & 2) * 0x1000]; + uint8_t plane[4]; + uint8_t mask, col, c; for (x = 0; x < (sigma->crtc[1] << 1); x++) { - plane[0] = vram[x]; - plane[1] = vram[0x8000 + x]; - plane[2] = vram[0x10000 + x]; - plane[3] = vram[0x18000 + x]; + plane[0] = vram[x]; + plane[1] = vram[0x8000 + x]; + plane[2] = vram[0x10000 + x]; + plane[3] = vram[0x18000 + x]; - mask = 0x80; - for (c = 0; c < 4; c++) { - col = ((plane[3] & mask) ? 2 : 0) | - ((plane[2] & mask) ? 1 : 0); - mask = mask >> 1; - col |= ((plane[3] & mask) ? 8 : 0) | - ((plane[2] & mask) ? 4 : 0); - col |= 16; - mask = mask >> 1; + mask = 0x80; + for (c = 0; c < 4; c++) { + col = ((plane[3] & mask) ? 2 : 0) | ((plane[2] & mask) ? 1 : 0); + mask = mask >> 1; + col |= ((plane[3] & mask) ? 8 : 0) | ((plane[2] & mask) ? 4 : 0); + col |= 16; + mask = mask >> 1; - buffer32->line[sigma->displine][(x << 3) + (c << 1) + 8] = - buffer32->line[sigma->displine][(x << 3) + (c << 1) + 9] = col; - } + buffer32->line[sigma->displine][(x << 3) + (c << 1) + 8] = buffer32->line[sigma->displine][(x << 3) + (c << 1) + 9] = col; + } - if (x & 1) - ++sigma->ma; + if (x & 1) + ++sigma->ma; } } - static void sigma_poll(void *p) { - sigma_t *sigma = (sigma_t *)p; - int x, c; - int oldvc; + sigma_t *sigma = (sigma_t *) p; + int x, c; + int oldvc; uint32_t cols[4]; - int oldsc; + int oldsc; if (!sigma->linepos) { - timer_advance_u64(&sigma->timer, sigma->dispofftime); - sigma->sigmastat |= STATUS_RETR_H; - sigma->linepos = 1; - oldsc = sigma->sc; - if ((sigma->crtc[8] & 3) == 3) - sigma->sc = ((sigma->sc << 1) + sigma->oddeven) & 7; - if (sigma->cgadispon) { - if (sigma->displine < sigma->firstline) { - sigma->firstline = sigma->displine; - video_wait_for_buffer(); - } - sigma->lastline = sigma->displine; + timer_advance_u64(&sigma->timer, sigma->dispofftime); + sigma->sigmastat |= STATUS_RETR_H; + sigma->linepos = 1; + oldsc = sigma->sc; + if ((sigma->crtc[8] & 3) == 3) + sigma->sc = ((sigma->sc << 1) + sigma->oddeven) & 7; + if (sigma->cgadispon) { + if (sigma->displine < sigma->firstline) { + sigma->firstline = sigma->displine; + video_wait_for_buffer(); + } + sigma->lastline = sigma->displine; - cols[0] = 16; - /* Left overscan */ - for (c = 0; c < 8; c++) { - buffer32->line[sigma->displine][c] = cols[0]; - if (sigma->sigmamode & MODE_80COLS) - buffer32->line[sigma->displine][c + (sigma->crtc[1] << 4) + 8] = cols[0]; - else - buffer32->line[sigma->displine][c + (sigma->crtc[1] << 5) + 8] = cols[0]; - } - if (sigma->sigmamode & MODE_GRAPHICS) { - if (sigma->sigmamode & MODE_640x400) - sigma_gfx400(sigma); - else if (sigma->sigmamode & MODE_HRGFX) - sigma_gfx200(sigma); - else - sigma_gfx4col(sigma); - } else { /* Text modes */ - if (sigma->sigmamode & MODE_80COLS) - sigma_text80(sigma); - else - sigma_text40(sigma); - } - } else { - cols[0] = 16; - if (sigma->sigmamode & MODE_80COLS) - hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 4) + 16, cols[0]); - else - hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 5) + 16, cols[0]); - } + cols[0] = 16; + /* Left overscan */ + for (c = 0; c < 8; c++) { + buffer32->line[sigma->displine][c] = cols[0]; + if (sigma->sigmamode & MODE_80COLS) + buffer32->line[sigma->displine][c + (sigma->crtc[1] << 4) + 8] = cols[0]; + else + buffer32->line[sigma->displine][c + (sigma->crtc[1] << 5) + 8] = cols[0]; + } + if (sigma->sigmamode & MODE_GRAPHICS) { + if (sigma->sigmamode & MODE_640x400) + sigma_gfx400(sigma); + else if (sigma->sigmamode & MODE_HRGFX) + sigma_gfx200(sigma); + else + sigma_gfx4col(sigma); + } else { /* Text modes */ + if (sigma->sigmamode & MODE_80COLS) + sigma_text80(sigma); + else + sigma_text40(sigma); + } + } else { + cols[0] = 16; + if (sigma->sigmamode & MODE_80COLS) + hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 4) + 16, cols[0]); + else + hline(buffer32, 0, sigma->displine, (sigma->crtc[1] << 5) + 16, cols[0]); + } - if (sigma->sigmamode & MODE_80COLS) - x = (sigma->crtc[1] << 4) + 16; - else - x = (sigma->crtc[1] << 5) + 16; + if (sigma->sigmamode & MODE_80COLS) + x = (sigma->crtc[1] << 4) + 16; + else + x = (sigma->crtc[1] << 5) + 16; - for (c = 0; c < x; c++) - buffer32->line[sigma->displine][c] = sigma->palette[buffer32->line[sigma->displine][c] & 0xf] | 16; + for (c = 0; c < x; c++) + buffer32->line[sigma->displine][c] = sigma->palette[buffer32->line[sigma->displine][c] & 0xf] | 16; - sigma->sc = oldsc; - if (sigma->vc == sigma->crtc[7] && !sigma->sc) - sigma->sigmastat |= STATUS_RETR_V; - sigma->displine++; - if (sigma->displine >= 560) - sigma->displine = 0; + sigma->sc = oldsc; + if (sigma->vc == sigma->crtc[7] && !sigma->sc) + sigma->sigmastat |= STATUS_RETR_V; + sigma->displine++; + if (sigma->displine >= 560) + sigma->displine = 0; } else { - timer_advance_u64(&sigma->timer, sigma->dispontime); - sigma->linepos = 0; - if (sigma->vsynctime) { - sigma->vsynctime--; - if (!sigma->vsynctime) - sigma->sigmastat &= ~STATUS_RETR_V; - } - if (sigma->sc == (sigma->crtc[11] & 31) || - ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[11] & 31) >> 1))) { - sigma->con = 0; - sigma->coff = 1; - } - if ((sigma->crtc[8] & 3) == 3 && sigma->sc == (sigma->crtc[9] >> 1)) - sigma->maback = sigma->ma; - if (sigma->vadj) { - sigma->sc++; - sigma->sc &= 31; - sigma->ma = sigma->maback; - sigma->vadj--; - if (!sigma->vadj) { - sigma->cgadispon = 1; - sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; - sigma->sc = 0; - } - } else if (sigma->sc == sigma->crtc[9]) { - sigma->maback = sigma->ma; - sigma->sc = 0; - oldvc = sigma->vc; - sigma->vc++; - sigma->vc &= 127; + timer_advance_u64(&sigma->timer, sigma->dispontime); + sigma->linepos = 0; + if (sigma->vsynctime) { + sigma->vsynctime--; + if (!sigma->vsynctime) + sigma->sigmastat &= ~STATUS_RETR_V; + } + if (sigma->sc == (sigma->crtc[11] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[11] & 31) >> 1))) { + sigma->con = 0; + sigma->coff = 1; + } + if ((sigma->crtc[8] & 3) == 3 && sigma->sc == (sigma->crtc[9] >> 1)) + sigma->maback = sigma->ma; + if (sigma->vadj) { + sigma->sc++; + sigma->sc &= 31; + sigma->ma = sigma->maback; + sigma->vadj--; + if (!sigma->vadj) { + sigma->cgadispon = 1; + sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + sigma->sc = 0; + } + } else if (sigma->sc == sigma->crtc[9]) { + sigma->maback = sigma->ma; + sigma->sc = 0; + oldvc = sigma->vc; + sigma->vc++; + sigma->vc &= 127; - if (sigma->vc == sigma->crtc[6]) - sigma->cgadispon = 0; + if (sigma->vc == sigma->crtc[6]) + sigma->cgadispon = 0; - if (oldvc == sigma->crtc[4]) { - sigma->vc = 0; - sigma->vadj = sigma->crtc[5]; - if (!sigma->vadj) sigma->cgadispon = 1; - if (!sigma->vadj) - sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; - if ((sigma->crtc[10] & 0x60) == 0x20) - sigma->cursoron = 0; - else - sigma->cursoron = sigma->cgablink & 8; - } + if (oldvc == sigma->crtc[4]) { + sigma->vc = 0; + sigma->vadj = sigma->crtc[5]; + if (!sigma->vadj) + sigma->cgadispon = 1; + if (!sigma->vadj) + sigma->ma = sigma->maback = (sigma->crtc[13] | (sigma->crtc[12] << 8)) & 0x3fff; + if ((sigma->crtc[10] & 0x60) == 0x20) + sigma->cursoron = 0; + else + sigma->cursoron = sigma->cgablink & 8; + } - if (sigma->vc == sigma->crtc[7]) { - sigma->cgadispon = 0; - sigma->displine = 0; - sigma->vsynctime = 16; - if (sigma->crtc[7]) { - if (sigma->sigmamode & MODE_80COLS) - x = (sigma->crtc[1] << 4) + 16; - else - x = (sigma->crtc[1] << 5) + 16; - sigma->lastline++; - if ((x != xsize) || ((sigma->lastline - sigma->firstline) != ysize) || - video_force_resize_get()) { - xsize = x; - ysize = sigma->lastline - sigma->firstline; - if (xsize < 64) - xsize = 656; - if (ysize < 32) - ysize = 200; - if (ysize <= 250) - set_screen_size(xsize, (ysize << 1) + 16); - else - set_screen_size(xsize, ysize + 8); + if (sigma->vc == sigma->crtc[7]) { + sigma->cgadispon = 0; + sigma->displine = 0; + sigma->vsynctime = 16; + if (sigma->crtc[7]) { + if (sigma->sigmamode & MODE_80COLS) + x = (sigma->crtc[1] << 4) + 16; + else + x = (sigma->crtc[1] << 5) + 16; + sigma->lastline++; + if ((x != xsize) || ((sigma->lastline - sigma->firstline) != ysize) || video_force_resize_get()) { + xsize = x; + ysize = sigma->lastline - sigma->firstline; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + if (ysize <= 250) + set_screen_size(xsize, (ysize << 1) + 16); + else + set_screen_size(xsize, ysize + 8); - if (video_force_resize_get()) - video_force_resize_set(0); - } + if (video_force_resize_get()) + video_force_resize_set(0); + } - video_blit_memtoscreen_8(0, sigma->firstline - 4, xsize, (sigma->lastline - sigma->firstline) + 8); - frames++; + video_blit_memtoscreen_8(0, sigma->firstline - 4, xsize, (sigma->lastline - sigma->firstline) + 8); + frames++; - video_res_x = xsize - 16; - video_res_y = ysize; - if (sigma->sigmamode & MODE_GRAPHICS) { - if (sigma->sigmamode & (MODE_HRGFX | MODE_640x400)) - video_bpp = 1; - else { - video_res_x /= 2; - video_bpp = 2; - } - } else if (sigma->sigmamode & MODE_80COLS) { - /* 80-column text */ - video_res_x /= 8; - video_res_y /= sigma->crtc[9] + 1; - video_bpp = 0; - } else { - /* 40-column text */ - video_res_x /= 16; - video_res_y /= sigma->crtc[9] + 1; - video_bpp = 0; - } - } - sigma->firstline = 1000; - sigma->lastline = 0; - sigma->cgablink++; - sigma->oddeven ^= 1; - } - } else { - sigma->sc++; - sigma->sc &= 31; - sigma->ma = sigma->maback; - } - if (sigma->cgadispon) - sigma->sigmastat &= ~STATUS_RETR_H; - if ((sigma->sc == (sigma->crtc[10] & 31) || - ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[10] & 31) >> 1)))) - sigma->con = 1; + video_res_x = xsize - 16; + video_res_y = ysize; + if (sigma->sigmamode & MODE_GRAPHICS) { + if (sigma->sigmamode & (MODE_HRGFX | MODE_640x400)) + video_bpp = 1; + else { + video_res_x /= 2; + video_bpp = 2; + } + } else if (sigma->sigmamode & MODE_80COLS) { + /* 80-column text */ + video_res_x /= 8; + video_res_y /= sigma->crtc[9] + 1; + video_bpp = 0; + } else { + /* 40-column text */ + video_res_x /= 16; + video_res_y /= sigma->crtc[9] + 1; + video_bpp = 0; + } + } + sigma->firstline = 1000; + sigma->lastline = 0; + sigma->cgablink++; + sigma->oddeven ^= 1; + } + } else { + sigma->sc++; + sigma->sc &= 31; + sigma->ma = sigma->maback; + } + if (sigma->cgadispon) + sigma->sigmastat &= ~STATUS_RETR_H; + if ((sigma->sc == (sigma->crtc[10] & 31) || ((sigma->crtc[8] & 3) == 3 && sigma->sc == ((sigma->crtc[10] & 31) >> 1)))) + sigma->con = 1; } } - static void -*sigma_init(const device_t *info) + * + sigma_init(const device_t *info) { - int bios_addr; + int bios_addr; sigma_t *sigma = malloc(sizeof(sigma_t)); memset(sigma, 0, sizeof(sigma_t)); @@ -817,7 +786,7 @@ static void loadfont(ROM_SIGMA_FONT, 7); rom_init(&sigma->bios_rom, ROM_SIGMA_BIOS, bios_addr, 0x2000, - 0x1FFF, 0, MEM_MAPPING_EXTERNAL); + 0x1FFF, 0, MEM_MAPPING_EXTERNAL); /* The BIOS ROM is overlaid by RAM, so remove its default mapping and access it through sigma_bread() / sigma_bwrite() below */ mem_mapping_disable(&sigma->bios_rom.mapping); @@ -827,62 +796,59 @@ static void timer_add(&sigma->timer, sigma_poll, sigma, 1); mem_mapping_add(&sigma->mapping, 0xb8000, 0x08000, - sigma_read, NULL, NULL, - sigma_write, NULL, NULL, - NULL, MEM_MAPPING_EXTERNAL, sigma); + sigma_read, NULL, NULL, + sigma_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, sigma); mem_mapping_add(&sigma->bios_ram, bios_addr, 0x2000, - sigma_bread, NULL, NULL, - sigma_bwrite, NULL, NULL, - sigma->bios_rom.rom, MEM_MAPPING_EXTERNAL, sigma); + sigma_bread, NULL, NULL, + sigma_bwrite, NULL, NULL, + sigma->bios_rom.rom, MEM_MAPPING_EXTERNAL, sigma); io_sethandler(0x03d0, 0x0010, - sigma_in, NULL, NULL, - sigma_out, NULL, NULL, sigma); + sigma_in, NULL, NULL, + sigma_out, NULL, NULL, sigma); io_sethandler(0x02d0, 0x0010, - sigma_in, NULL, NULL, - sigma_out, NULL, NULL, sigma); + sigma_in, NULL, NULL, + sigma_out, NULL, NULL, sigma); /* Start with ROM paged in, BIOS RAM paged out */ sigma->rom_paged = 0x80; cga_palette = device_get_config_int("rgb_type") << 1; if (cga_palette > 6) - cga_palette = 0; + cga_palette = 0; cgapal_rebuild(); if (sigma->enable_nmi) - sigma->sigmastat = STATUS_LPEN_T; + sigma->sigmastat = STATUS_LPEN_T; return sigma; } - static int sigma_available(void) { - return((rom_present(ROM_SIGMA_FONT) && rom_present(ROM_SIGMA_BIOS))); + return ((rom_present(ROM_SIGMA_FONT) && rom_present(ROM_SIGMA_BIOS))); } - static void sigma_close(void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *) p; free(sigma->vram); free(sigma); } - void sigma_speed_changed(void *p) { - sigma_t *sigma = (sigma_t *)p; + sigma_t *sigma = (sigma_t *) p; sigma_recalctimings(sigma); } device_config_t sigma_config[] = { -// clang-format off + // clang-format off { .name = "rgb_type", .description = "RGB type", @@ -982,15 +948,15 @@ device_config_t sigma_config[] = { }; const device_t sigma_device = { - .name = "Sigma Color 400", + .name = "Sigma Color 400", .internal_name = "sigma400", - .flags = DEVICE_ISA, - .local = 0, - .init = sigma_init, - .close = sigma_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = sigma_init, + .close = sigma_close, + .reset = NULL, { .available = sigma_available }, .speed_changed = sigma_speed_changed, - .force_redraw = NULL, - .config = sigma_config + .force_redraw = NULL, + .config = sigma_config }; diff --git a/src/video/vid_stg_ramdac.c b/src/video/vid_stg_ramdac.c index 49216dba2..161cf1177 100644 --- a/src/video/vid_stg_ramdac.c +++ b/src/video/vid_stg_ramdac.c @@ -28,205 +28,199 @@ #include <86box/video.h> #include <86box/vid_svga.h> - -typedef struct stg_ramdac_t -{ - int magic_count, index; +typedef struct stg_ramdac_t { + int magic_count, index; uint8_t regs[256]; uint8_t command; } stg_ramdac_t; - - -static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; -static int stg_state_write[8] = {0,0,0,0,0,6,7,7}; - +static int stg_state_read[2][8] = { + {1, 2, 3, 4, 0, 0, 0, 0}, + { 1, 2, 3, 4, 5, 6, 7, 7} +}; +static int stg_state_write[8] = { 0, 0, 0, 0, 0, 6, 7, 7 }; void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) { if (ramdac->command & 0x8) { switch (ramdac->regs[3]) { - case 0: - case 5: - case 7: - default: - svga->bpp = 8; - break; - case 1: - case 2: - case 8: - svga->bpp = 15; - break; - case 3: - case 6: - svga->bpp = 16; - break; - case 4: - case 9: - svga->bpp = 24; - break; - } + case 0: + case 5: + case 7: + default: + svga->bpp = 8; + break; + case 1: + case 2: + case 8: + svga->bpp = 15; + break; + case 3: + case 6: + svga->bpp = 16; + break; + case 4: + case 9: + svga->bpp = 24; + break; + } } else { - switch (ramdac->command >> 5) { - case 0: - default: - svga->bpp = 8; - break; - case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 16; - break; - case 7: - svga->bpp = 24; - break; - } + switch (ramdac->command >> 5) { + case 0: + default: + svga->bpp = 8; + break; + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 16; + break; + case 7: + svga->bpp = 24; + break; + } } svga_recalctimings(svga); } - void stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { stg_ramdac_t *ramdac = (stg_ramdac_t *) p; - int didwrite, old; + int didwrite, old; switch (addr) { - case 0x3c6: - switch (ramdac->magic_count) { - /* 0 = PEL mask register */ - case 0: - case 1: - case 2: - case 3: - break; - case 4: /* REG06 */ - old = ramdac->command; - ramdac->command = val; - if ((old ^ val) & 8) - stg_ramdac_set_bpp(svga, ramdac); - else { - if ((old ^ val) & 0xE0) - stg_ramdac_set_bpp(svga, ramdac); - } - break; - case 5: - ramdac->index = (ramdac->index & 0xff00) | val; - break; - case 6: - ramdac->index = (ramdac->index & 0xff) | (val << 8); - break; - case 7: - if (ramdac->index < 0x100) - ramdac->regs[ramdac->index] = val; - if ((ramdac->index == 3) && (ramdac->command & 8)) - stg_ramdac_set_bpp(svga, ramdac); - ramdac->index++; - break; - } - didwrite = (ramdac->magic_count >= 4); - ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; - if (didwrite) - return; - break; - case 0x3c7: - case 0x3c8: - case 0x3c9: - ramdac->magic_count=0; - break; + case 0x3c6: + switch (ramdac->magic_count) { + /* 0 = PEL mask register */ + case 0: + case 1: + case 2: + case 3: + break; + case 4: /* REG06 */ + old = ramdac->command; + ramdac->command = val; + if ((old ^ val) & 8) + stg_ramdac_set_bpp(svga, ramdac); + else { + if ((old ^ val) & 0xE0) + stg_ramdac_set_bpp(svga, ramdac); + } + break; + case 5: + ramdac->index = (ramdac->index & 0xff00) | val; + break; + case 6: + ramdac->index = (ramdac->index & 0xff) | (val << 8); + break; + case 7: + if (ramdac->index < 0x100) + ramdac->regs[ramdac->index] = val; + if ((ramdac->index == 3) && (ramdac->command & 8)) + stg_ramdac_set_bpp(svga, ramdac); + ramdac->index++; + break; + } + didwrite = (ramdac->magic_count >= 4); + ramdac->magic_count = stg_state_write[ramdac->magic_count & 7]; + if (didwrite) + return; + break; + case 0x3c7: + case 0x3c8: + case 0x3c9: + ramdac->magic_count = 0; + break; } svga_out(addr, val, svga); } - uint8_t stg_ramdac_in(uint16_t addr, void *p, svga_t *svga) { stg_ramdac_t *ramdac = (stg_ramdac_t *) p; - uint8_t temp = 0xff; + uint8_t temp = 0xff; switch (addr) { - case 0x3c6: - switch (ramdac->magic_count) { - case 0: - case 1: - case 2: - case 3: - temp = 0xff; - break; - case 4: - temp = ramdac->command; - break; - case 5: - temp = ramdac->index & 0xff; - break; - case 6: - temp = ramdac->index >> 8; - break; - case 7: - switch (ramdac->index) { - case 0: - temp = 0x44; - break; - case 1: - temp = 0x03; - break; - case 7: - temp = 0x88; - break; - default: - if (ramdac->index < 0x100) - temp = ramdac->regs[ramdac->index]; - else - temp = 0xff; - break; - } - ramdac->index++; - break; - } - ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; - return temp; - case 0x3c7: - case 0x3c8: - case 0x3c9: - ramdac->magic_count=0; - break; + case 0x3c6: + switch (ramdac->magic_count) { + case 0: + case 1: + case 2: + case 3: + temp = 0xff; + break; + case 4: + temp = ramdac->command; + break; + case 5: + temp = ramdac->index & 0xff; + break; + case 6: + temp = ramdac->index >> 8; + break; + case 7: + switch (ramdac->index) { + case 0: + temp = 0x44; + break; + case 1: + temp = 0x03; + break; + case 7: + temp = 0x88; + break; + default: + if (ramdac->index < 0x100) + temp = ramdac->regs[ramdac->index]; + else + temp = 0xff; + break; + } + ramdac->index++; + break; + } + ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7]; + return temp; + case 0x3c7: + case 0x3c8: + case 0x3c9: + ramdac->magic_count = 0; + break; } return svga_in(addr, svga); } - float stg_getclock(int clock, void *p) { - stg_ramdac_t *ramdac = (stg_ramdac_t *)p; - float t; - int m, n, n2; - uint16_t *c; + stg_ramdac_t *ramdac = (stg_ramdac_t *) p; + float t; + int m, n, n2; + uint16_t *c; if (clock == 0) - return 25175000.0; + return 25175000.0; if (clock == 1) - return 28322000.0; + return 28322000.0; - clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ - c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)]; - m = (*c & 0xff) + 2; /* B+2 */ - n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */ - n2 = ((*c >> 13) & 0x07); /* D */ + clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ + c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)]; + m = (*c & 0xff) + 2; /* B+2 */ + n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */ + n2 = ((*c >> 13) & 0x07); /* D */ n2 = (1 << n2); - t = (14318184.0f * (float)m) / (float)(n * n2); + t = (14318184.0f * (float) m) / (float) (n * n2); return t; } - static void * stg_ramdac_init(const device_t *info) { @@ -236,26 +230,25 @@ stg_ramdac_init(const device_t *info) return ramdac; } - static void stg_ramdac_close(void *priv) { stg_ramdac_t *ramdac = (stg_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t stg_ramdac_device = { - .name = "SGS-Thompson STG170x RAMDAC", + .name = "SGS-Thompson STG170x RAMDAC", .internal_name = "stg_ramdac", - .flags = 0, - .local = 0, - .init = stg_ramdac_init, - .close = stg_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = stg_ramdac_init, + .close = stg_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 9ab96c169..d6d9a9564 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -44,406 +44,397 @@ void svga_doblit(int wx, int wy, svga_t *svga); svga_t *svga_8514; -extern int cyc_total; -extern uint8_t edatlookup[4][4]; +extern int cyc_total; +extern uint8_t edatlookup[4][4]; uint8_t svga_rotate[8][256]; /*Primary SVGA device. As multiple video cards are not yet supported this is the only SVGA device.*/ static svga_t *svga_pri; -int vga_on, ibm8514_on; +int vga_on, ibm8514_on; svga_t -*svga_get_pri() + * + svga_get_pri() { return svga_pri; } - void svga_set_override(svga_t *svga, int val) { if (svga->override && !val) - svga->fullchange = changeframecount; + svga->fullchange = changeframecount; svga->override = val; if (!val) { - /* Override turned off, restore overscan X and Y per the CRTC. */ - if (enable_overscan) { - overscan_y = (svga->rowcount + 1) << 1; + /* Override turned off, restore overscan X and Y per the CRTC. */ + if (enable_overscan) { + overscan_y = (svga->rowcount + 1) << 1; - if (overscan_y < 16) - overscan_y = 16; - } + if (overscan_y < 16) + overscan_y = 16; + } - overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; + overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; - if (svga->seqregs[1] & 8) - overscan_x <<= 1; + if (svga->seqregs[1] & 8) + overscan_x <<= 1; } else - overscan_x = overscan_y = 16; - /* Override turned off, fix overcan X and Y to 16. */ + overscan_x = overscan_y = 16; + /* Override turned off, fix overcan X and Y to 16. */ } - void svga_out(uint16_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - int c; + svga_t *svga = (svga_t *) p; + int c; uint8_t o, index; switch (addr) { - case 0x3c0: - case 0x3c1: - if (!svga->attrff) { - svga->attraddr = val & 31; - if ((val & 0x20) != svga->attr_palette_enable) { - svga->fullchange = 3; - svga->attr_palette_enable = val & 0x20; - svga_recalctimings(svga); - } - } else { - if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) - svga->fullchange = changeframecount; - o = svga->attrregs[svga->attraddr & 31]; - svga->attrregs[svga->attraddr & 31] = val; - if (svga->attraddr < 16) - svga->fullchange = changeframecount; - if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (c = 0; c < 16; c++) { - if (svga->attrregs[0x10] & 0x80) { - svga->egapal[c] = (svga->attrregs[c] & 0xf) | - ((svga->attrregs[0x14] & 0xf) << 4); - } else { - svga->egapal[c] = (svga->attrregs[c] & 0x3f) | - ((svga->attrregs[0x14] & 0xc) << 4); - } - } - svga->fullchange = changeframecount; - } - /* Recalculate timings on change of attribute register 0x11 - (overscan border color) too. */ - if (svga->attraddr == 0x10) { - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x11) { - svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; - if (o != val) - svga_recalctimings(svga); - } else if (svga->attraddr == 0x12) { - if ((val & 0xf) != svga->plane_mask) - svga->fullchange = changeframecount; - svga->plane_mask = val & 0xf; - } - } - svga->attrff ^= 1; - break; - case 0x3c2: - svga->miscout = val; - svga->vidclock = val & 4; - io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); - if (!(val & 1)) - io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); - svga_recalctimings(svga); - break; - case 0x3c4: - svga->seqaddr = val; - break; - case 0x3c5: - if (svga->seqaddr > 0xf) - return; - o = svga->seqregs[svga->seqaddr & 0xf]; - svga->seqregs[svga->seqaddr & 0xf] = val; - if (o != val && (svga->seqaddr & 0xf) == 1) - svga_recalctimings(svga); - switch (svga->seqaddr & 0xf) { - case 1: - if (svga->scrblank && !(val & 0x20)) - svga->fullchange = 3; - svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); - svga_recalctimings(svga); - break; - case 2: - svga->writemask = val & 0xf; - break; - case 3: - svga->charsetb = (((val >> 2) & 3) * 0x10000) + 2; - svga->charseta = ((val & 3) * 0x10000) + 2; - if (val & 0x10) - svga->charseta += 0x8000; - if (val & 0x20) - svga->charsetb += 0x8000; - break; - case 4: - svga->chain2_write = !(val & 4); - svga->chain4 = val & 8; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); - break; - } - break; - case 0x3c6: - svga->dac_mask = val; - break; - case 0x3c7: - case 0x3c8: - svga->dac_pos = 0; - svga->dac_status = addr & 0x03; - svga->dac_addr = (val + (addr & 0x01)) & 255; - break; - case 0x3c9: - if (svga->adv_flags & FLAG_RAMDAC_SHIFT) - val <<= 2; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0: - svga->dac_r = val; - svga->dac_pos++; - break; - case 1: - svga->dac_g = val; - svga->dac_pos++; - break; - case 2: - index = svga->dac_addr & 255; - svga->vgapal[index].r = svga->dac_r; - svga->vgapal[index].g = svga->dac_g; - svga->vgapal[index].b = val; - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); - else - svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); - svga->dac_pos = 0; - svga->dac_addr = (svga->dac_addr + 1) & 255; - break; - } - break; - case 0x3ce: - svga->gdcaddr = val; - break; - case 0x3cf: - o = svga->gdcreg[svga->gdcaddr & 15]; - switch (svga->gdcaddr & 15) { - case 2: - svga->colourcompare = val; - break; - case 4: - svga->readplane = val & 3; - break; - case 5: - svga->writemode = val & 3; - svga->readmode = val & 8; - svga->chain2_read = val & 0x10; - break; - case 6: - if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { - switch (val&0xC) { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - break; - case 7: - svga->colournocare = val; - break; - } - svga->gdcreg[svga->gdcaddr & 15] = val; - svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && - !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only); - if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || - ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) - svga_recalctimings(svga); - break; + case 0x3c0: + case 0x3c1: + if (!svga->attrff) { + svga->attraddr = val & 31; + if ((val & 0x20) != svga->attr_palette_enable) { + svga->fullchange = 3; + svga->attr_palette_enable = val & 0x20; + svga_recalctimings(svga); + } + } else { + if ((svga->attraddr == 0x13) && (svga->attrregs[0x13] != val)) + svga->fullchange = changeframecount; + o = svga->attrregs[svga->attraddr & 31]; + svga->attrregs[svga->attraddr & 31] = val; + if (svga->attraddr < 16) + svga->fullchange = changeframecount; + if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { + for (c = 0; c < 16; c++) { + if (svga->attrregs[0x10] & 0x80) { + svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); + } else { + svga->egapal[c] = (svga->attrregs[c] & 0x3f) | ((svga->attrregs[0x14] & 0xc) << 4); + } + } + svga->fullchange = changeframecount; + } + /* Recalculate timings on change of attribute register 0x11 + (overscan border color) too. */ + if (svga->attraddr == 0x10) { + if (o != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x11) { + svga->overscan_color = svga->pallook[svga->attrregs[0x11]]; + if (o != val) + svga_recalctimings(svga); + } else if (svga->attraddr == 0x12) { + if ((val & 0xf) != svga->plane_mask) + svga->fullchange = changeframecount; + svga->plane_mask = val & 0xf; + } + } + svga->attrff ^= 1; + break; + case 0x3c2: + svga->miscout = val; + svga->vidclock = val & 4; + io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); + if (!(val & 1)) + io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); + svga_recalctimings(svga); + break; + case 0x3c4: + svga->seqaddr = val; + break; + case 0x3c5: + if (svga->seqaddr > 0xf) + return; + o = svga->seqregs[svga->seqaddr & 0xf]; + svga->seqregs[svga->seqaddr & 0xf] = val; + if (o != val && (svga->seqaddr & 0xf) == 1) + svga_recalctimings(svga); + switch (svga->seqaddr & 0xf) { + case 1: + if (svga->scrblank && !(val & 0x20)) + svga->fullchange = 3; + svga->scrblank = (svga->scrblank & ~0x20) | (val & 0x20); + svga_recalctimings(svga); + break; + case 2: + svga->writemask = val & 0xf; + break; + case 3: + svga->charsetb = (((val >> 2) & 3) * 0x10000) + 2; + svga->charseta = ((val & 3) * 0x10000) + 2; + if (val & 0x10) + svga->charseta += 0x8000; + if (val & 0x20) + svga->charsetb += 0x8000; + break; + case 4: + svga->chain2_write = !(val & 4); + svga->chain4 = val & 8; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && !(svga->adv_flags & FLAG_ADDR_BY8); + break; + } + break; + case 0x3c6: + svga->dac_mask = val; + break; + case 0x3c7: + case 0x3c8: + svga->dac_pos = 0; + svga->dac_status = addr & 0x03; + svga->dac_addr = (val + (addr & 0x01)) & 255; + break; + case 0x3c9: + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + val <<= 2; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 255; + svga->vgapal[index].r = svga->dac_r; + svga->vgapal[index].g = svga->dac_g; + svga->vgapal[index].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); + else + svga->pallook[index] = makecol32(video_6to8[svga->vgapal[index].r & 0x3f], video_6to8[svga->vgapal[index].g & 0x3f], video_6to8[svga->vgapal[index].b & 0x3f]); + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + break; + } + break; + case 0x3ce: + svga->gdcaddr = val; + break; + case 0x3cf: + o = svga->gdcreg[svga->gdcaddr & 15]; + switch (svga->gdcaddr & 15) { + case 2: + svga->colourcompare = val; + break; + case 4: + svga->readplane = val & 3; + break; + case 5: + svga->writemode = val & 3; + svga->readmode = val & 8; + svga->chain2_read = val & 0x10; + break; + case 6: + if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { + switch (val & 0xC) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + break; + case 7: + svga->colournocare = val; + break; + } + svga->gdcreg[svga->gdcaddr & 15] = val; + svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only); + if (((svga->gdcaddr & 15) == 5 && (val ^ o) & 0x70) || ((svga->gdcaddr & 15) == 6 && (val ^ o) & 1)) + svga_recalctimings(svga); + break; } } - uint8_t svga_in(uint16_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; uint8_t index, ret = 0xff; switch (addr) { - case 0x3c0: - ret = svga->attraddr | svga->attr_palette_enable; - break; - case 0x3c1: - ret = svga->attrregs[svga->attraddr]; - break; - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) - ret = 0; - else - ret = 0x10; - break; - case 0x3c4: - ret = svga->seqaddr; - break; - case 0x3c5: - ret = svga->seqregs[svga->seqaddr & 0x0f]; - break; - case 0x3c6: - ret = svga->dac_mask; - break; - case 0x3c7: - ret = svga->dac_status; - break; - case 0x3c8: - ret = svga->dac_addr; - break; - case 0x3c9: - index = (svga->dac_addr - 1) & 255; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[index].r; - else - ret = svga->vgapal[index].r & 0x3f; - break; - case 1: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[index].g; - else - ret = svga->vgapal[index].g & 0x3f; - break; - case 2: - svga->dac_pos=0; - svga->dac_addr = (svga->dac_addr + 1) & 255; - if (svga->ramdac_type == RAMDAC_8BIT) - ret = svga->vgapal[index].b; - else - ret = svga->vgapal[index].b & 0x3f; - break; - } - if (svga->adv_flags & FLAG_RAMDAC_SHIFT) - ret >>= 2; - break; - case 0x3cc: - ret = svga->miscout; - break; - case 0x3ce: - ret = svga->gdcaddr; - break; - case 0x3cf: - /* The spec says GDC addresses 0xF8 to 0xFB return the latch. */ - switch(svga->gdcaddr) { - case 0xf8: - ret = svga->latch.b[0]; - break; - case 0xf9: - ret = svga->latch.b[1]; - break; - case 0xfa: - ret = svga->latch.b[2]; - break; - case 0xfb: - ret = svga->latch.b[3]; - break; - default: - ret = svga->gdcreg[svga->gdcaddr & 0xf]; - break; - } - break; - case 0x3da: - svga->attrff = 0; + case 0x3c0: + ret = svga->attraddr | svga->attr_palette_enable; + break; + case 0x3c1: + ret = svga->attrregs[svga->attraddr]; + break; + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) + ret = 0; + else + ret = 0x10; + break; + case 0x3c4: + ret = svga->seqaddr; + break; + case 0x3c5: + ret = svga->seqregs[svga->seqaddr & 0x0f]; + break; + case 0x3c6: + ret = svga->dac_mask; + break; + case 0x3c7: + ret = svga->dac_status; + break; + case 0x3c8: + ret = svga->dac_addr; + break; + case 0x3c9: + index = (svga->dac_addr - 1) & 255; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].r; + else + ret = svga->vgapal[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].g; + else + ret = svga->vgapal[index].g & 0x3f; + break; + case 2: + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 255; + if (svga->ramdac_type == RAMDAC_8BIT) + ret = svga->vgapal[index].b; + else + ret = svga->vgapal[index].b & 0x3f; + break; + } + if (svga->adv_flags & FLAG_RAMDAC_SHIFT) + ret >>= 2; + break; + case 0x3cc: + ret = svga->miscout; + break; + case 0x3ce: + ret = svga->gdcaddr; + break; + case 0x3cf: + /* The spec says GDC addresses 0xF8 to 0xFB return the latch. */ + switch (svga->gdcaddr) { + case 0xf8: + ret = svga->latch.b[0]; + break; + case 0xf9: + ret = svga->latch.b[1]; + break; + case 0xfa: + ret = svga->latch.b[2]; + break; + case 0xfb: + ret = svga->latch.b[3]; + break; + default: + ret = svga->gdcreg[svga->gdcaddr & 0xf]; + break; + } + break; + case 0x3da: + svga->attrff = 0; - if (svga->cgastat & 0x01) - svga->cgastat &= ~0x30; - else - svga->cgastat ^= 0x30; - ret = svga->cgastat; - break; + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x30; + else + svga->cgastat ^= 0x30; + ret = svga->cgastat; + break; } - return(ret); + return (ret); } - void svga_set_ramdac_type(svga_t *svga, int type) { int c; if (svga->ramdac_type != type) { - svga->ramdac_type = type; + svga->ramdac_type = type; - for (c = 0; c < 256; c++) { - if (svga->ramdac_type == RAMDAC_8BIT) - svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); - else - svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, - (svga->vgapal[c].g & 0x3f) * 4, - (svga->vgapal[c].b & 0x3f) * 4); - } + for (c = 0; c < 256; c++) { + if (svga->ramdac_type == RAMDAC_8BIT) + svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); + else + svga->pallook[c] = makecol32((svga->vgapal[c].r & 0x3f) * 4, + (svga->vgapal[c].g & 0x3f) * 4, + (svga->vgapal[c].b & 0x3f) * 4); + } } } - void svga_recalctimings(svga_t *svga) { double crtcconst, _dispontime, _dispofftime, disptime; - svga->vtotal = svga->crtc[6]; - svga->dispend = svga->crtc[0x12]; - svga->vsyncstart = svga->crtc[0x10]; - svga->split = svga->crtc[0x18]; + svga->vtotal = svga->crtc[6]; + svga->dispend = svga->crtc[0x12]; + svga->vsyncstart = svga->crtc[0x10]; + svga->split = svga->crtc[0x18]; svga->vblankstart = svga->crtc[0x15]; if (svga->crtc[7] & 1) - svga->vtotal |= 0x100; + svga->vtotal |= 0x100; if (svga->crtc[7] & 32) - svga->vtotal |= 0x200; + svga->vtotal |= 0x200; svga->vtotal += 2; if (svga->crtc[7] & 2) - svga->dispend |= 0x100; + svga->dispend |= 0x100; if (svga->crtc[7] & 64) - svga->dispend |= 0x200; + svga->dispend |= 0x200; svga->dispend++; if (svga->crtc[7] & 4) - svga->vsyncstart |= 0x100; + svga->vsyncstart |= 0x100; if (svga->crtc[7] & 128) - svga->vsyncstart |= 0x200; + svga->vsyncstart |= 0x200; svga->vsyncstart++; if (svga->crtc[7] & 0x10) - svga->split|=0x100; + svga->split |= 0x100; if (svga->crtc[9] & 0x40) - svga->split|=0x200; + svga->split |= 0x200; svga->split++; if (svga->crtc[7] & 0x08) - svga->vblankstart |= 0x100; + svga->vblankstart |= 0x100; if (svga->crtc[9] & 0x20) - svga->vblankstart |= 0x200; + svga->vblankstart |= 0x200; svga->vblankstart++; svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5); svga->hdisp++; svga->htotal = svga->crtc[0]; - svga->htotal += 6; /*+6 is required for Tyrian*/ + svga->htotal += 6; /*+6 is required for Tyrian*/ svga->rowoffset = svga->crtc[0x13]; @@ -454,104 +445,105 @@ svga_recalctimings(svga_t *svga) svga->interlace = 0; svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - svga->ca_adj = 0; + svga->ca_adj = 0; svga->rowcount = svga->crtc[9] & 31; svga->hdisp_time = svga->hdisp; - svga->render = svga_render_blank; + svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) /*40 column*/ { - svga->render = svga_render_text_40; - svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; - /* Character clock is off by 1 now in 40-line modes, on all cards. */ - svga->ma_latch--; - svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; - } else { - svga->render = svga_render_text_80; - svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; - } - svga->hdisp_old = svga->hdisp; - } else { - svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; - svga->hdisp_old = svga->hdisp; + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 8) /*40 column*/ { + svga->render = svga_render_text_40; + svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; + /* Character clock is off by 1 now in 40-line modes, on all cards. */ + svga->ma_latch--; + svga->hdisp += (svga->seqregs[1] & 1) ? 16 : 18; + } else { + svga->render = svga_render_text_80; + svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; + } + svga->hdisp_old = svga->hdisp; + } else { + svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8; + svga->hdisp_old = svga->hdisp; - switch (svga->gdcreg[5] & 0x60) { - case 0x00: - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_4bpp_lowres; - else - svga->render = svga_render_4bpp_highres; - break; - case 0x20: /*4 colours*/ - if (svga->seqregs[1] & 8) /*Low res (320)*/ - svga->render = svga_render_2bpp_lowres; - else - svga->render = svga_render_2bpp_highres; - break; - case 0x40: case 0x60: /*256+ colours*/ - switch (svga->bpp) { - case 8: - svga->map8 = svga->pallook; - if (svga->lowres) - svga->render = svga_render_8bpp_lowres; - else - svga->render = svga_render_8bpp_highres; - break; - case 15: - if (svga->lowres) - svga->render = svga_render_15bpp_lowres; - else - svga->render = svga_render_15bpp_highres; - break; - case 16: - if (svga->lowres) - svga->render = svga_render_16bpp_lowres; - else - svga->render = svga_render_16bpp_highres; - break; - case 17: - if (svga->lowres) - svga->render = svga_render_15bpp_mix_lowres; - else - svga->render = svga_render_15bpp_mix_highres; - break; - case 24: - if (svga->lowres) - svga->render = svga_render_24bpp_lowres; - else - svga->render = svga_render_24bpp_highres; - break; - case 32: - if (svga->lowres) - svga->render = svga_render_32bpp_lowres; - else - svga->render = svga_render_32bpp_highres; - break; - } - break; - } - } + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else + svga->render = svga_render_8bpp_highres; + break; + case 15: + if (svga->lowres) + svga->render = svga_render_15bpp_lowres; + else + svga->render = svga_render_15bpp_highres; + break; + case 16: + if (svga->lowres) + svga->render = svga_render_16bpp_lowres; + else + svga->render = svga_render_16bpp_highres; + break; + case 17: + if (svga->lowres) + svga->render = svga_render_15bpp_mix_lowres; + else + svga->render = svga_render_15bpp_mix_highres; + break; + case 24: + if (svga->lowres) + svga->render = svga_render_24bpp_lowres; + else + svga->render = svga_render_24bpp_highres; + break; + case 32: + if (svga->lowres) + svga->render = svga_render_32bpp_lowres; + else + svga->render = svga_render_32bpp_highres; + break; + } + break; + } + } } - svga->linedbl = svga->crtc[9] & 0x80; - svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; + svga->linedbl = svga->crtc[9] & 0x80; + svga->char_width = (svga->seqregs[1] & 1) ? 8 : 9; if (enable_overscan) { - overscan_y = (svga->rowcount + 1) << 1; + overscan_y = (svga->rowcount + 1) << 1; - if (overscan_y < 16) - overscan_y = 16; + if (overscan_y < 16) + overscan_y = 16; } if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { - overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; + overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; - if (svga->seqregs[1] & 8) - overscan_x <<= 1; + if (svga->seqregs[1] & 8) + overscan_x <<= 1; } else - overscan_x = 16; + overscan_x = 16; if (vga_on) { if (svga->recalctimings_ex) { @@ -568,96 +560,94 @@ svga_recalctimings(svga_t *svga) svga->x_add = (overscan_x >> 1); if (svga->vblankstart < svga->dispend) - svga->dispend = svga->vblankstart; + svga->dispend = svga->vblankstart; crtcconst = svga->clock * svga->char_width; - disptime = svga->htotal; + disptime = svga->htotal; _dispontime = svga->hdisp_time; if (svga->seqregs[1] & 8) { - disptime *= 2; - _dispontime *= 2; + disptime *= 2; + _dispontime *= 2; } _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; _dispofftime *= crtcconst; - svga->dispontime = (uint64_t)(_dispontime); - svga->dispofftime = (uint64_t)(_dispofftime); + svga->dispontime = (uint64_t) (_dispontime); + svga->dispofftime = (uint64_t) (_dispofftime); if (svga->dispontime < TIMER_USEC) - svga->dispontime = TIMER_USEC; + svga->dispontime = TIMER_USEC; if (svga->dispofftime < TIMER_USEC) - svga->dispofftime = TIMER_USEC; + svga->dispofftime = TIMER_USEC; - if (!svga->force_old_addr) - svga_recalc_remap_func(svga); + if (!svga->force_old_addr) + svga_recalc_remap_func(svga); /* Inform the user interface of any DPMS mode changes. */ if (svga->dpms) { - if (!svga->dpms_ui) { - svga->dpms_ui = 1; - ui_sb_set_text_w(plat_get_string(IDS_2142)); - } + if (!svga->dpms_ui) { + svga->dpms_ui = 1; + ui_sb_set_text_w(plat_get_string(IDS_2142)); + } } else if (svga->dpms_ui) { - svga->dpms_ui = 0; - ui_sb_set_text_w(NULL); + svga->dpms_ui = 0; + ui_sb_set_text_w(NULL); } } - static void svga_do_render(svga_t *svga) { /* Always render a blank screen and nothing else while in DPMS mode. */ if (svga->dpms) { - svga_render_blank(svga); - return; + svga_render_blank(svga); + return; } if (!svga->override) { - svga->render(svga); + svga->render(svga); - svga->x_add = (overscan_x >> 1); - svga_render_overscan_left(svga); - svga_render_overscan_right(svga); - svga->x_add = (overscan_x >> 1) - svga->scrollcache; + svga->x_add = (overscan_x >> 1); + svga_render_overscan_left(svga); + svga_render_overscan_right(svga); + svga->x_add = (overscan_x >> 1) - svga->scrollcache; } if (svga->overlay_on) { - if (!svga->override && svga->overlay_draw) - svga->overlay_draw(svga, svga->displine + svga->y_add); - svga->overlay_on--; - if (svga->overlay_on && svga->interlace) - svga->overlay_on--; + if (!svga->override && svga->overlay_draw) + svga->overlay_draw(svga, svga->displine + svga->y_add); + svga->overlay_on--; + if (svga->overlay_on && svga->interlace) + svga->overlay_on--; } if (svga->dac_hwcursor_on) { - if (!svga->override && svga->dac_hwcursor_draw) - svga->dac_hwcursor_draw(svga, svga->displine + svga->y_add); - svga->dac_hwcursor_on--; - if (svga->dac_hwcursor_on && svga->interlace) - svga->dac_hwcursor_on--; + if (!svga->override && svga->dac_hwcursor_draw) + svga->dac_hwcursor_draw(svga, svga->displine + svga->y_add); + svga->dac_hwcursor_on--; + if (svga->dac_hwcursor_on && svga->interlace) + svga->dac_hwcursor_on--; } if (svga->hwcursor_on) { - if (!svga->override && svga->hwcursor_draw) - svga->hwcursor_draw(svga, svga->displine + svga->y_add); - svga->hwcursor_on--; - if (svga->hwcursor_on && svga->interlace) - svga->hwcursor_on--; + if (!svga->override && svga->hwcursor_draw) + svga->hwcursor_draw(svga, svga->displine + svga->y_add); + svga->hwcursor_on--; + if (svga->hwcursor_on && svga->interlace) + svga->hwcursor_on--; } } - void svga_poll(void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; uint32_t x, blink_delay; - int wx, wy; - int ret, old_ma; + int wx, wy; + int ret, old_ma; if (!vga_on && ibm8514_enabled && ibm8514_on) { ibm8514_poll(&svga->dev8514, svga); @@ -668,328 +658,323 @@ svga_poll(void *p) } if (!svga->linepos) { - if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { - svga->hwcursor_on = svga->hwcursor.cur_ysize - svga->hwcursor_latch.yoff; - svga->hwcursor_oddeven = 0; - } + if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { + svga->hwcursor_on = svga->hwcursor.cur_ysize - svga->hwcursor_latch.yoff; + svga->hwcursor_oddeven = 0; + } - if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && - svga->interlace) { - svga->hwcursor_on = svga->hwcursor.cur_ysize - (svga->hwcursor_latch.yoff + 1); - svga->hwcursor_oddeven = 1; - } + if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) { + svga->hwcursor_on = svga->hwcursor.cur_ysize - (svga->hwcursor_latch.yoff + 1); + svga->hwcursor_oddeven = 1; + } - if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) { - svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - svga->dac_hwcursor_latch.yoff; - svga->dac_hwcursor_oddeven = 0; - } + if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) { + svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - svga->dac_hwcursor_latch.yoff; + svga->dac_hwcursor_oddeven = 0; + } - if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && - svga->interlace) { - svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); - svga->dac_hwcursor_oddeven = 1; - } + if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { + svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); + svga->dac_hwcursor_oddeven = 1; + } - if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena) { - svga->overlay_on = svga->overlay_latch.cur_ysize - svga->overlay_latch.yoff; - svga->overlay_oddeven = 0; - } + if (svga->displine == svga->overlay_latch.y && svga->overlay_latch.ena) { + svga->overlay_on = svga->overlay_latch.cur_ysize - svga->overlay_latch.yoff; + svga->overlay_oddeven = 0; + } - if (svga->displine == svga->overlay_latch.y+1 && svga->overlay_latch.ena && svga->interlace) { - svga->overlay_on = svga->overlay_latch.cur_ysize - svga->overlay_latch.yoff; - svga->overlay_oddeven = 1; - } + if (svga->displine == svga->overlay_latch.y + 1 && svga->overlay_latch.ena && svga->interlace) { + svga->overlay_on = svga->overlay_latch.cur_ysize - svga->overlay_latch.yoff; + svga->overlay_oddeven = 1; + } - timer_advance_u64(&svga->timer, svga->dispofftime); - svga->cgastat |= 1; - svga->linepos = 1; + timer_advance_u64(&svga->timer, svga->dispofftime); + svga->cgastat |= 1; + svga->linepos = 1; - if (svga->dispon) { - svga->hdisp_on = 1; + if (svga->dispon) { + svga->hdisp_on = 1; - svga->ma &= svga->vram_display_mask; - if (svga->firstline == 2000) { - svga->firstline = svga->displine; - video_wait_for_buffer(); - } + svga->ma &= svga->vram_display_mask; + if (svga->firstline == 2000) { + svga->firstline = svga->displine; + video_wait_for_buffer(); + } - if (svga->hwcursor_on || svga->dac_hwcursor_on || svga->overlay_on) { - svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = - svga->interlace ? 3 : 2; - } + if (svga->hwcursor_on || svga->dac_hwcursor_on || svga->overlay_on) { + svga->changedvram[svga->ma >> 12] = svga->changedvram[(svga->ma >> 12) + 1] = svga->interlace ? 3 : 2; + } - if (svga->vertical_linedbl) { - old_ma = svga->ma; + if (svga->vertical_linedbl) { + old_ma = svga->ma; - svga->displine <<= 1; - svga->y_add <<= 1; + svga->displine <<= 1; + svga->y_add <<= 1; - svga_do_render(svga); + svga_do_render(svga); - svga->displine++; + svga->displine++; - svga->ma = old_ma; + svga->ma = old_ma; - svga_do_render(svga); + svga_do_render(svga); - svga->y_add >>= 1; - svga->displine >>= 1; - } else - svga_do_render(svga); + svga->y_add >>= 1; + svga->displine >>= 1; + } else + svga_do_render(svga); - if (svga->lastline < svga->displine) - svga->lastline = svga->displine; - } + if (svga->lastline < svga->displine) + svga->lastline = svga->displine; + } - svga->displine++; - if (svga->interlace) - svga->displine++; - if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) - svga->cgastat &= ~8; - svga->vslines++; - if (svga->displine > 1500) - svga->displine = 0; + svga->displine++; + if (svga->interlace) + svga->displine++; + if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) + svga->cgastat &= ~8; + svga->vslines++; + if (svga->displine > 1500) + svga->displine = 0; } else { - timer_advance_u64(&svga->timer, svga->dispontime); + timer_advance_u64(&svga->timer, svga->dispontime); - if (svga->dispon) - svga->cgastat &= ~1; - svga->hdisp_on = 0; + if (svga->dispon) + svga->cgastat &= ~1; + svga->hdisp_on = 0; - svga->linepos = 0; - if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) - svga->con = 0; - if (svga->dispon) { - if (svga->linedbl && !svga->linecountff) { - svga->linecountff = 1; - svga->ma = svga->maback; - } else if (svga->sc == svga->rowcount) { - svga->linecountff = 0; - svga->sc = 0; + svga->linepos = 0; + if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) + svga->con = 0; + if (svga->dispon) { + if (svga->linedbl && !svga->linecountff) { + svga->linecountff = 1; + svga->ma = svga->maback; + } else if (svga->sc == svga->rowcount) { + svga->linecountff = 0; + svga->sc = 0; - svga->maback += (svga->rowoffset << 3); - if (svga->interlace) - svga->maback += (svga->rowoffset << 3); - svga->maback &= svga->vram_display_mask; - svga->ma = svga->maback; - } else { - svga->linecountff = 0; - svga->sc++; - svga->sc &= 31; - svga->ma = svga->maback; - } - } + svga->maback += (svga->rowoffset << 3); + if (svga->interlace) + svga->maback += (svga->rowoffset << 3); + svga->maback &= svga->vram_display_mask; + svga->ma = svga->maback; + } else { + svga->linecountff = 0; + svga->sc++; + svga->sc &= 31; + svga->ma = svga->maback; + } + } - svga->hsync_divisor = !svga->hsync_divisor; + svga->hsync_divisor = !svga->hsync_divisor; - if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) - return; + if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) + return; - svga->vc++; - svga->vc &= 2047; + svga->vc++; + svga->vc &= 2047; - if (svga->vc == svga->split) { - ret = 1; + if (svga->vc == svga->split) { + ret = 1; - if (svga->line_compare) - ret = svga->line_compare(svga); + if (svga->line_compare) + ret = svga->line_compare(svga); - if (ret) { - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); - else - svga->ma = svga->maback = ((svga->crtc[5] & 0x60) >> 5); - svga->ma = (svga->ma << 2); - svga->maback = (svga->maback << 2); + if (ret) { + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + else + svga->ma = svga->maback = ((svga->crtc[5] & 0x60) >> 5); + svga->ma = (svga->ma << 2); + svga->maback = (svga->maback << 2); - svga->sc = 0; - if (svga->attrregs[0x10] & 0x20) { - svga->scrollcache = 0; - svga->x_add = (overscan_x >> 1); - } - } - } - if (svga->vc == svga->dispend) { - if (svga->vblank_start) - svga->vblank_start(svga); - svga->dispon = 0; - blink_delay = (svga->crtc[11] & 0x60) >> 5; - if (svga->crtc[10] & 0x20) - svga->cursoron = 0; - else if (blink_delay == 2) - svga->cursoron = ((svga->blink % 96) >= 48); - else - svga->cursoron = svga->blink & (16 + (16 * blink_delay)); + svga->sc = 0; + if (svga->attrregs[0x10] & 0x20) { + svga->scrollcache = 0; + svga->x_add = (overscan_x >> 1); + } + } + } + if (svga->vc == svga->dispend) { + if (svga->vblank_start) + svga->vblank_start(svga); + svga->dispon = 0; + blink_delay = (svga->crtc[11] & 0x60) >> 5; + if (svga->crtc[10] & 0x20) + svga->cursoron = 0; + else if (blink_delay == 2) + svga->cursoron = ((svga->blink % 96) >= 48); + else + svga->cursoron = svga->blink & (16 + (16 * blink_delay)); - if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) - svga->fullchange = 2; - svga->blink = (svga->blink + 1) & 0x7f; + if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) + svga->fullchange = 2; + svga->blink = (svga->blink + 1) & 0x7f; - for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) { - if (svga->changedvram[x]) - svga->changedvram[x]--; - } - if (svga->fullchange) - svga->fullchange--; - } - if (svga->vc == svga->vsyncstart) { - svga->dispon = 0; - svga->cgastat |= 8; - x = svga->hdisp; + for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) { + if (svga->changedvram[x]) + svga->changedvram[x]--; + } + if (svga->fullchange) + svga->fullchange--; + } + if (svga->vc == svga->vsyncstart) { + svga->dispon = 0; + svga->cgastat |= 8; + x = svga->hdisp; - if (svga->interlace && !svga->oddeven) - svga->lastline++; - if (svga->interlace && svga->oddeven) - svga->firstline--; + if (svga->interlace && !svga->oddeven) + svga->lastline++; + if (svga->interlace && svga->oddeven) + svga->firstline--; - wx = x; + wx = x; - if (!svga->override) { - if (svga->vertical_linedbl) { - wy = (svga->lastline - svga->firstline) << 1; - svga_doblit(wx, wy, svga); - } else { - wy = svga->lastline - svga->firstline; - svga_doblit(wx, wy, svga); - } - } + if (!svga->override) { + if (svga->vertical_linedbl) { + wy = (svga->lastline - svga->firstline) << 1; + svga_doblit(wx, wy, svga); + } else { + wy = svga->lastline - svga->firstline; + svga_doblit(wx, wy, svga); + } + } - svga->firstline = 2000; - svga->lastline = 0; + svga->firstline = 2000; + svga->lastline = 0; - svga->firstline_draw = 2000; - svga->lastline_draw = 0; + svga->firstline_draw = 2000; + svga->lastline_draw = 0; - svga->oddeven ^= 1; + svga->oddeven ^= 1; - changeframecount = svga->interlace ? 3 : 2; - svga->vslines = 0; + changeframecount = svga->interlace ? 3 : 2; + svga->vslines = 0; - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); - else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); - svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + else + svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); + svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; - svga->ma = (svga->ma << 2); - svga->maback = (svga->maback << 2); - svga->ca = (svga->ca << 2); + svga->ma = (svga->ma << 2); + svga->maback = (svga->maback << 2); + svga->ca = (svga->ca << 2); - if (svga->vsync_callback) - svga->vsync_callback(svga); - } - if (svga->vc == svga->vtotal) { - svga->vc = 0; - svga->sc = 0; - svga->dispon = 1; - svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; + if (svga->vsync_callback) + svga->vsync_callback(svga); + } + if (svga->vc == svga->vtotal) { + svga->vc = 0; + svga->sc = 0; + svga->dispon = 1; + svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; - svga->scrollcache = (svga->attrregs[0x13] & 0x0f); - if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 1) - svga->scrollcache &= 0x07; - else { - svga->scrollcache++; - if (svga->scrollcache > 8) - svga->scrollcache = 0; - } - } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || - (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) - svga->scrollcache &= 0x07; - else - svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + svga->scrollcache = (svga->attrregs[0x13] & 0x0f); + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ + if (svga->seqregs[1] & 1) + svga->scrollcache &= 0x07; + else { + svga->scrollcache++; + if (svga->scrollcache > 8) + svga->scrollcache = 0; + } + } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + svga->scrollcache &= 0x07; + else + svga->scrollcache = (svga->scrollcache & 0x06) >> 1; - if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) - svga->scrollcache <<= 1; + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) + svga->scrollcache <<= 1; - svga->x_add = (overscan_x >> 1) - svga->scrollcache; + svga->x_add = (overscan_x >> 1) - svga->scrollcache; - svga->linecountff = 0; + svga->linecountff = 0; - svga->hwcursor_on = 0; - svga->hwcursor_latch = svga->hwcursor; + svga->hwcursor_on = 0; + svga->hwcursor_latch = svga->hwcursor; - svga->dac_hwcursor_on = 0; - svga->dac_hwcursor_latch = svga->dac_hwcursor; + svga->dac_hwcursor_on = 0; + svga->dac_hwcursor_latch = svga->dac_hwcursor; - svga->overlay_on = 0; - svga->overlay_latch = svga->overlay; - } - if (svga->sc == (svga->crtc[10] & 31)) - svga->con = 1; + svga->overlay_on = 0; + svga->overlay_latch = svga->overlay; + } + if (svga->sc == (svga->crtc[10] & 31)) + svga->con = 1; } } - int svga_init(const device_t *info, svga_t *svga, void *p, int memsize, - void (*recalctimings_ex)(struct svga_t *svga), - uint8_t (*video_in) (uint16_t addr, void *p), - void (*video_out)(uint16_t addr, uint8_t val, void *p), - void (*hwcursor_draw)(struct svga_t *svga, int displine), - void (*overlay_draw)(struct svga_t *svga, int displine)) + void (*recalctimings_ex)(struct svga_t *svga), + uint8_t (*video_in)(uint16_t addr, void *p), + void (*video_out)(uint16_t addr, uint8_t val, void *p), + void (*hwcursor_draw)(struct svga_t *svga, int displine), + void (*overlay_draw)(struct svga_t *svga, int displine)) { int c, d, e; svga->p = p; for (c = 0; c < 256; c++) { - e = c; - for (d = 0; d < 8; d++) { - svga_rotate[d][c] = e; - e = (e >> 1) | ((e & 1) ? 0x80 : 0); - } + e = c; + for (d = 0; d < 8; d++) { + svga_rotate[d][c] = e; + e = (e >> 1) | ((e & 1) ? 0x80 : 0); + } } svga->readmode = 0; svga->attrregs[0x11] = 0; svga->overscan_color = 0x000000; - overscan_x = 16; - overscan_y = 32; + overscan_x = 16; + overscan_y = 32; svga->x_add = 8; svga->y_add = 16; - svga->crtc[0] = 63; - svga->crtc[6] = 255; - svga->dispontime = 1000ull << 32; - svga->dispofftime = 1000ull << 32; - svga->bpp = 8; - svga->vram = calloc(memsize, 1); - svga->vram_max = memsize; + svga->crtc[0] = 63; + svga->crtc[6] = 255; + svga->dispontime = 1000ull << 32; + svga->dispofftime = 1000ull << 32; + svga->bpp = 8; + svga->vram = calloc(memsize, 1); + svga->vram_max = memsize; svga->vram_display_mask = svga->vram_mask = memsize - 1; - svga->decode_mask = 0x7fffff; - svga->changedvram = calloc(memsize >> 12, 1); - svga->recalctimings_ex = recalctimings_ex; - svga->video_in = video_in; - svga->video_out = video_out; - svga->hwcursor_draw = hwcursor_draw; - svga->overlay_draw = overlay_draw; + svga->decode_mask = 0x7fffff; + svga->changedvram = calloc(memsize >> 12, 1); + svga->recalctimings_ex = recalctimings_ex; + svga->video_in = video_in; + svga->video_out = video_out; + svga->hwcursor_draw = hwcursor_draw; + svga->overlay_draw = overlay_draw; svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = 32; svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 32; - svga->translate_address = NULL; + svga->translate_address = NULL; svga->ksc5601_english_font_type = 0; vga_on = 1; if ((info->flags & DEVICE_PCI) || (info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) { - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, - svga_read, svga_readw, svga_readl, - svga_write, svga_writew, svga_writel, - NULL, MEM_MAPPING_EXTERNAL, svga); + 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)) { - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, - svga_read, svga_readw, NULL, - svga_write, svga_writew, NULL, - NULL, MEM_MAPPING_EXTERNAL, svga); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, + svga_read, svga_readw, NULL, + svga_write, svga_writew, NULL, + NULL, MEM_MAPPING_EXTERNAL, svga); } else { - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, - svga_read, NULL, NULL, - svga_write, NULL, NULL, - NULL, MEM_MAPPING_EXTERNAL, svga); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, + svga_read, NULL, NULL, + svga_write, NULL, NULL, + NULL, MEM_MAPPING_EXTERNAL, svga); } timer_add(&svga->timer, svga_poll, svga, 1); @@ -1003,7 +988,6 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, return 0; } - void svga_close(svga_t *svga) { @@ -1011,12 +995,11 @@ svga_close(svga_t *svga) free(svga->vram); if (svga->dpms_ui) - ui_sb_set_text_w(NULL); + ui_sb_set_text_w(NULL); svga_pri = NULL; } - static uint32_t svga_decode_addr(svga_t *svga, uint32_t addr, int write) { @@ -1025,111 +1008,110 @@ svga_decode_addr(svga_t *svga, uint32_t addr, int write) addr &= 0x1ffff; switch (memory_map_mode) { - case 0: - break; - case 1: - if (addr >= 0x10000) - return 0xffffffff; - break; - case 2: - addr -= 0x10000; - if (addr >= 0x8000) - return 0xffffffff; - break; - default: - case 3: - addr -= 0x18000; - if (addr >= 0x8000) - return 0xffffffff; - break; + case 0: + break; + case 1: + if (addr >= 0x10000) + return 0xffffffff; + break; + case 2: + addr -= 0x10000; + if (addr >= 0x8000) + return 0xffffffff; + break; + default: + case 3: + addr -= 0x18000; + if (addr >= 0x8000) + return 0xffffffff; + break; } if (memory_map_mode <= 1) { - if (svga->adv_flags & FLAG_EXTRA_BANKS) - addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; - else { - if (write) - addr += svga->write_bank; - else - addr += svga->read_bank; - } + if (svga->adv_flags & FLAG_EXTRA_BANKS) + addr = (addr & 0x17fff) + svga->extra_banks[(addr >> 15) & 1]; + else { + if (write) + addr += svga->write_bank; + else + addr += svga->read_bank; + } } return addr; } - static __inline void svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; - int writemask2 = svga->writemask, reset_wm = 0; + int writemask2 = svga->writemask, reset_wm = 0; latch_t vall; uint8_t wm = svga->writemask; uint8_t count, i; if (svga->adv_flags & FLAG_ADDR_BY8) - writemask2 = svga->seqregs[2]; + writemask2 = svga->seqregs[2]; cycles -= video_timing_write_b; if (!linear) { - if (xga_enabled) { - 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; - return; - } else if (val == 0x12 || val == 0x34) { - addr += svga->xga.write_bank; - svga->xga.vram[addr & svga->xga.vram_mask] = val; - svga->xga.linear_endian_reverse = 1; - return; - } - } else - svga->xga.on = 0; - } - addr = svga_decode_addr(svga, addr, 1); + if (xga_enabled) { + 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; + return; + } else if (val == 0x12 || val == 0x34) { + addr += svga->xga.write_bank; + svga->xga.vram[addr & svga->xga.vram_mask] = val; + svga->xga.linear_endian_reverse = 1; + return; + } + } else + svga->xga.on = 0; + } + addr = svga_decode_addr(svga, addr, 1); - if (addr == 0xffffffff) - return; + if (addr == 0xffffffff) + return; } if (!(svga->gdcreg[6] & 1)) - svga->fullchange = 2; + svga->fullchange = 2; - if ((svga->adv_flags & FLAG_ADDR_BY16) && (svga->writemode == 4 || svga->writemode == 5)) - addr <<= 4; + if ((svga->adv_flags & FLAG_ADDR_BY16) && (svga->writemode == 4 || svga->writemode == 5)) + addr <<= 4; else if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4)) - addr <<= 3; + addr <<= 3; else if (((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) && (svga->writemode < 4)) { - writemask2 = 1 << (addr & 3); - addr &= ~3; - } else if (svga->chain4 && (svga->writemode < 4)) { - writemask2 = 1 << (addr & 3); - if (!linear) - addr &= ~3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + writemask2 = 1 << (addr & 3); + addr &= ~3; + } else if (svga->chain4 && (svga->writemode < 4)) { + writemask2 = 1 << (addr & 3); + if (!linear) + addr &= ~3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); } else if (svga->chain2_write) { - writemask2 &= ~0xa; - if (addr & 1) - writemask2 <<= 1; - addr &= ~1; - addr <<= 2; + writemask2 &= ~0xa; + if (addr & 1) + writemask2 <<= 1; + addr &= ~1; + addr <<= 2; } else - addr <<= 2; + addr <<= 2; addr &= svga->decode_mask; if (svga->translate_address) - addr = svga->translate_address(addr, p); + addr = svga->translate_address(addr, p); if (addr >= svga->vram_max) - return; + return; addr &= svga->vram_mask; @@ -1137,611 +1119,590 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) count = 4; if (svga->adv_flags & FLAG_LATCH8) - count = 8; + count = 8; /* Undocumented Cirrus Logic behavior: The datasheet says that, with EXT_WRITE and FLAG_ADDR_BY8, the write mask only changes meaning in write modes 4 and 5, as well as write mode 1. In reality, however, all other write modes are also affected, as proven by the Windows 3.1 CL-GD 5422/4 drivers in 8bpp modes. */ switch (svga->writemode) { - case 0: - val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); - if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - for (i = 0; i < count; i++) { - if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = val; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = val; - } - } - return; - } else { - for (i = 0; i < count; i++) { - if (svga->gdcreg[1] & (1 << i)) - vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; - else - vall.b[i] = val; - } - } - break; - case 1: - for (i = 0; i < count; i++) { - if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = svga->latch.b[i]; - } - } - return; - case 2: - for (i = 0; i < count; i++) - vall.b[i] = !!(val & (1 << i)) * 0xff; + case 0: + val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); + if ((svga->gdcreg[8] == 0xff) && !(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = val; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = val; + } + } + return; + } else { + for (i = 0; i < count; i++) { + if (svga->gdcreg[1] & (1 << i)) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + else + vall.b[i] = val; + } + } + break; + case 1: + for (i = 0; i < count; i++) { + if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = svga->latch.b[i]; + } + } + return; + case 2: + for (i = 0; i < count; i++) + vall.b[i] = !!(val & (1 << i)) * 0xff; - if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { - for (i = 0; i < count; i++) { - if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } - } - return; - } - break; - case 3: - val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); - wm = svga->gdcreg[8]; - svga->gdcreg[8] &= val; + if (!(svga->gdcreg[3] & 0x18) && (!svga->gdcreg[1] || svga->set_reset_disabled)) { + for (i = 0; i < count; i++) { + if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + } + return; + } + break; + case 3: + val = ((val >> (svga->gdcreg[3] & 7)) | (val << (8 - (svga->gdcreg[3] & 7)))); + wm = svga->gdcreg[8]; + svga->gdcreg[8] &= val; - for (i = 0; i < count; i++) - vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; + for (i = 0; i < count; i++) + vall.b[i] = !!(svga->gdcreg[0] & (1 << i)) * 0xff; - reset_wm = 1; - break; - default: - if (svga->ven_write) - svga->ven_write(svga, val, addr); - return; + reset_wm = 1; + break; + default: + if (svga->ven_write) + svga->ven_write(svga, val, addr); + return; } switch (svga->gdcreg[3] & 0x18) { - case 0x00: /* Set */ - for (i = 0; i < count; i++) { - if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); - } - } - break; - case 0x08: /* AND */ - for (i = 0; i < count; i++) { - if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; - } - } - break; - case 0x10: /* OR */ - for (i = 0; i < count; i++) { - if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; - } - } - break; - case 0x18: /* XOR */ - for (i = 0; i < count; i++) { - if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { - if (writemask2 & (0x80 >> i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; - } else { - if (writemask2 & (1 << i)) - svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; - } - } - break; + case 0x00: /* Set */ + for (i = 0; i < count; i++) { + if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | (svga->latch.b[i] & ~svga->gdcreg[8]); + } + } + break; + case 0x08: /* AND */ + for (i = 0; i < count; i++) { + if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] | ~svga->gdcreg[8]) & svga->latch.b[i]; + } + } + break; + case 0x10: /* OR */ + for (i = 0; i < count; i++) { + if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) | svga->latch.b[i]; + } + } + break; + case 0x18: /* XOR */ + for (i = 0; i < count; i++) { + if ((svga->adv_flags & FLAG_EXT_WRITE) && (svga->adv_flags & FLAG_ADDR_BY8)) { + if (writemask2 & (0x80 >> i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; + } else { + if (writemask2 & (1 << i)) + svga->vram[addr | i] = (vall.b[i] & svga->gdcreg[8]) ^ svga->latch.b[i]; + } + } + break; } if (reset_wm) - svga->gdcreg[8] = wm; + svga->gdcreg[8] = wm; } - static __inline uint8_t svga_read_common(uint32_t addr, uint8_t linear, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; uint32_t latch_addr = 0; - int readplane = svga->readplane; - uint8_t count, i; - uint8_t plane, pixel; - uint8_t temp, ret; + int readplane = svga->readplane; + uint8_t count, i; + uint8_t plane, pixel; + uint8_t temp, ret; if (svga->adv_flags & FLAG_ADDR_BY8) - readplane = svga->gdcreg[4] & 7; + readplane = svga->gdcreg[4] & 7; cycles -= video_timing_read_b; if (!linear) { - if (xga_enabled) { - if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { - if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/ - svga->xga.on = 1; - return svga->xga.test; - } else if (svga->xga.test == 0x5a) { - svga->xga.on = 1; - return svga->xga.test; - } else if (addr == 0xa0000 || addr == 0xa0010) { - addr += svga->xga.read_bank; - return svga->xga.vram[addr & svga->xga.vram_mask]; - } - } else - svga->xga.on = 0; - } - addr = svga_decode_addr(svga, addr, 0); + if (xga_enabled) { + if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { + if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/ + svga->xga.on = 1; + return svga->xga.test; + } else if (svga->xga.test == 0x5a) { + svga->xga.on = 1; + return svga->xga.test; + } else if (addr == 0xa0000 || addr == 0xa0010) { + addr += svga->xga.read_bank; + return svga->xga.vram[addr & svga->xga.vram_mask]; + } + } else + svga->xga.on = 0; + } + addr = svga_decode_addr(svga, addr, 0); - if (addr == 0xffffffff) - return 0xff; + if (addr == 0xffffffff) + return 0xff; } count = 2; if (svga->adv_flags & FLAG_LATCH8) - count = 3; + count = 3; latch_addr = (addr << count) & svga->decode_mask; - count = (1 << count); + count = (1 << count); - if (svga->adv_flags & FLAG_ADDR_BY16) - addr <<= 4; + if (svga->adv_flags & FLAG_ADDR_BY16) + addr <<= 4; else if (svga->adv_flags & FLAG_ADDR_BY8) - addr <<= 3; + addr <<= 3; else if ((svga->chain4 && (svga->packed_chain4 || svga->force_old_addr)) || svga->fb_only) { - addr &= svga->decode_mask; - if (svga->translate_address) - addr = svga->translate_address(addr, p); - if (addr >= svga->vram_max) - return 0xff; - latch_addr = (addr & svga->vram_mask) & ~3; - for (i = 0; i < count; i++) - svga->latch.b[i] = svga->vram[latch_addr | i]; - return svga->vram[addr & svga->vram_mask]; - } else if (svga->chain4 && !svga->force_old_addr) { - readplane = addr & 3; - addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); + addr &= svga->decode_mask; + if (svga->translate_address) + addr = svga->translate_address(addr, p); + if (addr >= svga->vram_max) + return 0xff; + latch_addr = (addr & svga->vram_mask) & ~3; + for (i = 0; i < count; i++) + svga->latch.b[i] = svga->vram[latch_addr | i]; + return svga->vram[addr & svga->vram_mask]; + } else if (svga->chain4 && !svga->force_old_addr) { + readplane = addr & 3; + addr = ((addr & 0xfffc) << 2) | ((addr & 0x30000) >> 14) | (addr & ~0x3ffff); } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); - addr &= ~1; - addr <<= 2; + readplane = (readplane & 2) | (addr & 1); + addr &= ~1; + addr <<= 2; } else - addr <<= 2; + addr <<= 2; addr &= svga->decode_mask; if (svga->translate_address) { - latch_addr = svga->translate_address(latch_addr, p); - addr = svga->translate_address(addr, p); + latch_addr = svga->translate_address(latch_addr, p); + addr = svga->translate_address(addr, p); } /* standard VGA latched access */ if (latch_addr >= svga->vram_max) { - for (i = 0; i < count; i++) - svga->latch.b[i] = 0xff; + for (i = 0; i < count; i++) + svga->latch.b[i] = 0xff; } else { - latch_addr &= svga->vram_mask; + latch_addr &= svga->vram_mask; - for (i = 0; i < count; i++) - svga->latch.b[i] = svga->vram[latch_addr | i]; + for (i = 0; i < count; i++) + svga->latch.b[i] = svga->vram[latch_addr | i]; } if (addr >= svga->vram_max) - return 0xff; + return 0xff; addr &= svga->vram_mask; if (svga->readmode) { - temp = 0xff; + temp = 0xff; - for (pixel = 0; pixel < 8; pixel++) { - for (plane = 0; plane < count; plane++) { - if (svga->colournocare & (1 << plane)) { - /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ - if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) - temp &= ~(1 << pixel); - } - } - } + for (pixel = 0; pixel < 8; pixel++) { + for (plane = 0; plane < count; plane++) { + if (svga->colournocare & (1 << plane)) { + /* If we care about a plane, and the pixel has a mismatch on it, clear its bit. */ + if (((svga->latch.b[plane] >> pixel) & 1) != ((svga->colourcompare >> plane) & 1)) + temp &= ~(1 << pixel); + } + } + } - ret = temp; + ret = temp; } else - ret = svga->vram[addr | readplane]; + ret = svga->vram[addr | readplane]; return ret; } - void svga_write(uint32_t addr, uint8_t val, void *p) { svga_write_common(addr, val, 0, p); } - void svga_write_linear(uint32_t addr, uint8_t val, void *p) { svga_write_common(addr, val, 1, p); } - uint8_t svga_read(uint32_t addr, void *p) { return svga_read_common(addr, 0, p); } - uint8_t svga_read_linear(uint32_t addr, void *p) { return svga_read_common(addr, 1, p); } - void svga_doblit(int wx, int wy, svga_t *svga) { - int y_add, x_add, y_start, x_start, bottom; + int y_add, x_add, y_start, x_start, bottom; uint32_t *p; - int i, j; - int xs_temp, ys_temp; + int i, j; + int xs_temp, ys_temp; - y_add = (enable_overscan) ? overscan_y : 0; - x_add = (enable_overscan) ? overscan_x : 0; + y_add = (enable_overscan) ? overscan_y : 0; + x_add = (enable_overscan) ? overscan_x : 0; y_start = (enable_overscan) ? 0 : (overscan_y >> 1); x_start = (enable_overscan) ? 0 : (overscan_x >> 1); - bottom = (overscan_y >> 1) + (svga->crtc[8] & 0x1f); + bottom = (overscan_y >> 1) + (svga->crtc[8] & 0x1f); if (svga->vertical_linedbl) { - y_add <<= 1; - y_start <<= 1; - bottom <<= 1; + y_add <<= 1; + y_start <<= 1; + bottom <<= 1; } if ((wx <= 0) || (wy <= 0)) - return; + return; if (svga->vertical_linedbl) - svga->y_add <<= 1; + svga->y_add <<= 1; xs_temp = wx; ys_temp = wy + 1; if (svga->vertical_linedbl) - ys_temp++; + ys_temp++; if (xs_temp < 64) - xs_temp = 640; + xs_temp = 640; if (ys_temp < 32) - ys_temp = 200; + ys_temp = 200; if ((svga->crtc[0x17] & 0x80) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) { - /* Screen res has changed.. fix up, and let them know. */ - xsize = xs_temp; - ysize = ys_temp; + /* Screen res has changed.. fix up, and let them know. */ + xsize = xs_temp; + ysize = ys_temp; - if ((xsize > 1984) || (ysize > 2016)) { - /* 2048x2048 is the biggest safe render texture, to account for overscan, - we suppress overscan starting from x 1984 and y 2016. */ - x_add = 0; - y_add = 0; - suppress_overscan = 1; - } else - suppress_overscan = 0; + if ((xsize > 1984) || (ysize > 2016)) { + /* 2048x2048 is the biggest safe render texture, to account for overscan, + we suppress overscan starting from x 1984 and y 2016. */ + x_add = 0; + y_add = 0; + suppress_overscan = 1; + } else + suppress_overscan = 0; - /* Block resolution changes while in DPMS mode to avoid getting a bogus - screen width (320). We're already rendering a blank screen anyway. */ - if (!svga->dpms) - set_screen_size(xsize + x_add, ysize + y_add); + /* Block resolution changes while in DPMS mode to avoid getting a bogus + screen width (320). We're already rendering a blank screen anyway. */ + if (!svga->dpms) + set_screen_size(xsize + x_add, ysize + y_add); - if (video_force_resize_get()) - video_force_resize_set(0); + if (video_force_resize_get()) + video_force_resize_set(0); } if ((wx >= 160) && ((wy + 1) >= 120)) { - /* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */ - for (i = 0; i < svga->y_add; i++) { - p = &buffer32->line[i & 0x7ff][0]; + /* Draw (overscan_size - scroll size) lines of overscan on top and bottom. */ + for (i = 0; i < svga->y_add; i++) { + p = &buffer32->line[i & 0x7ff][0]; - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga->overscan_color; - } + for (j = 0; j < (xsize + x_add); j++) + p[j] = svga->overscan_color; + } - for (i = 0; i < bottom; i++) { - p = &buffer32->line[(ysize + svga->y_add + i) & 0x7ff][0]; + for (i = 0; i < bottom; i++) { + p = &buffer32->line[(ysize + svga->y_add + i) & 0x7ff][0]; - for (j = 0; j < (xsize + x_add); j++) - p[j] = svga->overscan_color; - } + for (j = 0; j < (xsize + x_add); j++) + p[j] = svga->overscan_color; + } } video_blit_memtoscreen(x_start, y_start, xsize + x_add, ysize + y_add); if (svga->vertical_linedbl) - svga->vertical_linedbl >>= 1; + svga->vertical_linedbl >>= 1; } - void svga_writeb_linear(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; if (!svga->fast) { - svga_write_linear(addr, val, p); - return; + svga_write_linear(addr, val, p); + return; } addr &= svga->decode_mask; if (addr >= svga->vram_max) - return; + return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint8_t *)&svga->vram[addr] = val; + svga->changedvram[addr >> 12] = changeframecount; + *(uint8_t *) &svga->vram[addr] = val; } - void svga_writew_common(uint32_t addr, uint16_t val, uint8_t linear, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; if (!svga->fast) { - svga_write_common(addr, val, linear, p); - svga_write_common(addr + 1, val >> 8, linear, p); - return; + svga_write_common(addr, val, linear, p); + svga_write_common(addr + 1, val >> 8, linear, p); + return; } cycles -= video_timing_write_w; if (!linear) { - addr = svga_decode_addr(svga, addr, 1); + addr = svga_decode_addr(svga, addr, 1); - if (addr == 0xffffffff) - return; + if (addr == 0xffffffff) + return; } addr &= svga->decode_mask; - if(svga->translate_address) { - uint32_t addr2 = svga->translate_address(addr, p); - if (addr2 < svga->vram_max) { - svga->vram[addr2 & svga->vram_mask] = val & 0xff; - svga->changedvram[addr2 >> 12] = changeframecount; - } - addr2 = svga->translate_address(addr+1, p); - if (addr2 < svga->vram_max) { - svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; - svga->changedvram[addr2 >> 12] = changeframecount; - } - return; + if (svga->translate_address) { + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = val & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr + 1, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + return; } if (addr >= svga->vram_max) - return; + return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr] = val; + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *) &svga->vram[addr] = val; } - void svga_writew(uint32_t addr, uint16_t val, void *p) { svga_writew_common(addr, val, 0, p); } - void svga_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_writew_common(addr, val, 1, p); } - void svga_writel_common(uint32_t addr, uint32_t val, uint8_t linear, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; if (!svga->fast) { - svga_write_common(addr, val, linear, p); - svga_write_common(addr + 1, val >> 8, linear, p); - svga_write_common(addr + 2, val >> 16, linear, p); - svga_write_common(addr + 3, val >> 24, linear, p); - return; + svga_write_common(addr, val, linear, p); + svga_write_common(addr + 1, val >> 8, linear, p); + svga_write_common(addr + 2, val >> 16, linear, p); + svga_write_common(addr + 3, val >> 24, linear, p); + return; } cycles -= video_timing_write_l; if (!linear) { - addr = svga_decode_addr(svga, addr, 1); + addr = svga_decode_addr(svga, addr, 1); - if (addr == 0xffffffff) - return; + if (addr == 0xffffffff) + return; } addr &= svga->decode_mask; if (svga->translate_address) { - uint32_t addr2 = svga->translate_address(addr, p); - if (addr2 < svga->vram_max) { - svga->vram[addr2 & svga->vram_mask] = val & 0xff; - svga->changedvram[addr2 >> 12] = changeframecount; - } - addr2 = svga->translate_address(addr+1, p); - if (addr2 < svga->vram_max) { - svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; - svga->changedvram[addr2 >> 12] = changeframecount; - } - addr2 = svga->translate_address(addr+2, p); - if (addr2 < svga->vram_max) { - svga->vram[addr2 & svga->vram_mask] = (val >> 16) & 0xff; - svga->changedvram[addr2 >> 12] = changeframecount; - } - addr2 = svga->translate_address(addr+3, p); - if (addr2 < svga->vram_max) { - svga->vram[addr2 & svga->vram_mask] = (val >> 24) & 0xff; - svga->changedvram[addr2 >> 12] = changeframecount; - } - return; + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = val & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr + 1, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 8) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr + 2, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 16) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + addr2 = svga->translate_address(addr + 3, p); + if (addr2 < svga->vram_max) { + svga->vram[addr2 & svga->vram_mask] = (val >> 24) & 0xff; + svga->changedvram[addr2 >> 12] = changeframecount; + } + return; } if (addr >= svga->vram_max) - return; + return; addr &= svga->vram_mask; - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr] = val; + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *) &svga->vram[addr] = val; } - void svga_writel(uint32_t addr, uint32_t val, void *p) { svga_writel_common(addr, val, 0, p); } - void svga_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_writel_common(addr, val, 1, p); } - uint8_t svga_readb_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; if (!svga->fast) - return svga_read_linear(addr, p); + return svga_read_linear(addr, p); addr &= svga->decode_mask; if (addr >= svga->vram_max) - return 0xff; + return 0xff; - return *(uint8_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint8_t *) &svga->vram[addr & svga->vram_mask]; } - uint16_t svga_readw_common(uint32_t addr, uint8_t linear, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; if (!svga->fast) - return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8); + return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8); cycles -= video_timing_read_w; if (!linear) { - addr = svga_decode_addr(svga, addr, 0); + addr = svga_decode_addr(svga, addr, 0); - if (addr == 0xffffffff) - return 0xffff; + if (addr == 0xffffffff) + return 0xffff; } addr &= svga->decode_mask; if (svga->translate_address) { - uint8_t val1 = 0xff, val2 = 0xff; - uint32_t addr2 = svga->translate_address(addr, p); - if (addr2 < svga->vram_max) - val1 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr+1, p); - if (addr2 < svga->vram_max) - val2 = svga->vram[addr2 & svga->vram_mask]; - return (val2 << 8) | val1; + uint8_t val1 = 0xff, val2 = 0xff; + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) + val1 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr + 1, p); + if (addr2 < svga->vram_max) + val2 = svga->vram[addr2 & svga->vram_mask]; + return (val2 << 8) | val1; } if (addr >= svga->vram_max) - return 0xffff; + return 0xffff; - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint16_t *) &svga->vram[addr & svga->vram_mask]; } - uint16_t svga_readw(uint32_t addr, void *p) { return svga_readw_common(addr, 0, p); } - uint16_t svga_readw_linear(uint32_t addr, void *p) { return svga_readw_common(addr, 1, p); } - uint32_t svga_readl_common(uint32_t addr, uint8_t linear, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; if (!svga->fast) { - return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8) | - (svga_read_common(addr + 2, linear, p) << 16) | (svga_read_common(addr + 3, linear, p) << 24); + return svga_read_common(addr, linear, p) | (svga_read_common(addr + 1, linear, p) << 8) | (svga_read_common(addr + 2, linear, p) << 16) | (svga_read_common(addr + 3, linear, p) << 24); } cycles -= video_timing_read_l; if (!linear) { - addr = svga_decode_addr(svga, addr, 0); + addr = svga_decode_addr(svga, addr, 0); - if (addr == 0xffffffff) - return 0xffffffff; + if (addr == 0xffffffff) + return 0xffffffff; } addr &= svga->decode_mask; if (svga->translate_address) { - uint8_t val1 = 0xff, val2 = 0xff, val3 = 0xff, val4 = 0xff; - uint32_t addr2 = svga->translate_address(addr, p); - if (addr2 < svga->vram_max) - val1 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr+1, p); - if (addr2 < svga->vram_max) - val2 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr+2, p); - if (addr2 < svga->vram_max) - val3 = svga->vram[addr2 & svga->vram_mask]; - addr2 = svga->translate_address(addr+3, p); - if (addr2 < svga->vram_max) - val4 = svga->vram[addr2 & svga->vram_mask]; - return (val4 << 24) | (val3 << 16) | (val2 << 8) | val1; + uint8_t val1 = 0xff, val2 = 0xff, val3 = 0xff, val4 = 0xff; + uint32_t addr2 = svga->translate_address(addr, p); + if (addr2 < svga->vram_max) + val1 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr + 1, p); + if (addr2 < svga->vram_max) + val2 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr + 2, p); + if (addr2 < svga->vram_max) + val3 = svga->vram[addr2 & svga->vram_mask]; + addr2 = svga->translate_address(addr + 3, p); + if (addr2 < svga->vram_max) + val4 = svga->vram[addr2 & svga->vram_mask]; + return (val4 << 24) | (val3 << 16) | (val2 << 8) | val1; } if (addr >= svga->vram_max) - return 0xffffffff; + return 0xffffffff; - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; + return *(uint32_t *) &svga->vram[addr & svga->vram_mask]; } - uint32_t svga_readl(uint32_t addr, void *p) { return svga_readl_common(addr, 0, p); } - uint32_t svga_readl_linear(uint32_t addr, void *p) { diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 3a8c4b10a..30d2c93b0 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -33,10 +33,10 @@ void svga_render_null(svga_t *svga) { if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; + svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; } @@ -67,12 +67,11 @@ svga_render_blank(svga_t *svga) break; } - uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - uint32_t line_width = (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); + uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + uint32_t line_width = (svga->hdisp + svga->scrollcache) * char_width * sizeof(uint32_t); memset(line_ptr, 0, line_width); } - void svga_render_overscan_left(svga_t *svga) { @@ -89,7 +88,6 @@ svga_render_overscan_left(svga_t *svga) *line_ptr++ = svga->overscan_color; } - void svga_render_overscan_right(svga_t *svga) { @@ -102,153 +100,155 @@ svga_render_overscan_right(svga_t *svga) return; uint32_t *line_ptr = &buffer32->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp]; - right = (overscan_x >> 1); + right = (overscan_x >> 1); for (i = 0; i < right; i++) *line_ptr++ = svga->overscan_color; } - void svga_render_text_40(svga_t *svga) { uint32_t *p; - int x, xx; - int drawcursor, xinc; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - uint32_t addr = 0; + int x, xx; + int drawcursor, xinc; + uint8_t chr, attr, dat; + uint32_t charaddr; + int fg, bg; + uint32_t addr = 0; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; + svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; if (svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - xinc = (svga->seqregs[1] & 1) ? 16 : 18; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + xinc = (svga->seqregs[1] & 1) ? 16 : 18; - for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - if (!svga->force_old_addr) - addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { + if (!svga->force_old_addr) + addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - if (svga->force_old_addr) { - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - } else { - chr = svga->vram[addr]; - attr = svga->vram[addr+1]; - } + if (svga->force_old_addr) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else { + chr = svga->vram[addr]; + attr = svga->vram[addr + 1]; + } - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); + if (attr & 8) + charaddr = svga->charsetb + (chr * 128); + else + charaddr = svga->charseta + (chr * 128); - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - } else { - for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(svga->attrregs[0x10] & 4)) - p[16] = p[17] = bg; - else - p[16] = p[17] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; + dat = svga->vram[charaddr + (svga->sc << 2)]; + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 16; xx += 2) + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + } else { + for (xx = 0; xx < 16; xx += 2) + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(svga->attrregs[0x10] & 4)) + p[16] = p[17] = bg; + else + p[16] = p[17] = (dat & 1) ? fg : bg; + } + svga->ma += 4; + p += xinc; + } + svga->ma &= svga->vram_display_mask; } } - void svga_render_text_80(svga_t *svga) { uint32_t *p; - int x, xx; - int drawcursor, xinc; - uint8_t chr, attr, dat; - uint32_t charaddr; - int fg, bg; - uint32_t addr = 0; + int x, xx; + int drawcursor, xinc; + uint8_t chr, attr, dat; + uint32_t charaddr; + int fg, bg; + uint32_t addr = 0; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; + svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; if (svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - xinc = (svga->seqregs[1] & 1) ? 8 : 9; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - if (!svga->force_old_addr) - addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { + if (!svga->force_old_addr) + addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - if (svga->force_old_addr) { - chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - } else { - chr = svga->vram[addr]; - attr = svga->vram[addr+1]; - } + if (svga->force_old_addr) { + chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + } else { + chr = svga->vram[addr]; + attr = svga->vram[addr + 1]; + } - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); + if (attr & 8) + charaddr = svga->charsetb + (chr * 128); + else + charaddr = svga->charseta + (chr * 128); - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - dat = svga->vram[charaddr + (svga->sc << 2)]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; - } - svga->ma &= svga->vram_display_mask; + dat = svga->vram[charaddr + (svga->sc << 2)]; + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } + svga->ma += 4; + p += xinc; + } + svga->ma &= svga->vram_display_mask; } } @@ -257,1607 +257,1590 @@ void svga_render_text_80_ksc5601(svga_t *svga) { uint32_t *p; - int x, xx; - int drawcursor, xinc; - uint8_t chr, attr, dat, nextchr; - uint32_t charaddr; - int fg, bg; + int x, xx; + int drawcursor, xinc; + uint8_t chr, attr, dat, nextchr; + uint32_t charaddr; + int fg, bg; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; + svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; if (svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - xinc = (svga->seqregs[1] & 1) ? 8 : 9; + xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { - uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; - drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); - chr = svga->vram[addr]; - nextchr = svga->vram[addr + 8]; - attr = svga->vram[addr + 1]; + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { + uint32_t addr = svga->remap_func(svga, svga->ma) & svga->vram_display_mask; + drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); + chr = svga->vram[addr]; + nextchr = svga->vram[addr + 8]; + attr = svga->vram[addr + 1]; - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - if ((x + xinc) < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { - if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; - else if (nextchr & 0x80) { - if (svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff)) { - if(chr >= 0x80 && chr < 0x99) chr += 0x30; - else if(chr >= 0xB0 && chr < 0xC9) chr -= 0x30; - } - dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; - } else - dat = 0xff; - } else { - if (attr & 8) charaddr = svga->charsetb + (chr * 128); - else charaddr = svga->charseta + (chr * 128); + if ((x + xinc) < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { + if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc]; + else if (nextchr & 0x80) { + if (svga->ksc5601_swap_mode == 1 && (nextchr > 0xa0 && nextchr < 0xff)) { + if (chr >= 0x80 && chr < 0x99) + chr += 0x30; + else if (chr >= 0xB0 && chr < 0xC9) + chr -= 0x30; + } + dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc]; + } else + dat = 0xff; + } else { + if (attr & 8) + charaddr = svga->charsetb + (chr * 128); + else + charaddr = svga->charseta + (chr * 128); - if ((svga->ksc5601_english_font_type >> 8) == 1) - dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)].chr[((chr & 1) << 4) | svga->sc]; - else - dat = svga->vram[charaddr + (svga->sc << 2)]; - } + if ((svga->ksc5601_english_font_type >> 8) == 1) + dat = fontdatksc5601[((svga->ksc5601_english_font_type & 0x7F) << 7) | (chr >> 1)].chr[((chr & 1) << 4) | svga->sc]; + else + dat = svga->vram[charaddr + (svga->sc << 2)]; + } - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if (((chr & ~0x1f) != 0xc0) || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } - svga->ma += 4; - p += xinc; + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if (((chr & ~0x1f) != 0xc0) || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } + svga->ma += 4; + p += xinc; - if ((x + xinc) < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { - attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; + if ((x + xinc) < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) { + attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; - if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15]]; - fg = svga->pallook[svga->egapal[attr >> 4]]; - } else { - fg = svga->pallook[svga->egapal[attr & 15]]; - bg = svga->pallook[svga->egapal[attr >> 4]]; - if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; - if (svga->blink & 16) - fg = bg; - } - } + if (drawcursor) { + bg = svga->pallook[svga->egapal[attr & 15]]; + fg = svga->pallook[svga->egapal[attr >> 4]]; + } else { + fg = svga->pallook[svga->egapal[attr & 15]]; + bg = svga->pallook[svga->egapal[attr >> 4]]; + if (attr & 0x80 && svga->attrregs[0x10] & 8) { + bg = svga->pallook[svga->egapal[(attr >> 4) & 7]]; + if (svga->blink & 16) + fg = bg; + } + } - if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) - dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; - else if(nextchr & 0x80) - dat = fontdatksc5601[((chr & 0x7f) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; - else - dat = 0xff; + if ((chr == svga->ksc5601_udc_area_msb[0] || chr == svga->ksc5601_udc_area_msb[1]) && (nextchr > 0xa0 && nextchr < 0xff)) + dat = fontdatksc5601_user[(chr == svga->ksc5601_udc_area_msb[1] ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16]; + else if (nextchr & 0x80) + dat = fontdatksc5601[((chr & 0x7f) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16]; + else + dat = 0xff; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if (((chr & ~0x1f) != 0xc0) || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; - } + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if (((chr & ~0x1f) != 0xc0) || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } - svga->ma += 4; - p += xinc; - x += xinc; - } - } - svga->ma &= svga->vram_display_mask; + svga->ma += 4; + p += xinc; + x += xinc; + } + } + svga->ma &= svga->vram_display_mask; } } - void svga_render_2bpp_lowres(svga_t *svga) { - int changed_offset; - int x; - uint8_t dat[2]; + int changed_offset; + int x; + uint8_t dat[2]; uint32_t addr, *p; - uint32_t changed_addr; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->force_old_addr) { - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->ma; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->ma; - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; - addr &= ~7; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; + addr &= ~7; - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; - } + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; - svga->ma &= svga->vram_mask; - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; - p += 16; - } - } + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + svga->ma &= svga->vram_mask; + p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + p += 16; + } + } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->remap_func(svga, svga->ma); - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; - svga->ma &= svga->vram_mask; + svga->ma &= svga->vram_mask; - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; + p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3]]; - p += 16; - } - } + p += 16; + } + } } } - void svga_render_2bpp_highres(svga_t *svga) { - int changed_offset; - int x; - uint8_t dat[2]; + int changed_offset; + int x; + uint8_t dat[2]; uint32_t addr, *p; - uint32_t changed_addr; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->force_old_addr) { - changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + changed_offset = ((svga->ma << 1) + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->ma; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->ma; - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; - addr &= ~7; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; + addr &= ~7; - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; - } + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; - svga->ma &= svga->vram_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; - p += 8; - } - } + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; + svga->ma &= svga->vram_mask; + p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + p += 8; + } + } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); - dat[0] = svga->vram[addr]; - dat[1] = svga->vram[addr | 0x1]; - if (svga->seqregs[1] & 4) - svga->ma += 2; - else - svga->ma += 4; + dat[0] = svga->vram[addr]; + dat[1] = svga->vram[addr | 0x1]; + if (svga->seqregs[1] & 4) + svga->ma += 2; + else + svga->ma += 4; - svga->ma &= svga->vram_mask; + svga->ma &= svga->vram_mask; - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; + p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3]]; + p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3]]; + p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3]]; + p[3] = svga->pallook[svga->egapal[dat[0] & 3]]; + p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3]]; + p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3]]; + p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3]]; + p[7] = svga->pallook[svga->egapal[dat[1] & 3]]; - p += 8; - } - } + p += 8; + } + } } } - void svga_render_2bpp_headland_highres(svga_t *svga) { - int x; - int oddeven; + int x; + int oddeven; uint32_t addr, *p; - uint8_t edat[4]; - uint8_t dat; - uint32_t changed_addr; + uint8_t edat[4]; + uint8_t dat; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) - return; + return; changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + oddeven = 0; - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - } - svga->ma += 4; - svga->ma &= svga->vram_mask; + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + } else { + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); + } + svga->ma += 4; + svga->ma &= svga->vram_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - p += 8; - } + p += 8; + } } } void svga_render_4bpp_lowres(svga_t *svga) { - int x, oddeven; + int x, oddeven; uint32_t addr, *p; - uint8_t edat[4]; - uint8_t dat; - uint32_t changed_addr; + uint8_t edat[4]; + uint8_t dat; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->ma; - oddeven = 0; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->ma; + oddeven = 0; - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; - if (svga->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; + if (svga->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; - addr &= ~7; + addr &= ~7; - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; - } + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); - if (svga->seqregs[1] & 4) { - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; - } - svga->ma &= svga->vram_mask; + if (svga->seqregs[1] & 4) { + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - p += 16; - } - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + p += 16; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { + addr = svga->remap_func(svga, svga->ma); + oddeven = 0; - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; - } - svga->ma &= svga->vram_mask; + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - p += 16; - } - } - } + p += 16; + } + } + } } - void svga_render_4bpp_highres(svga_t *svga) { - int changed_offset; - int x, oddeven; + int changed_offset; + int x, oddeven; uint32_t addr, *p; - uint8_t edat[4]; - uint8_t dat; - uint32_t changed_addr; + uint8_t edat[4]; + uint8_t dat; + uint32_t changed_addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; + if (svga->force_old_addr) { + changed_offset = (svga->ma + (svga->sc & ~svga->crtc[0x17] & 3) * 0x8000) >> 12; - if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->ma; - oddeven = 0; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->ma; + oddeven = 0; - if (!(svga->crtc[0x17] & 0x40)) { - addr = (addr << 1) & svga->vram_mask; + if (!(svga->crtc[0x17] & 0x40)) { + addr = (addr << 1) & svga->vram_mask; - if (svga->seqregs[1] & 4) - oddeven = (addr & 4) ? 1 : 0; + if (svga->seqregs[1] & 4) + oddeven = (addr & 4) ? 1 : 0; - addr &= ~7; + addr &= ~7; - if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) - addr |= 4; - if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) - addr |= 4; - } + if ((svga->crtc[0x17] & 0x20) && (svga->ma & 0x20000)) + addr |= 4; + if (!(svga->crtc[0x17] & 0x20) && (svga->ma & 0x8000)) + addr |= 4; + } - if (!(svga->crtc[0x17] & 0x01)) - addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); - if (!(svga->crtc[0x17] & 0x02)) - addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); + if (!(svga->crtc[0x17] & 0x01)) + addr = (addr & ~0x8000) | ((svga->sc & 1) ? 0x8000 : 0); + if (!(svga->crtc[0x17] & 0x02)) + addr = (addr & ~0x10000) | ((svga->sc & 2) ? 0x10000 : 0); - if (svga->seqregs[1] & 4) { - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; - } - svga->ma &= svga->vram_mask; + if (svga->seqregs[1] & 4) { + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - p += 8; - } - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + p += 8; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - oddeven = 0; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + oddeven = 0; - if (svga->seqregs[1] & 4) { - oddeven = (addr & 4) ? 1 : 0; - edat[0] = svga->vram[addr | oddeven]; - edat[2] = svga->vram[addr | oddeven | 0x2]; - edat[1] = edat[3] = 0; - svga->ma += 2; - } else { - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[addr]); - svga->ma += 4; - } - svga->ma &= svga->vram_mask; + if (svga->seqregs[1] & 4) { + oddeven = (addr & 4) ? 1 : 0; + edat[0] = svga->vram[addr | oddeven]; + edat[2] = svga->vram[addr | oddeven | 0x2]; + edat[1] = edat[3] = 0; + svga->ma += 2; + } else { + *(uint32_t *) (&edat[0]) = *(uint32_t *) (&svga->vram[addr]); + svga->ma += 4; + } + svga->ma &= svga->vram_mask; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask]]; + p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask]]; - p += 8; - } - } - } + p += 8; + } + } + } } - void svga_render_8bpp_lowres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr; - uint32_t addr; + uint32_t dat; + uint32_t changed_addr; + uint32_t addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = p[1] = svga->map8[dat & 0xff]; - p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 4; - p += 8; - } - svga->ma &= svga->vram_display_mask; - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + svga->ma += 4; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = p[1] = svga->map8[dat & 0xff]; - p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 4; - p += 8; - } - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = svga->map8[dat & 0xff]; - p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; - p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; - p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; + svga->ma += 4; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + p[0] = p[1] = svga->map8[dat & 0xff]; + p[2] = p[3] = svga->map8[(dat >> 8) & 0xff]; + p[4] = p[5] = svga->map8[(dat >> 16) & 0xff]; + p[6] = p[7] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 4; - p += 8; - } - } - svga->ma &= svga->vram_display_mask; - } - } + svga->ma += 4; + p += 8; + } + } + svga->ma &= svga->vram_display_mask; + } + } } - void svga_render_8bpp_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr; - uint32_t addr; + uint32_t dat; + uint32_t changed_addr; + uint32_t addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 8; - p += 8; - } - svga->ma &= svga->vram_display_mask; - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + svga->ma += 8; + p += 8; + } + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - p[4] = svga->map8[dat & 0xff]; - p[5] = svga->map8[(dat >> 8) & 0xff]; - p[6] = svga->map8[(dat >> 16) & 0xff]; - p[7] = svga->map8[(dat >> 24) & 0xff]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + p[4] = svga->map8[dat & 0xff]; + p[5] = svga->map8[(dat >> 8) & 0xff]; + p[6] = svga->map8[(dat >> 16) & 0xff]; + p[7] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 8; - p += 8; - } - } else { - for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 4) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - p[0] = svga->map8[dat & 0xff]; - p[1] = svga->map8[(dat >> 8) & 0xff]; - p[2] = svga->map8[(dat >> 16) & 0xff]; - p[3] = svga->map8[(dat >> 24) & 0xff]; + svga->ma += 8; + p += 8; + } + } else { + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + p[0] = svga->map8[dat & 0xff]; + p[1] = svga->map8[(dat >> 8) & 0xff]; + p[2] = svga->map8[(dat >> 16) & 0xff]; + p[3] = svga->map8[(dat >> 24) & 0xff]; - svga->ma += 4; - p += 4; - } - } - svga->ma &= svga->vram_display_mask; - } - } + svga->ma += 4; + p += 4; + } + } + svga->ma &= svga->vram_display_mask; + } + } } void svga_render_8bpp_tseng_lowres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; + uint32_t dat; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[0] = p[1] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[2] = p[3] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[4] = p[5] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[6] = p[7] = svga->map8[dat & 0xff]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[0] = p[1] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[2] = p[3] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[4] = p[5] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[6] = p[7] = svga->map8[dat & 0xff]; - svga->ma += 4; - p += 8; - } - svga->ma &= svga->vram_display_mask; + svga->ma += 4; + p += 8; + } + svga->ma &= svga->vram_display_mask; } } - void svga_render_8bpp_tseng_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; + uint32_t dat; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[0] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[1] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[2] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[3] = svga->map8[dat & 0xff]; + for (x = 0; x <= (svga->hdisp /* + svga->scrollcache*/); x += 8) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[0] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[1] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[2] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[3] = svga->map8[dat & 0xff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[4] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[5] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[6] = svga->map8[dat & 0xff]; - dat >>= 8; - if (svga->attrregs[0x10] & 0x80) - dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); - p[7] = svga->map8[dat & 0xff]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[4] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[5] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[6] = svga->map8[dat & 0xff]; + dat >>= 8; + if (svga->attrregs[0x10] & 0x80) + dat = (dat & ~0xf0) | ((svga->attrregs[0x14] & 0x0f) << 4); + p[7] = svga->map8[dat & 0xff]; - svga->ma += 8; - p += 8; - } - svga->ma &= svga->vram_display_mask; + svga->ma += 8; + p += 8; + } + svga->ma &= svga->vram_display_mask; } } - void svga_render_15bpp_lowres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; + p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } + p[(x << 1) + 4] = p[(x << 1) + 5] = video_15to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_15to32[dat >> 16]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } } } - void svga_render_15bpp_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = video_15to32[dat & 0xffff]; + p[x + 1] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = video_15to32[dat & 0xffff]; + p[x + 3] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = video_15to32[dat & 0xffff]; + p[x + 5] = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = video_15to32[dat & 0xffff]; + p[x + 7] = video_15to32[dat >> 16]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } } else { - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_15to32[dat & 0xffff]; - *p++ = video_15to32[dat >> 16]; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } + *p++ = video_15to32[dat & 0xffff]; + *p++ = video_15to32[dat >> 16]; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } } } - void svga_render_15bpp_mix_lowres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; + uint32_t dat; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[(x << 1)] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[(x << 1)] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[(x << 1) + 2] = p[(x << 1) + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[(x << 1) + 4] = p[(x << 1) + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; + dat >>= 16; + p[(x << 1) + 6] = p[(x << 1) + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; } } - void svga_render_15bpp_mix_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; + uint32_t dat; if ((svga->displine + svga->y_add) < 0) - return; + return; if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 3] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 5] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - dat >>= 16; - p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + dat >>= 16; + p[x + 7] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; } } - void svga_render_16bpp_lowres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; - p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; + p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; - p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[(x << 1) + 4] = p[(x << 1) + 5] = video_16to32[dat & 0xffff]; + p[(x << 1) + 6] = p[(x << 1) + 7] = video_16to32[dat >> 16]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } - svga->ma += 4; - } - svga->ma &= svga->vram_display_mask; - } - } + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + svga->ma += 4; + } + svga->ma &= svga->vram_display_mask; + } + } } - void svga_render_16bpp_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + uint32_t dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + p[x] = video_16to32[dat & 0xffff]; + p[x + 1] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + p[x + 2] = video_16to32[dat & 0xffff]; + p[x + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + p[x + 4] = video_16to32[dat & 0xffff]; + p[x + 5] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; - } - svga->ma += x << 1; - svga->ma &= svga->vram_display_mask; + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + p[x + 6] = video_16to32[dat & 0xffff]; + p[x + 7] = video_16to32[dat >> 16]; + } + svga->ma += x << 1; + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); + + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + } + svga->ma += x << 1; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + + *p++ = video_16to32[dat & 0xffff]; + *p++ = video_16to32[dat >> 16]; + + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } } - } else { - changed_addr = svga->remap_func(svga, svga->ma); - - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 4) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 8) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1) + 12) & svga->vram_display_mask]); - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - } - svga->ma += x << 1; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 2) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - - *p++ = video_16to32[dat & 0xffff]; - *p++ = video_16to32[dat >> 16]; - - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } - } } - void svga_render_24bpp_lowres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t changed_addr, addr; - uint32_t dat0, dat1, dat2; - uint32_t fg; + uint32_t changed_addr, addr; + uint32_t dat0, dat1, dat2; + uint32_t fg; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if ((svga->displine + svga->y_add) < 0) - return; + if (svga->force_old_addr) { + if ((svga->displine + svga->y_add) < 0) + return; - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 3; - svga->ma &= svga->vram_display_mask; - buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = - buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; - } - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + svga->ma += 3; + svga->ma &= svga->vram_display_mask; + buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = fg; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat0 = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; - svga->ma += 12; - } - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - addr = svga->remap_func(svga, svga->ma); - dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); - dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); - dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + svga->ma += 12; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - p[0] = p[1] = dat0 & 0xffffff; - p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); - p[6] = p[7] = dat2 >> 8; + p[0] = p[1] = dat0 & 0xffffff; + p[2] = p[3] = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + p[4] = p[5] = (dat1 >> 16) | ((dat2 & 0xff) << 16); + p[6] = p[7] = dat2 >> 8; - svga->ma += 12; - } - } - svga->ma &= svga->vram_display_mask; - } - } + svga->ma += 12; + } + } + svga->ma &= svga->vram_display_mask; + } + } } - void svga_render_24bpp_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t changed_addr, addr; - uint32_t dat0, dat1, dat2; - uint32_t dat; + uint32_t changed_addr, addr; + uint32_t dat0, dat1, dat2; + uint32_t dat; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - p[x] = dat & 0xffffff; + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + dat = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + p[x] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); - p[x + 1] = dat & 0xffffff; + dat = *(uint32_t *) (&svga->vram[(svga->ma + 3) & svga->vram_display_mask]); + p[x + 1] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); - p[x + 2] = dat & 0xffffff; + dat = *(uint32_t *) (&svga->vram[(svga->ma + 6) & svga->vram_display_mask]); + p[x + 2] = dat & 0xffffff; - dat = *(uint32_t *)(&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); - p[x + 3] = dat & 0xffffff; + dat = *(uint32_t *) (&svga->vram[(svga->ma + 9) & svga->vram_display_mask]); + p[x + 3] = dat & 0xffffff; - svga->ma += 12; - } - svga->ma &= svga->vram_display_mask; - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + svga->ma += 12; + } + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - dat0 = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); - dat1 = *(uint32_t *)(&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); - dat2 = *(uint32_t *)(&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + dat0 = *(uint32_t *) (&svga->vram[svga->ma & svga->vram_display_mask]); + dat1 = *(uint32_t *) (&svga->vram[(svga->ma + 4) & svga->vram_display_mask]); + dat2 = *(uint32_t *) (&svga->vram[(svga->ma + 8) & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; - svga->ma += 12; - } - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { - addr = svga->remap_func(svga, svga->ma); - dat0 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 4); - dat1 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - addr = svga->remap_func(svga, svga->ma + 8); - dat2 = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); + svga->ma += 12; + } + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { + addr = svga->remap_func(svga, svga->ma); + dat0 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 4); + dat1 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + addr = svga->remap_func(svga, svga->ma + 8); + dat2 = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat0 & 0xffffff; - *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); - *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); - *p++ = dat2 >> 8; + *p++ = dat0 & 0xffffff; + *p++ = (dat0 >> 24) | ((dat1 & 0xffff) << 8); + *p++ = (dat1 >> 16) | ((dat2 & 0xff) << 16); + *p++ = dat2 >> 8; - svga->ma += 12; - } - } - svga->ma &= svga->vram_display_mask; - } - } + svga->ma += 12; + } + } + svga->ma &= svga->vram_display_mask; + } + } } - void svga_render_32bpp_lowres(svga_t *svga) { - int x; - uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + int x; + uint32_t *p; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = - buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat; - } - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); + svga->ma += 4; + svga->ma &= svga->vram_display_mask; + buffer32->line[svga->displine + svga->y_add][(x << 1) + svga->x_add] = buffer32->line[svga->displine + svga->y_add][(x << 1) + 1 + svga->x_add] = dat; + } + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; - } - svga->ma += (x * 4); - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - *p++ = dat & 0xffffff; - svga->ma += 4; - } - svga->ma &= svga->vram_display_mask; - } - } - } + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + *p++ = dat & 0xffffff; + svga->ma += 4; + } + svga->ma &= svga->vram_display_mask; + } + } + } } - void svga_render_32bpp_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - if (svga->force_old_addr) { - if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->force_old_addr) { + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->changedvram[(svga->ma >> 12) + 2] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - p[x] = dat & 0xffffff; - } - svga->ma += 4; - svga->ma &= svga->vram_display_mask; - } - } else { - changed_addr = svga->remap_func(svga, svga->ma); + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + p[x] = dat & 0xffffff; + } + svga->ma += 4; + svga->ma &= svga->vram_display_mask; + } + } else { + changed_addr = svga->remap_func(svga, svga->ma); - if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat & 0xffffff; - } - svga->ma += (x * 4); - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat & 0xffffff; + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat & 0xffffff; + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat & 0xffffff; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; - } - } + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; + } + } } - void svga_render_ABGR8888_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->ma); if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - } - svga->ma += x*4; - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + } + svga->ma += x * 4; + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + *p++ = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } - void svga_render_RGBA8888_highres(svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; - uint32_t changed_addr, addr; + uint32_t dat; + uint32_t changed_addr, addr; if ((svga->displine + svga->y_add) < 0) - return; + return; - changed_addr = svga->remap_func(svga, svga->ma); + changed_addr = svga->remap_func(svga, svga->ma); if (svga->changedvram[changed_addr >> 12] || svga->changedvram[(changed_addr >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; - if (!svga->remap_required) { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); - *p++ = dat >> 8; - } - svga->ma += (x * 4); - } else { - for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { - addr = svga->remap_func(svga, svga->ma); - dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]); - *p++ = dat >> 8; + if (!svga->remap_required) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + dat = *(uint32_t *) (&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); + *p++ = dat >> 8; + } + svga->ma += (x * 4); + } else { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { + addr = svga->remap_func(svga, svga->ma); + dat = *(uint32_t *) (&svga->vram[addr & svga->vram_display_mask]); + *p++ = dat >> 8; - svga->ma += 4; - } - } - svga->ma &= svga->vram_display_mask; + svga->ma += 4; + } + } + svga->ma &= svga->vram_display_mask; } } diff --git a/src/video/vid_table.c b/src/video/vid_table.c index 5f53f4d8a..8a44ac075 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -37,47 +37,45 @@ #include <86box/vid_colorplus.h> #include <86box/vid_mda.h> - typedef struct { - const device_t *device; - int flags; + const device_t *device; + int flags; } VIDEO_CARD; - -static video_timings_t timing_default = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +static video_timings_t timing_default = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; static int was_reset = 0; static const device_t vid_none_device = { - .name = "None", + .name = "None", .internal_name = "none", - .flags = 0, - .local = 0, - .init = NULL, - .close = NULL, - .reset = NULL, + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; static const device_t vid_internal_device = { - .name = "Internal", + .name = "Internal", .internal_name = "internal", - .flags = 0, - .local = 0, - .init = NULL, - .close = NULL, - .reset = NULL, + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; +// clang-format off static const VIDEO_CARD video_cards[] = { -// clang-format off { &vid_none_device }, { &vid_internal_device }, { &atiega_device }, @@ -252,30 +250,27 @@ video_cards[] = { { &voodoo_3_2000_agp_device }, { &voodoo_3_3000_agp_device }, { NULL } -// clang-format off }; - +// clang-format on #ifdef ENABLE_VID_TABLE_LOG int vid_table_do_log = ENABLE_VID_TABLE_LOG; - static void vid_table_log(const char *fmt, ...) { va_list ap; if (vid_table_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define vid_table_log(fmt, ...) +# define vid_table_log(fmt, ...) #endif - void video_reset_close(void) { @@ -287,14 +282,13 @@ video_reset_close(void) was_reset = 0; } - static void video_prepare(void) { /* Reset (deallocate) the video font arrays. */ if (fontdatksc5601) { - free(fontdatksc5601); - fontdatksc5601 = NULL; + free(fontdatksc5601); + fontdatksc5601 = NULL; } /* Reset the blend. */ @@ -302,7 +296,8 @@ video_prepare(void) for (int i = 0; i < MONITORS_NUM; i++) { /* Reset the CGA palette. */ - if (monitors[i].mon_cga_palette) *monitors[i].mon_cga_palette = 0; + if (monitors[i].mon_cga_palette) + *monitors[i].mon_cga_palette = 0; cgapal_rebuild_monitor(i); /* Do an inform on the default values, so that that there's some sane values initialized @@ -311,38 +306,34 @@ video_prepare(void) } } - void video_pre_reset(int card) { - if ((card == VID_NONE) || \ - (card == VID_INTERNAL) || machine_has_flags(machine, MACHINE_VIDEO_ONLY)) - video_prepare(); + if ((card == VID_NONE) || (card == VID_INTERNAL) || machine_has_flags(machine, MACHINE_VIDEO_ONLY)) + video_prepare(); } - void video_reset(int card) { /* This is needed to avoid duplicate resets. */ if ((video_get_type() != VIDEO_FLAG_TYPE_NONE) && was_reset) - return; + return; vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n", - card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0); + card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0); monitor_index_global = 0; loadfont("roms/video/mda/mda.rom", 0); /* Do not initialize internal cards here. */ - if (!(card == VID_NONE) && \ - !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { - vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name); + if (!(card == VID_NONE) && !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) { + vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name); - video_prepare(); + video_prepare(); - /* Initialize the video card. */ - device_add(video_cards[card].device); + /* Initialize the video card. */ + device_add(video_cards[card].device); } if (!(card == VID_NONE) @@ -358,19 +349,18 @@ video_reset(int card) /* Enable the Voodoo if configured. */ if (voodoo_enabled) - device_add(&voodoo_device); + device_add(&voodoo_device); was_reset = 1; } - int video_card_available(int card) { if (video_cards[card].device) - return(device_available(video_cards[card].device)); + return (device_available(video_cards[card].device)); - return(1); + return (1); } int @@ -382,55 +372,50 @@ video_card_get_flags(int card) const device_t * video_card_getdevice(int card) { - return(video_cards[card].device); + return (video_cards[card].device); } - int video_card_has_config(int card) { - if (video_cards[card].device == NULL) return(0); + if (video_cards[card].device == NULL) + return (0); - return(device_has_config(video_cards[card].device) ? 1 : 0); + return (device_has_config(video_cards[card].device) ? 1 : 0); } - char * video_get_internal_name(int card) { return device_get_internal_name(video_cards[card].device); } - int video_get_video_from_internal_name(char *s) { int c = 0; while (video_cards[c].device != NULL) { - if (!strcmp((char *) video_cards[c].device->internal_name, s)) - return(c); - c++; + if (!strcmp((char *) video_cards[c].device->internal_name, s)) + return (c); + c++; } - return(0); + return (0); } - int video_is_mda(void) { return (video_get_type() == VIDEO_FLAG_TYPE_MDA); } - int video_is_cga(void) { return (video_get_type() == VIDEO_FLAG_TYPE_CGA); } - int video_is_ega_vga(void) { diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index bac0242e1..af7ffb3de 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -75,115 +75,113 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define ROM_TGUI_9400CXI "roms/video/tgui9440/9400CXI.VBI" -#define ROM_TGUI_9440 "roms/video/tgui9440/BIOS.BIN" -#define ROM_TGUI_96xx "roms/video/tgui9660/Union.VBI" +#define ROM_TGUI_9400CXI "roms/video/tgui9440/9400CXI.VBI" +#define ROM_TGUI_9440 "roms/video/tgui9440/BIOS.BIN" +#define ROM_TGUI_96xx "roms/video/tgui9660/Union.VBI" #define EXT_CTRL_16BIT 0x01 #define EXT_CTRL_MONO_EXPANSION 0x02 #define EXT_CTRL_MONO_TRANSPARENT 0x04 #define EXT_CTRL_LATCH_COPY 0x08 -enum -{ - TGUI_9400CXI = 0, - TGUI_9440, - TGUI_9660, - TGUI_9680 +enum { + TGUI_9400CXI = 0, + TGUI_9440, + TGUI_9660, + TGUI_9680 }; -#define ONBOARD 0x0100 +#define ONBOARD 0x0100 -typedef struct tgui_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t accel_mapping; - mem_mapping_t mmio_mapping; +typedef struct tgui_t { + mem_mapping_t linear_mapping; + mem_mapping_t accel_mapping; + mem_mapping_t mmio_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; - int pci; + svga_t svga; + int pci; - int type, card; + int type, card; - uint8_t int_line; - uint8_t pci_regs[256]; + uint8_t int_line; + uint8_t pci_regs[256]; - struct - { - int16_t src_x, src_y; - int16_t src_x_clip, src_y_clip; - int16_t dst_x, dst_y; - int16_t dst_y_clip, dst_x_clip; - int16_t size_x, size_y; - uint16_t sv_size_y; - uint16_t patloc; - uint32_t fg_col, bg_col; - uint32_t style, ckey; - uint8_t rop; - uint32_t flags; - uint8_t pattern[0x80]; - int command; - int offset; - uint16_t ger22; + struct + { + int16_t src_x, src_y; + int16_t src_x_clip, src_y_clip; + int16_t dst_x, dst_y; + int16_t dst_y_clip, dst_x_clip; + int16_t size_x, size_y; + uint16_t sv_size_y; + uint16_t patloc; + uint32_t fg_col, bg_col; + uint32_t style, ckey; + uint8_t rop; + uint32_t flags; + uint8_t pattern[0x80]; + int command; + int offset; + uint16_t ger22; - int16_t err, top, left, bottom, right; - int x, y, dx, dy; - uint32_t src, dst, src_old, dst_old; - int pat_x, pat_y; - int use_src; + int16_t err, top, left, bottom, right; + int x, y, dx, dy; + uint32_t src, dst, src_old, dst_old; + int pat_x, pat_y; + int use_src; - int pitch, bpp; - uint32_t fill_pattern[8*8]; - uint32_t mono_pattern[8*8]; - uint32_t pattern_8[8*8]; - uint32_t pattern_16[8*8]; - uint32_t pattern_32[8*8]; - } accel; + int pitch, bpp; + uint32_t fill_pattern[8 * 8]; + uint32_t mono_pattern[8 * 8]; + uint32_t pattern_8[8 * 8]; + uint32_t pattern_16[8 * 8]; + uint32_t pattern_32[8 * 8]; + } accel; - uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/ - uint8_t copy_latch[16]; + uint8_t ext_gdc_regs[16]; /*TGUI9400CXi only*/ + uint8_t copy_latch[16]; - uint8_t tgui_3d8, tgui_3d9; - int oldmode; - uint8_t oldctrl1, newctrl1; - uint8_t oldctrl2, newctrl2; - uint8_t oldgr0e, newgr0e; + uint8_t tgui_3d8, tgui_3d9; + int oldmode; + uint8_t oldctrl1, newctrl1; + uint8_t oldctrl2, newctrl2; + uint8_t oldgr0e, newgr0e; - uint32_t linear_base, linear_size, ge_base, - mmio_base; - uint32_t hwc_fg_col, hwc_bg_col; + uint32_t linear_base, linear_size, ge_base, + mmio_base; + uint32_t hwc_fg_col, hwc_bg_col; - int ramdac_state; - uint8_t ramdac_ctrl; + int ramdac_state; + uint8_t ramdac_ctrl; - int clock_m, clock_n, clock_k; + int clock_m, clock_n, clock_k; - uint32_t vram_size, vram_mask; + uint32_t vram_size, vram_mask; - volatile int write_blitter; - void *i2c, *ddc; + volatile int write_blitter; + void *i2c, *ddc; - int has_bios; + int has_bios; } tgui_t; -video_timings_t timing_tgui_vlb = {VIDEO_BUS, 4, 8, 16, 4, 8, 16}; -video_timings_t timing_tgui_pci = {VIDEO_PCI, 4, 8, 16, 4, 8, 16}; +video_timings_t timing_tgui_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 8, .write_l = 16, .read_b = 4, .read_w = 8, .read_l = 16 }; +video_timings_t timing_tgui_pci = { .type = VIDEO_PCI, .write_b = 4, .write_w = 8, .write_l = 16, .read_b = 4, .read_w = 8, .read_l = 16 }; -static void tgui_out(uint16_t addr, uint8_t val, void *p); +static void tgui_out(uint16_t addr, uint8_t val, void *p); static uint8_t tgui_in(uint16_t addr, void *p); static void tgui_recalcmapping(tgui_t *tgui); -static void tgui_accel_out(uint16_t addr, uint8_t val, void *p); -static void tgui_accel_out_w(uint16_t addr, uint16_t val, void *p); -static void tgui_accel_out_l(uint16_t addr, uint32_t val, void *p); -static uint8_t tgui_accel_in(uint16_t addr, void *p); +static void tgui_accel_out(uint16_t addr, uint8_t val, void *p); +static void tgui_accel_out_w(uint16_t addr, uint16_t val, void *p); +static void tgui_accel_out_l(uint16_t addr, uint32_t val, void *p); +static uint8_t tgui_accel_in(uint16_t addr, void *p); static uint16_t tgui_accel_in_w(uint16_t addr, void *p); static uint32_t tgui_accel_in_l(uint16_t addr, void *p); -static uint8_t tgui_accel_read(uint32_t addr, void *priv); +static uint8_t tgui_accel_read(uint32_t addr, void *priv); static uint16_t tgui_accel_read_w(uint32_t addr, void *priv); static uint32_t tgui_accel_read_l(uint32_t addr, void *priv); @@ -196,2985 +194,3372 @@ static void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *priv); static void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *priv); static uint8_t tgui_ext_linear_read(uint32_t addr, void *p); -static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p); -static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p); -static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p); +static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p); +static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p); +static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p); static uint8_t tgui_ext_read(uint32_t addr, void *p); -static void tgui_ext_write(uint32_t addr, uint8_t val, void *p); -static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p); -static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p); - +static void tgui_ext_write(uint32_t addr, uint8_t val, void *p); +static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p); +static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p); /*Remap address for chain-4/doubleword style layout*/ static __inline uint32_t dword_remap(svga_t *svga, uint32_t in_addr) { - if (svga->packed_chain4) - return in_addr; + if (svga->packed_chain4) + return in_addr; - return ((in_addr << 2) & 0x3fff0) | - ((in_addr >> 14) & 0xc) | - (in_addr & ~0x3fffc); + return ((in_addr << 2) & 0x3fff0) | ((in_addr >> 14) & 0xc) | (in_addr & ~0x3fffc); } static void tgui_update_irqs(tgui_t *tgui) { - if (!tgui->pci) - return; + if (!tgui->pci) + return; - if (!(tgui->oldctrl1 & 0x40)) { - pci_set_irq(tgui->card, PCI_INTA); - } else { - pci_clear_irq(tgui->card, PCI_INTA); - } + if (!(tgui->oldctrl1 & 0x40)) { + pci_set_irq(tgui->card, PCI_INTA); + } else { + pci_clear_irq(tgui->card, PCI_INTA); + } } static void tgui_remove_io(tgui_t *tgui) { - io_removehandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - if (tgui->type >= TGUI_9440) { - io_removehandler(0x43c6, 0x0004, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - io_removehandler(0x83c6, 0x0003, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - io_removehandler(0x2120, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2122, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2124, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2127, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2128, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x212c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2130, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2134, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2138, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x213a, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x213c, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x213e, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2140, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2142, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2144, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2148, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2168, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2178, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x217c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_removehandler(0x2180, 0x0080, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - } + io_removehandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + if (tgui->type >= TGUI_9440) { + io_removehandler(0x43c6, 0x0004, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + io_removehandler(0x83c6, 0x0003, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + io_removehandler(0x2120, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2122, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2124, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2127, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2128, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x212c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2130, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2134, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2138, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x213a, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x213c, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x213e, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2140, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2142, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2144, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2148, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2168, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2178, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x217c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_removehandler(0x2180, 0x0080, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + } } static void tgui_set_io(tgui_t *tgui) { - tgui_remove_io(tgui); + tgui_remove_io(tgui); - io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - if (tgui->type >= TGUI_9440) { - io_sethandler(0x43c6, 0x0004, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - io_sethandler(0x83c6, 0x0003, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); - io_sethandler(0x2120, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2122, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2124, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2127, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2128, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x212c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2130, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2134, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2138, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x213a, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x213c, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x213e, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2140, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2142, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2144, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2148, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2168, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2178, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x217c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - io_sethandler(0x2180, 0x0080, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); - } + io_sethandler(0x03c0, 0x0020, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + if (tgui->type >= TGUI_9440) { + io_sethandler(0x43c6, 0x0004, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + io_sethandler(0x83c6, 0x0003, tgui_in, NULL, NULL, tgui_out, NULL, NULL, tgui); + io_sethandler(0x2120, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2122, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2124, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2127, 0x0001, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2128, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x212c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2130, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2134, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2138, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x213a, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x213c, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x213e, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2140, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2142, 0x0002, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2144, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2148, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2168, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2178, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x217c, 0x0004, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + io_sethandler(0x2180, 0x0080, tgui_accel_in, tgui_accel_in_w, tgui_accel_in_l, tgui_accel_out, tgui_accel_out_w, tgui_accel_out_l, tgui); + } } static void tgui_out(uint16_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - uint8_t old; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; + uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3C5: - switch (svga->seqaddr) - { - case 0xB: - tgui->oldmode = 1; + switch (addr) { + case 0x3C5: + switch (svga->seqaddr) { + case 0xB: + tgui->oldmode = 1; + break; + case 0xC: + if (svga->seqregs[0x0e] & 0x80) + svga->seqregs[0x0c] = val; + break; + case 0xd: + if (tgui->oldmode) + tgui->oldctrl2 = val; + else + tgui->newctrl2 = val; + break; + case 0xE: + if (tgui->oldmode) { + tgui->oldctrl1 = val; + tgui_update_irqs(tgui); + svga->write_bank = (tgui->oldctrl1) * 65536; + } else { + svga->seqregs[0xe] = val ^ 2; + svga->write_bank = (svga->seqregs[0xe]) * 65536; + } + if (!(svga->gdcreg[0xf] & 1)) + svga->read_bank = svga->write_bank; + return; + } + break; + + case 0x3C6: + if (tgui->type == TGUI_9400CXI) { + tkd8001_ramdac_out(addr, val, svga->ramdac, svga); + return; + } + if (tgui->ramdac_state == 4) { + tgui->ramdac_state = 0; + tgui->ramdac_ctrl = val; + switch ((tgui->ramdac_ctrl >> 4) & 0x0f) { + case 1: + svga->bpp = 15; break; - case 0xC: - if (svga->seqregs[0x0e] & 0x80) - svga->seqregs[0x0c] = val; + case 3: + svga->bpp = 16; break; - case 0xd: + case 0x0d: + svga->bpp = (tgui->type >= TGUI_9660) ? 32 : 24; + break; + default: + svga->bpp = 8; + break; + } + svga_recalctimings(svga); + return; + } + break; + + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tgui->type == TGUI_9400CXI) { + tkd8001_ramdac_out(addr, val, svga->ramdac, svga); + return; + } + tgui->ramdac_state = 0; + break; + + case 0x3CF: + if (svga->gdcaddr == 0x23) { + svga->dpms = !!(val & 0x03); + svga_recalctimings(svga); + } + if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) { + old = tgui->ext_gdc_regs[svga->gdcaddr & 15]; + tgui->ext_gdc_regs[svga->gdcaddr & 15] = val; + if (svga->gdcaddr == 16) + tgui_recalcmapping(tgui); + return; + } + switch (svga->gdcaddr) { + case 0x6: + if (svga->gdcreg[6] != val) { + svga->gdcreg[6] = val; + tgui_recalcmapping(tgui); + } + return; + + case 0x0e: + svga->gdcreg[0xe] = val ^ 2; + if ((svga->gdcreg[0xf] & 1) == 1) + svga->read_bank = (svga->gdcreg[0xe]) * 65536; + break; + case 0x0f: + if (val & 1) + svga->read_bank = (svga->gdcreg[0xe]) * 65536; + else { if (tgui->oldmode) - tgui->oldctrl2 = val; + svga->read_bank = (tgui->oldctrl1) * 65536; else - tgui->newctrl2 = val; - break; - case 0xE: - if (tgui->oldmode) { - tgui->oldctrl1 = val; - tgui_update_irqs(tgui); - svga->write_bank = (tgui->oldctrl1) * 65536; - } else { - svga->seqregs[0xe] = val ^ 2; - svga->write_bank = (svga->seqregs[0xe]) * 65536; - } - if (!(svga->gdcreg[0xf] & 1)) - svga->read_bank = svga->write_bank; - return; - } - break; + svga->read_bank = (svga->seqregs[0xe]) * 65536; + } - case 0x3C6: - if (tgui->type == TGUI_9400CXI) - { - tkd8001_ramdac_out(addr, val, svga->ramdac, svga); - return; - } - if (tgui->ramdac_state == 4) - { - tgui->ramdac_state = 0; - tgui->ramdac_ctrl = val; - switch ((tgui->ramdac_ctrl >> 4) & 0x0f) - { - case 1: - svga->bpp = 15; - break; - case 3: - svga->bpp = 16; - break; - case 0x0d: - svga->bpp = (tgui->type >= TGUI_9660) ? 32 : 24; - break; - default: - svga->bpp = 8; - break; - } - svga_recalctimings(svga); - return; - } - break; + if (tgui->oldmode) + svga->write_bank = (tgui->oldctrl1) * 65536; + else + svga->write_bank = (svga->seqregs[0xe]) * 65536; + break; - case 0x3C7: case 0x3C8: case 0x3C9: - if (tgui->type == TGUI_9400CXI) - { - tkd8001_ramdac_out(addr, val, svga->ramdac, svga); - return; - } - tgui->ramdac_state = 0; - break; + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + svga->gdcreg[svga->gdcaddr] = val; + break; + } + break; + case 0x3D4: + svga->crtcreg = val; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; - case 0x3CF: - if (svga->gdcaddr == 0x23) - { - svga->dpms = !!(val & 0x03); + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; svga_recalctimings(svga); + } } - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) - { - old = tgui->ext_gdc_regs[svga->gdcaddr & 15]; - tgui->ext_gdc_regs[svga->gdcaddr & 15] = val; - if (svga->gdcaddr == 16) - tgui_recalcmapping(tgui); - return; - } - switch (svga->gdcaddr) - { - case 0x6: - if (svga->gdcreg[6] != val) - { - svga->gdcreg[6] = val; - tgui_recalcmapping(tgui); - } - return; + } + switch (svga->crtcreg) { + case 0x1e: + svga->vram_display_mask = (val & 0x80) ? tgui->vram_mask : 0x3ffff; + break; - case 0x0e: - svga->gdcreg[0xe] = val ^ 2; - if ((svga->gdcreg[0xf] & 1) == 1) - svga->read_bank = (svga->gdcreg[0xe]) * 65536; - break; - case 0x0f: - if (val & 1) - svga->read_bank = (svga->gdcreg[0xe]) * 65536; - else { - if (tgui->oldmode) - svga->read_bank = (tgui->oldctrl1) * 65536; - else - svga->read_bank = (svga->seqregs[0xe]) * 65536; - } - - if (tgui->oldmode) - svga->write_bank = (tgui->oldctrl1) * 65536; - else - svga->write_bank = (svga->seqregs[0xe]) * 65536; - break; - - case 0x5a: - case 0x5b: - case 0x5c: - case 0x5d: - case 0x5e: - case 0x5f: - svga->gdcreg[svga->gdcaddr] = val; - break; - } - break; - case 0x3D4: - svga->crtcreg = val; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } + case 0x21: + if (old != val) { + if (!tgui->pci) { + tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20; + tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; + svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; } - } - switch (svga->crtcreg) { - case 0x1e: - svga->vram_display_mask = (val & 0x80) ? tgui->vram_mask : 0x3ffff; - break; + tgui_recalcmapping(tgui); + } + break; - case 0x21: - if (old != val) { - if (!tgui->pci) { - tgui->linear_base = ((val & 0xf) | ((val >> 2) & 0x30)) << 20; - tgui->linear_size = (val & 0x10) ? 0x200000 : 0x100000; - svga->decode_mask = (val & 0x10) ? 0x1fffff : 0xfffff; - } - tgui_recalcmapping(tgui); - } - break; + case 0x34: + case 0x35: + if (tgui->type >= TGUI_9440) { + tgui->ge_base = ((svga->crtc[0x35] << 0x18) | (svga->crtc[0x34] << 0x10)); + tgui_recalcmapping(tgui); + } + break; - case 0x34: - case 0x35: - if (tgui->type >= TGUI_9440) { - tgui->ge_base = ((svga->crtc[0x35] << 0x18) | (svga->crtc[0x34] << 0x10)); - tgui_recalcmapping(tgui); - } - break; + case 0x36: + case 0x39: + tgui_recalcmapping(tgui); + break; - case 0x36: - case 0x39: - tgui_recalcmapping(tgui); - break; + case 0x37: + if (tgui->type >= TGUI_9440) + i2c_gpio_set(tgui->i2c, (val & 0x02) || !(val & 0x04), (val & 0x01) || !(val & 0x08)); + break; - case 0x37: - if (tgui->type >= TGUI_9440) - i2c_gpio_set(tgui->i2c, (val & 0x02) || !(val & 0x04), (val & 0x01) || !(val & 0x08)); - break; - - case 0x40: case 0x41: case 0x42: case 0x43: - case 0x44: case 0x45: case 0x46: case 0x47: - if (tgui->type >= TGUI_9440) { - svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; - svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; - if (tgui->type >= TGUI_9660 && (tgui->accel.ger22 & 0xff) == 8) { - svga->hwcursor.x <<= 1; - } - svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; - svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; - svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x0f) << 18) | (svga->hwcursor.yoff * 8); + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + if (tgui->type >= TGUI_9440) { + svga->hwcursor.x = (svga->crtc[0x40] | (svga->crtc[0x41] << 8)) & 0x7ff; + svga->hwcursor.y = (svga->crtc[0x42] | (svga->crtc[0x43] << 8)) & 0x7ff; + if (tgui->type >= TGUI_9660 && (tgui->accel.ger22 & 0xff) == 8) { + svga->hwcursor.x <<= 1; } - break; + svga->hwcursor.xoff = svga->crtc[0x46] & 0x3f; + svga->hwcursor.yoff = svga->crtc[0x47] & 0x3f; + svga->hwcursor.addr = (svga->crtc[0x44] << 10) | ((svga->crtc[0x45] & 0x0f) << 18) | (svga->hwcursor.yoff * 8); + } + break; - case 0x50: - if (tgui->type >= TGUI_9440) { - svga->hwcursor.ena = !!(val & 0x80); - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & 1) ? 64 : 32); - } - break; - } - return; + case 0x50: + if (tgui->type >= TGUI_9440) { + svga->hwcursor.ena = !!(val & 0x80); + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((val & 1) ? 64 : 32); + } + break; + } + return; - case 0x3D8: - tgui->tgui_3d8 = val; - if (svga->gdcreg[0xf] & 4) { - svga->write_bank = (val & 0x3f) * 65536; - if (!(svga->gdcreg[0xf] & 1)) { - svga->read_bank = (val & 0x3f) * 65536; - } + case 0x3D8: + tgui->tgui_3d8 = val; + if (svga->gdcreg[0xf] & 4) { + svga->write_bank = (val & 0x3f) * 65536; + if (!(svga->gdcreg[0xf] & 1)) { + svga->read_bank = (val & 0x3f) * 65536; } - return; - case 0x3D9: - tgui->tgui_3d9 = val; - if ((svga->gdcreg[0xf] & 5) == 5) - svga->read_bank = (val & 0x3f) * 65536; - return; + } + return; + case 0x3D9: + tgui->tgui_3d9 = val; + if ((svga->gdcreg[0xf] & 5) == 5) + svga->read_bank = (val & 0x3f) * 65536; + return; - case 0x43c8: - tgui->clock_n = val & 0x7f; - tgui->clock_m = (tgui->clock_m & ~1) | (val >> 7); - break; - case 0x43c9: - tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e); - tgui->clock_k = (val & 0x10) >> 4; - break; - } - svga_out(addr, val, svga); + case 0x43c8: + tgui->clock_n = val & 0x7f; + tgui->clock_m = (tgui->clock_m & ~1) | (val >> 7); + break; + case 0x43c9: + tgui->clock_m = (tgui->clock_m & ~0x1e) | ((val << 1) & 0x1e); + tgui->clock_k = (val & 0x10) >> 4; + break; + } + svga_out(addr, val, svga); } static uint8_t tgui_in(uint16_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - uint8_t temp; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; + uint8_t temp; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3C5: - if (svga->seqaddr == 9) { - if (tgui->type == TGUI_9680) - return 0x01; /*TGUI9680XGi*/ - } - if (svga->seqaddr == 0x0b) - { - tgui->oldmode = 0; - switch (tgui->type) - { - case TGUI_9400CXI: - return 0x93; /*TGUI9400CXi*/ - case TGUI_9440: - return 0xe3; /*TGUI9440AGi*/ - case TGUI_9660: - case TGUI_9680: - return 0xd3; /*TGUI9660XGi*/ - } + switch (addr) { + case 0x3C5: + if (svga->seqaddr == 9) { + if (tgui->type == TGUI_9680) + return 0x01; /*TGUI9680XGi*/ + } + if (svga->seqaddr == 0x0b) { + tgui->oldmode = 0; + switch (tgui->type) { + case TGUI_9400CXI: + return 0x93; /*TGUI9400CXi*/ + case TGUI_9440: + return 0xe3; /*TGUI9440AGi*/ + case TGUI_9660: + case TGUI_9680: + return 0xd3; /*TGUI9660XGi*/ } - if (svga->seqaddr == 0x0d) - { - if (tgui->oldmode) - return tgui->oldctrl2; - return tgui->newctrl2; - } - if (svga->seqaddr == 0x0c) - { - if (svga->seqregs[0x0e] & 0x80) - return svga->seqregs[0x0c]; - } - if (svga->seqaddr == 0x0e) - { - if (tgui->oldmode) - return tgui->oldctrl1 | 0x88; - return svga->seqregs[0x0e]; - } - break; + } + if (svga->seqaddr == 0x0d) { + if (tgui->oldmode) + return tgui->oldctrl2; + return tgui->newctrl2; + } + if (svga->seqaddr == 0x0c) { + if (svga->seqregs[0x0e] & 0x80) + return svga->seqregs[0x0c]; + } + if (svga->seqaddr == 0x0e) { + if (tgui->oldmode) + return tgui->oldctrl1 | 0x88; + return svga->seqregs[0x0e]; + } + break; - case 0x3C6: - if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, svga->ramdac, svga); - if (tgui->ramdac_state == 4) - return tgui->ramdac_ctrl; - tgui->ramdac_state++; - break; + case 0x3C6: + if (tgui->type == TGUI_9400CXI) + return tkd8001_ramdac_in(addr, svga->ramdac, svga); + if (tgui->ramdac_state == 4) + return tgui->ramdac_ctrl; + tgui->ramdac_state++; + break; - case 0x3C7: case 0x3C8: case 0x3C9: - if (tgui->type == TGUI_9400CXI) - return tkd8001_ramdac_in(addr, svga->ramdac, svga); - tgui->ramdac_state = 0; - break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tgui->type == TGUI_9400CXI) + return tkd8001_ramdac_in(addr, svga->ramdac, svga); + tgui->ramdac_state = 0; + break; - case 0x3CF: - if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) - return tgui->ext_gdc_regs[svga->gdcaddr & 15]; - if (svga->gdcaddr >= 0x5a && svga->gdcaddr <= 0x5f) - return svga->gdcreg[svga->gdcaddr]; - break; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - if ((svga->crtcreg == 0x37) && (tgui->type >= TGUI_9440)) { - if (!(temp & 0x04)) { - temp &= ~0x02; - if (i2c_gpio_get_scl(tgui->i2c)) - temp |= 0x02; - } - if (!(temp & 0x08)) { - temp &= ~0x01; - if (i2c_gpio_get_sda(tgui->i2c)) - temp |= 0x01; - } + case 0x3CF: + if (tgui->type == TGUI_9400CXI && svga->gdcaddr >= 16 && svga->gdcaddr < 32) + return tgui->ext_gdc_regs[svga->gdcaddr & 15]; + if (svga->gdcaddr >= 0x5a && svga->gdcaddr <= 0x5f) + return svga->gdcreg[svga->gdcaddr]; + break; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + if ((svga->crtcreg == 0x37) && (tgui->type >= TGUI_9440)) { + if (!(temp & 0x04)) { + temp &= ~0x02; + if (i2c_gpio_get_scl(tgui->i2c)) + temp |= 0x02; } - return temp; - case 0x3d8: - return tgui->tgui_3d8; - case 0x3d9: - return tgui->tgui_3d9; - } - return svga_in(addr, svga); + if (!(temp & 0x08)) { + temp &= ~0x01; + if (i2c_gpio_get_sda(tgui->i2c)) + temp |= 0x01; + } + } + return temp; + case 0x3d8: + return tgui->tgui_3d8; + case 0x3d9: + return tgui->tgui_3d9; + } + return svga_in(addr, svga); } -void tgui_recalctimings(svga_t *svga) +void +tgui_recalctimings(svga_t *svga) { - tgui_t *tgui = (tgui_t *)svga->p; + tgui_t *tgui = (tgui_t *) svga->p; - if (!svga->rowoffset) - svga->rowoffset = 0x100; + if (!svga->rowoffset) + svga->rowoffset = 0x100; - if (svga->crtc[0x29] & 0x10) - svga->rowoffset |= 0x100; + if (svga->crtc[0x29] & 0x10) + svga->rowoffset |= 0x100; - if (tgui->type >= TGUI_9440 && svga->bpp >= 24) { - if ((tgui->accel.bpp == 0) && (tgui->accel.ger22 & 0xff) != 14 && (svga->bpp == 24)) - svga->hdisp = (svga->crtc[1] + 1) * 8; - if (tgui->accel.bpp == 3 && (tgui->accel.ger22 & 0xff) == 14 && (svga->bpp == 32) && (tgui->type == TGUI_9440)) - svga->rowoffset <<= 1; - } + if (tgui->type >= TGUI_9440 && svga->bpp >= 24) { + if ((tgui->accel.bpp == 0) && (tgui->accel.ger22 & 0xff) != 14 && (svga->bpp == 24)) + svga->hdisp = (svga->crtc[1] + 1) * 8; + if (tgui->accel.bpp == 3 && (tgui->accel.ger22 & 0xff) == 14 && (svga->bpp == 32) && (tgui->type == TGUI_9440)) + svga->rowoffset <<= 1; + } + if ((svga->crtc[0x1e] & 0xA0) == 0xA0) + svga->ma_latch |= 0x10000; + if ((svga->crtc[0x27] & 0x01) == 0x01) + svga->ma_latch |= 0x20000; + if ((svga->crtc[0x27] & 0x02) == 0x02) + svga->ma_latch |= 0x40000; + if ((svga->crtc[0x27] & 0x04) == 0x04) + svga->ma_latch |= 0x80000; + if (svga->crtc[0x27] & 0x08) + svga->split |= 0x400; + if (svga->crtc[0x27] & 0x10) + svga->dispend |= 0x400; + if (svga->crtc[0x27] & 0x20) + svga->vsyncstart |= 0x400; + if (svga->crtc[0x27] & 0x40) + svga->vblankstart |= 0x400; + if (svga->crtc[0x27] & 0x80) + svga->vtotal |= 0x400; - if ((svga->crtc[0x1e] & 0xA0) == 0xA0) - svga->ma_latch |= 0x10000; - if ((svga->crtc[0x27] & 0x01) == 0x01) - svga->ma_latch |= 0x20000; - if ((svga->crtc[0x27] & 0x02) == 0x02) - svga->ma_latch |= 0x40000; - if ((svga->crtc[0x27] & 0x04) == 0x04) - svga->ma_latch |= 0x80000; + if (tgui->oldctrl2 & 0x10) { + svga->rowoffset <<= 1; + svga->lowres = 0; + } - if (svga->crtc[0x27] & 0x08) - svga->split |= 0x400; - if (svga->crtc[0x27] & 0x10) - svga->dispend |= 0x400; - if (svga->crtc[0x27] & 0x20) - svga->vsyncstart |= 0x400; - if (svga->crtc[0x27] & 0x40) - svga->vblankstart |= 0x400; - if (svga->crtc[0x27] & 0x80) - svga->vtotal |= 0x400; + if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) + svga->ma_latch <<= 1; - if (tgui->oldctrl2 & 0x10) { - svga->rowoffset <<= 1; - svga->lowres = 0; - } + svga->lowres = !(svga->crtc[0x2a] & 0x40); - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) - svga->ma_latch <<= 1; + svga->interlace = !!(svga->crtc[0x1e] & 4); + if (svga->interlace && tgui->type < TGUI_9440) + svga->rowoffset >>= 1; - svga->lowres = !(svga->crtc[0x2a] & 0x40); + if (tgui->type >= TGUI_9440) { + if (svga->miscout & 8) + svga->clock = (cpuclock * (double) (1ull << 32)) / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); - svga->interlace = !!(svga->crtc[0x1e] & 4); - if (svga->interlace && tgui->type < TGUI_9440) - svga->rowoffset >>= 1; - - if (tgui->type >= TGUI_9440) - { - if (svga->miscout & 8) - svga->clock = (cpuclock * (double)(1ull << 32)) / (((tgui->clock_n + 8) * 14318180.0) / ((tgui->clock_m + 2) * (1 << tgui->clock_k))); - - if (svga->gdcreg[0xf] & 0x08) - svga->clock *= 2; - else if (svga->gdcreg[0xf] & 0x40) - svga->clock *= 3; + if (svga->gdcreg[0xf] & 0x08) + svga->clock *= 2; + else if (svga->gdcreg[0xf] & 0x40) + svga->clock *= 3; + } else { + switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) { + case 0x02: + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; + break; + case 0x03: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + case 0x04: + svga->clock = (cpuclock * (double) (1ull << 32)) / 57272000.0; + break; + case 0x05: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0; + break; + case 0x06: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0; + break; + case 0x07: + svga->clock = (cpuclock * (double) (1ull << 32)) / 40000000.0; + break; + case 0x08: + svga->clock = (cpuclock * (double) (1ull << 32)) / 88000000.0; + break; + case 0x09: + svga->clock = (cpuclock * (double) (1ull << 32)) / 98000000.0; + break; + case 0x0a: + svga->clock = (cpuclock * (double) (1ull << 32)) / 118800000.0; + break; + case 0x0b: + svga->clock = (cpuclock * (double) (1ull << 32)) / 108000000.0; + break; + case 0x0c: + svga->clock = (cpuclock * (double) (1ull << 32)) / 72000000.0; + break; + case 0x0d: + svga->clock = (cpuclock * (double) (1ull << 32)) / 77000000.0; + break; + case 0x0e: + svga->clock = (cpuclock * (double) (1ull << 32)) / 80000000.0; + break; + case 0x0f: + svga->clock = (cpuclock * (double) (1ull << 32)) / 75000000.0; + break; } - else - { - switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) - { - case 0x02: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; - case 0x03: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; - case 0x04: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break; - case 0x05: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; - case 0x06: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; - case 0x07: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; - case 0x08: svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; break; - case 0x09: svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; break; - case 0x0a: svga->clock = (cpuclock * (double)(1ull << 32)) /118800000.0; break; - case 0x0b: svga->clock = (cpuclock * (double)(1ull << 32)) /108000000.0; break; - case 0x0c: svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; break; - case 0x0d: svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; break; - case 0x0e: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break; - case 0x0f: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; - } - if (svga->gdcreg[0xf] & 0x08) - { - svga->htotal <<= 1; - svga->hdisp <<= 1; - svga->hdisp_time <<= 1; - } + if (svga->gdcreg[0xf] & 0x08) { + svga->htotal <<= 1; + svga->hdisp <<= 1; + svga->hdisp_time <<= 1; } + } - if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) - { - switch (svga->bpp) - { - case 8: - svga->render = svga_render_8bpp_highres; - if (tgui->type >= TGUI_9660) { - if (svga->dispend == 512) - svga->hdisp = 1280; - else if (svga->dispend == 600 && svga->hdisp == 800 && svga->vtotal == 651) - svga->hdisp = 1600; - } - break; - case 15: - svga->render = svga_render_15bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp >>= 1; - break; - case 16: - svga->render = svga_render_16bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp >>= 1; - break; - case 24: - svga->render = svga_render_24bpp_highres; - if (tgui->type < TGUI_9440) - svga->hdisp = (svga->hdisp << 1) / 3; - break; - case 32: - svga->render = svga_render_32bpp_highres; - if (tgui->type >= TGUI_9660) { - if (svga->hdisp == 1024) { - svga->rowoffset <<= 1; - } - } - break; + if ((tgui->oldctrl2 & 0x10) || (svga->crtc[0x2a] & 0x40)) { + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + if (tgui->type >= TGUI_9660) { + if (svga->dispend == 512) + svga->hdisp = 1280; + else if (svga->dispend == 600 && svga->hdisp == 800 && svga->vtotal == 651) + svga->hdisp = 1600; } + break; + case 15: + svga->render = svga_render_15bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp >>= 1; + break; + case 16: + svga->render = svga_render_16bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp >>= 1; + break; + case 24: + svga->render = svga_render_24bpp_highres; + if (tgui->type < TGUI_9440) + svga->hdisp = (svga->hdisp << 1) / 3; + break; + case 32: + svga->render = svga_render_32bpp_highres; + if (tgui->type >= TGUI_9660) { + if (svga->hdisp == 1024) { + svga->rowoffset <<= 1; + } + } + break; } + } } static void tgui_recalcmapping(tgui_t *tgui) { - svga_t *svga = &tgui->svga; + svga_t *svga = &tgui->svga; - if (tgui->type == TGUI_9400CXI) - { - if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) - { - mem_mapping_set_handler(&tgui->linear_mapping, - tgui_ext_linear_read, NULL, NULL, - tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); - mem_mapping_set_handler(&svga->mapping, - tgui_ext_read, NULL, NULL, - tgui_ext_write, tgui_ext_writew, tgui_ext_writel); - } - else if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_EXPANSION) - { - mem_mapping_set_handler(&tgui->linear_mapping, - svga_read_linear, svga_readw_linear, svga_readl_linear, - tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); - mem_mapping_set_handler(&svga->mapping, - svga_read, svga_readw, svga_readl, - tgui_ext_write, tgui_ext_writew, tgui_ext_writel); - } - else - { - mem_mapping_set_handler(&tgui->linear_mapping, - svga_read_linear, svga_readw_linear, svga_readl_linear, - svga_write_linear, svga_writew_linear, svga_writel_linear); - mem_mapping_set_handler(&svga->mapping, - svga_read, svga_readw, svga_readl, - svga_write, svga_writew, svga_writel); - } + if (tgui->type == TGUI_9400CXI) { + if (tgui->ext_gdc_regs[0] & EXT_CTRL_LATCH_COPY) { + mem_mapping_set_handler(&tgui->linear_mapping, + tgui_ext_linear_read, NULL, NULL, + tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); + mem_mapping_set_handler(&svga->mapping, + tgui_ext_read, NULL, NULL, + tgui_ext_write, tgui_ext_writew, tgui_ext_writel); + } else if (tgui->ext_gdc_regs[0] & EXT_CTRL_MONO_EXPANSION) { + mem_mapping_set_handler(&tgui->linear_mapping, + svga_read_linear, svga_readw_linear, svga_readl_linear, + tgui_ext_linear_write, tgui_ext_linear_writew, tgui_ext_linear_writel); + mem_mapping_set_handler(&svga->mapping, + svga_read, svga_readw, svga_readl, + tgui_ext_write, tgui_ext_writew, tgui_ext_writel); + } else { + mem_mapping_set_handler(&tgui->linear_mapping, + svga_read_linear, svga_readw_linear, svga_readl_linear, + svga_write_linear, svga_writew_linear, svga_writel_linear); + mem_mapping_set_handler(&svga->mapping, + svga_read, svga_readw, svga_readl, + svga_write, svga_writew, svga_writel); } - - if (tgui->pci && !(tgui->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&tgui->linear_mapping); - mem_mapping_disable(&tgui->accel_mapping); - mem_mapping_disable(&tgui->mmio_mapping); - return; - } - - if (svga->crtc[0x21] & 0x20) - { - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); - if (tgui->type >= TGUI_9440) - { - if ((svga->crtc[0x36] & 0x03) == 0x01) - mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x02) - mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x03) - mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); - mem_mapping_disable(&svga->mapping); - } - else - { - switch (svga->gdcreg[6] & 0xC) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } - } - } - else - { - mem_mapping_disable(&tgui->linear_mapping); - mem_mapping_disable(&tgui->accel_mapping); - switch (svga->gdcreg[6] & 0xC) - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - if ((svga->crtc[0x36] & 0x03) == 0x01) - mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x02) - mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); - else if ((svga->crtc[0x36] & 0x03) == 0x03) - mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } } - if (tgui->type >= TGUI_9440) { - if ((tgui->mmio_base != 0x00000000) && (svga->crtc[0x39] & 1)) - mem_mapping_set_addr(&tgui->mmio_mapping, tgui->mmio_base, 0x10000); - else - mem_mapping_disable(&tgui->mmio_mapping); - } + if (tgui->pci && !(tgui->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&tgui->linear_mapping); + mem_mapping_disable(&tgui->accel_mapping); + mem_mapping_disable(&tgui->mmio_mapping); + return; + } + + if (svga->crtc[0x21] & 0x20) { + mem_mapping_disable(&svga->mapping); + mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); + if (tgui->type >= TGUI_9440) { + if ((svga->crtc[0x36] & 0x03) == 0x01) + mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x02) + mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x03) + mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); + mem_mapping_disable(&svga->mapping); + } else { + switch (svga->gdcreg[6] & 0xC) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + } else { + mem_mapping_disable(&tgui->linear_mapping); + mem_mapping_disable(&tgui->accel_mapping); + switch (svga->gdcreg[6] & 0xC) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + if ((svga->crtc[0x36] & 0x03) == 0x01) + mem_mapping_set_addr(&tgui->accel_mapping, 0xb4000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x02) + mem_mapping_set_addr(&tgui->accel_mapping, 0xbc000, 0x4000); + else if ((svga->crtc[0x36] & 0x03) == 0x03) + mem_mapping_set_addr(&tgui->accel_mapping, tgui->ge_base, 0x4000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + + if (tgui->type >= TGUI_9440) { + if ((tgui->mmio_base != 0x00000000) && (svga->crtc[0x39] & 1)) + mem_mapping_set_addr(&tgui->mmio_mapping, tgui->mmio_base, 0x10000); + else + mem_mapping_disable(&tgui->mmio_mapping); + } } static void tgui_hwcursor_draw(svga_t *svga, int displine) { - uint32_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; - int pitch = (svga->hwcursor_latch.cur_xsize == 64) ? 16 : 8; + uint32_t dat[2]; + int xx; + int offset = svga->hwcursor_latch.x + svga->hwcursor_latch.xoff; + int pitch = (svga->hwcursor_latch.cur_xsize == 64) ? 16 : 8; - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; - dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; - dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7]; - for (xx = 0; xx < 32; xx++) { - if (svga->crtc[0x50] & 0x40) { - if (offset >= svga->hwcursor_latch.x) - { - if (dat[0] & 0x80000000) - ((uint32_t *)buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; - } - } else { - if (offset >= svga->hwcursor_latch.x) - { - if (!(dat[0] & 0x80000000)) - ((uint32_t *)buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; - else if (dat[1] & 0x80000000) - ((uint32_t *)buffer32->line[displine])[svga->x_add + offset] ^= 0xffffff; - } - } - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr += pitch; - - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; -} - -uint8_t tgui_pci_read(int func, int addr, void *p) -{ - tgui_t *tgui = (tgui_t *)p; - - switch (addr) - { - case 0x00: return 0x23; /*Trident*/ - case 0x01: return 0x10; - - case 0x02: return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI9660XGi*/ - case 0x03: return (tgui->type == TGUI_9440) ? 0x94 : 0x96; - - case PCI_REG_COMMAND: return tgui->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - - case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ - - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - - case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ - case 0x0b: return 0x03; - - case 0x10: return 0x00; /*Linear frame buffer address*/ - case 0x11: return 0x00; - case 0x12: return tgui->linear_base >> 16; - case 0x13: return tgui->linear_base >> 24; - - case 0x14: return 0x00; /*MMIO address*/ - case 0x15: return 0x00; - case 0x16: return tgui->mmio_base >> 16; - case 0x17: return tgui->mmio_base >> 24; - - case 0x30: return tgui->has_bios ? (tgui->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return tgui->has_bios ? tgui->pci_regs[0x32] : 0x00; - case 0x33: return tgui->has_bios ? tgui->pci_regs[0x33] : 0x00; - - case 0x3c: return tgui->int_line; - case 0x3d: return PCI_INTA; + dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 24) | (svga->vram[svga->hwcursor_latch.addr + 1] << 16) | (svga->vram[svga->hwcursor_latch.addr + 2] << 8) | svga->vram[svga->hwcursor_latch.addr + 3]; + dat[1] = (svga->vram[svga->hwcursor_latch.addr + 4] << 24) | (svga->vram[svga->hwcursor_latch.addr + 5] << 16) | (svga->vram[svga->hwcursor_latch.addr + 6] << 8) | svga->vram[svga->hwcursor_latch.addr + 7]; + for (xx = 0; xx < 32; xx++) { + if (svga->crtc[0x50] & 0x40) { + if (offset >= svga->hwcursor_latch.x) { + if (dat[0] & 0x80000000) + ((uint32_t *) buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; + } + } else { + if (offset >= svga->hwcursor_latch.x) { + if (!(dat[0] & 0x80000000)) + ((uint32_t *) buffer32->line[displine])[svga->x_add + offset] = (dat[1] & 0x80000000) ? 0xffffff : 0; + else if (dat[1] & 0x80000000) + ((uint32_t *) buffer32->line[displine])[svga->x_add + offset] ^= 0xffffff; + } } - return 0; + offset++; + dat[0] <<= 1; + dat[1] <<= 1; + } + svga->hwcursor_latch.addr += pitch; + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; } -void tgui_pci_write(int func, int addr, uint8_t val, void *p) +uint8_t +tgui_pci_read(int func, int addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; - switch (addr) - { - case PCI_REG_COMMAND: - tgui->pci_regs[PCI_REG_COMMAND] = (val & 0x23); - if (val & PCI_COMMAND_IO) { - tgui_set_io(tgui); - } else - tgui_remove_io(tgui); - tgui_recalcmapping(tgui); - break; + switch (addr) { + case 0x00: + return 0x23; /*Trident*/ + case 0x01: + return 0x10; - case 0x12: - if (tgui->type >= TGUI_9660) - tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xc0) << 16); - else - tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); - tgui->linear_size = tgui->vram_size; - svga->decode_mask = tgui->vram_mask; - tgui_recalcmapping(tgui); - break; - case 0x13: - if (tgui->type >= TGUI_9660) - tgui->linear_base = (tgui->linear_base & 0xc00000) | (val << 24); - else - tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); - tgui->linear_size = tgui->vram_size; - svga->decode_mask = tgui->vram_mask; - tgui_recalcmapping(tgui); - break; + case 0x02: + return (tgui->type == TGUI_9440) ? 0x40 : 0x60; /*TGUI9440AGi or TGUI9660XGi*/ + case 0x03: + return (tgui->type == TGUI_9440) ? 0x94 : 0x96; - case 0x16: - if (tgui->type >= TGUI_9660) - tgui->mmio_base = (tgui->mmio_base & 0xff000000) | ((val & 0xc0) << 16); - else - tgui->mmio_base = (tgui->mmio_base & 0xff000000) | ((val & 0xe0) << 16); - tgui_recalcmapping(tgui); - break; - case 0x17: - if (tgui->type >= TGUI_9660) - tgui->mmio_base = (tgui->mmio_base & 0x00c00000) | (val << 24); - else - tgui->mmio_base = (tgui->mmio_base & 0x00e00000) | (val << 24); - tgui_recalcmapping(tgui); - break; + case PCI_REG_COMMAND: + return tgui->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ - case 0x30: case 0x32: case 0x33: - if (tgui->has_bios) { - tgui->pci_regs[addr] = val; - if (tgui->pci_regs[0x30] & 0x01) - { - uint32_t biosaddr = (tgui->pci_regs[0x32] << 16) | (tgui->pci_regs[0x33] << 24); - mem_mapping_set_addr(&tgui->bios_rom.mapping, biosaddr, 0x8000); - } - else - { - mem_mapping_disable(&tgui->bios_rom.mapping); - } - } - return; + case 0x07: + return 1 << 1; /*Medium DEVSEL timing*/ - case 0x3c: - tgui->int_line = val; - return; - } + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + + case 0x0a: + return 0x01; /*Supports VGA interface, XGA compatible*/ + case 0x0b: + return 0x03; + + case 0x10: + return 0x00; /*Linear frame buffer address*/ + case 0x11: + return 0x00; + case 0x12: + return tgui->linear_base >> 16; + case 0x13: + return tgui->linear_base >> 24; + + case 0x14: + return 0x00; /*MMIO address*/ + case 0x15: + return 0x00; + case 0x16: + return tgui->mmio_base >> 16; + case 0x17: + return tgui->mmio_base >> 24; + + case 0x30: + return tgui->has_bios ? (tgui->pci_regs[0x30] & 0x01) : 0x00; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return tgui->has_bios ? tgui->pci_regs[0x32] : 0x00; + case 0x33: + return tgui->has_bios ? tgui->pci_regs[0x33] : 0x00; + + case 0x3c: + return tgui->int_line; + case 0x3d: + return PCI_INTA; + } + return 0; } -static uint8_t tgui_ext_linear_read(uint32_t addr, void *p) +void +tgui_pci_write(int func, int addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; - cycles -= video_timing_read_b; + switch (addr) { + case PCI_REG_COMMAND: + tgui->pci_regs[PCI_REG_COMMAND] = (val & 0x23); + if (val & PCI_COMMAND_IO) { + tgui_set_io(tgui); + } else + tgui_remove_io(tgui); + tgui_recalcmapping(tgui); + break; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return 0xff; + case 0x12: + if (tgui->type >= TGUI_9660) + tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xc0) << 16); + else + tgui->linear_base = (tgui->linear_base & 0xff000000) | ((val & 0xe0) << 16); + tgui->linear_size = tgui->vram_size; + svga->decode_mask = tgui->vram_mask; + tgui_recalcmapping(tgui); + break; + case 0x13: + if (tgui->type >= TGUI_9660) + tgui->linear_base = (tgui->linear_base & 0xc00000) | (val << 24); + else + tgui->linear_base = (tgui->linear_base & 0xe00000) | (val << 24); + tgui->linear_size = tgui->vram_size; + svga->decode_mask = tgui->vram_mask; + tgui_recalcmapping(tgui); + break; - addr &= ~0xf; - addr = dword_remap(svga, addr); + case 0x16: + if (tgui->type >= TGUI_9660) + tgui->mmio_base = (tgui->mmio_base & 0xff000000) | ((val & 0xc0) << 16); + else + tgui->mmio_base = (tgui->mmio_base & 0xff000000) | ((val & 0xe0) << 16); + tgui_recalcmapping(tgui); + break; + case 0x17: + if (tgui->type >= TGUI_9660) + tgui->mmio_base = (tgui->mmio_base & 0x00c00000) | (val << 24); + else + tgui->mmio_base = (tgui->mmio_base & 0x00e00000) | (val << 24); + tgui_recalcmapping(tgui); + break; - for (c = 0; c < 16; c++) { - tgui->copy_latch[c] = svga->vram[addr+c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - - return svga->vram[addr & svga->vram_mask]; -} - -static uint8_t tgui_ext_read(uint32_t addr, void *p) -{ - svga_t *svga = (svga_t *)p; - - addr = (addr & svga->banked_mask) + svga->read_bank; - - return tgui_ext_linear_read(addr, svga); -} - -static void tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) -{ - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; - uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; - uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; - uint8_t mask = tgui->ext_gdc_regs[7]; - - cycles -= video_timing_write_b; - - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; - - addr = dword_remap(svga, addr); - svga->changedvram[addr >> 12] = changeframecount; - - switch (tgui->ext_gdc_regs[0] & 0xf) - { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 7; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c == 4) ? 13 : 1; + case 0x30: + case 0x32: + case 0x33: + if (tgui->has_bios) { + tgui->pci_regs[addr] = val; + if (tgui->pci_regs[0x30] & 0x01) { + uint32_t biosaddr = (tgui->pci_regs[0x32] << 16) | (tgui->pci_regs[0x33] << 24); + mem_mapping_set_addr(&tgui->bios_rom.mapping, biosaddr, 0x8000); + } else { + mem_mapping_disable(&tgui->bios_rom.mapping); } - break; + } + return; - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 7; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; - } - break; - - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 7; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[0]; - addr += (c == 4) ? 13 : 1; - } - break; - - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 7; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c == 4) ? 13 : 1; - } - break; - - case 0x8: case 0x9: case 0xa: case 0xb: - case 0xc: case 0xd: case 0xe: case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *)&svga->vram[addr] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - break; - } + case 0x3c: + tgui->int_line = val; + return; + } } -static void tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) +static uint8_t +tgui_ext_linear_read(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; - int c; - uint8_t fg[2] = {tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5]}; - uint8_t bg[2] = {tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2]}; - uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; + svga_t *svga = (svga_t *) p; + tgui_t *tgui = (tgui_t *) svga->p; + int c; - cycles -= video_timing_write_w; + cycles -= video_timing_read_b; - addr &= svga->decode_mask; - if (addr >= svga->vram_max) - return; - addr &= svga->vram_mask; - addr &= ~0xf; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; - addr = dword_remap(svga, addr); - svga->changedvram[addr >> 12] = changeframecount; + addr &= ~0xf; + addr = dword_remap(svga, addr); - val = (val >> 8) | (val << 8); + for (c = 0; c < 16; c++) { + tgui->copy_latch[c] = svga->vram[addr + c]; + addr += ((c & 3) == 3) ? 13 : 1; + } - switch (tgui->ext_gdc_regs[0] & 0xf) - { - /*8-bit mono->colour expansion, unmasked*/ - case 2: - for (c = 15; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; - addr += (c & 3) ? 1 : 13; - } - break; - - /*16-bit mono->colour expansion, unmasked*/ - case 3: - for (c = 15; c >= 0; c--) - { - if (mask & (1 << c)) - *(uint8_t *)&svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; - } - break; - - /*8-bit mono->colour expansion, masked*/ - case 6: - for (c = 15; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[0]; - addr += (c & 3) ? 1 : 13; - } - break; - - /*16-bit mono->colour expansion, masked*/ - case 7: - for (c = 15; c >= 0; c--) - { - if ((val & mask) & (1 << c)) - *(uint8_t *)&svga->vram[addr] = fg[(c & 1) ^ 1]; - addr += (c & 3) ? 1 : 13; - } - break; - - case 0x8: case 0x9: case 0xa: case 0xb: - case 0xc: case 0xd: case 0xe: case 0xf: - for (c = 0; c < 16; c++) { - *(uint8_t *)&svga->vram[addr+c] = tgui->copy_latch[c]; - addr += ((c & 3) == 3) ? 13 : 1; - } - break; - } + return svga->vram[addr & svga->vram_mask]; } -static void tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p) +static uint8_t +tgui_ext_read(uint32_t addr, void *p) { - tgui_ext_linear_writew(addr, val, p); + svga_t *svga = (svga_t *) p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + return tgui_ext_linear_read(addr, svga); } - -static void tgui_ext_write(uint32_t addr, uint8_t val, void *p) +static void +tgui_ext_linear_write(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; + tgui_t *tgui = (tgui_t *) svga->p; + int c; + uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; + uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; + uint8_t mask = tgui->ext_gdc_regs[7]; - addr = (addr & svga->banked_mask) + svga->read_bank; + cycles -= video_timing_write_b; - tgui_ext_linear_write(addr, val, svga); -} -static void tgui_ext_writew(uint32_t addr, uint16_t val, void *p) -{ - svga_t *svga = (svga_t *)p; + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= (tgui->ext_gdc_regs[0] & 8) ? ~0xf : ~0x7; - addr = (addr & svga->banked_mask) + svga->read_bank; + addr = dword_remap(svga, addr); + svga->changedvram[addr >> 12] = changeframecount; - tgui_ext_linear_writew(addr, val, svga); -} -static void tgui_ext_writel(uint32_t addr, uint32_t val, void *p) -{ - svga_t *svga = (svga_t *)p; + switch (tgui->ext_gdc_regs[0] & 0xf) { + /*8-bit mono->colour expansion, unmasked*/ + case 2: + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; + addr += (c == 4) ? 13 : 1; + } + break; - addr = (addr & svga->banked_mask) + svga->read_bank; + /*16-bit mono->colour expansion, unmasked*/ + case 3: + for (c = 7; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c == 4) ? 13 : 1; + } + break; - tgui_ext_linear_writel(addr, val, svga); + /*8-bit mono->colour expansion, masked*/ + case 6: + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *) &svga->vram[addr] = fg[0]; + addr += (c == 4) ? 13 : 1; + } + break; + + /*16-bit mono->colour expansion, masked*/ + case 7: + for (c = 7; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c == 4) ? 13 : 1; + } + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + for (c = 0; c < 16; c++) { + *(uint8_t *) &svga->vram[addr] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } + break; + } } - -enum +static void +tgui_ext_linear_writew(uint32_t addr, uint16_t val, void *p) { - TGUI_BITBLT = 1, - TGUI_SCANLINE = 3, - TGUI_BRESENHAMLINE = 4, - TGUI_SHORTVECTOR = 5, - TGUI_FASTLINE = 6 + svga_t *svga = (svga_t *) p; + tgui_t *tgui = (tgui_t *) svga->p; + int c; + uint8_t fg[2] = { tgui->ext_gdc_regs[4], tgui->ext_gdc_regs[5] }; + uint8_t bg[2] = { tgui->ext_gdc_regs[1], tgui->ext_gdc_regs[2] }; + uint16_t mask = (tgui->ext_gdc_regs[7] << 8) | tgui->ext_gdc_regs[8]; + + cycles -= video_timing_write_w; + + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return; + addr &= svga->vram_mask; + addr &= ~0xf; + + addr = dword_remap(svga, addr); + svga->changedvram[addr >> 12] = changeframecount; + + val = (val >> 8) | (val << 8); + + switch (tgui->ext_gdc_regs[0] & 0xf) { + /*8-bit mono->colour expansion, unmasked*/ + case 2: + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[0] : bg[0]; + addr += (c & 3) ? 1 : 13; + } + break; + + /*16-bit mono->colour expansion, unmasked*/ + case 3: + for (c = 15; c >= 0; c--) { + if (mask & (1 << c)) + *(uint8_t *) &svga->vram[addr] = (val & (1 << c)) ? fg[(c & 1) ^ 1] : bg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + } + break; + + /*8-bit mono->colour expansion, masked*/ + case 6: + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *) &svga->vram[addr] = fg[0]; + addr += (c & 3) ? 1 : 13; + } + break; + + /*16-bit mono->colour expansion, masked*/ + case 7: + for (c = 15; c >= 0; c--) { + if ((val & mask) & (1 << c)) + *(uint8_t *) &svga->vram[addr] = fg[(c & 1) ^ 1]; + addr += (c & 3) ? 1 : 13; + } + break; + + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + for (c = 0; c < 16; c++) { + *(uint8_t *) &svga->vram[addr + c] = tgui->copy_latch[c]; + addr += ((c & 3) == 3) ? 13 : 1; + } + break; + } +} + +static void +tgui_ext_linear_writel(uint32_t addr, uint32_t val, void *p) +{ + tgui_ext_linear_writew(addr, val, p); +} + +static void +tgui_ext_write(uint32_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + tgui_ext_linear_write(addr, val, svga); +} +static void +tgui_ext_writew(uint32_t addr, uint16_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + tgui_ext_linear_writew(addr, val, svga); +} +static void +tgui_ext_writel(uint32_t addr, uint32_t val, void *p) +{ + svga_t *svga = (svga_t *) p; + + addr = (addr & svga->banked_mask) + svga->read_bank; + + tgui_ext_linear_writel(addr, val, svga); +} + +enum { + TGUI_BITBLT = 1, + TGUI_SCANLINE = 3, + TGUI_BRESENHAMLINE = 4, + TGUI_SHORTVECTOR = 5, + TGUI_FASTLINE = 6 }; -enum -{ - TGUI_SRCCPU = 0, - TGUI_SRCPAT = 0x02, /*Source is from pattern*/ - TGUI_SRCDISP = 0x04, /*Source is from display*/ - TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/ - TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/ - TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/ - TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/ - TGUI_SOLIDFILL = 0x4000, /*Pattern set to foreground color*/ - TGUI_STENCIL = 0x8000 /*Stencil*/ +enum { + TGUI_SRCCPU = 0, + TGUI_SRCPAT = 0x02, /*Source is from pattern*/ + TGUI_SRCDISP = 0x04, /*Source is from display*/ + TGUI_PATMONO = 0x20, /*Pattern is monochrome and needs expansion*/ + TGUI_SRCMONO = 0x40, /*Source is monochrome from CPU and needs expansion*/ + TGUI_TRANSENA = 0x1000, /*Transparent (no draw when source == bg col)*/ + TGUI_TRANSREV = 0x2000, /*Reverse fg/bg for transparent*/ + TGUI_SOLIDFILL = 0x4000, /*Pattern set to foreground color*/ + TGUI_STENCIL = 0x8000 /*Stencil*/ }; -#define READ(addr, dat) if (tgui->accel.bpp == 0) dat = svga->vram[(addr) & tgui->vram_mask]; \ - else if (tgui->accel.bpp == 1) dat = vram_w[(addr) & (tgui->vram_mask >> 1)]; \ - else dat = vram_l[(addr) & (tgui->vram_mask >> 2)]; \ +#define READ(addr, dat) \ + if (tgui->accel.bpp == 0) \ + dat = svga->vram[(addr) &tgui->vram_mask]; \ + else if (tgui->accel.bpp == 1) \ + dat = vram_w[(addr) & (tgui->vram_mask >> 1)]; \ + else \ + dat = vram_l[(addr) & (tgui->vram_mask >> 2)]; -#define MIX() do \ - { \ - out = 0; \ - for (c=0;c<32;c++) \ - { \ - d=(dst_dat & (1<accel.rop & (1<accel.rop & (1 << d)) \ + out |= (1 << c); \ + } \ + } while (0) -#define WRITE(addr, dat) if (tgui->accel.bpp == 0) \ - { \ - svga->vram[(addr) & tgui->vram_mask] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = changeframecount; \ - } \ - else if (tgui->accel.bpp == 1) \ - { \ - vram_w[(addr) & (tgui->vram_mask >> 1)] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = changeframecount; \ - } \ - else \ - { \ - vram_l[(addr) & (tgui->vram_mask >> 2)] = dat; \ - svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = changeframecount; \ - } +#define WRITE(addr, dat) \ + if (tgui->accel.bpp == 0) { \ + svga->vram[(addr) &tgui->vram_mask] = dat; \ + svga->changedvram[((addr) & (tgui->vram_mask)) >> 12] = changeframecount; \ + } else if (tgui->accel.bpp == 1) { \ + vram_w[(addr) & (tgui->vram_mask >> 1)] = dat; \ + svga->changedvram[((addr) & (tgui->vram_mask >> 1)) >> 11] = changeframecount; \ + } else { \ + vram_l[(addr) & (tgui->vram_mask >> 2)] = dat; \ + svga->changedvram[((addr) & (tgui->vram_mask >> 2)) >> 10] = changeframecount; \ + } static void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { - svga_t *svga = &tgui->svga; - uint32_t *pattern_data; - int x, y; - int c, d; - uint32_t out; - uint32_t src_dat = 0, dst_dat, pat_dat; - int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; - int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; - uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; - uint16_t *vram_w = (uint16_t *)svga->vram; - uint32_t *vram_l = (uint32_t *)svga->vram; - - if (tgui->accel.bpp == 0) { - trans_col &= 0xff; - } else if (tgui->accel.bpp == 1) { - trans_col &= 0xffff; - } - - if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) - { - count -= (tgui->accel.flags >> 24) & 7; - cpu_dat <<= (tgui->accel.flags >> 24) & 7; - } - - if (count == -1) - tgui->accel.x = tgui->accel.y = 0; - - if (tgui->accel.flags & TGUI_SOLIDFILL) { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.fill_pattern[(y*8) + (7 - x)] = tgui->accel.fg_col; - } - } - pattern_data = tgui->accel.fill_pattern; - } else if (tgui->accel.flags & TGUI_PATMONO) { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.mono_pattern[(y*8) + (7 - x)] = (tgui->accel.pattern[y] & (1 << x)) ? tgui->accel.fg_col : tgui->accel.bg_col; - } - } - pattern_data = tgui->accel.mono_pattern; - } else { - if (tgui->accel.bpp == 0) { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.pattern_8[(y*8) + (7 - x)] = tgui->accel.pattern[x + y*8]; - } - } - pattern_data = tgui->accel.pattern_8; - } else if (tgui->accel.bpp == 1) { - for (y = 0; y < 8; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.pattern_16[(y*8) + (7 - x)] = tgui->accel.pattern[x*2 + y*16] | (tgui->accel.pattern[x*2 + y*16 + 1] << 8); - } - } - pattern_data = tgui->accel.pattern_16; - } else { - for (y = 0; y < 4; y++) - { - for (x = 0; x < 8; x++) - { - tgui->accel.pattern_32[(y*8) + (7 - x)] = tgui->accel.pattern[x*4 + y*32] | (tgui->accel.pattern[x*4 + y*32 + 1] << 8) | (tgui->accel.pattern[x*4 + y*32 + 2] << 16) | (tgui->accel.pattern[x*4 + y*32 + 3] << 24); - tgui->accel.pattern_32[((y+4)*8) + (7 - x)] = tgui->accel.pattern[x*4 + y*32] | (tgui->accel.pattern[x*4 + y*32 + 1] << 8) | (tgui->accel.pattern[x*4 + y*32 + 2] << 16) | (tgui->accel.pattern[x*4 + y*32 + 3] << 24); - } - } - pattern_data = tgui->accel.pattern_32; - } - } - - /*Other than mode stuff, this bit is undocumented*/ - switch (tgui->accel.ger22 & 0xff) { - case 0: - switch (tgui->accel.ger22 >> 8) { - case 0x41: - tgui->accel.pitch = 640; - break; - } - break; - - case 4: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; - } - break; - case 8: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = 2048; - break; - case 0x60: - tgui->accel.pitch = 1280; - break; - } - break; - case 9: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = svga->hdisp; - if (tgui->type == TGUI_9440) - tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; - } - break; - case 13: - switch (tgui->accel.ger22 >> 8) { - case 0x60: - tgui->accel.pitch = 2048; - if (tgui->type >= TGUI_9660) { - if (svga->hdisp == 1280) - tgui->accel.pitch = svga->hdisp; - } - break; - } - break; - case 14: - switch (tgui->accel.ger22 >> 8) { - case 0: - tgui->accel.pitch = 1024; - break; - case 0x40: - tgui->accel.pitch = 640; - break; - case 0x50: - tgui->accel.pitch = 832; - break; - } - break; - } - - switch (tgui->accel.command) - { - case TGUI_BITBLT: - if (count == -1) { - tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); - tgui->accel.src = tgui->accel.src_old; - - tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old; - - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y = tgui->accel.dst_y; - - tgui->accel.dx = tgui->accel.dst_x & 0xfff; - tgui->accel.dy = tgui->accel.dst_y & 0xfff; - - tgui->accel.left = tgui->accel.src_x_clip & 0xfff; - tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; - tgui->accel.top = tgui->accel.src_y_clip & 0xfff; - tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; - - if (tgui->accel.bpp == 1) { - tgui->accel.left >>= 1; - tgui->accel.right >>= 1; - } else if (tgui->accel.bpp == 3) { - tgui->accel.left >>= 2; - tgui->accel.right >>= 2; - } - } - - switch (tgui->accel.flags & (TGUI_SRCMONO|TGUI_SRCDISP)) - { - case TGUI_SRCCPU: - if (count == -1) { - if (svga->crtc[0x21] & 0x20) - tgui->write_blitter = 1; - if (tgui->accel.use_src) - return; - } else - count >>= 3; - - while (count) { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && - tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { - if (tgui->accel.bpp == 0) { - src_dat = cpu_dat >> 24; - cpu_dat <<= 8; - } else if (tgui->accel.bpp == 1) { - src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); - cpu_dat <<= 16; - count--; - } else { - src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0x0000ff00) | ((cpu_dat << 8) & 0x00ff0000); - cpu_dat <<= 16; - count -= 3; - } - - READ(tgui->accel.dst, dst_dat); - - pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - if ((((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == (TGUI_TRANSENA|TGUI_PATMONO)) && (pat_dat != trans_col)) || !(tgui->accel.flags & TGUI_PATMONO) || - ((tgui->accel.flags & (TGUI_PATMONO|TGUI_TRANSENA)) == TGUI_PATMONO) || (tgui->accel.ger22 & 0x200)) { - MIX(); - - WRITE(tgui->accel.dst, out); - } - } - - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; - if (tgui->type >= TGUI_9660) - tgui->accel.dx += xdir; - - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) { - tgui->accel.x = 0; - - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y += ydir; - - if (tgui->type >= TGUI_9660) { - tgui->accel.dx = tgui->accel.dst_x & 0xfff; - tgui->accel.dy += ydir; - } - - tgui->accel.src_old += (ydir * tgui->accel.pitch); - tgui->accel.dst_old += (ydir * tgui->accel.pitch); - - tgui->accel.src = tgui->accel.src_old; - tgui->accel.dst = tgui->accel.dst_old; - - tgui->accel.y++; - - if (tgui->accel.y > tgui->accel.size_y) { - if (svga->crtc[0x21] & 0x20) - tgui->write_blitter = 0; - return; - } - if (tgui->accel.use_src) - return; - } - count--; - } - break; - - case TGUI_SRCMONO | TGUI_SRCCPU: - if (count == -1) { - if (svga->crtc[0x21] & 0x20) - tgui->write_blitter = 1; - if (tgui->accel.use_src) - return; - } - - while (count--) { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && - tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { - src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); - if (tgui->accel.bpp == 0) - src_dat &= 0xff; - else if (tgui->accel.bpp == 1) - src_dat &= 0xffff; - - READ(tgui->accel.dst, dst_dat); - - pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { - MIX(); - - WRITE(tgui->accel.dst, out); - } - } - - cpu_dat <<= 1; - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; - if (tgui->type >= TGUI_9660) - tgui->accel.dx += xdir; - - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) { - tgui->accel.x = 0; - - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y += ydir; - - if (tgui->type >= TGUI_9660) { - tgui->accel.dx = tgui->accel.dst_x & 0xfff; - tgui->accel.dy += ydir; - } - - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); - - tgui->accel.y++; - - if (tgui->accel.y > tgui->accel.size_y) { - if (svga->crtc[0x21] & 0x20) - tgui->write_blitter = 0; - return; - } - if (tgui->accel.use_src) - return; - } - } - break; - - default: - while (count--) { - READ(tgui->accel.src, src_dat); - READ(tgui->accel.dst, dst_dat); - - pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { - MIX(); - - WRITE(tgui->accel.dst, out); - } - - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; - - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) - { - tgui->accel.x = 0; - tgui->accel.y++; - - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y += ydir; - - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); - - if (tgui->accel.y > tgui->accel.size_y) - return; - } - } - break; - } - break; - - case TGUI_SCANLINE: - { - if (count == -1) { - tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); - tgui->accel.src = tgui->accel.src_old; - - tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old; - - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.pat_y = tgui->accel.dst_y; - } - - while (count--) { - READ(tgui->accel.src, src_dat); - READ(tgui->accel.dst, dst_dat); - - pat_dat = pattern_data[((tgui->accel.pat_y & 7)*8) + (tgui->accel.pat_x & 7)]; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { - MIX(); - - WRITE(tgui->accel.dst, out); - } - - tgui->accel.src += xdir; - tgui->accel.dst += xdir; - tgui->accel.pat_x += xdir; - - tgui->accel.x++; - if (tgui->accel.x > tgui->accel.size_x) - { - tgui->accel.x = 0; - - tgui->accel.pat_x = tgui->accel.dst_x; - tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); - tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); - tgui->accel.pat_y += ydir; - return; - } - } - } - break; - - case TGUI_BRESENHAMLINE: - { - int steep = 1; - int16_t dminor, dmajor, destxtmp, tmpswap; - int16_t cx, cy, dx, dy, err; - -#define SWAP(a,b) tmpswap = a; a = b; b = tmpswap; - - dminor = tgui->accel.src_y; - if (tgui->accel.src_y & 0x1000) - dminor |= ~0xfff; - dminor >>= 1; - - destxtmp = tgui->accel.src_x; - if (tgui->accel.src_x & 0x1000) - destxtmp |= ~0xfff; - - dmajor = -(destxtmp - (dminor << 1)) >> 1; - - cx = dmajor; - cy = dminor; - - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; - - tgui->accel.left = tgui->accel.src_x_clip & 0xfff; - tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; - tgui->accel.top = tgui->accel.src_y_clip & 0xfff; - tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; - - if (tgui->accel.bpp == 1) { - tgui->accel.left >>= 1; - tgui->accel.right >>= 1; - } else if (tgui->accel.bpp == 3) { - tgui->accel.left >>= 2; - tgui->accel.right >>= 2; - } - - err = tgui->accel.size_x + tgui->accel.src_y; - if ((tgui->accel.size_x + tgui->accel.src_y) & 0x1000) - err |= ~0xfff; - - if (tgui->accel.flags & 0x400) { - steep = 0; - SWAP(dx, dy); - SWAP(xdir, ydir); - } - - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if (steep) { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && - dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dx + (dy * tgui->accel.pitch), out); - } - } else { - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dy >= tgui->accel.left && dy <= tgui->accel.right && - dx >= tgui->accel.top && dx <= tgui->accel.bottom)) { - READ(dy + (dx * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dy + (dx * tgui->accel.pitch), out); - } - } - - if (tgui->accel.y == tgui->accel.size_y) - break; - - while (err > 0) { - dy += ydir; - err -= (cx << 1); - } - dx += xdir; - err += (cy << 1); - - tgui->accel.y++; - } - } - break; - - case TGUI_SHORTVECTOR: - { - int16_t dx, dy; - - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; - - tgui->accel.left = tgui->accel.src_x_clip & 0xfff; - tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; - tgui->accel.top = tgui->accel.src_y_clip & 0xfff; - tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; - - if (tgui->accel.bpp == 1) { - tgui->accel.left >>= 1; - tgui->accel.right >>= 1; - } else if (tgui->accel.bpp == 3) { - tgui->accel.left >>= 2; - tgui->accel.right >>= 2; - } - - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && - dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dx + (dy * tgui->accel.pitch), out); - } - - if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) - break; - - switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { - case 0x00: - dx++; - break; - case 0x20: - dx++; - dy--; - break; - case 0x40: - dy--; - break; - case 0x60: - dx--; - dy--; - break; - case 0x80: - dx--; - break; - case 0xa0: - dx--; - dy++; - break; - case 0xc0: - dy++; - break; - case 0xe0: - dx++; - dy++; - break; - } - - tgui->accel.y++; - } - } - break; - - case TGUI_FASTLINE: - { - if (tgui->type < TGUI_9660) - break; - - int16_t dx, dy; - - dx = tgui->accel.dst_x & 0xfff; - dy = tgui->accel.dst_y & 0xfff; - - tgui->accel.left = tgui->accel.src_x_clip & 0xfff; - tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; - tgui->accel.top = tgui->accel.src_y_clip & 0xfff; - tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; - - if (tgui->accel.bpp == 1) { - tgui->accel.left >>= 1; - tgui->accel.right >>= 1; - } else if (tgui->accel.bpp == 3) { - tgui->accel.left >>= 2; - tgui->accel.right >>= 2; - } - - while (count--) { - READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); - - /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ - if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && - dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { - READ(dx + (dy * tgui->accel.pitch), dst_dat); - - pat_dat = tgui->accel.fg_col; - - if (tgui->accel.bpp == 0) - pat_dat &= 0xff; - else if (tgui->accel.bpp == 1) - pat_dat &= 0xffff; - - MIX(); - - WRITE(dx + (dy * tgui->accel.pitch), out); - } - - if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) - break; - - switch ((tgui->accel.size_y >> 8) & 0xe0) { - case 0x00: - dx++; - break; - case 0x20: - dx++; - dy--; - break; - case 0x40: - dy--; - break; - case 0x60: - dx--; - dy--; - break; - case 0x80: - dx--; - break; - case 0xa0: - dx--; - dy++; - break; - case 0xc0: - dy++; - break; - case 0xe0: - dx++; - dy++; - break; - } - - tgui->accel.y++; - } - } - break; - } + svga_t *svga = &tgui->svga; + uint32_t *pattern_data; + int x, y; + int c, d; + uint32_t out; + uint32_t src_dat = 0, dst_dat, pat_dat; + int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; + int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; + uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; + + if (tgui->accel.bpp == 0) { + trans_col &= 0xff; + } else if (tgui->accel.bpp == 1) { + trans_col &= 0xffff; + } + + if (count != -1 && !tgui->accel.x && (tgui->accel.flags & TGUI_SRCMONO)) { + count -= (tgui->accel.flags >> 24) & 7; + cpu_dat <<= (tgui->accel.flags >> 24) & 7; + } + + if (count == -1) + tgui->accel.x = tgui->accel.y = 0; + + if (tgui->accel.flags & TGUI_SOLIDFILL) { + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.fill_pattern[(y * 8) + (7 - x)] = tgui->accel.fg_col; + } + } + pattern_data = tgui->accel.fill_pattern; + } else if (tgui->accel.flags & TGUI_PATMONO) { + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.mono_pattern[(y * 8) + (7 - x)] = (tgui->accel.pattern[y] & (1 << x)) ? tgui->accel.fg_col : tgui->accel.bg_col; + } + } + pattern_data = tgui->accel.mono_pattern; + } else { + if (tgui->accel.bpp == 0) { + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.pattern_8[(y * 8) + (7 - x)] = tgui->accel.pattern[x + y * 8]; + } + } + pattern_data = tgui->accel.pattern_8; + } else if (tgui->accel.bpp == 1) { + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.pattern_16[(y * 8) + (7 - x)] = tgui->accel.pattern[x * 2 + y * 16] | (tgui->accel.pattern[x * 2 + y * 16 + 1] << 8); + } + } + pattern_data = tgui->accel.pattern_16; + } else { + for (y = 0; y < 4; y++) { + for (x = 0; x < 8; x++) { + tgui->accel.pattern_32[(y * 8) + (7 - x)] = tgui->accel.pattern[x * 4 + y * 32] | (tgui->accel.pattern[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern[x * 4 + y * 32 + 3] << 24); + tgui->accel.pattern_32[((y + 4) * 8) + (7 - x)] = tgui->accel.pattern[x * 4 + y * 32] | (tgui->accel.pattern[x * 4 + y * 32 + 1] << 8) | (tgui->accel.pattern[x * 4 + y * 32 + 2] << 16) | (tgui->accel.pattern[x * 4 + y * 32 + 3] << 24); + } + } + pattern_data = tgui->accel.pattern_32; + } + } + + /*Other than mode stuff, this bit is undocumented*/ + switch (tgui->accel.ger22 & 0xff) { + case 0: + switch (tgui->accel.ger22 >> 8) { + case 0x41: + tgui->accel.pitch = 640; + break; + } + break; + + case 4: + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = 1024; + break; + case 0x40: + tgui->accel.pitch = 640; + break; + case 0x50: + tgui->accel.pitch = 832; + break; + } + break; + case 8: + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = 2048; + break; + case 0x60: + tgui->accel.pitch = 1280; + break; + } + break; + case 9: + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = svga->hdisp; + if (tgui->type == TGUI_9440) + tgui->accel.pitch = 1024; + break; + case 0x40: + tgui->accel.pitch = 640; + break; + case 0x50: + tgui->accel.pitch = 832; + break; + } + break; + case 13: + switch (tgui->accel.ger22 >> 8) { + case 0x60: + tgui->accel.pitch = 2048; + if (tgui->type >= TGUI_9660) { + if (svga->hdisp == 1280) + tgui->accel.pitch = svga->hdisp; + } + break; + } + break; + case 14: + switch (tgui->accel.ger22 >> 8) { + case 0: + tgui->accel.pitch = 1024; + break; + case 0x40: + tgui->accel.pitch = 640; + break; + case 0x50: + tgui->accel.pitch = 832; + break; + } + break; + } + + switch (tgui->accel.command) { + case TGUI_BITBLT: + if (count == -1) { + tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); + tgui->accel.src = tgui->accel.src_old; + + tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old; + + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_y = tgui->accel.dst_y; + + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy = tgui->accel.dst_y & 0xfff; + + tgui->accel.left = tgui->accel.src_x_clip & 0xfff; + tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; + tgui->accel.top = tgui->accel.src_y_clip & 0xfff; + tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; + + if (tgui->accel.bpp == 1) { + tgui->accel.left >>= 1; + tgui->accel.right >>= 1; + } else if (tgui->accel.bpp == 3) { + tgui->accel.left >>= 2; + tgui->accel.right >>= 2; + } + } + + switch (tgui->accel.flags & (TGUI_SRCMONO | TGUI_SRCDISP)) { + case TGUI_SRCCPU: + if (count == -1) { + if (svga->crtc[0x21] & 0x20) + tgui->write_blitter = 1; + if (tgui->accel.use_src) + return; + } else + count >>= 3; + + while (count) { + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + if (tgui->accel.bpp == 0) { + src_dat = cpu_dat >> 24; + cpu_dat <<= 8; + } else if (tgui->accel.bpp == 1) { + src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0xff00); + cpu_dat <<= 16; + count--; + } else { + src_dat = (cpu_dat >> 24) | ((cpu_dat >> 8) & 0x0000ff00) | ((cpu_dat << 8) & 0x00ff0000); + cpu_dat <<= 16; + count -= 3; + } + + READ(tgui->accel.dst, dst_dat); + + pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + if ((((tgui->accel.flags & (TGUI_PATMONO | TGUI_TRANSENA)) == (TGUI_TRANSENA | TGUI_PATMONO)) && (pat_dat != trans_col)) || !(tgui->accel.flags & TGUI_PATMONO) || ((tgui->accel.flags & (TGUI_PATMONO | TGUI_TRANSENA)) == TGUI_PATMONO) || (tgui->accel.ger22 & 0x200)) { + MIX(); + + WRITE(tgui->accel.dst, out); + } + } + + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; + if (tgui->type >= TGUI_9660) + tgui->accel.dx += xdir; + + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; + + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_y += ydir; + + if (tgui->type >= TGUI_9660) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy += ydir; + } + + tgui->accel.src_old += (ydir * tgui->accel.pitch); + tgui->accel.dst_old += (ydir * tgui->accel.pitch); + + tgui->accel.src = tgui->accel.src_old; + tgui->accel.dst = tgui->accel.dst_old; + + tgui->accel.y++; + + if (tgui->accel.y > tgui->accel.size_y) { + if (svga->crtc[0x21] & 0x20) + tgui->write_blitter = 0; + return; + } + if (tgui->accel.use_src) + return; + } + count--; + } + break; + + case TGUI_SRCMONO | TGUI_SRCCPU: + if (count == -1) { + if (svga->crtc[0x21] & 0x20) + tgui->write_blitter = 1; + if (tgui->accel.use_src) + return; + } + + while (count--) { + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { + src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); + if (tgui->accel.bpp == 0) + src_dat &= 0xff; + else if (tgui->accel.bpp == 1) + src_dat &= 0xffff; + + READ(tgui->accel.dst, dst_dat); + + pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { + MIX(); + + WRITE(tgui->accel.dst, out); + } + } + + cpu_dat <<= 1; + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; + if (tgui->type >= TGUI_9660) + tgui->accel.dx += xdir; + + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; + + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_y += ydir; + + if (tgui->type >= TGUI_9660) { + tgui->accel.dx = tgui->accel.dst_x & 0xfff; + tgui->accel.dy += ydir; + } + + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); + + tgui->accel.y++; + + if (tgui->accel.y > tgui->accel.size_y) { + if (svga->crtc[0x21] & 0x20) + tgui->write_blitter = 0; + return; + } + if (tgui->accel.use_src) + return; + } + } + break; + + default: + while (count--) { + READ(tgui->accel.src, src_dat); + READ(tgui->accel.dst, dst_dat); + + pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { + MIX(); + + WRITE(tgui->accel.dst, out); + } + + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; + + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; + tgui->accel.y++; + + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_y += ydir; + + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); + + if (tgui->accel.y > tgui->accel.size_y) + return; + } + } + break; + } + break; + + case TGUI_SCANLINE: + { + if (count == -1) { + tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); + tgui->accel.src = tgui->accel.src_old; + + tgui->accel.dst_old = tgui->accel.dst_x + (tgui->accel.dst_y * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old; + + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.pat_y = tgui->accel.dst_y; + } + + while (count--) { + READ(tgui->accel.src, src_dat); + READ(tgui->accel.dst, dst_dat); + + pat_dat = pattern_data[((tgui->accel.pat_y & 7) * 8) + (tgui->accel.pat_x & 7)]; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + if (!(tgui->accel.flags & TGUI_TRANSENA) || (src_dat != trans_col)) { + MIX(); + + WRITE(tgui->accel.dst, out); + } + + tgui->accel.src += xdir; + tgui->accel.dst += xdir; + tgui->accel.pat_x += xdir; + + tgui->accel.x++; + if (tgui->accel.x > tgui->accel.size_x) { + tgui->accel.x = 0; + + tgui->accel.pat_x = tgui->accel.dst_x; + tgui->accel.src = tgui->accel.src_old = tgui->accel.src_old + (ydir * tgui->accel.pitch); + tgui->accel.dst = tgui->accel.dst_old = tgui->accel.dst_old + (ydir * tgui->accel.pitch); + tgui->accel.pat_y += ydir; + return; + } + } + } + break; + + case TGUI_BRESENHAMLINE: + { + int steep = 1; + int16_t dminor, dmajor, destxtmp, tmpswap; + int16_t cx, cy, dx, dy, err; + +#define SWAP(a, b) \ + tmpswap = a; \ + a = b; \ + b = tmpswap; + + dminor = tgui->accel.src_y; + if (tgui->accel.src_y & 0x1000) + dminor |= ~0xfff; + dminor >>= 1; + + destxtmp = tgui->accel.src_x; + if (tgui->accel.src_x & 0x1000) + destxtmp |= ~0xfff; + + dmajor = -(destxtmp - (dminor << 1)) >> 1; + + cx = dmajor; + cy = dminor; + + dx = tgui->accel.dst_x & 0xfff; + dy = tgui->accel.dst_y & 0xfff; + + tgui->accel.left = tgui->accel.src_x_clip & 0xfff; + tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; + tgui->accel.top = tgui->accel.src_y_clip & 0xfff; + tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; + + if (tgui->accel.bpp == 1) { + tgui->accel.left >>= 1; + tgui->accel.right >>= 1; + } else if (tgui->accel.bpp == 3) { + tgui->accel.left >>= 2; + tgui->accel.right >>= 2; + } + + err = tgui->accel.size_x + tgui->accel.src_y; + if ((tgui->accel.size_x + tgui->accel.src_y) & 0x1000) + err |= ~0xfff; + + if (tgui->accel.flags & 0x400) { + steep = 0; + SWAP(dx, dy); + SWAP(xdir, ydir); + } + + while (count--) { + READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if (steep) { + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { + READ(dx + (dy * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(dx + (dy * tgui->accel.pitch), out); + } + } else { + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dy >= tgui->accel.left && dy <= tgui->accel.right && dx >= tgui->accel.top && dx <= tgui->accel.bottom)) { + READ(dy + (dx * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(dy + (dx * tgui->accel.pitch), out); + } + } + + if (tgui->accel.y == tgui->accel.size_y) + break; + + while (err > 0) { + dy += ydir; + err -= (cx << 1); + } + dx += xdir; + err += (cy << 1); + + tgui->accel.y++; + } + } + break; + + case TGUI_SHORTVECTOR: + { + int16_t dx, dy; + + dx = tgui->accel.dst_x & 0xfff; + dy = tgui->accel.dst_y & 0xfff; + + tgui->accel.left = tgui->accel.src_x_clip & 0xfff; + tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; + tgui->accel.top = tgui->accel.src_y_clip & 0xfff; + tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; + + if (tgui->accel.bpp == 1) { + tgui->accel.left >>= 1; + tgui->accel.right >>= 1; + } else if (tgui->accel.bpp == 3) { + tgui->accel.left >>= 2; + tgui->accel.right >>= 2; + } + + while (count--) { + READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { + READ(dx + (dy * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(dx + (dy * tgui->accel.pitch), out); + } + + if (tgui->accel.y == (tgui->accel.sv_size_y & 0xfff)) + break; + + switch ((tgui->accel.sv_size_y >> 8) & 0xe0) { + case 0x00: + dx++; + break; + case 0x20: + dx++; + dy--; + break; + case 0x40: + dy--; + break; + case 0x60: + dx--; + dy--; + break; + case 0x80: + dx--; + break; + case 0xa0: + dx--; + dy++; + break; + case 0xc0: + dy++; + break; + case 0xe0: + dx++; + dy++; + break; + } + + tgui->accel.y++; + } + } + break; + + case TGUI_FASTLINE: + { + if (tgui->type < TGUI_9660) + break; + + int16_t dx, dy; + + dx = tgui->accel.dst_x & 0xfff; + dy = tgui->accel.dst_y & 0xfff; + + tgui->accel.left = tgui->accel.src_x_clip & 0xfff; + tgui->accel.right = tgui->accel.dst_x_clip & 0xfff; + tgui->accel.top = tgui->accel.src_y_clip & 0xfff; + tgui->accel.bottom = tgui->accel.dst_y_clip & 0xfff; + + if (tgui->accel.bpp == 1) { + tgui->accel.left >>= 1; + tgui->accel.right >>= 1; + } else if (tgui->accel.bpp == 3) { + tgui->accel.left >>= 2; + tgui->accel.right >>= 2; + } + + while (count--) { + READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + + /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ + if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && dx >= tgui->accel.left && dx <= tgui->accel.right && dy >= tgui->accel.top && dy <= tgui->accel.bottom)) { + READ(dx + (dy * tgui->accel.pitch), dst_dat); + + pat_dat = tgui->accel.fg_col; + + if (tgui->accel.bpp == 0) + pat_dat &= 0xff; + else if (tgui->accel.bpp == 1) + pat_dat &= 0xffff; + + MIX(); + + WRITE(dx + (dy * tgui->accel.pitch), out); + } + + if (tgui->accel.y == (tgui->accel.size_y & 0xfff)) + break; + + switch ((tgui->accel.size_y >> 8) & 0xe0) { + case 0x00: + dx++; + break; + case 0x20: + dx++; + dy--; + break; + case 0x40: + dy--; + break; + case 0x60: + dx--; + dy--; + break; + case 0x80: + dx--; + break; + case 0xa0: + dx--; + dy++; + break; + case 0xc0: + dy++; + break; + case 0xe0: + dx++; + dy++; + break; + } + + tgui->accel.y++; + } + } + break; + } } static void tgui_accel_out(uint16_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *) p; - switch (addr) - { - case 0x2122: - tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val & 0xff) { - case 4: - case 8: - tgui->accel.bpp = 0; - break; + switch (addr) { + case 0x2122: + tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; + switch (val & 0xff) { + case 4: + case 8: + tgui->accel.bpp = 0; + break; - case 9: - tgui->accel.bpp = 1; - break; + case 9: + tgui->accel.bpp = 1; + break; - case 13: - case 14: - switch (tgui->svga.bpp) { - case 15: - case 16: - tgui->accel.bpp = 1; - break; + case 13: + case 14: + switch (tgui->svga.bpp) { + case 15: + case 16: + tgui->accel.bpp = 1; + break; - case 24: - tgui->accel.bpp = 0; - break; + case 24: + tgui->accel.bpp = 0; + break; - case 32: - tgui->accel.bpp = 3; - break; - } - break; - } - break; + case 32: + tgui->accel.bpp = 3; + break; + } + break; + } + break; - case 0x2123: - tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); - break; + case 0x2123: + tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); + break; - case 0x2124: /*Command*/ - tgui->accel.command = val; - tgui_accel_command(-1, 0, tgui); - break; + case 0x2124: /*Command*/ + tgui->accel.command = val; + tgui_accel_command(-1, 0, tgui); + break; - case 0x2127: /*ROP*/ - tgui->accel.rop = val; - tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); - break; + case 0x2127: /*ROP*/ + tgui->accel.rop = val; + tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); + break; - case 0x2128: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xffffff00) | val; - break; - case 0x2129: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xffff00ff) | (val << 8); - break; - case 0x212a: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xff00ffff) | (val << 16); - break; - case 0x212b: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0x0000ffff) | (val << 24); - break; + case 0x2128: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xffffff00) | val; + break; + case 0x2129: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xffff00ff) | (val << 8); + break; + case 0x212a: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xff00ffff) | (val << 16); + break; + case 0x212b: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0x0000ffff) | (val << 24); + break; - case 0x212c: /*Foreground colour*/ - case 0x2178: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xffffff00) | val; - break; - case 0x212d: /*Foreground colour*/ - case 0x2179: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xffff00ff) | (val << 8); - break; - case 0x212e: /*Foreground colour*/ - case 0x217a: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x212f: /*Foreground colour*/ - case 0x217b: - tgui->accel.fg_col = (tgui->accel.fg_col & 0x00ffffff) | (val << 24); - break; + case 0x212c: /*Foreground colour*/ + case 0x2178: + tgui->accel.fg_col = (tgui->accel.fg_col & 0xffffff00) | val; + break; + case 0x212d: /*Foreground colour*/ + case 0x2179: + tgui->accel.fg_col = (tgui->accel.fg_col & 0xffff00ff) | (val << 8); + break; + case 0x212e: /*Foreground colour*/ + case 0x217a: + tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00ffff) | (val << 16); + break; + case 0x212f: /*Foreground colour*/ + case 0x217b: + tgui->accel.fg_col = (tgui->accel.fg_col & 0x00ffffff) | (val << 24); + break; - case 0x2130: /*Background colour*/ - case 0x217c: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xffffff00) | val; - break; - case 0x2131: /*Background colour*/ - case 0x217d: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xffff00ff) | (val << 8); - break; - case 0x2132: /*Background colour*/ - case 0x217e: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x2133: /*Background colour*/ - case 0x217f: - tgui->accel.bg_col = (tgui->accel.bg_col & 0x00ffffff) | (val << 24); - break; + case 0x2130: /*Background colour*/ + case 0x217c: + tgui->accel.bg_col = (tgui->accel.bg_col & 0xffffff00) | val; + break; + case 0x2131: /*Background colour*/ + case 0x217d: + tgui->accel.bg_col = (tgui->accel.bg_col & 0xffff00ff) | (val << 8); + break; + case 0x2132: /*Background colour*/ + case 0x217e: + tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00ffff) | (val << 16); + break; + case 0x2133: /*Background colour*/ + case 0x217f: + tgui->accel.bg_col = (tgui->accel.bg_col & 0x00ffffff) | (val << 24); + break; - case 0x2134: /*Pattern location*/ - tgui->accel.patloc = (tgui->accel.patloc & 0xff00) | val; - break; - case 0x2135: /*Pattern location*/ - tgui->accel.patloc = (tgui->accel.patloc & 0xff) | (val << 8); - break; + case 0x2134: /*Pattern location*/ + tgui->accel.patloc = (tgui->accel.patloc & 0xff00) | val; + break; + case 0x2135: /*Pattern location*/ + tgui->accel.patloc = (tgui->accel.patloc & 0xff) | (val << 8); + break; - case 0x2138: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; - break; - case 0x2139: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); - break; - case 0x213a: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; - break; - case 0x213b: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); - break; + case 0x2138: /*Dest X*/ + tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; + break; + case 0x2139: /*Dest X*/ + tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); + break; + case 0x213a: /*Dest Y*/ + tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; + break; + case 0x213b: /*Dest Y*/ + tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); + break; - case 0x213c: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; - break; - case 0x213d: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); - break; - case 0x213e: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; - break; - case 0x213f: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); - break; + case 0x213c: /*Src X*/ + tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; + break; + case 0x213d: /*Src X*/ + tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); + break; + case 0x213e: /*Src Y*/ + tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; + break; + case 0x213f: /*Src Y*/ + tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); + break; - case 0x2140: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; - break; - case 0x2141: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - break; - case 0x2142: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; - tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; - break; - case 0x2143: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); - tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); - break; + case 0x2140: /*Size X*/ + tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; + break; + case 0x2141: /*Size X*/ + tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); + break; + case 0x2142: /*Size Y*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; + break; + case 0x2143: /*Size Y*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); + break; - case 0x2144: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xffffff00) | val; - break; - case 0x2145: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xffff00ff) | (val << 8); - break; - case 0x2146: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xff00ffff) | (val << 16); - break; - case 0x2147: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0x00ffffff) | (val << 24); - break; + case 0x2144: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0xffffff00) | val; + break; + case 0x2145: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0xffff00ff) | (val << 8); + break; + case 0x2146: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0xff00ffff) | (val << 16); + break; + case 0x2147: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0x00ffffff) | (val << 24); + break; - case 0x2148: /*Clip Src X*/ - tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff00) | val; - break; - case 0x2149: /*Clip Src X*/ - tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff) | (val << 8); - break; - case 0x214a: /*Clip Src Y*/ - tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff00) | val; - break; - case 0x214b: /*Clip Src Y*/ - tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff) | (val << 8); - break; + case 0x2148: /*Clip Src X*/ + tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff00) | val; + break; + case 0x2149: /*Clip Src X*/ + tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff) | (val << 8); + break; + case 0x214a: /*Clip Src Y*/ + tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff00) | val; + break; + case 0x214b: /*Clip Src Y*/ + tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff) | (val << 8); + break; - case 0x214c: /*Clip Dest X*/ - tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff00) | val; - break; - case 0x214d: /*Clip Dest X*/ - tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff) | (val << 8); - break; - case 0x214e: /*Clip Dest Y*/ - tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff00) | val; - break; - case 0x214f: /*Clip Dest Y*/ - tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff) | (val << 8); - break; + case 0x214c: /*Clip Dest X*/ + tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff00) | val; + break; + case 0x214d: /*Clip Dest X*/ + tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff) | (val << 8); + break; + case 0x214e: /*Clip Dest Y*/ + tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff00) | val; + break; + case 0x214f: /*Clip Dest Y*/ + tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff) | (val << 8); + break; - case 0x2168: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xffffff00) | val; - break; - case 0x2169: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xffff00ff) | (val << 8); - break; - case 0x216a: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xff00ffff) | (val << 16); - break; - case 0x216b: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0x00ffffff) | (val << 24); - break; + case 0x2168: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0xffffff00) | val; + break; + case 0x2169: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0xffff00ff) | (val << 8); + break; + case 0x216a: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0xff00ffff) | (val << 16); + break; + case 0x216b: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0x00ffffff) | (val << 24); + break; - case 0x2180: case 0x2181: case 0x2182: case 0x2183: - case 0x2184: case 0x2185: case 0x2186: case 0x2187: - case 0x2188: case 0x2189: case 0x218a: case 0x218b: - case 0x218c: case 0x218d: case 0x218e: case 0x218f: - case 0x2190: case 0x2191: case 0x2192: case 0x2193: - case 0x2194: case 0x2195: case 0x2196: case 0x2197: - case 0x2198: case 0x2199: case 0x219a: case 0x219b: - case 0x219c: case 0x219d: case 0x219e: case 0x219f: - case 0x21a0: case 0x21a1: case 0x21a2: case 0x21a3: - case 0x21a4: case 0x21a5: case 0x21a6: case 0x21a7: - case 0x21a8: case 0x21a9: case 0x21aa: case 0x21ab: - case 0x21ac: case 0x21ad: case 0x21ae: case 0x21af: - case 0x21b0: case 0x21b1: case 0x21b2: case 0x21b3: - case 0x21b4: case 0x21b5: case 0x21b6: case 0x21b7: - case 0x21b8: case 0x21b9: case 0x21ba: case 0x21bb: - case 0x21bc: case 0x21bd: case 0x21be: case 0x21bf: - case 0x21c0: case 0x21c1: case 0x21c2: case 0x21c3: - case 0x21c4: case 0x21c5: case 0x21c6: case 0x21c7: - case 0x21c8: case 0x21c9: case 0x21ca: case 0x21cb: - case 0x21cc: case 0x21cd: case 0x21ce: case 0x21cf: - case 0x21d0: case 0x21d1: case 0x21d2: case 0x21d3: - case 0x21d4: case 0x21d5: case 0x21d6: case 0x21d7: - case 0x21d8: case 0x21d9: case 0x21da: case 0x21db: - case 0x21dc: case 0x21dd: case 0x21de: case 0x21df: - case 0x21e0: case 0x21e1: case 0x21e2: case 0x21e3: - case 0x21e4: case 0x21e5: case 0x21e6: case 0x21e7: - case 0x21e8: case 0x21e9: case 0x21ea: case 0x21eb: - case 0x21ec: case 0x21ed: case 0x21ee: case 0x21ef: - case 0x21f0: case 0x21f1: case 0x21f2: case 0x21f3: - case 0x21f4: case 0x21f5: case 0x21f6: case 0x21f7: - case 0x21f8: case 0x21f9: case 0x21fa: case 0x21fb: - case 0x21fc: case 0x21fd: case 0x21fe: case 0x21ff: - tgui->accel.pattern[addr & 0x7f] = val; - break; - } + case 0x2180: + case 0x2181: + case 0x2182: + case 0x2183: + case 0x2184: + case 0x2185: + case 0x2186: + case 0x2187: + case 0x2188: + case 0x2189: + case 0x218a: + case 0x218b: + case 0x218c: + case 0x218d: + case 0x218e: + case 0x218f: + case 0x2190: + case 0x2191: + case 0x2192: + case 0x2193: + case 0x2194: + case 0x2195: + case 0x2196: + case 0x2197: + case 0x2198: + case 0x2199: + case 0x219a: + case 0x219b: + case 0x219c: + case 0x219d: + case 0x219e: + case 0x219f: + case 0x21a0: + case 0x21a1: + case 0x21a2: + case 0x21a3: + case 0x21a4: + case 0x21a5: + case 0x21a6: + case 0x21a7: + case 0x21a8: + case 0x21a9: + case 0x21aa: + case 0x21ab: + case 0x21ac: + case 0x21ad: + case 0x21ae: + case 0x21af: + case 0x21b0: + case 0x21b1: + case 0x21b2: + case 0x21b3: + case 0x21b4: + case 0x21b5: + case 0x21b6: + case 0x21b7: + case 0x21b8: + case 0x21b9: + case 0x21ba: + case 0x21bb: + case 0x21bc: + case 0x21bd: + case 0x21be: + case 0x21bf: + case 0x21c0: + case 0x21c1: + case 0x21c2: + case 0x21c3: + case 0x21c4: + case 0x21c5: + case 0x21c6: + case 0x21c7: + case 0x21c8: + case 0x21c9: + case 0x21ca: + case 0x21cb: + case 0x21cc: + case 0x21cd: + case 0x21ce: + case 0x21cf: + case 0x21d0: + case 0x21d1: + case 0x21d2: + case 0x21d3: + case 0x21d4: + case 0x21d5: + case 0x21d6: + case 0x21d7: + case 0x21d8: + case 0x21d9: + case 0x21da: + case 0x21db: + case 0x21dc: + case 0x21dd: + case 0x21de: + case 0x21df: + case 0x21e0: + case 0x21e1: + case 0x21e2: + case 0x21e3: + case 0x21e4: + case 0x21e5: + case 0x21e6: + case 0x21e7: + case 0x21e8: + case 0x21e9: + case 0x21ea: + case 0x21eb: + case 0x21ec: + case 0x21ed: + case 0x21ee: + case 0x21ef: + case 0x21f0: + case 0x21f1: + case 0x21f2: + case 0x21f3: + case 0x21f4: + case 0x21f5: + case 0x21f6: + case 0x21f7: + case 0x21f8: + case 0x21f9: + case 0x21fa: + case 0x21fb: + case 0x21fc: + case 0x21fd: + case 0x21fe: + case 0x21ff: + tgui->accel.pattern[addr & 0x7f] = val; + break; + } } static void tgui_accel_out_w(uint16_t addr, uint16_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - tgui_accel_out(addr, val, tgui); - tgui_accel_out(addr + 1, val >> 8, tgui); + tgui_t *tgui = (tgui_t *) p; + tgui_accel_out(addr, val, tgui); + tgui_accel_out(addr + 1, val >> 8, tgui); } static void tgui_accel_out_l(uint16_t addr, uint32_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *) p; - switch (addr) { - case 0x2124: /*Long version of Command and ROP together*/ - tgui->accel.command = val & 0xff; - tgui->accel.rop = val >> 24; - tgui->accel.use_src = (tgui->accel.rop & 0x33) ^ ((tgui->accel.rop >> 2) & 0x33); - tgui_accel_command(-1, 0, tgui); - break; + switch (addr) { + case 0x2124: /*Long version of Command and ROP together*/ + tgui->accel.command = val & 0xff; + tgui->accel.rop = val >> 24; + tgui->accel.use_src = (tgui->accel.rop & 0x33) ^ ((tgui->accel.rop >> 2) & 0x33); + tgui_accel_command(-1, 0, tgui); + break; - default: - tgui_accel_out(addr, val, tgui); - tgui_accel_out(addr + 1, val >> 8, tgui); - tgui_accel_out(addr + 2, val >> 16, tgui); - tgui_accel_out(addr + 3, val >> 24, tgui); - break; - } + default: + tgui_accel_out(addr, val, tgui); + tgui_accel_out(addr + 1, val >> 8, tgui); + tgui_accel_out(addr + 2, val >> 16, tgui); + tgui_accel_out(addr + 3, val >> 24, tgui); + break; + } } static uint8_t tgui_accel_in(uint16_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *) p; - switch (addr) - { - case 0x2120: /*Status*/ - return 0; + switch (addr) { + case 0x2120: /*Status*/ + return 0; - case 0x2122: - return tgui->accel.ger22 & 0xff; + case 0x2122: + return tgui->accel.ger22 & 0xff; - case 0x2123: - return tgui->accel.ger22 >> 8; + case 0x2123: + return tgui->accel.ger22 >> 8; - case 0x2127: /*ROP*/ - return tgui->accel.rop; + case 0x2127: /*ROP*/ + return tgui->accel.rop; - case 0x2128: /*Flags*/ - return tgui->accel.flags & 0xff; - case 0x2129: /*Flags*/ - return tgui->accel.flags >> 8; - case 0x212a: /*Flags*/ - return tgui->accel.flags >> 16; - case 0x212b: - return tgui->accel.flags >> 24; + case 0x2128: /*Flags*/ + return tgui->accel.flags & 0xff; + case 0x2129: /*Flags*/ + return tgui->accel.flags >> 8; + case 0x212a: /*Flags*/ + return tgui->accel.flags >> 16; + case 0x212b: + return tgui->accel.flags >> 24; - case 0x212c: /*Foreground colour*/ - case 0x2178: - return tgui->accel.fg_col & 0xff; - case 0x212d: /*Foreground colour*/ - case 0x2179: - return tgui->accel.fg_col >> 8; - case 0x212e: /*Foreground colour*/ - case 0x217a: - return tgui->accel.fg_col >> 16; - case 0x212f: /*Foreground colour*/ - case 0x217b: - return tgui->accel.fg_col >> 24; + case 0x212c: /*Foreground colour*/ + case 0x2178: + return tgui->accel.fg_col & 0xff; + case 0x212d: /*Foreground colour*/ + case 0x2179: + return tgui->accel.fg_col >> 8; + case 0x212e: /*Foreground colour*/ + case 0x217a: + return tgui->accel.fg_col >> 16; + case 0x212f: /*Foreground colour*/ + case 0x217b: + return tgui->accel.fg_col >> 24; - case 0x2130: /*Background colour*/ - case 0x217c: - return tgui->accel.bg_col & 0xff; - case 0x2131: /*Background colour*/ - case 0x217d: - return tgui->accel.bg_col >> 8; - case 0x2132: /*Background colour*/ - case 0x217e: - return tgui->accel.bg_col >> 16; - case 0x2133: /*Background colour*/ - case 0x217f: - return tgui->accel.bg_col >> 24; + case 0x2130: /*Background colour*/ + case 0x217c: + return tgui->accel.bg_col & 0xff; + case 0x2131: /*Background colour*/ + case 0x217d: + return tgui->accel.bg_col >> 8; + case 0x2132: /*Background colour*/ + case 0x217e: + return tgui->accel.bg_col >> 16; + case 0x2133: /*Background colour*/ + case 0x217f: + return tgui->accel.bg_col >> 24; - case 0x2134: /*Pattern location*/ - return tgui->accel.patloc & 0xff; - case 0x2135: /*Pattern location*/ - return tgui->accel.patloc >> 8; + case 0x2134: /*Pattern location*/ + return tgui->accel.patloc & 0xff; + case 0x2135: /*Pattern location*/ + return tgui->accel.patloc >> 8; - case 0x2138: /*Dest X*/ - return tgui->accel.dst_x & 0xff; - case 0x2139: /*Dest X*/ - return tgui->accel.dst_x >> 8; - case 0x213a: /*Dest Y*/ - return tgui->accel.dst_y & 0xff; - case 0x213b: /*Dest Y*/ - return tgui->accel.dst_y >> 8; + case 0x2138: /*Dest X*/ + return tgui->accel.dst_x & 0xff; + case 0x2139: /*Dest X*/ + return tgui->accel.dst_x >> 8; + case 0x213a: /*Dest Y*/ + return tgui->accel.dst_y & 0xff; + case 0x213b: /*Dest Y*/ + return tgui->accel.dst_y >> 8; - case 0x213c: /*Src X*/ - return tgui->accel.src_x & 0xff; - case 0x213d: /*Src X*/ - return tgui->accel.src_x >> 8; - case 0x213e: /*Src Y*/ - return tgui->accel.src_y & 0xff; - case 0x213f: /*Src Y*/ - return tgui->accel.src_y >> 8; + case 0x213c: /*Src X*/ + return tgui->accel.src_x & 0xff; + case 0x213d: /*Src X*/ + return tgui->accel.src_x >> 8; + case 0x213e: /*Src Y*/ + return tgui->accel.src_y & 0xff; + case 0x213f: /*Src Y*/ + return tgui->accel.src_y >> 8; - case 0x2140: /*Size X*/ - return tgui->accel.size_x & 0xff; - case 0x2141: /*Size X*/ - return tgui->accel.size_x >> 8; - case 0x2142: /*Size Y*/ - return tgui->accel.size_y & 0xff; - case 0x2143: /*Size Y*/ - return tgui->accel.size_y >> 8; + case 0x2140: /*Size X*/ + return tgui->accel.size_x & 0xff; + case 0x2141: /*Size X*/ + return tgui->accel.size_x >> 8; + case 0x2142: /*Size Y*/ + return tgui->accel.size_y & 0xff; + case 0x2143: /*Size Y*/ + return tgui->accel.size_y >> 8; - case 0x2144: /*Style*/ - return tgui->accel.style & 0xff; - case 0x2145: /*Style*/ - return tgui->accel.style >> 8; - case 0x2146: /*Style*/ - return tgui->accel.style >> 16; - case 0x2147: /*Style*/ - return tgui->accel.style >> 24; + case 0x2144: /*Style*/ + return tgui->accel.style & 0xff; + case 0x2145: /*Style*/ + return tgui->accel.style >> 8; + case 0x2146: /*Style*/ + return tgui->accel.style >> 16; + case 0x2147: /*Style*/ + return tgui->accel.style >> 24; - case 0x2148: /*Clip Src X*/ - return tgui->accel.src_x_clip & 0xff; - case 0x2149: /*Clip Src X*/ - return tgui->accel.src_x_clip >> 8; - case 0x214a: /*Clip Src Y*/ - return tgui->accel.src_y_clip & 0xff; - case 0x214b: /*Clip Src Y*/ - return tgui->accel.src_y_clip >> 8; + case 0x2148: /*Clip Src X*/ + return tgui->accel.src_x_clip & 0xff; + case 0x2149: /*Clip Src X*/ + return tgui->accel.src_x_clip >> 8; + case 0x214a: /*Clip Src Y*/ + return tgui->accel.src_y_clip & 0xff; + case 0x214b: /*Clip Src Y*/ + return tgui->accel.src_y_clip >> 8; - case 0x214c: /*Clip Dest X*/ - return tgui->accel.dst_x_clip & 0xff; - case 0x214d: /*Clip Dest X*/ - return tgui->accel.dst_x_clip >> 8; - case 0x214e: /*Clip Dest Y*/ - return tgui->accel.dst_y_clip & 0xff; - case 0x214f: /*Clip Dest Y*/ - return tgui->accel.dst_y_clip >> 8; + case 0x214c: /*Clip Dest X*/ + return tgui->accel.dst_x_clip & 0xff; + case 0x214d: /*Clip Dest X*/ + return tgui->accel.dst_x_clip >> 8; + case 0x214e: /*Clip Dest Y*/ + return tgui->accel.dst_y_clip & 0xff; + case 0x214f: /*Clip Dest Y*/ + return tgui->accel.dst_y_clip >> 8; - case 0x2168: /*CKey*/ - return tgui->accel.ckey & 0xff; - case 0x2169: /*CKey*/ - return tgui->accel.ckey >> 8; - case 0x216a: /*CKey*/ - return tgui->accel.ckey >> 16; - case 0x216b: /*CKey*/ - return tgui->accel.ckey >> 24; + case 0x2168: /*CKey*/ + return tgui->accel.ckey & 0xff; + case 0x2169: /*CKey*/ + return tgui->accel.ckey >> 8; + case 0x216a: /*CKey*/ + return tgui->accel.ckey >> 16; + case 0x216b: /*CKey*/ + return tgui->accel.ckey >> 24; - case 0x2180: case 0x2181: case 0x2182: case 0x2183: - case 0x2184: case 0x2185: case 0x2186: case 0x2187: - case 0x2188: case 0x2189: case 0x218a: case 0x218b: - case 0x218c: case 0x218d: case 0x218e: case 0x218f: - case 0x2190: case 0x2191: case 0x2192: case 0x2193: - case 0x2194: case 0x2195: case 0x2196: case 0x2197: - case 0x2198: case 0x2199: case 0x219a: case 0x219b: - case 0x219c: case 0x219d: case 0x219e: case 0x219f: - case 0x21a0: case 0x21a1: case 0x21a2: case 0x21a3: - case 0x21a4: case 0x21a5: case 0x21a6: case 0x21a7: - case 0x21a8: case 0x21a9: case 0x21aa: case 0x21ab: - case 0x21ac: case 0x21ad: case 0x21ae: case 0x21af: - case 0x21b0: case 0x21b1: case 0x21b2: case 0x21b3: - case 0x21b4: case 0x21b5: case 0x21b6: case 0x21b7: - case 0x21b8: case 0x21b9: case 0x21ba: case 0x21bb: - case 0x21bc: case 0x21bd: case 0x21be: case 0x21bf: - case 0x21c0: case 0x21c1: case 0x21c2: case 0x21c3: - case 0x21c4: case 0x21c5: case 0x21c6: case 0x21c7: - case 0x21c8: case 0x21c9: case 0x21ca: case 0x21cb: - case 0x21cc: case 0x21cd: case 0x21ce: case 0x21cf: - case 0x21d0: case 0x21d1: case 0x21d2: case 0x21d3: - case 0x21d4: case 0x21d5: case 0x21d6: case 0x21d7: - case 0x21d8: case 0x21d9: case 0x21da: case 0x21db: - case 0x21dc: case 0x21dd: case 0x21de: case 0x21df: - case 0x21e0: case 0x21e1: case 0x21e2: case 0x21e3: - case 0x21e4: case 0x21e5: case 0x21e6: case 0x21e7: - case 0x21e8: case 0x21e9: case 0x21ea: case 0x21eb: - case 0x21ec: case 0x21ed: case 0x21ee: case 0x21ef: - case 0x21f0: case 0x21f1: case 0x21f2: case 0x21f3: - case 0x21f4: case 0x21f5: case 0x21f6: case 0x21f7: - case 0x21f8: case 0x21f9: case 0x21fa: case 0x21fb: - case 0x21fc: case 0x21fd: case 0x21fe: case 0x21ff: - return tgui->accel.pattern[addr & 0x7f]; - } - return 0; + case 0x2180: + case 0x2181: + case 0x2182: + case 0x2183: + case 0x2184: + case 0x2185: + case 0x2186: + case 0x2187: + case 0x2188: + case 0x2189: + case 0x218a: + case 0x218b: + case 0x218c: + case 0x218d: + case 0x218e: + case 0x218f: + case 0x2190: + case 0x2191: + case 0x2192: + case 0x2193: + case 0x2194: + case 0x2195: + case 0x2196: + case 0x2197: + case 0x2198: + case 0x2199: + case 0x219a: + case 0x219b: + case 0x219c: + case 0x219d: + case 0x219e: + case 0x219f: + case 0x21a0: + case 0x21a1: + case 0x21a2: + case 0x21a3: + case 0x21a4: + case 0x21a5: + case 0x21a6: + case 0x21a7: + case 0x21a8: + case 0x21a9: + case 0x21aa: + case 0x21ab: + case 0x21ac: + case 0x21ad: + case 0x21ae: + case 0x21af: + case 0x21b0: + case 0x21b1: + case 0x21b2: + case 0x21b3: + case 0x21b4: + case 0x21b5: + case 0x21b6: + case 0x21b7: + case 0x21b8: + case 0x21b9: + case 0x21ba: + case 0x21bb: + case 0x21bc: + case 0x21bd: + case 0x21be: + case 0x21bf: + case 0x21c0: + case 0x21c1: + case 0x21c2: + case 0x21c3: + case 0x21c4: + case 0x21c5: + case 0x21c6: + case 0x21c7: + case 0x21c8: + case 0x21c9: + case 0x21ca: + case 0x21cb: + case 0x21cc: + case 0x21cd: + case 0x21ce: + case 0x21cf: + case 0x21d0: + case 0x21d1: + case 0x21d2: + case 0x21d3: + case 0x21d4: + case 0x21d5: + case 0x21d6: + case 0x21d7: + case 0x21d8: + case 0x21d9: + case 0x21da: + case 0x21db: + case 0x21dc: + case 0x21dd: + case 0x21de: + case 0x21df: + case 0x21e0: + case 0x21e1: + case 0x21e2: + case 0x21e3: + case 0x21e4: + case 0x21e5: + case 0x21e6: + case 0x21e7: + case 0x21e8: + case 0x21e9: + case 0x21ea: + case 0x21eb: + case 0x21ec: + case 0x21ed: + case 0x21ee: + case 0x21ef: + case 0x21f0: + case 0x21f1: + case 0x21f2: + case 0x21f3: + case 0x21f4: + case 0x21f5: + case 0x21f6: + case 0x21f7: + case 0x21f8: + case 0x21f9: + case 0x21fa: + case 0x21fb: + case 0x21fc: + case 0x21fd: + case 0x21fe: + case 0x21ff: + return tgui->accel.pattern[addr & 0x7f]; + } + return 0; } static uint16_t tgui_accel_in_w(uint16_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - return tgui_accel_in(addr, tgui) | (tgui_accel_in(addr + 1, tgui) << 8); + tgui_t *tgui = (tgui_t *) p; + return tgui_accel_in(addr, tgui) | (tgui_accel_in(addr + 1, tgui) << 8); } static uint32_t tgui_accel_in_l(uint16_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - return tgui_accel_in_w(addr, tgui) | (tgui_accel_in_w(addr + 2, tgui) << 16); + tgui_t *tgui = (tgui_t *) p; + return tgui_accel_in_w(addr, tgui) | (tgui_accel_in_w(addr + 2, tgui) << 16); } - static void tgui_accel_write(uint32_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; - if ((svga->crtc[0x36] & 0x03) == 0x02) { - if ((addr & ~0xff) != 0xbff00) - return; - } else if ((svga->crtc[0x36] & 0x03) == 0x01) { - if ((addr & ~0xff) != 0xb7f00) - return; - } + if ((svga->crtc[0x36] & 0x03) == 0x02) { + if ((addr & ~0xff) != 0xbff00) + return; + } else if ((svga->crtc[0x36] & 0x03) == 0x01) { + if ((addr & ~0xff) != 0xb7f00) + return; + } - switch (addr & 0xff) - { - case 0x22: - tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; - switch (val & 0xff) { - case 4: - case 8: - tgui->accel.bpp = 0; - break; + switch (addr & 0xff) { + case 0x22: + tgui->accel.ger22 = (tgui->accel.ger22 & 0xff00) | val; + switch (val & 0xff) { + case 4: + case 8: + tgui->accel.bpp = 0; + break; - case 9: - tgui->accel.bpp = 1; - break; + case 9: + tgui->accel.bpp = 1; + break; - case 13: - case 14: - switch (tgui->svga.bpp) { - case 15: - case 16: - tgui->accel.bpp = 1; - break; + case 13: + case 14: + switch (tgui->svga.bpp) { + case 15: + case 16: + tgui->accel.bpp = 1; + break; - case 24: - tgui->accel.bpp = 0; - break; + case 24: + tgui->accel.bpp = 0; + break; - case 32: - tgui->accel.bpp = 3; - break; - } - break; - } - break; + case 32: + tgui->accel.bpp = 3; + break; + } + break; + } + break; - case 0x23: - tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); - break; + case 0x23: + tgui->accel.ger22 = (tgui->accel.ger22 & 0xff) | (val << 8); + break; - case 0x24: /*Command*/ - tgui->accel.command = val; - tgui_accel_command(-1, 0, tgui); - break; + case 0x24: /*Command*/ + tgui->accel.command = val; + tgui_accel_command(-1, 0, tgui); + break; - case 0x27: /*ROP*/ - tgui->accel.rop = val; - tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); - break; + case 0x27: /*ROP*/ + tgui->accel.rop = val; + tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); + break; - case 0x28: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xffffff00) | val; - break; - case 0x29: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xffff00ff) | (val << 8); - break; - case 0x2a: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0xff00ffff) | (val << 16); - break; - case 0x2b: /*Flags*/ - tgui->accel.flags = (tgui->accel.flags & 0x0000ffff) | (val << 24); - break; + case 0x28: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xffffff00) | val; + break; + case 0x29: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xffff00ff) | (val << 8); + break; + case 0x2a: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0xff00ffff) | (val << 16); + break; + case 0x2b: /*Flags*/ + tgui->accel.flags = (tgui->accel.flags & 0x0000ffff) | (val << 24); + break; - case 0x2c: /*Foreground colour*/ - case 0x78: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xffffff00) | val; - break; - case 0x2d: /*Foreground colour*/ - case 0x79: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xffff00ff) | (val << 8); - break; - case 0x2e: /*Foreground colour*/ - case 0x7a: - tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00ffff) | (val << 16); - break; - case 0x2f: /*Foreground colour*/ - case 0x7b: - tgui->accel.fg_col = (tgui->accel.fg_col & 0x00ffffff) | (val << 24); - break; + case 0x2c: /*Foreground colour*/ + case 0x78: + tgui->accel.fg_col = (tgui->accel.fg_col & 0xffffff00) | val; + break; + case 0x2d: /*Foreground colour*/ + case 0x79: + tgui->accel.fg_col = (tgui->accel.fg_col & 0xffff00ff) | (val << 8); + break; + case 0x2e: /*Foreground colour*/ + case 0x7a: + tgui->accel.fg_col = (tgui->accel.fg_col & 0xff00ffff) | (val << 16); + break; + case 0x2f: /*Foreground colour*/ + case 0x7b: + tgui->accel.fg_col = (tgui->accel.fg_col & 0x00ffffff) | (val << 24); + break; - case 0x30: /*Background colour*/ - case 0x7c: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xffffff00) | val; - break; - case 0x31: /*Background colour*/ - case 0x7d: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xffff00ff) | (val << 8); - break; - case 0x32: /*Background colour*/ - case 0x7e: - tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00ffff) | (val << 16); - break; - case 0x33: /*Background colour*/ - case 0x7f: - tgui->accel.bg_col = (tgui->accel.bg_col & 0x00ffffff) | (val << 24); - break; + case 0x30: /*Background colour*/ + case 0x7c: + tgui->accel.bg_col = (tgui->accel.bg_col & 0xffffff00) | val; + break; + case 0x31: /*Background colour*/ + case 0x7d: + tgui->accel.bg_col = (tgui->accel.bg_col & 0xffff00ff) | (val << 8); + break; + case 0x32: /*Background colour*/ + case 0x7e: + tgui->accel.bg_col = (tgui->accel.bg_col & 0xff00ffff) | (val << 16); + break; + case 0x33: /*Background colour*/ + case 0x7f: + tgui->accel.bg_col = (tgui->accel.bg_col & 0x00ffffff) | (val << 24); + break; - case 0x34: /*Pattern location*/ - tgui->accel.patloc = (tgui->accel.patloc & 0xff00) | val; - break; - case 0x35: /*Pattern location*/ - tgui->accel.patloc = (tgui->accel.patloc & 0xff) | (val << 8); - break; + case 0x34: /*Pattern location*/ + tgui->accel.patloc = (tgui->accel.patloc & 0xff00) | val; + break; + case 0x35: /*Pattern location*/ + tgui->accel.patloc = (tgui->accel.patloc & 0xff) | (val << 8); + break; - case 0x38: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; - break; - case 0x39: /*Dest X*/ - tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); - break; - case 0x3a: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; - break; - case 0x3b: /*Dest Y*/ - tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); - break; + case 0x38: /*Dest X*/ + tgui->accel.dst_x = (tgui->accel.dst_x & 0xff00) | val; + break; + case 0x39: /*Dest X*/ + tgui->accel.dst_x = (tgui->accel.dst_x & 0xff) | (val << 8); + break; + case 0x3a: /*Dest Y*/ + tgui->accel.dst_y = (tgui->accel.dst_y & 0xff00) | val; + break; + case 0x3b: /*Dest Y*/ + tgui->accel.dst_y = (tgui->accel.dst_y & 0xff) | (val << 8); + break; - case 0x3c: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; - break; - case 0x3d: /*Src X*/ - tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); - break; - case 0x3e: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; - break; - case 0x3f: /*Src Y*/ - tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); - break; + case 0x3c: /*Src X*/ + tgui->accel.src_x = (tgui->accel.src_x & 0xff00) | val; + break; + case 0x3d: /*Src X*/ + tgui->accel.src_x = (tgui->accel.src_x & 0xff) | (val << 8); + break; + case 0x3e: /*Src Y*/ + tgui->accel.src_y = (tgui->accel.src_y & 0xff00) | val; + break; + case 0x3f: /*Src Y*/ + tgui->accel.src_y = (tgui->accel.src_y & 0xff) | (val << 8); + break; - case 0x40: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; - break; - case 0x41: /*Size X*/ - tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - break; - case 0x42: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; - tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; - break; - case 0x43: /*Size Y*/ - tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); - tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); - break; + case 0x40: /*Size X*/ + tgui->accel.size_x = (tgui->accel.size_x & 0xff00) | val; + break; + case 0x41: /*Size X*/ + tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); + break; + case 0x42: /*Size Y*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xff00) | val; + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff00) | val; + break; + case 0x43: /*Size Y*/ + tgui->accel.size_y = (tgui->accel.size_y & 0xff) | (val << 8); + tgui->accel.sv_size_y = (tgui->accel.sv_size_y & 0xff) | (val << 8); + break; - case 0x44: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xffffff00) | val; - break; - case 0x45: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xffff00ff) | (val << 8); - break; - case 0x46: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0xff00ffff) | (val << 16); - break; - case 0x47: /*Style*/ - tgui->accel.style = (tgui->accel.style & 0x00ffffff) | (val << 24); - break; + case 0x44: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0xffffff00) | val; + break; + case 0x45: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0xffff00ff) | (val << 8); + break; + case 0x46: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0xff00ffff) | (val << 16); + break; + case 0x47: /*Style*/ + tgui->accel.style = (tgui->accel.style & 0x00ffffff) | (val << 24); + break; - case 0x48: /*Clip Src X*/ - tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff00) | val; - break; - case 0x49: /*Clip Src X*/ - tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff) | (val << 8); - break; - case 0x4a: /*Clip Src Y*/ - tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff00) | val; - break; - case 0x4b: /*Clip Src Y*/ - tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff) | (val << 8); - break; + case 0x48: /*Clip Src X*/ + tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff00) | val; + break; + case 0x49: /*Clip Src X*/ + tgui->accel.src_x_clip = (tgui->accel.src_x_clip & 0xff) | (val << 8); + break; + case 0x4a: /*Clip Src Y*/ + tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff00) | val; + break; + case 0x4b: /*Clip Src Y*/ + tgui->accel.src_y_clip = (tgui->accel.src_y_clip & 0xff) | (val << 8); + break; - case 0x4c: /*Clip Dest X*/ - tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff00) | val; - break; - case 0x4d: /*Clip Dest X*/ - tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff) | (val << 8); - break; - case 0x4e: /*Clip Dest Y*/ - tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff00) | val; - break; - case 0x4f: /*Clip Dest Y*/ - tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff) | (val << 8); - break; + case 0x4c: /*Clip Dest X*/ + tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff00) | val; + break; + case 0x4d: /*Clip Dest X*/ + tgui->accel.dst_x_clip = (tgui->accel.dst_x_clip & 0xff) | (val << 8); + break; + case 0x4e: /*Clip Dest Y*/ + tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff00) | val; + break; + case 0x4f: /*Clip Dest Y*/ + tgui->accel.dst_y_clip = (tgui->accel.dst_y_clip & 0xff) | (val << 8); + break; - case 0x68: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xffffff00) | val; - break; - case 0x69: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xffff00ff) | (val << 8); - break; - case 0x6a: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0xff00ffff) | (val << 16); - break; - case 0x6b: /*CKey*/ - tgui->accel.ckey = (tgui->accel.ckey & 0x00ffffff) | (val << 24); - break; + case 0x68: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0xffffff00) | val; + break; + case 0x69: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0xffff00ff) | (val << 8); + break; + case 0x6a: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0xff00ffff) | (val << 16); + break; + case 0x6b: /*CKey*/ + tgui->accel.ckey = (tgui->accel.ckey & 0x00ffffff) | (val << 24); + break; - case 0x80: case 0x81: case 0x82: case 0x83: - case 0x84: case 0x85: case 0x86: case 0x87: - case 0x88: case 0x89: case 0x8a: case 0x8b: - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - case 0x90: case 0x91: case 0x92: case 0x93: - case 0x94: case 0x95: case 0x96: case 0x97: - case 0x98: case 0x99: case 0x9a: case 0x9b: - case 0x9c: case 0x9d: case 0x9e: case 0x9f: - case 0xa0: case 0xa1: case 0xa2: case 0xa3: - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - case 0xa8: case 0xa9: case 0xaa: case 0xab: - case 0xac: case 0xad: case 0xae: case 0xaf: - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - case 0xe0: case 0xe1: case 0xe2: case 0xe3: - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: - case 0xec: case 0xed: case 0xee: case 0xef: - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - tgui->accel.pattern[addr & 0x7f] = val; - break; - } + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + case 0xf0: + case 0xf1: + case 0xf2: + case 0xf3: + case 0xf4: + case 0xf5: + case 0xf6: + case 0xf7: + case 0xf8: + case 0xf9: + case 0xfa: + case 0xfb: + case 0xfc: + case 0xfd: + case 0xfe: + case 0xff: + tgui->accel.pattern[addr & 0x7f] = val; + break; + } } static void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *) p; - tgui_accel_write(addr, val, tgui); - tgui_accel_write(addr + 1, val >> 8, tgui); + tgui_accel_write(addr, val, tgui); + tgui_accel_write(addr + 1, val >> 8, tgui); } static void tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; - switch (addr & 0xff) { - case 0x24: /*Long version of Command and ROP together*/ - if ((svga->crtc[0x36] & 0x03) == 0x02) { - if ((addr & ~0xff) != 0xbff00) - return; - } else if ((svga->crtc[0x36] & 0x03) == 0x01) { - if ((addr & ~0xff) != 0xb7f00) - return; - } - tgui->accel.command = val & 0xff; - tgui->accel.rop = val >> 24; - tgui->accel.use_src = ((val >> 24) & 0x33) ^ (((val >> 24) >> 2) & 0x33); - tgui_accel_command(-1, 0, tgui); - break; + switch (addr & 0xff) { + case 0x24: /*Long version of Command and ROP together*/ + if ((svga->crtc[0x36] & 0x03) == 0x02) { + if ((addr & ~0xff) != 0xbff00) + return; + } else if ((svga->crtc[0x36] & 0x03) == 0x01) { + if ((addr & ~0xff) != 0xb7f00) + return; + } + tgui->accel.command = val & 0xff; + tgui->accel.rop = val >> 24; + tgui->accel.use_src = ((val >> 24) & 0x33) ^ (((val >> 24) >> 2) & 0x33); + tgui_accel_command(-1, 0, tgui); + break; - default: - tgui_accel_write_w(addr, val, tgui); - tgui_accel_write_w(addr + 2, val >> 16, tgui); - break; - } + default: + tgui_accel_write_w(addr, val, tgui); + tgui_accel_write_w(addr + 2, val >> 16, tgui); + break; + } } static uint8_t tgui_accel_read(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; - if ((svga->crtc[0x36] & 0x03) == 0x02) { - if ((addr & ~0xff) != 0xbff00) - return 0xff; - } else if ((svga->crtc[0x36] & 0x03) == 0x01) { - if ((addr & ~0xff) != 0xb7f00) - return 0xff; - } + if ((svga->crtc[0x36] & 0x03) == 0x02) { + if ((addr & ~0xff) != 0xbff00) + return 0xff; + } else if ((svga->crtc[0x36] & 0x03) == 0x01) { + if ((addr & ~0xff) != 0xb7f00) + return 0xff; + } - switch (addr & 0xff) - { - case 0x20: /*Status*/ - return 0; + switch (addr & 0xff) { + case 0x20: /*Status*/ + return 0; - case 0x22: - return tgui->accel.ger22 & 0xff; + case 0x22: + return tgui->accel.ger22 & 0xff; - case 0x23: - return tgui->accel.ger22 >> 8; + case 0x23: + return tgui->accel.ger22 >> 8; - case 0x27: /*ROP*/ - return tgui->accel.rop; + case 0x27: /*ROP*/ + return tgui->accel.rop; - case 0x28: /*Flags*/ - return tgui->accel.flags & 0xff; - case 0x29: /*Flags*/ - return tgui->accel.flags >> 8; - case 0x2a: /*Flags*/ - return tgui->accel.flags >> 16; - case 0x2b: - return tgui->accel.flags >> 24; + case 0x28: /*Flags*/ + return tgui->accel.flags & 0xff; + case 0x29: /*Flags*/ + return tgui->accel.flags >> 8; + case 0x2a: /*Flags*/ + return tgui->accel.flags >> 16; + case 0x2b: + return tgui->accel.flags >> 24; - case 0x2c: /*Foreground colour*/ - case 0x78: - return tgui->accel.fg_col & 0xff; - case 0x2d: /*Foreground colour*/ - case 0x79: - return tgui->accel.fg_col >> 8; - case 0x2e: /*Foreground colour*/ - case 0x7a: - return tgui->accel.fg_col >> 16; - case 0x2f: /*Foreground colour*/ - case 0x7b: - return tgui->accel.fg_col >> 24; + case 0x2c: /*Foreground colour*/ + case 0x78: + return tgui->accel.fg_col & 0xff; + case 0x2d: /*Foreground colour*/ + case 0x79: + return tgui->accel.fg_col >> 8; + case 0x2e: /*Foreground colour*/ + case 0x7a: + return tgui->accel.fg_col >> 16; + case 0x2f: /*Foreground colour*/ + case 0x7b: + return tgui->accel.fg_col >> 24; - case 0x30: /*Background colour*/ - case 0x7c: - return tgui->accel.bg_col & 0xff; - case 0x31: /*Background colour*/ - case 0x7d: - return tgui->accel.bg_col >> 8; - case 0x32: /*Background colour*/ - case 0x7e: - return tgui->accel.bg_col >> 16; - case 0x33: /*Background colour*/ - case 0x7f: - return tgui->accel.bg_col >> 24; + case 0x30: /*Background colour*/ + case 0x7c: + return tgui->accel.bg_col & 0xff; + case 0x31: /*Background colour*/ + case 0x7d: + return tgui->accel.bg_col >> 8; + case 0x32: /*Background colour*/ + case 0x7e: + return tgui->accel.bg_col >> 16; + case 0x33: /*Background colour*/ + case 0x7f: + return tgui->accel.bg_col >> 24; - case 0x34: /*Pattern location*/ - return tgui->accel.patloc & 0xff; - case 0x35: /*Pattern location*/ - return tgui->accel.patloc >> 8; + case 0x34: /*Pattern location*/ + return tgui->accel.patloc & 0xff; + case 0x35: /*Pattern location*/ + return tgui->accel.patloc >> 8; - case 0x38: /*Dest X*/ - return tgui->accel.dst_x & 0xff; - case 0x39: /*Dest X*/ - return tgui->accel.dst_x >> 8; - case 0x3a: /*Dest Y*/ - return tgui->accel.dst_y & 0xff; - case 0x3b: /*Dest Y*/ - return tgui->accel.dst_y >> 8; + case 0x38: /*Dest X*/ + return tgui->accel.dst_x & 0xff; + case 0x39: /*Dest X*/ + return tgui->accel.dst_x >> 8; + case 0x3a: /*Dest Y*/ + return tgui->accel.dst_y & 0xff; + case 0x3b: /*Dest Y*/ + return tgui->accel.dst_y >> 8; - case 0x3c: /*Src X*/ - return tgui->accel.src_x & 0xff; - case 0x3d: /*Src X*/ - return tgui->accel.src_x >> 8; - case 0x3e: /*Src Y*/ - return tgui->accel.src_y & 0xff; - case 0x3f: /*Src Y*/ - return tgui->accel.src_y >> 8; + case 0x3c: /*Src X*/ + return tgui->accel.src_x & 0xff; + case 0x3d: /*Src X*/ + return tgui->accel.src_x >> 8; + case 0x3e: /*Src Y*/ + return tgui->accel.src_y & 0xff; + case 0x3f: /*Src Y*/ + return tgui->accel.src_y >> 8; - case 0x40: /*Size X*/ - return tgui->accel.size_x & 0xff; - case 0x41: /*Size X*/ - return tgui->accel.size_x >> 8; - case 0x42: /*Size Y*/ - return tgui->accel.size_y & 0xff; - case 0x43: /*Size Y*/ - return tgui->accel.size_y >> 8; + case 0x40: /*Size X*/ + return tgui->accel.size_x & 0xff; + case 0x41: /*Size X*/ + return tgui->accel.size_x >> 8; + case 0x42: /*Size Y*/ + return tgui->accel.size_y & 0xff; + case 0x43: /*Size Y*/ + return tgui->accel.size_y >> 8; - case 0x44: /*Style*/ - return tgui->accel.style & 0xff; - case 0x45: /*Style*/ - return tgui->accel.style >> 8; - case 0x46: /*Style*/ - return tgui->accel.style >> 16; - case 0x47: /*Style*/ - return tgui->accel.style >> 24; + case 0x44: /*Style*/ + return tgui->accel.style & 0xff; + case 0x45: /*Style*/ + return tgui->accel.style >> 8; + case 0x46: /*Style*/ + return tgui->accel.style >> 16; + case 0x47: /*Style*/ + return tgui->accel.style >> 24; - case 0x48: /*Clip Src X*/ - return tgui->accel.src_x_clip & 0xff; - case 0x49: /*Clip Src X*/ - return tgui->accel.src_x_clip >> 8; - case 0x4a: /*Clip Src Y*/ - return tgui->accel.src_y_clip & 0xff; - case 0x4b: /*Clip Src Y*/ - return tgui->accel.src_y_clip >> 8; + case 0x48: /*Clip Src X*/ + return tgui->accel.src_x_clip & 0xff; + case 0x49: /*Clip Src X*/ + return tgui->accel.src_x_clip >> 8; + case 0x4a: /*Clip Src Y*/ + return tgui->accel.src_y_clip & 0xff; + case 0x4b: /*Clip Src Y*/ + return tgui->accel.src_y_clip >> 8; - case 0x4c: /*Clip Dest X*/ - return tgui->accel.dst_x_clip & 0xff; - case 0x4d: /*Clip Dest X*/ - return tgui->accel.dst_x_clip >> 8; - case 0x4e: /*Clip Dest Y*/ - return tgui->accel.dst_y_clip & 0xff; - case 0x4f: /*Clip Dest Y*/ - return tgui->accel.dst_y_clip >> 8; + case 0x4c: /*Clip Dest X*/ + return tgui->accel.dst_x_clip & 0xff; + case 0x4d: /*Clip Dest X*/ + return tgui->accel.dst_x_clip >> 8; + case 0x4e: /*Clip Dest Y*/ + return tgui->accel.dst_y_clip & 0xff; + case 0x4f: /*Clip Dest Y*/ + return tgui->accel.dst_y_clip >> 8; - case 0x68: /*CKey*/ - return tgui->accel.ckey & 0xff; - case 0x69: /*CKey*/ - return tgui->accel.ckey >> 8; - case 0x6a: /*CKey*/ - return tgui->accel.ckey >> 16; - case 0x6b: /*CKey*/ - return tgui->accel.ckey >> 24; + case 0x68: /*CKey*/ + return tgui->accel.ckey & 0xff; + case 0x69: /*CKey*/ + return tgui->accel.ckey >> 8; + case 0x6a: /*CKey*/ + return tgui->accel.ckey >> 16; + case 0x6b: /*CKey*/ + return tgui->accel.ckey >> 24; - case 0x80: case 0x81: case 0x82: case 0x83: - case 0x84: case 0x85: case 0x86: case 0x87: - case 0x88: case 0x89: case 0x8a: case 0x8b: - case 0x8c: case 0x8d: case 0x8e: case 0x8f: - case 0x90: case 0x91: case 0x92: case 0x93: - case 0x94: case 0x95: case 0x96: case 0x97: - case 0x98: case 0x99: case 0x9a: case 0x9b: - case 0x9c: case 0x9d: case 0x9e: case 0x9f: - case 0xa0: case 0xa1: case 0xa2: case 0xa3: - case 0xa4: case 0xa5: case 0xa6: case 0xa7: - case 0xa8: case 0xa9: case 0xaa: case 0xab: - case 0xac: case 0xad: case 0xae: case 0xaf: - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - case 0xe0: case 0xe1: case 0xe2: case 0xe3: - case 0xe4: case 0xe5: case 0xe6: case 0xe7: - case 0xe8: case 0xe9: case 0xea: case 0xeb: - case 0xec: case 0xed: case 0xee: case 0xef: - case 0xf0: case 0xf1: case 0xf2: case 0xf3: - case 0xf4: case 0xf5: case 0xf6: case 0xf7: - case 0xf8: case 0xf9: case 0xfa: case 0xfb: - case 0xfc: case 0xfd: case 0xfe: case 0xff: - return tgui->accel.pattern[addr & 0x7f]; - } - return 0xff; + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + case 0xf0: + case 0xf1: + case 0xf2: + case 0xf3: + case 0xf4: + case 0xf5: + case 0xf6: + case 0xf7: + case 0xf8: + case 0xf9: + case 0xfa: + case 0xfb: + case 0xfc: + case 0xfd: + case 0xfe: + case 0xff: + return tgui->accel.pattern[addr & 0x7f]; + } + return 0xff; } static uint16_t tgui_accel_read_w(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8); + tgui_t *tgui = (tgui_t *) p; + return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8); } static uint32_t tgui_accel_read_l(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16); + tgui_t *tgui = (tgui_t *) p; + return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16); } static void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; + svga_t *svga = (svga_t *) p; + tgui_t *tgui = (tgui_t *) svga->p; - if (tgui->write_blitter) { - tgui_accel_command(8, val << 24, tgui); - } else - svga_write_linear(addr, val, svga); + if (tgui->write_blitter) { + tgui_accel_command(8, val << 24, tgui); + } else + svga_write_linear(addr, val, svga); } static void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; + svga_t *svga = (svga_t *) p; + tgui_t *tgui = (tgui_t *) svga->p; - if (tgui->write_blitter) - tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui); - else - svga_writew_linear(addr, val, svga); + if (tgui->write_blitter) + tgui_accel_command(16, (((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)) << 16, tgui); + else + svga_writew_linear(addr, val, svga); } static void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; - tgui_t *tgui = (tgui_t *)svga->p; + svga_t *svga = (svga_t *) p; + tgui_t *tgui = (tgui_t *) svga->p; - if (tgui->write_blitter) - tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui); - else - svga_writel_linear(addr, val, svga); + if (tgui->write_blitter) + tgui_accel_command(32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24), tgui); + else + svga_writel_linear(addr, val, svga); } static void tgui_mmio_write(uint32_t addr, uint8_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; - addr &= 0x0000ffff; + addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - tgui_accel_out(addr, val, p); - else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - tgui_accel_write(addr, val, p); - else - tgui_out(addr, val, p); + tgui_accel_out(addr, val, p); + else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) + tgui_accel_write(addr, val, p); + else + tgui_out(addr, val, p); } - static void tgui_mmio_write_w(uint32_t addr, uint16_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; - addr &= 0x0000ffff; + addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - tgui_accel_out_w(addr, val, p); - else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - tgui_accel_write_w(addr, val, p); - else { - tgui_out(addr, val & 0xff, p); - tgui_out(addr + 1, val >> 8, p); - } + tgui_accel_out_w(addr, val, p); + else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) + tgui_accel_write_w(addr, val, p); + else { + tgui_out(addr, val & 0xff, p); + tgui_out(addr + 1, val >> 8, p); + } } - static void tgui_mmio_write_l(uint32_t addr, uint32_t val, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; - addr &= 0x0000ffff; + addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - tgui_accel_out_l(addr, val, p); - else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - tgui_accel_write_l(addr, val, p); - else { - tgui_out(addr, val & 0xff, p); - tgui_out(addr + 1, val >> 8, p); - tgui_out(addr + 2, val >> 16, p); - tgui_out(addr + 3, val >> 24, p); - } + tgui_accel_out_l(addr, val, p); + else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) + tgui_accel_write_l(addr, val, p); + else { + tgui_out(addr, val & 0xff, p); + tgui_out(addr + 1, val >> 8, p); + tgui_out(addr + 2, val >> 16, p); + tgui_out(addr + 3, val >> 24, p); + } } - static uint8_t tgui_mmio_read(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; uint8_t ret = 0xff; - addr &= 0x0000ffff; + addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - ret = tgui_accel_in(addr, p); - else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - ret = tgui_accel_read(addr, p); - else - ret = tgui_in(addr, p); + ret = tgui_accel_in(addr, p); + else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) + ret = tgui_accel_read(addr, p); + else + ret = tgui_in(addr, p); return ret; } - static uint16_t tgui_mmio_read_w(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - uint16_t ret = 0xffff; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; + uint16_t ret = 0xffff; - addr &= 0x0000ffff; + addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - ret = tgui_accel_in_w(addr, p); - else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - ret = tgui_accel_read_w(addr, p); - else - ret = tgui_in(addr, p) | (tgui_in(addr + 1, p) << 8); + ret = tgui_accel_in_w(addr, p); + else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) + ret = tgui_accel_read_w(addr, p); + else + ret = tgui_in(addr, p) | (tgui_in(addr + 1, p) << 8); return ret; } - static uint32_t tgui_mmio_read_l(uint32_t addr, void *p) { - tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - uint32_t ret = 0xffffffff; + tgui_t *tgui = (tgui_t *) p; + svga_t *svga = &tgui->svga; + uint32_t ret = 0xffffffff; - addr &= 0x0000ffff; + addr &= 0x0000ffff; if (((svga->crtc[0x36] & 0x03) == 0x00) && (addr >= 0x2100 && addr <= 0x21ff)) - ret = tgui_accel_in_l(addr, p); - else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) - ret = tgui_accel_read_l(addr, p); - else - ret = tgui_in(addr, p) | (tgui_in(addr + 1, p) << 8) | (tgui_in(addr + 2, p) << 16) | (tgui_in(addr + 3, p) << 24); + ret = tgui_accel_in_l(addr, p); + else if (((svga->crtc[0x36] & 0x03) > 0x00) && (addr <= 0xff)) + ret = tgui_accel_read_l(addr, p); + else + ret = tgui_in(addr, p) | (tgui_in(addr + 1, p) << 8) | (tgui_in(addr + 2, p) << 16) | (tgui_in(addr + 3, p) << 24); return ret; } -static void *tgui_init(const device_t *info) +static void * +tgui_init(const device_t *info) { - const char *bios_fn; + const char *bios_fn; - tgui_t *tgui = malloc(sizeof(tgui_t)); - svga_t *svga = &tgui->svga; - memset(tgui, 0, sizeof(tgui_t)); + tgui_t *tgui = malloc(sizeof(tgui_t)); + svga_t *svga = &tgui->svga; + memset(tgui, 0, sizeof(tgui_t)); - tgui->vram_size = device_get_config_int("memory") << 20; - tgui->vram_mask = tgui->vram_size - 1; + tgui->vram_size = device_get_config_int("memory") << 20; + tgui->vram_mask = tgui->vram_size - 1; - tgui->type = info->local & 0xff; + tgui->type = info->local & 0xff; - tgui->pci = !!(info->flags & DEVICE_PCI); + tgui->pci = !!(info->flags & DEVICE_PCI); - switch(tgui->type) { - case TGUI_9400CXI: - bios_fn = ROM_TGUI_9400CXI; - break; - case TGUI_9440: - bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_9440; - break; - case TGUI_9660: - case TGUI_9680: - bios_fn = ROM_TGUI_96xx; - break; - default: - free(tgui); - return NULL; - } + switch (tgui->type) { + case TGUI_9400CXI: + bios_fn = ROM_TGUI_9400CXI; + break; + case TGUI_9440: + bios_fn = (info->local & ONBOARD) ? NULL : ROM_TGUI_9440; + break; + case TGUI_9660: + case TGUI_9680: + bios_fn = ROM_TGUI_96xx; + break; + default: + free(tgui); + return NULL; + } - tgui->has_bios = (bios_fn != NULL); + tgui->has_bios = (bios_fn != NULL); - if (tgui->has_bios) { - rom_init(&tgui->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (tgui->pci) - mem_mapping_disable(&tgui->bios_rom.mapping); - } + if (tgui->has_bios) { + rom_init(&tgui->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (tgui->pci) + mem_mapping_disable(&tgui->bios_rom.mapping); + } - if (tgui->pci) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_vlb); + if (tgui->pci) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_pci); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tgui_vlb); - svga_init(info, svga, tgui, tgui->vram_size, - tgui_recalctimings, - tgui_in, tgui_out, - tgui_hwcursor_draw, - NULL); + svga_init(info, svga, tgui, tgui->vram_size, + tgui_recalctimings, + tgui_in, tgui_out, + tgui_hwcursor_draw, + NULL); - if (tgui->type == TGUI_9400CXI) - svga->ramdac = device_add(&tkd8001_ramdac_device); + if (tgui->type == TGUI_9400CXI) + svga->ramdac = device_add(&tkd8001_ramdac_device); - mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, svga); - mem_mapping_add(&tgui->accel_mapping, 0, 0, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); - if (tgui->type >= TGUI_9440) - mem_mapping_add(&tgui->mmio_mapping, 0, 0, tgui_mmio_read, tgui_mmio_read_w, tgui_mmio_read_l, tgui_mmio_write, tgui_mmio_write_w, tgui_mmio_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); - mem_mapping_disable(&tgui->accel_mapping); - mem_mapping_disable(&tgui->mmio_mapping); + mem_mapping_add(&tgui->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l, NULL, MEM_MAPPING_EXTERNAL, svga); + mem_mapping_add(&tgui->accel_mapping, 0, 0, tgui_accel_read, tgui_accel_read_w, tgui_accel_read_l, tgui_accel_write, tgui_accel_write_w, tgui_accel_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); + if (tgui->type >= TGUI_9440) + mem_mapping_add(&tgui->mmio_mapping, 0, 0, tgui_mmio_read, tgui_mmio_read_w, tgui_mmio_read_l, tgui_mmio_write, tgui_mmio_write_w, tgui_mmio_write_l, NULL, MEM_MAPPING_EXTERNAL, tgui); + mem_mapping_disable(&tgui->accel_mapping); + mem_mapping_disable(&tgui->mmio_mapping); - tgui_set_io(tgui); + tgui_set_io(tgui); - if (tgui->pci && (tgui->type >= TGUI_9440)) { - if (tgui->has_bios) - tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); - else - tgui->card = pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui); - } + if (tgui->pci && (tgui->type >= TGUI_9440)) { + if (tgui->has_bios) + tgui->card = pci_add_card(PCI_ADD_VIDEO, tgui_pci_read, tgui_pci_write, tgui); + else + tgui->card = pci_add_card(PCI_ADD_VIDEO | PCI_ADD_STRICT, tgui_pci_read, tgui_pci_write, tgui); + } - tgui->pci_regs[PCI_REG_COMMAND] = 7; + tgui->pci_regs[PCI_REG_COMMAND] = 7; - if (tgui->has_bios) { - tgui->pci_regs[0x30] = 0x00; - tgui->pci_regs[0x32] = 0x0c; - tgui->pci_regs[0x33] = 0x00; - } + if (tgui->has_bios) { + tgui->pci_regs[0x30] = 0x00; + tgui->pci_regs[0x32] = 0x0c; + tgui->pci_regs[0x33] = 0x00; + } - if (tgui->type >= TGUI_9440) { - svga->packed_chain4 = 1; + if (tgui->type >= TGUI_9440) { + svga->packed_chain4 = 1; - tgui->i2c = i2c_gpio_init("ddc_tgui"); - tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c)); - } + tgui->i2c = i2c_gpio_init("ddc_tgui"); + tgui->ddc = ddc_init(i2c_gpio_get_bus(tgui->i2c)); + } - return tgui; + return tgui; } -static int tgui9400cxi_available(void) +static int +tgui9400cxi_available(void) { - return rom_present(ROM_TGUI_9400CXI); + return rom_present(ROM_TGUI_9400CXI); } -static int tgui9440_available(void) +static int +tgui9440_available(void) { - return rom_present(ROM_TGUI_9440); + return rom_present(ROM_TGUI_9440); } -static int tgui96xx_available(void) +static int +tgui96xx_available(void) { - return rom_present(ROM_TGUI_96xx); + return rom_present(ROM_TGUI_96xx); } -void tgui_close(void *p) +void +tgui_close(void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *) p; svga_close(&tgui->svga); - if (tgui->type >= TGUI_9440) { + if (tgui->type >= TGUI_9440) { ddc_close(tgui->ddc); i2c_gpio_close(tgui->i2c); - }; + }; free(tgui); } -void tgui_speed_changed(void *p) +void +tgui_speed_changed(void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *) p; - svga_recalctimings(&tgui->svga); + svga_recalctimings(&tgui->svga); } -void tgui_force_redraw(void *p) +void +tgui_force_redraw(void *p) { - tgui_t *tgui = (tgui_t *)p; + tgui_t *tgui = (tgui_t *) p; - tgui->svga.fullchange = changeframecount; + tgui->svga.fullchange = changeframecount; } // clang-format off @@ -3234,85 +3619,85 @@ static const device_config_t tgui96xx_config[] = { // clang-format on const device_t tgui9400cxi_device = { - .name = "Trident TGUI 9400CXi", + .name = "Trident TGUI 9400CXi", .internal_name = "tgui9400cxi_vlb", - .flags = DEVICE_VLB, - .local = TGUI_9400CXI, - .init = tgui_init, - .close = tgui_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = TGUI_9400CXI, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, { .available = tgui9400cxi_available }, .speed_changed = tgui_speed_changed, - .force_redraw = tgui_force_redraw, - .config = tgui9440_config + .force_redraw = tgui_force_redraw, + .config = tgui9440_config }; const device_t tgui9440_vlb_device = { - .name = "Trident TGUI 9440AGi VLB", + .name = "Trident TGUI 9440AGi VLB", .internal_name = "tgui9440_vlb", - .flags = DEVICE_VLB, - .local = TGUI_9440, - .init = tgui_init, - .close = tgui_close, - .reset = NULL, + .flags = DEVICE_VLB, + .local = TGUI_9440, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, { .available = tgui9440_available }, .speed_changed = tgui_speed_changed, - .force_redraw = tgui_force_redraw, - .config = tgui9440_config + .force_redraw = tgui_force_redraw, + .config = tgui9440_config }; const device_t tgui9440_pci_device = { - .name = "Trident TGUI 9440AGi PCI", + .name = "Trident TGUI 9440AGi PCI", .internal_name = "tgui9440_pci", - .flags = DEVICE_PCI, - .local = TGUI_9440, - .init = tgui_init, - .close = tgui_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = TGUI_9440, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, { .available = tgui9440_available }, .speed_changed = tgui_speed_changed, - .force_redraw = tgui_force_redraw, - .config = tgui9440_config + .force_redraw = tgui_force_redraw, + .config = tgui9440_config }; const device_t tgui9440_onboard_pci_device = { - .name = "Trident TGUI 9440AGi On-Board PCI", + .name = "Trident TGUI 9440AGi On-Board PCI", .internal_name = "tgui9440_onboard_pci", - .flags = DEVICE_PCI, - .local = TGUI_9440 | ONBOARD, - .init = tgui_init, - .close = tgui_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = TGUI_9440 | ONBOARD, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, { .available = NULL }, .speed_changed = tgui_speed_changed, - .force_redraw = tgui_force_redraw, - .config = tgui9440_config + .force_redraw = tgui_force_redraw, + .config = tgui9440_config }; const device_t tgui9660_pci_device = { - .name = "Trident TGUI 9660XGi PCI", + .name = "Trident TGUI 9660XGi PCI", .internal_name = "tgui9660_pci", - .flags = DEVICE_PCI, - .local = TGUI_9660, - .init = tgui_init, - .close = tgui_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = TGUI_9660, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, { .available = tgui96xx_available }, .speed_changed = tgui_speed_changed, - .force_redraw = tgui_force_redraw, - .config = tgui96xx_config + .force_redraw = tgui_force_redraw, + .config = tgui96xx_config }; const device_t tgui9680_pci_device = { - .name = "Trident TGUI 9680XGi PCI", + .name = "Trident TGUI 9680XGi PCI", .internal_name = "tgui9680_pci", - .flags = DEVICE_PCI, - .local = TGUI_9680, - .init = tgui_init, - .close = tgui_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = TGUI_9680, + .init = tgui_init, + .close = tgui_close, + .reset = NULL, { .available = tgui96xx_available }, .speed_changed = tgui_speed_changed, - .force_redraw = tgui_force_redraw, - .config = tgui96xx_config + .force_redraw = tgui_force_redraw, + .config = tgui96xx_config }; diff --git a/src/video/vid_ti_cf62011.c b/src/video/vid_ti_cf62011.c index 36db5b89d..417f85861 100644 --- a/src/video/vid_ti_cf62011.c +++ b/src/video/vid_ti_cf62011.c @@ -66,30 +66,28 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef struct { - svga_t svga; + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - int enabled; + int enabled; - uint32_t vram_size; + uint32_t vram_size; - uint8_t banking; - uint8_t reg_2100; - uint8_t reg_210a; + uint8_t banking; + uint8_t reg_2100; + uint8_t reg_210a; } tivga_t; -static video_timings_t timing_ti_cf62011 = {VIDEO_ISA, 6, 8,16, 6, 8,16}; - +static video_timings_t timing_ti_cf62011 = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; static void vid_out(uint16_t addr, uint8_t val, void *priv) { - tivga_t *ti = (tivga_t *)priv; - svga_t *svga = &ti->svga; - uint8_t old; + tivga_t *ti = (tivga_t *) priv; + svga_t *svga = &ti->svga; + uint8_t old; #if 0 if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && @@ -97,60 +95,59 @@ vid_out(uint16_t addr, uint8_t val, void *priv) #endif switch (addr) { - case 0x0102: - ti->enabled = (val & 0x01); - return; + case 0x0102: + ti->enabled = (val & 0x01); + return; - case 0x03d4: - svga->crtcreg = val & 0x3f; - return; + case 0x03d4: + svga->crtcreg = val & 0x3f; + return; - case 0x03d5: - if (svga->crtcreg & 0x20) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - break; + case 0x03d5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + break; - case 0x2100: - ti->reg_2100 = val; - if ((val & 7) < 4) - svga->read_bank = svga->write_bank = 0; - else - svga->read_bank = svga->write_bank = (ti->banking & 0x7) * 0x10000; - break; + case 0x2100: + ti->reg_2100 = val; + if ((val & 7) < 4) + svga->read_bank = svga->write_bank = 0; + else + svga->read_bank = svga->write_bank = (ti->banking & 0x7) * 0x10000; + break; - case 0x2108: - if ((ti->reg_2100 & 7) >= 4) - svga->read_bank = svga->write_bank = (val & 0x7) * 0x10000; - ti->banking = val; - break; + case 0x2108: + if ((ti->reg_2100 & 7) >= 4) + svga->read_bank = svga->write_bank = (val & 0x7) * 0x10000; + ti->banking = val; + break; - case 0x210a: - ti->reg_210a = val; - break; + case 0x210a: + ti->reg_210a = val; + break; } svga_out(addr, val, svga); } - static uint8_t vid_in(uint16_t addr, void *priv) { - tivga_t *ti = (tivga_t *)priv; - svga_t *svga = &ti->svga; - uint8_t ret; + tivga_t *ti = (tivga_t *) priv; + svga_t *svga = &ti->svga; + uint8_t ret; #if 0 if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) && @@ -158,120 +155,116 @@ vid_in(uint16_t addr, void *priv) #endif switch (addr) { - case 0x0100: - ret = 0xfe; - break; + case 0x0100: + ret = 0xfe; + break; - case 0x0101: - ret = 0xe8; - break; + case 0x0101: + ret = 0xe8; + break; - case 0x0102: - ret = ti->enabled; - break; + case 0x0102: + ret = ti->enabled; + break; - case 0x03d4: - ret = svga->crtcreg; - break; + case 0x03d4: + ret = svga->crtcreg; + break; - case 0x03d5: - if (svga->crtcreg & 0x20) - ret = 0xff; - else - ret = svga->crtc[svga->crtcreg]; - break; + case 0x03d5: + if (svga->crtcreg & 0x20) + ret = 0xff; + else + ret = svga->crtc[svga->crtcreg]; + break; - case 0x2100: - ret = ti->reg_2100; - break; + case 0x2100: + ret = ti->reg_2100; + break; - case 0x2108: - ret = ti->banking; - break; + case 0x2108: + ret = ti->banking; + break; - case 0x210a: - ret = ti->reg_210a; - break; + case 0x210a: + ret = ti->reg_210a; + break; - default: - ret = svga_in(addr, svga); - break; + default: + ret = svga_in(addr, svga); + break; } - return(ret); + return (ret); } - static void vid_speed_changed(void *priv) { - tivga_t *ti = (tivga_t *)priv; + tivga_t *ti = (tivga_t *) priv; svga_recalctimings(&ti->svga); } - static void vid_force_redraw(void *priv) { - tivga_t *ti = (tivga_t *)priv; + tivga_t *ti = (tivga_t *) priv; ti->svga.fullchange = changeframecount; } - static void vid_close(void *priv) { - tivga_t *ti = (tivga_t *)priv; + tivga_t *ti = (tivga_t *) priv; svga_close(&ti->svga); free(ti); } - static void * vid_init(const device_t *info) { tivga_t *ti; /* Allocate control block and initialize. */ - ti = (tivga_t *)malloc(sizeof(tivga_t)); + ti = (tivga_t *) malloc(sizeof(tivga_t)); memset(ti, 0x00, sizeof(tivga_t)); /* Set amount of VRAM in KB. */ if (info->local == 0) - ti->vram_size = device_get_config_int("vram_size"); + ti->vram_size = device_get_config_int("vram_size"); else - ti->vram_size = info->local; + ti->vram_size = info->local; video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ti_cf62011); svga_init(info, &ti->svga, ti, - ti->vram_size<<10, - NULL, vid_in, vid_out, NULL, NULL); + ti->vram_size << 10, + NULL, vid_in, vid_out, NULL, NULL); io_sethandler(0x0100, 2, vid_in, NULL, NULL, NULL, NULL, NULL, ti); io_sethandler(0x03c0, 32, vid_in, NULL, NULL, vid_out, NULL, NULL, ti); io_sethandler(0x2100, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, ti); - ti->svga.bpp = 8; + ti->svga.bpp = 8; ti->svga.miscout = 1; - return(ti); + return (ti); } const device_t ibm_ps1_2121_device = { - .name = "IBM PS/1 Model 2121 SVGA", + .name = "IBM PS/1 Model 2121 SVGA", .internal_name = "ibm_ps1_2121", - .flags = DEVICE_ISA, - .local = 512, - .init = vid_init, - .close = vid_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 512, + .init = vid_init, + .close = vid_close, + .reset = NULL, { .available = NULL }, .speed_changed = vid_speed_changed, - .force_redraw = vid_force_redraw, - .config = NULL + .force_redraw = vid_force_redraw, + .config = NULL }; diff --git a/src/video/vid_tkd8001_ramdac.c b/src/video/vid_tkd8001_ramdac.c index e2b7ed498..225c91c4b 100644 --- a/src/video/vid_tkd8001_ramdac.c +++ b/src/video/vid_tkd8001_ramdac.c @@ -28,76 +28,71 @@ #include <86box/video.h> #include <86box/vid_svga.h> - -typedef struct tkd8001_ramdac_t -{ - int state; +typedef struct tkd8001_ramdac_t { + int state; uint8_t ctrl; } tkd8001_ramdac_t; - void tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga) { tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; switch (addr) { - case 0x3C6: - if (ramdac->state == 4) { - ramdac->state = 0; - ramdac->ctrl = val; - switch (val >> 5) { - case 0: - case 1: - case 2: - case 3: - svga->bpp = 8; - break; - case 5: - svga->bpp = 15; - break; - case 6: - svga->bpp = 24; - break; - case 7: - svga->bpp = 16; - break; - } - return; - } - break; - case 0x3C7: - case 0x3C8: - case 0x3C9: - ramdac->state = 0; - break; + case 0x3C6: + if (ramdac->state == 4) { + ramdac->state = 0; + ramdac->ctrl = val; + switch (val >> 5) { + case 0: + case 1: + case 2: + case 3: + svga->bpp = 8; + break; + case 5: + svga->bpp = 15; + break; + case 6: + svga->bpp = 24; + break; + case 7: + svga->bpp = 16; + break; + } + return; + } + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; } svga_out(addr, val, svga); } - uint8_t tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga) { tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p; switch (addr) { - case 0x3C6: - if (ramdac->state == 4) - return ramdac->ctrl; - ramdac->state++; - break; - case 0x3C7: - case 0x3C8: - case 0x3C9: - ramdac->state = 0; - break; + case 0x3C6: + if (ramdac->state == 4) + return ramdac->ctrl; + ramdac->state++; + break; + case 0x3C7: + case 0x3C8: + case 0x3C9: + ramdac->state = 0; + break; } return svga_in(addr, svga); } - static void * tkd8001_ramdac_init(const device_t *info) { @@ -107,26 +102,25 @@ tkd8001_ramdac_init(const device_t *info) return ramdac; } - static void tkd8001_ramdac_close(void *priv) { tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t tkd8001_ramdac_device = { - .name = "Trident TKD8001 RAMDAC", + .name = "Trident TKD8001 RAMDAC", .internal_name = "tkd8001_ramdac", - .flags = 0, - .local = 0, - .init = tkd8001_ramdac_init, - .close = tkd8001_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = tkd8001_ramdac_init, + .close = tkd8001_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 8d488552e..0af37ac94 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -31,420 +31,453 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define TVGA8900B_ID 0x03 -#define TVGA9000B_ID 0x23 -#define TVGA8900CLD_ID 0x33 +#define TVGA8900B_ID 0x03 +#define TVGA9000B_ID 0x23 +#define TVGA8900CLD_ID 0x33 -#define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi" -#define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin" -#define ROM_TVGA_9000B "roms/video/tvga/tvga9000b.bin" +#define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi" +#define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin" +#define ROM_TVGA_9000B "roms/video/tvga/tvga9000b.bin" -typedef struct tvga_t -{ - mem_mapping_t linear_mapping; - mem_mapping_t accel_mapping; +typedef struct tvga_t { + mem_mapping_t linear_mapping; + mem_mapping_t accel_mapping; - svga_t svga; + svga_t svga; - rom_t bios_rom; - uint8_t card_id; + rom_t bios_rom; + uint8_t card_id; - uint8_t tvga_3d8, tvga_3d9; - int oldmode; - uint8_t oldctrl1; - uint8_t oldctrl2, newctrl2; + uint8_t tvga_3d8, tvga_3d9; + int oldmode; + uint8_t oldctrl1; + uint8_t oldctrl2, newctrl2; - int vram_size; - uint32_t vram_mask; + int vram_size; + uint32_t vram_mask; } tvga_t; -video_timings_t timing_tvga8900 = {VIDEO_ISA, 3, 3, 6, 8, 8, 12}; -video_timings_t timing_tvga9000 = {VIDEO_ISA, 7, 7, 12, 7, 7, 12}; +video_timings_t timing_tvga8900 = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 }; +video_timings_t timing_tvga9000 = { .type = VIDEO_ISA, .write_b = 7, .write_w = 7, .write_l = 12, .read_b = 7, .read_w = 7, .read_l = 12 }; -static uint8_t crtc_mask[0x40] = -{ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef, - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +static uint8_t crtc_mask[0x40] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static void tvga_recalcbanking(tvga_t *tvga); -void tvga_out(uint16_t addr, uint8_t val, void *p) +void +tvga_out(uint16_t addr, uint8_t val, void *p) { - tvga_t *tvga = (tvga_t *)p; - svga_t *svga = &tvga->svga; + tvga_t *tvga = (tvga_t *) p; + svga_t *svga = &tvga->svga; - uint8_t old; + uint8_t old; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3C5: - switch (svga->seqaddr & 0xf) - { - case 0xB: - tvga->oldmode=1; - break; - case 0xC: - if (svga->seqregs[0xe] & 0x80) - svga->seqregs[0xc] = val; - break; - case 0xd: - if (tvga->oldmode) - tvga->oldctrl2 = val; - else - { - tvga->newctrl2 = val; - svga_recalctimings(svga); - } - break; - case 0xE: - if (tvga->oldmode) - tvga->oldctrl1 = val; - else - { - svga->seqregs[0xe] = val ^ 2; - tvga->tvga_3d8 = svga->seqregs[0xe] & 0xf; - tvga_recalcbanking(tvga); - } - return; - } - break; - - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (tvga->card_id != TVGA9000B_ID) { - tkd8001_ramdac_out(addr, val, svga->ramdac, svga); - return; - } - break; - - case 0x3CF: - switch (svga->gdcaddr & 15) - { - case 0x6: - old = svga->gdcreg[6]; - svga_out(addr, val, svga); - if ((old & 0xc) != 0 && (val & 0xc) == 0) - { - /*override mask - TVGA supports linear 128k at A0000*/ - svga->banked_mask = 0x1ffff; - } - return; - case 0xE: - svga->gdcreg[0xe] = val ^ 2; - tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf; - tvga_recalcbanking(tvga); - break; - case 0xF: - svga->gdcreg[0xf] = val; - tvga_recalcbanking(tvga); - break; - } - break; - case 0x3D4: - svga->crtcreg = val & 0x3f; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - val &= crtc_mask[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - } - switch (svga->crtcreg) { - case 0x1e: - svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; - break; - } - return; - case 0x3D8: - if (svga->gdcreg[0xf] & 4) { - tvga->tvga_3d8 = val; - tvga_recalcbanking(tvga); - } - return; - case 0x3D9: - if (svga->gdcreg[0xf] & 4) { - tvga->tvga_3d9 = val; - tvga_recalcbanking(tvga); - } - return; - case 0x3DB: - if (tvga->card_id != TVGA9000B_ID) { - /*3db appears to be a 4 bit clock select register on 8900D*/ - svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2); - tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2); - tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1); + switch (addr) { + case 0x3C5: + switch (svga->seqaddr & 0xf) { + case 0xB: + tvga->oldmode = 1; + break; + case 0xC: + if (svga->seqregs[0xe] & 0x80) + svga->seqregs[0xc] = val; + break; + case 0xd: + if (tvga->oldmode) + tvga->oldctrl2 = val; + else { + tvga->newctrl2 = val; svga_recalctimings(svga); + } + break; + case 0xE: + if (tvga->oldmode) + tvga->oldctrl1 = val; + else { + svga->seqregs[0xe] = val ^ 2; + tvga->tvga_3d8 = svga->seqregs[0xe] & 0xf; + tvga_recalcbanking(tvga); + } + return; + } + break; + + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tvga->card_id != TVGA9000B_ID) { + tkd8001_ramdac_out(addr, val, svga->ramdac, svga); + return; + } + break; + + case 0x3CF: + switch (svga->gdcaddr & 15) { + case 0x6: + old = svga->gdcreg[6]; + svga_out(addr, val, svga); + if ((old & 0xc) != 0 && (val & 0xc) == 0) { + /*override mask - TVGA supports linear 128k at A0000*/ + svga->banked_mask = 0x1ffff; + } + return; + case 0xE: + svga->gdcreg[0xe] = val ^ 2; + tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf; + tvga_recalcbanking(tvga); + break; + case 0xF: + svga->gdcreg[0xf] = val; + tvga_recalcbanking(tvga); + break; + } + break; + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + val &= crtc_mask[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } - break; - } - svga_out(addr, val, svga); + } + switch (svga->crtcreg) { + case 0x1e: + svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff; + break; + } + return; + case 0x3D8: + if (svga->gdcreg[0xf] & 4) { + tvga->tvga_3d8 = val; + tvga_recalcbanking(tvga); + } + return; + case 0x3D9: + if (svga->gdcreg[0xf] & 4) { + tvga->tvga_3d9 = val; + tvga_recalcbanking(tvga); + } + return; + case 0x3DB: + if (tvga->card_id != TVGA9000B_ID) { + /*3db appears to be a 4 bit clock select register on 8900D*/ + svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2); + tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2); + tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1); + svga_recalctimings(svga); + } + break; + } + svga_out(addr, val, svga); } -uint8_t tvga_in(uint16_t addr, void *p) +uint8_t +tvga_in(uint16_t addr, void *p) { - tvga_t *tvga = (tvga_t *)p; - svga_t *svga = &tvga->svga; + tvga_t *tvga = (tvga_t *) p; + svga_t *svga = &tvga->svga; - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3C5: - if ((svga->seqaddr & 0xf) == 0xb) - { - tvga->oldmode = 0; - return tvga->card_id; /*Must be at least a TVGA8900*/ - } - if ((svga->seqaddr & 0xf) == 0xd) - { - if (tvga->oldmode) return tvga->oldctrl2; - return tvga->newctrl2; - } - if ((svga->seqaddr & 0xf) == 0xe) - { - if (tvga->oldmode) - return tvga->oldctrl1; - } - break; - case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (tvga->card_id != TVGA9000B_ID) { - return tkd8001_ramdac_in(addr, svga->ramdac, svga); - } - break; - case 0x3D4: - return svga->crtcreg; - case 0x3D5: - if (svga->crtcreg > 0x18 && svga->crtcreg < 0x1e) - return 0xff; - return svga->crtc[svga->crtcreg]; - case 0x3d8: - return tvga->tvga_3d8; - case 0x3d9: - return tvga->tvga_3d9; - } - return svga_in(addr, svga); + switch (addr) { + case 0x3C5: + if ((svga->seqaddr & 0xf) == 0xb) { + tvga->oldmode = 0; + return tvga->card_id; /*Must be at least a TVGA8900*/ + } + if ((svga->seqaddr & 0xf) == 0xd) { + if (tvga->oldmode) + return tvga->oldctrl2; + return tvga->newctrl2; + } + if ((svga->seqaddr & 0xf) == 0xe) { + if (tvga->oldmode) + return tvga->oldctrl1; + } + break; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + if (tvga->card_id != TVGA9000B_ID) { + return tkd8001_ramdac_in(addr, svga->ramdac, svga); + } + break; + case 0x3D4: + return svga->crtcreg; + case 0x3D5: + if (svga->crtcreg > 0x18 && svga->crtcreg < 0x1e) + return 0xff; + return svga->crtc[svga->crtcreg]; + case 0x3d8: + return tvga->tvga_3d8; + case 0x3d9: + return tvga->tvga_3d9; + } + return svga_in(addr, svga); } -static void tvga_recalcbanking(tvga_t *tvga) +static void +tvga_recalcbanking(tvga_t *tvga) { - svga_t *svga = &tvga->svga; + svga_t *svga = &tvga->svga; - svga->write_bank = (tvga->tvga_3d8 & 0x1f) * 65536; + svga->write_bank = (tvga->tvga_3d8 & 0x1f) * 65536; - if (svga->gdcreg[0xf] & 1) - svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536; - else - svga->read_bank = svga->write_bank; + if (svga->gdcreg[0xf] & 1) + svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536; + else + svga->read_bank = svga->write_bank; } -void tvga_recalctimings(svga_t *svga) +void +tvga_recalctimings(svga_t *svga) { - tvga_t *tvga = (tvga_t *)svga->p; - int clksel; - int high_res_256 = 0; + tvga_t *tvga = (tvga_t *) svga->p; + int clksel; + int high_res_256 = 0; - if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, - given that TVGA8900D has no overflow bits. - Some sort of overflow is required for 320x200x24 and 1024x768x16*/ - if (svga->crtc[0x29] & 0x10) - svga->rowoffset += 0x100; + if (!svga->rowoffset) + svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled, + given that TVGA8900D has no overflow bits. + Some sort of overflow is required for 320x200x24 and 1024x768x16*/ + if (svga->crtc[0x29] & 0x10) + svga->rowoffset += 0x100; - if (svga->bpp == 24) - svga->hdisp = (svga->crtc[1] + 1) * 8; + if (svga->bpp == 24) + svga->hdisp = (svga->crtc[1] + 1) * 8; - if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000; - if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000; - if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000; + if ((svga->crtc[0x1e] & 0xA0) == 0xA0) + svga->ma_latch |= 0x10000; + if ((svga->crtc[0x27] & 0x01) == 0x01) + svga->ma_latch |= 0x20000; + if ((svga->crtc[0x27] & 0x02) == 0x02) + svga->ma_latch |= 0x40000; - if (tvga->oldctrl2 & 0x10) - { - svga->rowoffset <<= 1; - svga->ma_latch <<= 1; - } + if (tvga->oldctrl2 & 0x10) { + svga->rowoffset <<= 1; + svga->ma_latch <<= 1; + } - if (svga->gdcreg[0xf] & 0x08) - { - svga->htotal *= 2; - svga->hdisp *= 2; - svga->hdisp_time *= 2; - } + if (svga->gdcreg[0xf] & 0x08) { + svga->htotal *= 2; + svga->hdisp *= 2; + svga->hdisp_time *= 2; + } - svga->interlace = (svga->crtc[0x1e] & 4); + svga->interlace = (svga->crtc[0x1e] & 4); + if (svga->interlace) + svga->rowoffset >>= 1; + + if (tvga->card_id == TVGA8900CLD_ID) + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1); + else + clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3); + + switch (clksel) { + case 0x2: + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; + break; + case 0x3: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + case 0x4: + svga->clock = (cpuclock * (double) (1ull << 32)) / 57272000.0; + break; + case 0x5: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0; + break; + case 0x6: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0; + break; + case 0x7: + svga->clock = (cpuclock * (double) (1ull << 32)) / 40000000.0; + break; + case 0x8: + svga->clock = (cpuclock * (double) (1ull << 32)) / 88000000.0; + break; + case 0x9: + svga->clock = (cpuclock * (double) (1ull << 32)) / 98000000.0; + break; + case 0xa: + svga->clock = (cpuclock * (double) (1ull << 32)) / 118800000.0; + break; + case 0xb: + svga->clock = (cpuclock * (double) (1ull << 32)) / 108000000.0; + break; + case 0xc: + svga->clock = (cpuclock * (double) (1ull << 32)) / 72000000.0; + break; + case 0xd: + svga->clock = (cpuclock * (double) (1ull << 32)) / 77000000.0; + break; + case 0xe: + svga->clock = (cpuclock * (double) (1ull << 32)) / 80000000.0; + break; + case 0xf: + svga->clock = (cpuclock * (double) (1ull << 32)) / 75000000.0; + break; + } + + if (tvga->card_id != TVGA8900CLD_ID) { + /*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode + (without the VGA pixel doubling). Instead it implements these modes by + doubling the horizontal pixel count and pixel clock. Hence we use a + basic heuristic to detect this*/ if (svga->interlace) - svga->rowoffset >>= 1; + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); + else + high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); + } - if (tvga->card_id == TVGA8900CLD_ID) - clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1); - else - clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3); - - switch (clksel) { - case 0x2: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break; - case 0x3: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break; - case 0x4: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break; - case 0x5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break; - case 0x6: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break; - case 0x7: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break; - case 0x8: svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; break; - case 0x9: svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; break; - case 0xa: svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; break; - case 0xb: svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; break; - case 0xc: svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; break; - case 0xd: svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; break; - case 0xe: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break; - case 0xf: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break; - } - - if (tvga->card_id != TVGA8900CLD_ID) { - /*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode - (without the VGA pixel doubling). Instead it implements these modes by - doubling the horizontal pixel count and pixel clock. Hence we use a - basic heuristic to detect this*/ - if (svga->interlace) - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4); - else - high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2); - } - - if ((tvga->oldctrl2 & 0x10) || high_res_256) - { - if (high_res_256) - svga->hdisp /= 2; - switch (svga->bpp) - { - case 8: - svga->render = svga_render_8bpp_highres; - break; - case 15: - svga->render = svga_render_15bpp_highres; - svga->hdisp /= 2; - break; - case 16: - svga->render = svga_render_16bpp_highres; - svga->hdisp /= 2; - break; - case 24: - svga->render = svga_render_24bpp_highres; - svga->hdisp /= 3; - break; - } - svga->lowres = 0; + if ((tvga->oldctrl2 & 0x10) || high_res_256) { + if (high_res_256) + svga->hdisp /= 2; + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + svga->hdisp /= 2; + break; + case 16: + svga->render = svga_render_16bpp_highres; + svga->hdisp /= 2; + break; + case 24: + svga->render = svga_render_24bpp_highres; + svga->hdisp /= 3; + break; } + svga->lowres = 0; + } } - -static void *tvga_init(const device_t *info) +static void * +tvga_init(const device_t *info) { - const char *bios_fn; - tvga_t *tvga = malloc(sizeof(tvga_t)); - memset(tvga, 0, sizeof(tvga_t)); + const char *bios_fn; + tvga_t *tvga = malloc(sizeof(tvga_t)); + memset(tvga, 0, sizeof(tvga_t)); - if (info->local == TVGA9000B_ID) { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); - tvga->vram_size = 512 << 10; - } else { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); - tvga->vram_size = device_get_config_int("memory") << 10; - } + if (info->local == TVGA9000B_ID) { + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000); + tvga->vram_size = 512 << 10; + } else { + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900); + tvga->vram_size = device_get_config_int("memory") << 10; + } - tvga->vram_mask = tvga->vram_size - 1; + tvga->vram_mask = tvga->vram_size - 1; - tvga->card_id = info->local; + tvga->card_id = info->local; - switch (info->local) - { - case TVGA8900B_ID: - bios_fn = ROM_TVGA_8900B; - break; - case TVGA8900CLD_ID: - bios_fn = ROM_TVGA_8900CLD; - break; - case TVGA9000B_ID: - bios_fn = ROM_TVGA_9000B; - break; - default: - free(tvga); - return NULL; - } + switch (info->local) { + case TVGA8900B_ID: + bios_fn = ROM_TVGA_8900B; + break; + case TVGA8900CLD_ID: + bios_fn = ROM_TVGA_8900CLD; + break; + case TVGA9000B_ID: + bios_fn = ROM_TVGA_9000B; + break; + default: + free(tvga); + return NULL; + } - rom_init(&tvga->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tvga->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - svga_init(info, &tvga->svga, tvga, tvga->vram_size, - tvga_recalctimings, - tvga_in, tvga_out, - NULL, - NULL); + svga_init(info, &tvga->svga, tvga, tvga->vram_size, + tvga_recalctimings, + tvga_in, tvga_out, + NULL, + NULL); - if (info->local != TVGA9000B_ID) - tvga->svga.ramdac = device_add(&tkd8001_ramdac_device); + if (info->local != TVGA9000B_ID) + tvga->svga.ramdac = device_add(&tkd8001_ramdac_device); - io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); + io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga); - return tvga; + return tvga; } -static int tvga8900b_available(void) +static int +tvga8900b_available(void) { - return rom_present(ROM_TVGA_8900B); + return rom_present(ROM_TVGA_8900B); } -static int tvga8900d_available(void) +static int +tvga8900d_available(void) { - return rom_present(ROM_TVGA_8900CLD); + return rom_present(ROM_TVGA_8900CLD); } -static int tvga9000b_available(void) +static int +tvga9000b_available(void) { - return rom_present(ROM_TVGA_9000B); + return rom_present(ROM_TVGA_9000B); } -void tvga_close(void *p) +void +tvga_close(void *p) { - tvga_t *tvga = (tvga_t *)p; + tvga_t *tvga = (tvga_t *) p; - svga_close(&tvga->svga); + svga_close(&tvga->svga); - free(tvga); + free(tvga); } -void tvga_speed_changed(void *p) +void +tvga_speed_changed(void *p) { - tvga_t *tvga = (tvga_t *)p; + tvga_t *tvga = (tvga_t *) p; - svga_recalctimings(&tvga->svga); + svga_recalctimings(&tvga->svga); } -void tvga_force_redraw(void *p) +void +tvga_force_redraw(void *p) { - tvga_t *tvga = (tvga_t *)p; + tvga_t *tvga = (tvga_t *) p; - tvga->svga.fullchange = changeframecount; + tvga->svga.fullchange = changeframecount; } static const device_config_t tvga_config[] = { -// clang-format off + // clang-format off { .name = "memory", .description = "Memory size", diff --git a/src/video/vid_tvp3026_ramdac.c b/src/video/vid_tvp3026_ramdac.c index 580e96990..cde953b01 100644 --- a/src/video/vid_tvp3026_ramdac.c +++ b/src/video/vid_tvp3026_ramdac.c @@ -28,410 +28,406 @@ #include <86box/video.h> #include <86box/vid_svga.h> - typedef struct { - PALETTE extpal; - uint32_t extpallook[256]; - uint8_t cursor64_data[1024]; - int hwc_y, hwc_x; - uint8_t ind_idx; - uint8_t dcc, dc_init; - uint8_t ccr; - uint8_t true_color; - uint8_t latch_cntl; - uint8_t mcr; - uint8_t ppr; - uint8_t general_cntl; - uint8_t mclk; - uint8_t misc; - uint8_t type; - uint8_t mode; - uint8_t pll_addr; - uint8_t clock_sel; - struct - { - uint8_t m, n, p; - } pix, mem, loop; + PALETTE extpal; + uint32_t extpallook[256]; + uint8_t cursor64_data[1024]; + int hwc_y, hwc_x; + uint8_t ind_idx; + uint8_t dcc, dc_init; + uint8_t ccr; + uint8_t true_color; + uint8_t latch_cntl; + uint8_t mcr; + uint8_t ppr; + uint8_t general_cntl; + uint8_t mclk; + uint8_t misc; + uint8_t type; + uint8_t mode; + uint8_t pll_addr; + uint8_t clock_sel; + struct + { + uint8_t m, n, p; + } pix, mem, loop; } tvp3026_ramdac_t; static void tvp3026_set_bpp(tvp3026_ramdac_t *ramdac, svga_t *svga) { - if ((ramdac->true_color & 0x80) == 0x80) { - if (ramdac->mcr & 0x08) - svga->bpp = 8; - else - svga->bpp = 4; - } else { - switch (ramdac->true_color & 0x0f) { - case 0x01: - case 0x03: - case 0x05: - svga->bpp = 16; - break; - case 0x04: - svga->bpp = 15; - break; - case 0x06: - case 0x07: - if (ramdac->true_color & 0x10) - svga->bpp = 24; - else - svga->bpp = 32; - break; - case 0x0e: - case 0x0f: - svga->bpp = 24; - break; - } - } + if ((ramdac->true_color & 0x80) == 0x80) { + if (ramdac->mcr & 0x08) + svga->bpp = 8; + else + svga->bpp = 4; + } else { + switch (ramdac->true_color & 0x0f) { + case 0x01: + case 0x03: + case 0x05: + svga->bpp = 16; + break; + case 0x04: + svga->bpp = 15; + break; + case 0x06: + case 0x07: + if (ramdac->true_color & 0x10) + svga->bpp = 24; + else + svga->bpp = 32; + break; + case 0x0e: + case 0x0f: + svga->bpp = 24; + break; + } + } svga_recalctimings(svga); } - void tvp3026_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga) { tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; - uint32_t o32; - uint8_t *cd; - uint16_t index; - uint8_t rs = (addr & 0x03); - uint16_t da_mask = 0x03ff; + uint32_t o32; + uint8_t *cd; + uint16_t index; + uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; rs |= (!!rs2 << 2); rs |= (!!rs3 << 3); switch (rs) { - case 0x00: /* Palette Write Index Register (RS value = 0000) */ - ramdac->ind_idx = val; - case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ - case 0x03: - case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ - svga->dac_pos = 0; - svga->dac_status = addr & 0x03; - svga->dac_addr = val; - if (svga->dac_status) - svga->dac_addr = (svga->dac_addr + 1) & da_mask; - break; - case 0x01: /* Palette Data Register (RS value = 0001) */ - case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - svga_out(addr, val, svga); - break; - case 0x05: /* Ext Palette Data Register (RS value = 0101) */ - svga->dac_status = 0; - svga->fullchange = changeframecount; - switch (svga->dac_pos) { - case 0: - svga->dac_r = val; - svga->dac_pos++; - break; - case 1: - svga->dac_g = val; - svga->dac_pos++; - break; - case 2: - index = svga->dac_addr & 3; - ramdac->extpal[index].r = svga->dac_r; - ramdac->extpal[index].g = svga->dac_g; - ramdac->extpal[index].b = val; - if (svga->ramdac_type == RAMDAC_8BIT) - ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b); - else - ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]); + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + ramdac->ind_idx = val; + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + case 0x03: + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + svga->dac_pos = 0; + svga->dac_status = addr & 0x03; + svga->dac_addr = val; + if (svga->dac_status) + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + svga_out(addr, val, svga); + break; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + svga->dac_status = 0; + svga->fullchange = changeframecount; + switch (svga->dac_pos) { + case 0: + svga->dac_r = val; + svga->dac_pos++; + break; + case 1: + svga->dac_g = val; + svga->dac_pos++; + break; + case 2: + index = svga->dac_addr & 3; + ramdac->extpal[index].r = svga->dac_r; + ramdac->extpal[index].g = svga->dac_g; + ramdac->extpal[index].b = val; + if (svga->ramdac_type == RAMDAC_8BIT) + ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b); + else + ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]); - if (svga->ext_overscan && !index) { - o32 = svga->overscan_color; - svga->overscan_color = ramdac->extpallook[0]; - if (o32 != svga->overscan_color) - svga_recalctimings(svga); - } - svga->dac_addr = (svga->dac_addr + 1) & 0xff; - svga->dac_pos = 0; - break; - } - break; - case 0x09: /* Direct Cursor Control (RS value = 1001) */ - ramdac->dcc = val; - if (ramdac->ccr & 0x80) { - svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; - svga->dac_hwcursor.ena = !!(val & 0x03); - ramdac->mode = val & 0x03; - } - break; - case 0x0a: /* Indexed Data (RS value = 1010) */ - switch (ramdac->ind_idx) { - case 0x06: /* Indirect Cursor Control */ - ramdac->ccr = val; + if (svga->ext_overscan && !index) { + o32 = svga->overscan_color; + svga->overscan_color = ramdac->extpallook[0]; + if (o32 != svga->overscan_color) + svga_recalctimings(svga); + } + svga->dac_addr = (svga->dac_addr + 1) & 0xff; + svga->dac_pos = 0; + break; + } + break; + case 0x09: /* Direct Cursor Control (RS value = 1001) */ + ramdac->dcc = val; + if (ramdac->ccr & 0x80) { svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; - svga->dac_hwcursor.ena = !!(val & 0x03); - ramdac->mode = val & 0x03; - break; - case 0x0f: /* Latch Control */ - ramdac->latch_cntl = val; - break; - case 0x18: /* True Color Control */ - ramdac->true_color = val; - tvp3026_set_bpp(ramdac, svga); - break; - case 0x19: /* Multiplex Control */ - ramdac->mcr = val; - tvp3026_set_bpp(ramdac, svga); - break; - case 0x1a: /* Clock Selection */ - ramdac->clock_sel = val; - break; - case 0x1c: /* Palette-Page Register */ - ramdac->ppr = val; - break; - case 0x1d: /* General Control Register */ - ramdac->general_cntl = val; - break; - case 0x1e: /* Miscellaneous Control */ - ramdac->misc = val; - svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT; - break; - case 0x2c: /* PLL Address */ - ramdac->pll_addr = val; - break; - case 0x2d: /* Pixel clock PLL data */ - switch (ramdac->pll_addr & 3) { - case 0: - ramdac->pix.n = val; - break; - case 1: - ramdac->pix.m = val; - break; - case 2: - ramdac->pix.p = val; - break; - } - ramdac->pll_addr = ((ramdac->pll_addr + 1) & 3) | (ramdac->pll_addr & 0xfc); - break; - case 0x2e: /* Memory Clock PLL Data */ - switch ((ramdac->pll_addr >> 2) & 3) { - case 0: - ramdac->mem.n = val; - break; - case 1: - ramdac->mem.m = val; - break; - case 2: - ramdac->mem.p = val; - break; - } - ramdac->pll_addr = ((ramdac->pll_addr + 4) & 0x0c) | (ramdac->pll_addr & 0xf3); - break; - case 0x2f: /* Loop Clock PLL Data */ - switch ((ramdac->pll_addr >> 4) & 3) { - case 0: - ramdac->loop.n = val; - break; - case 1: - ramdac->loop.m = val; - break; - case 2: - ramdac->loop.p = val; - break; - } - ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf); - break; - case 0x39: /* MCLK/Loop Clock Control */ - ramdac->mclk = val; - break; - - } - break; - case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ - index = svga->dac_addr & da_mask; - cd = (uint8_t *) ramdac->cursor64_data; - cd[index] = val; - svga->dac_addr = (svga->dac_addr + 1) & da_mask; - break; - case 0x0c: /* Cursor X Low Register (RS value = 1100) */ - ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - break; - case 0x0d: /* Cursor X High Register (RS value = 1101) */ - ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; - break; - case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ - ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; - break; - case 0x0f: /* Cursor Y High Register (RS value = 1111) */ - ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); - svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; - break; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; + svga->dac_hwcursor.ena = !!(val & 0x03); + ramdac->mode = val & 0x03; + } + break; + case 0x0a: /* Indexed Data (RS value = 1010) */ + switch (ramdac->ind_idx) { + case 0x06: /* Indirect Cursor Control */ + ramdac->ccr = val; + svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = 64; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; + svga->dac_hwcursor.ena = !!(val & 0x03); + ramdac->mode = val & 0x03; + break; + case 0x0f: /* Latch Control */ + ramdac->latch_cntl = val; + break; + case 0x18: /* True Color Control */ + ramdac->true_color = val; + tvp3026_set_bpp(ramdac, svga); + break; + case 0x19: /* Multiplex Control */ + ramdac->mcr = val; + tvp3026_set_bpp(ramdac, svga); + break; + case 0x1a: /* Clock Selection */ + ramdac->clock_sel = val; + break; + case 0x1c: /* Palette-Page Register */ + ramdac->ppr = val; + break; + case 0x1d: /* General Control Register */ + ramdac->general_cntl = val; + break; + case 0x1e: /* Miscellaneous Control */ + ramdac->misc = val; + svga->ramdac_type = (val & 0x08) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x2c: /* PLL Address */ + ramdac->pll_addr = val; + break; + case 0x2d: /* Pixel clock PLL data */ + switch (ramdac->pll_addr & 3) { + case 0: + ramdac->pix.n = val; + break; + case 1: + ramdac->pix.m = val; + break; + case 2: + ramdac->pix.p = val; + break; + } + ramdac->pll_addr = ((ramdac->pll_addr + 1) & 3) | (ramdac->pll_addr & 0xfc); + break; + case 0x2e: /* Memory Clock PLL Data */ + switch ((ramdac->pll_addr >> 2) & 3) { + case 0: + ramdac->mem.n = val; + break; + case 1: + ramdac->mem.m = val; + break; + case 2: + ramdac->mem.p = val; + break; + } + ramdac->pll_addr = ((ramdac->pll_addr + 4) & 0x0c) | (ramdac->pll_addr & 0xf3); + break; + case 0x2f: /* Loop Clock PLL Data */ + switch ((ramdac->pll_addr >> 4) & 3) { + case 0: + ramdac->loop.n = val; + break; + case 1: + ramdac->loop.m = val; + break; + case 2: + ramdac->loop.p = val; + break; + } + ramdac->pll_addr = ((ramdac->pll_addr + 0x10) & 0x30) | (ramdac->pll_addr & 0xcf); + break; + case 0x39: /* MCLK/Loop Clock Control */ + ramdac->mclk = val; + break; + } + break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + index = svga->dac_addr & da_mask; + cd = (uint8_t *) ramdac->cursor64_data; + cd[index] = val; + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val; + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8); + svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val; + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8); + svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize; + break; } return; } - uint8_t tvp3026_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga) { tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; - uint8_t temp = 0xff; - uint8_t *cd; - uint16_t index; - uint8_t rs = (addr & 0x03); - uint16_t da_mask = 0x03ff; + uint8_t temp = 0xff; + uint8_t *cd; + uint16_t index; + uint8_t rs = (addr & 0x03); + uint16_t da_mask = 0x03ff; rs |= (!!rs2 << 2); rs |= (!!rs3 << 3); switch (rs) { - case 0x00: /* Palette Write Index Register (RS value = 0000) */ - case 0x01: /* Palette Data Register (RS value = 0001) */ - case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ - case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ - temp = svga_in(addr, svga); - break; - case 0x03: /* Palette Read Index Register (RS value = 0011) */ - case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ - temp = svga->dac_addr & 0xff; - break; - case 0x05: /* Ext Palette Data Register (RS value = 0101) */ - index = (svga->dac_addr - 1) & 3; - svga->dac_status = 3; - switch (svga->dac_pos) { - case 0: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - temp = ramdac->extpal[index].r; - else - temp = ramdac->extpal[index].r & 0x3f; - break; - case 1: - svga->dac_pos++; - if (svga->ramdac_type == RAMDAC_8BIT) - temp = ramdac->extpal[index].g; - else - temp = ramdac->extpal[index].g & 0x3f; - break; - case 2: - svga->dac_pos=0; - svga->dac_addr = svga->dac_addr + 1; - if (svga->ramdac_type == RAMDAC_8BIT) - temp = ramdac->extpal[index].b; - else - temp = ramdac->extpal[index].b & 0x3f; - break; - } - break; - case 0x09: /* Direct Cursor Control (RS value = 1001) */ - temp = ramdac->dcc; - break; - case 0x0a: /* Indexed Data (RS value = 1010) */ - switch (ramdac->ind_idx) { - case 0x01: /* Silicon Revision */ - temp = 0x00; - break; - case 0x06: /* Indirect Cursor Control */ - temp = ramdac->ccr; - break; - case 0x0f: /* Latch Control */ - temp = ramdac->latch_cntl; - break; - case 0x18: /* True Color Control */ - temp = ramdac->true_color; - break; - case 0x19: /* Multiplex Control */ - temp = ramdac->mcr; - break; - case 0x1a: /* Clock Selection */ - temp = ramdac->clock_sel; - break; - case 0x1c: /* Palette-Page Register */ - temp = ramdac->ppr; - break; - case 0x1d: /* General Control Register */ - temp = ramdac->general_cntl; - break; - case 0x1e: /* Miscellaneous Control */ - temp = ramdac->misc; - break; - case 0x2c: /* PLL Address */ - temp = ramdac->pll_addr; - break; - case 0x2d: /* Pixel clock PLL data */ - switch (ramdac->pll_addr & 3) { - case 0: - temp = ramdac->pix.n; - break; - case 1: - temp = ramdac->pix.m; - break; - case 2: - temp = ramdac->pix.p; - break; - case 3: - temp = 0x40; /*PLL locked to frequency*/ - break; - } - break; - case 0x2e: /* Memory Clock PLL Data */ - switch ((ramdac->pll_addr >> 2) & 3) { - case 0: - temp = ramdac->mem.n; - break; - case 1: - temp = ramdac->mem.m; - break; - case 2: - temp = ramdac->mem.p; - break; - case 3: - temp = 0x40; /*PLL locked to frequency*/ - break; - } - break; - case 0x2f: /* Loop Clock PLL Data */ - switch ((ramdac->pll_addr >> 4) & 3) { - case 0: - temp = ramdac->loop.n; - break; - case 1: - temp = ramdac->loop.m; - break; - case 2: - temp = ramdac->loop.p; - break; - } - break; - case 0x39: /* MCLK/Loop Clock Control */ - temp = ramdac->mclk; - break; - case 0x3f: /* ID */ - temp = 0x26; - break; - } - break; - case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ - index = (svga->dac_addr - 1) & da_mask; - cd = (uint8_t *) ramdac->cursor64_data; - temp = cd[index]; + case 0x00: /* Palette Write Index Register (RS value = 0000) */ + case 0x01: /* Palette Data Register (RS value = 0001) */ + case 0x02: /* Pixel Read Mask Register (RS value = 0010) */ + case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ + temp = svga_in(addr, svga); + break; + case 0x03: /* Palette Read Index Register (RS value = 0011) */ + case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ + temp = svga->dac_addr & 0xff; + break; + case 0x05: /* Ext Palette Data Register (RS value = 0101) */ + index = (svga->dac_addr - 1) & 3; + svga->dac_status = 3; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].r; + else + temp = ramdac->extpal[index].r & 0x3f; + break; + case 1: + svga->dac_pos++; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].g; + else + temp = ramdac->extpal[index].g & 0x3f; + break; + case 2: + svga->dac_pos = 0; + svga->dac_addr = svga->dac_addr + 1; + if (svga->ramdac_type == RAMDAC_8BIT) + temp = ramdac->extpal[index].b; + else + temp = ramdac->extpal[index].b & 0x3f; + break; + } + break; + case 0x09: /* Direct Cursor Control (RS value = 1001) */ + temp = ramdac->dcc; + break; + case 0x0a: /* Indexed Data (RS value = 1010) */ + switch (ramdac->ind_idx) { + case 0x01: /* Silicon Revision */ + temp = 0x00; + break; + case 0x06: /* Indirect Cursor Control */ + temp = ramdac->ccr; + break; + case 0x0f: /* Latch Control */ + temp = ramdac->latch_cntl; + break; + case 0x18: /* True Color Control */ + temp = ramdac->true_color; + break; + case 0x19: /* Multiplex Control */ + temp = ramdac->mcr; + break; + case 0x1a: /* Clock Selection */ + temp = ramdac->clock_sel; + break; + case 0x1c: /* Palette-Page Register */ + temp = ramdac->ppr; + break; + case 0x1d: /* General Control Register */ + temp = ramdac->general_cntl; + break; + case 0x1e: /* Miscellaneous Control */ + temp = ramdac->misc; + break; + case 0x2c: /* PLL Address */ + temp = ramdac->pll_addr; + break; + case 0x2d: /* Pixel clock PLL data */ + switch (ramdac->pll_addr & 3) { + case 0: + temp = ramdac->pix.n; + break; + case 1: + temp = ramdac->pix.m; + break; + case 2: + temp = ramdac->pix.p; + break; + case 3: + temp = 0x40; /*PLL locked to frequency*/ + break; + } + break; + case 0x2e: /* Memory Clock PLL Data */ + switch ((ramdac->pll_addr >> 2) & 3) { + case 0: + temp = ramdac->mem.n; + break; + case 1: + temp = ramdac->mem.m; + break; + case 2: + temp = ramdac->mem.p; + break; + case 3: + temp = 0x40; /*PLL locked to frequency*/ + break; + } + break; + case 0x2f: /* Loop Clock PLL Data */ + switch ((ramdac->pll_addr >> 4) & 3) { + case 0: + temp = ramdac->loop.n; + break; + case 1: + temp = ramdac->loop.m; + break; + case 2: + temp = ramdac->loop.p; + break; + } + break; + case 0x39: /* MCLK/Loop Clock Control */ + temp = ramdac->mclk; + break; + case 0x3f: /* ID */ + temp = 0x26; + break; + } + break; + case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */ + index = (svga->dac_addr - 1) & da_mask; + cd = (uint8_t *) ramdac->cursor64_data; + temp = cd[index]; - svga->dac_addr = (svga->dac_addr + 1) & da_mask; - break; - case 0x0c: /* Cursor X Low Register (RS value = 1100) */ - temp = ramdac->hwc_x & 0xff; - break; - case 0x0d: /* Cursor X High Register (RS value = 1101) */ - temp = (ramdac->hwc_x >> 8) & 0xff; - break; - case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ - temp = ramdac->hwc_y & 0xff; - break; - case 0x0f: /* Cursor Y High Register (RS value = 1111) */ - temp = (ramdac->hwc_y >> 8) & 0xff; - break; + svga->dac_addr = (svga->dac_addr + 1) & da_mask; + break; + case 0x0c: /* Cursor X Low Register (RS value = 1100) */ + temp = ramdac->hwc_x & 0xff; + break; + case 0x0d: /* Cursor X High Register (RS value = 1101) */ + temp = (ramdac->hwc_x >> 8) & 0xff; + break; + case 0x0e: /* Cursor Y Low Register (RS value = 1110) */ + temp = ramdac->hwc_y & 0xff; + break; + case 0x0f: /* Cursor Y High Register (RS value = 1111) */ + temp = (ramdac->hwc_y >> 8) & 0xff; + break; } return temp; @@ -445,16 +441,15 @@ tvp3026_recalctimings(void *p, svga_t *svga) svga->interlace = (ramdac->ccr & 0x40); } - void tvp3026_hwcursor_draw(svga_t *svga, int displine) { - int x, xx, comb, b0, b1; - uint16_t dat[2]; - int offset = svga->dac_hwcursor_latch.x + svga->dac_hwcursor_latch.xoff; - int pitch, bppl, mode, x_pos, y_pos; - uint32_t clr1, clr2, clr3, *p; - uint8_t *cd; + int x, xx, comb, b0, b1; + uint16_t dat[2]; + int offset = svga->dac_hwcursor_latch.x + svga->dac_hwcursor_latch.xoff; + int pitch, bppl, mode, x_pos, y_pos; + uint32_t clr1, clr2, clr3, *p; + uint8_t *cd; tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) svga->ramdac; clr1 = ramdac->extpallook[1]; @@ -464,101 +459,98 @@ tvp3026_hwcursor_draw(svga_t *svga, int displine) /* The planes come in two parts, and each plane is 1bpp, so a 32x32 cursor has 4 bytes per line, and a 64x64 cursor has 8 bytes per line. */ - pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */ + pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */ /* A 32x32 cursor has 128 bytes per line, and a 64x64 cursor has 512 bytes per line. */ - bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */ + bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */ mode = ramdac->mode; if (svga->interlace && svga->dac_hwcursor_oddeven) - svga->dac_hwcursor_latch.addr += pitch; + svga->dac_hwcursor_latch.addr += pitch; - cd = (uint8_t *) ramdac->cursor64_data; + cd = (uint8_t *) ramdac->cursor64_data; for (x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += 16) { - dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | - cd[svga->dac_hwcursor_latch.addr + 1]; - dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | - cd[svga->dac_hwcursor_latch.addr + bppl + 1]; + dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | cd[svga->dac_hwcursor_latch.addr + 1]; + dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | cd[svga->dac_hwcursor_latch.addr + bppl + 1]; - for (xx = 0; xx < 16; xx++) { - b0 = (dat[0] >> (15 - xx)) & 1; - b1 = (dat[1] >> (15 - xx)) & 1; - comb = (b0 | (b1 << 1)); + for (xx = 0; xx < 16; xx++) { + b0 = (dat[0] >> (15 - xx)) & 1; + b1 = (dat[1] >> (15 - xx)) & 1; + comb = (b0 | (b1 << 1)); - y_pos = displine; - x_pos = offset + svga->x_add; - p = buffer32->line[y_pos]; + y_pos = displine; + x_pos = offset + svga->x_add; + p = buffer32->line[y_pos]; - if (offset >= svga->dac_hwcursor_latch.x) { - switch (mode) { - case 1: /* Three Color */ - switch (comb) { - case 1: - p[x_pos] = clr1; - break; - case 2: - p[x_pos] = clr2; - break; - case 3: - p[x_pos] = clr3; - break; - } - break; - case 2: /* XGA */ - switch (comb) { - case 0: - p[x_pos] = clr1; - break; - case 1: - p[x_pos] = clr2; - break; - case 3: - p[x_pos] ^= 0xffffff; - break; - } - break; - case 3: /* X-Windows */ - switch (comb) { - case 2: - p[x_pos] = clr1; - break; - case 3: - p[x_pos] = clr2; - break; - } - break; - } - } - offset++; - } - svga->dac_hwcursor_latch.addr += 2; + if (offset >= svga->dac_hwcursor_latch.x) { + switch (mode) { + case 1: /* Three Color */ + switch (comb) { + case 1: + p[x_pos] = clr1; + break; + case 2: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] = clr3; + break; + } + break; + case 2: /* XGA */ + switch (comb) { + case 0: + p[x_pos] = clr1; + break; + case 1: + p[x_pos] = clr2; + break; + case 3: + p[x_pos] ^= 0xffffff; + break; + } + break; + case 3: /* X-Windows */ + switch (comb) { + case 2: + p[x_pos] = clr1; + break; + case 3: + p[x_pos] = clr2; + break; + } + break; + } + } + offset++; + } + svga->dac_hwcursor_latch.addr += 2; } if (svga->interlace && !svga->dac_hwcursor_oddeven) - svga->dac_hwcursor_latch.addr += pitch; + svga->dac_hwcursor_latch.addr += pitch; } - float tvp3026_getclock(int clock, void *p) { - tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; - int n, m, pl; - float f_vco, f_pll; + tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) p; + int n, m, pl; + float f_vco, f_pll; if (clock == 0) - return 25175000.0; + return 25175000.0; if (clock == 1) - return 28322000.0; + return 28322000.0; -/*Fvco = 8 x Fref x (65 - M) / (65 - N)*/ -/*Fpll = Fvco / 2^P*/ - n = ramdac->pix.n & 0x3f; - m = ramdac->pix.m & 0x3f; - pl = ramdac->pix.p & 0x03; - f_vco = 8.0 * 14318184 * (float)(65 - m) / (float)(65 - n); - f_pll = f_vco / (float)(1 << pl); + /*Fvco = 8 x Fref x (65 - M) / (65 - N)*/ + /*Fpll = Fvco / 2^P*/ + n = ramdac->pix.n & 0x3f; + m = ramdac->pix.m & 0x3f; + pl = ramdac->pix.p & 0x03; + f_vco = 8.0 * 14318184 * (float) (65 - m) / (float) (65 - n); + f_pll = f_vco / (float) (1 << pl); return f_pll; } @@ -571,35 +563,34 @@ tvp3026_ramdac_init(const device_t *info) ramdac->type = info->local; - ramdac->latch_cntl = 0x06; - ramdac->true_color = 0x80; - ramdac->mcr = 0x98; - ramdac->clock_sel = 0x07; - ramdac->mclk = 0x18; + ramdac->latch_cntl = 0x06; + ramdac->true_color = 0x80; + ramdac->mcr = 0x98; + ramdac->clock_sel = 0x07; + ramdac->mclk = 0x18; return ramdac; } - static void tvp3026_ramdac_close(void *priv) { tvp3026_ramdac_t *ramdac = (tvp3026_ramdac_t *) priv; if (ramdac) - free(ramdac); + free(ramdac); } const device_t tvp3026_ramdac_device = { - .name = "TI TVP3026 RAMDAC", + .name = "TI TVP3026 RAMDAC", .internal_name = "tvp3026_ramdac", - .flags = 0, - .local = 0, - .init = tvp3026_ramdac_init, - .close = tvp3026_ramdac_close, - .reset = NULL, + .flags = 0, + .local = 0, + .init = tvp3026_ramdac_init, + .close = tvp3026_ramdac_close, + .reset = NULL, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_vga.c b/src/video/vid_vga.c index 6dd81416f..e581f237c 100644 --- a/src/video/vid_vga.c +++ b/src/video/vid_vga.c @@ -31,194 +31,195 @@ #include <86box/vid_svga.h> #include <86box/vid_vga.h> +static video_timings_t timing_ps1_svga_isa = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; +static video_timings_t timing_ps1_svga_mca = { .type = VIDEO_MCA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 }; -static video_timings_t timing_ps1_svga_isa = {VIDEO_ISA, 6, 8, 16, 6, 8, 16}; -static video_timings_t timing_ps1_svga_mca = {VIDEO_MCA, 6, 8, 16, 6, 8, 16}; - -void vga_out(uint16_t addr, uint8_t val, void *p) +void +vga_out(uint16_t addr, uint8_t val, void *p) { - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; - uint8_t old; + vga_t *vga = (vga_t *) p; + svga_t *svga = &vga->svga; + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3D4: - svga->crtcreg = val & 0x3f; + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) return; - case 0x3D5: - if (svga->crtcreg & 0x20) - return; - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } } - break; - } - svga_out(addr, val, svga); + } + break; + } + svga_out(addr, val, svga); } -uint8_t vga_in(uint16_t addr, void *p) +uint8_t +vga_in(uint16_t addr, void *p) { - vga_t *vga = (vga_t *)p; - svga_t *svga = &vga->svga; - uint8_t temp; + vga_t *vga = (vga_t *) p; + svga_t *svga = &vga->svga; + uint8_t temp; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - if (svga->crtcreg & 0x20) - temp = 0xff; - else - temp = svga->crtc[svga->crtcreg]; - break; - default: - temp = svga_in(addr, svga); - break; - } - return temp; + switch (addr) { + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + return temp; } - -static void *vga_init(const device_t *info) +static void * +vga_init(const device_t *info) { - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); + vga_t *vga = malloc(sizeof(vga_t)); + memset(vga, 0, sizeof(vga_t)); - rom_init(&vga->bios_rom, "roms/video/vga/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); + rom_init(&vga->bios_rom, "roms/video/vga/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_vga); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_vga); - svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); + svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/ + NULL, + vga_in, vga_out, + NULL, + NULL); - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - vga->svga.bpp = 8; - vga->svga.miscout = 1; + vga->svga.bpp = 8; + vga->svga.miscout = 1; - return vga; + return vga; } - /*PS/1 uses a standard VGA controller, but with no option ROM*/ -void *ps1vga_init(const device_t *info) +void * +ps1vga_init(const device_t *info) { - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); + vga_t *vga = malloc(sizeof(vga_t)); + memset(vga, 0, sizeof(vga_t)); - if (info->flags & DEVICE_MCA) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_mca); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_isa); + if (info->flags & DEVICE_MCA) + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_mca); + else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_isa); - svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); + svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/ + NULL, + vga_in, vga_out, + NULL, + NULL); - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - vga->svga.bpp = 8; - vga->svga.miscout = 1; + vga->svga.bpp = 8; + vga->svga.miscout = 1; - return vga; + return vga; } -static int vga_available(void) +static int +vga_available(void) { - return rom_present("roms/video/vga/ibm_vga.bin"); + return rom_present("roms/video/vga/ibm_vga.bin"); } -void vga_close(void *p) +void +vga_close(void *p) { - vga_t *vga = (vga_t *)p; + vga_t *vga = (vga_t *) p; - svga_close(&vga->svga); + svga_close(&vga->svga); - free(vga); + free(vga); } -void vga_speed_changed(void *p) +void +vga_speed_changed(void *p) { - vga_t *vga = (vga_t *)p; + vga_t *vga = (vga_t *) p; - svga_recalctimings(&vga->svga); + svga_recalctimings(&vga->svga); } -void vga_force_redraw(void *p) +void +vga_force_redraw(void *p) { - vga_t *vga = (vga_t *)p; + vga_t *vga = (vga_t *) p; - vga->svga.fullchange = changeframecount; + vga->svga.fullchange = changeframecount; } const device_t vga_device = { - .name = "VGA", + .name = "VGA", .internal_name = "vga", - .flags = DEVICE_ISA, - .local = 0, - .init = vga_init, - .close = vga_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = vga_init, + .close = vga_close, + .reset = NULL, { .available = vga_available }, .speed_changed = vga_speed_changed, - .force_redraw = vga_force_redraw, - .config = NULL + .force_redraw = vga_force_redraw, + .config = NULL }; const device_t ps1vga_device = { - .name = "PS/1 VGA", + .name = "PS/1 VGA", .internal_name = "ps1vga", - .flags = DEVICE_ISA, - .local = 0, - .init = ps1vga_init, - .close = vga_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = ps1vga_init, + .close = vga_close, + .reset = NULL, { .available = vga_available }, .speed_changed = vga_speed_changed, - .force_redraw = vga_force_redraw, - .config = NULL + .force_redraw = vga_force_redraw, + .config = NULL }; const device_t ps1vga_mca_device = { - .name = "PS/1 VGA", + .name = "PS/1 VGA", .internal_name = "ps1vga_mca", - .flags = DEVICE_MCA, - .local = 0, - .init = ps1vga_init, - .close = vga_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = 0, + .init = ps1vga_init, + .close = vga_close, + .reset = NULL, { .available = vga_available }, .speed_changed = vga_speed_changed, - .force_redraw = vga_force_redraw, - .config = NULL + .force_redraw = vga_force_redraw, + .config = NULL }; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index df3d59076..2838d5f93 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -53,1255 +53,1222 @@ int tris = 0; #ifdef ENABLE_VOODOO_LOG int voodoo_do_log = ENABLE_VOODOO_LOG; - static void voodoo_log(const char *fmt, ...) { va_list ap; if (voodoo_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoo_log(fmt, ...) +# define voodoo_log(fmt, ...) #endif - -void voodoo_recalc(voodoo_t *voodoo) +void +voodoo_recalc(voodoo_t *voodoo) { - uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096; + uint32_t buffer_offset = ((voodoo->fbiInit2 >> 11) & 511) * 4096; - if (voodoo->type >= VOODOO_BANSHEE) - return; + if (voodoo->type >= VOODOO_BANSHEE) + return; - voodoo->params.front_offset = voodoo->disp_buffer*buffer_offset; - voodoo->back_offset = voodoo->draw_buffer*buffer_offset; + voodoo->params.front_offset = voodoo->disp_buffer * buffer_offset; + voodoo->back_offset = voodoo->draw_buffer * buffer_offset; - voodoo->buffer_cutoff = TRIPLE_BUFFER ? (buffer_offset * 4) : (buffer_offset * 3); - if (TRIPLE_BUFFER) - voodoo->params.aux_offset = buffer_offset * 3; - else - voodoo->params.aux_offset = buffer_offset * 2; + voodoo->buffer_cutoff = TRIPLE_BUFFER ? (buffer_offset * 4) : (buffer_offset * 3); + if (TRIPLE_BUFFER) + voodoo->params.aux_offset = buffer_offset * 3; + else + voodoo->params.aux_offset = buffer_offset * 2; - switch (voodoo->lfbMode & LFB_WRITE_MASK) - { - case LFB_WRITE_FRONT: - voodoo->fb_write_offset = voodoo->params.front_offset; - voodoo->fb_write_buffer = voodoo->disp_buffer; - break; - case LFB_WRITE_BACK: - voodoo->fb_write_offset = voodoo->back_offset; - voodoo->fb_write_buffer = voodoo->draw_buffer; - break; + switch (voodoo->lfbMode & LFB_WRITE_MASK) { + case LFB_WRITE_FRONT: + voodoo->fb_write_offset = voodoo->params.front_offset; + voodoo->fb_write_buffer = voodoo->disp_buffer; + break; + case LFB_WRITE_BACK: + voodoo->fb_write_offset = voodoo->back_offset; + voodoo->fb_write_buffer = voodoo->draw_buffer; + break; - default: - /*BreakNeck sets invalid LFB write buffer select*/ - voodoo->fb_write_offset = voodoo->params.front_offset; - break; - } + default: + /*BreakNeck sets invalid LFB write buffer select*/ + voodoo->fb_write_offset = voodoo->params.front_offset; + break; + } - switch (voodoo->lfbMode & LFB_READ_MASK) - { - case LFB_READ_FRONT: - voodoo->fb_read_offset = voodoo->params.front_offset; - break; - case LFB_READ_BACK: - voodoo->fb_read_offset = voodoo->back_offset; - break; - case LFB_READ_AUX: - voodoo->fb_read_offset = voodoo->params.aux_offset; - break; + switch (voodoo->lfbMode & LFB_READ_MASK) { + case LFB_READ_FRONT: + voodoo->fb_read_offset = voodoo->params.front_offset; + break; + case LFB_READ_BACK: + voodoo->fb_read_offset = voodoo->back_offset; + break; + case LFB_READ_AUX: + voodoo->fb_read_offset = voodoo->params.aux_offset; + break; - default: - fatal("voodoo_recalc : unknown lfb source\n"); - } + default: + fatal("voodoo_recalc : unknown lfb source\n"); + } - switch (voodoo->params.fbzMode & FBZ_DRAW_MASK) - { - case FBZ_DRAW_FRONT: - voodoo->params.draw_offset = voodoo->params.front_offset; - voodoo->fb_draw_buffer = voodoo->disp_buffer; - break; - case FBZ_DRAW_BACK: - voodoo->params.draw_offset = voodoo->back_offset; - voodoo->fb_draw_buffer = voodoo->draw_buffer; - break; + switch (voodoo->params.fbzMode & FBZ_DRAW_MASK) { + case FBZ_DRAW_FRONT: + voodoo->params.draw_offset = voodoo->params.front_offset; + voodoo->fb_draw_buffer = voodoo->disp_buffer; + break; + case FBZ_DRAW_BACK: + voodoo->params.draw_offset = voodoo->back_offset; + voodoo->fb_draw_buffer = voodoo->draw_buffer; + break; - default: - fatal("voodoo_recalc : unknown draw buffer\n"); - } + default: + fatal("voodoo_recalc : unknown draw buffer\n"); + } - voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; - if (voodoo->fbiInit6 & (1 << 30)) - voodoo->block_width += 1; - if (voodoo->fbiInit1 & (1 << 24)) - voodoo->block_width += 32; - voodoo->row_width = voodoo->block_width * 32 * 2; - voodoo->params.row_width = voodoo->row_width; - voodoo->aux_row_width = voodoo->row_width; - voodoo->params.aux_row_width = voodoo->aux_row_width; + voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; + if (voodoo->fbiInit6 & (1 << 30)) + voodoo->block_width += 1; + if (voodoo->fbiInit1 & (1 << 24)) + voodoo->block_width += 32; + voodoo->row_width = voodoo->block_width * 32 * 2; + voodoo->params.row_width = voodoo->row_width; + voodoo->aux_row_width = voodoo->row_width; + voodoo->params.aux_row_width = voodoo->aux_row_width; } - -static uint16_t voodoo_readw(uint32_t addr, void *p) +static uint16_t +voodoo_readw(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *) p; - addr &= 0xffffff; + addr &= 0xffffff; - cycles -= voodoo->read_time; + cycles -= voodoo->read_time; - if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ - { - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; + if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ + { + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - } - - voodoo->flush = 1; - while (!FIFO_EMPTY) - { - voodoo_wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - voodoo_wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; - - return voodoo_fb_readw(addr, voodoo); + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; } - return 0xffff; + voodoo->flush = 1; + while (!FIFO_EMPTY) { + voodoo_wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); + } + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; + + return voodoo_fb_readw(addr, voodoo); + } + + return 0xffff; } - -static uint32_t voodoo_readl(uint32_t addr, void *p) +static uint32_t +voodoo_readl(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - uint32_t temp = 0xffffffff; - int fifo_size; - voodoo->rd_count++; - addr &= 0xffffff; + voodoo_t *voodoo = (voodoo_t *) p; + uint32_t temp = 0xffffffff; + int fifo_size; + voodoo->rd_count++; + addr &= 0xffffff; - cycles -= voodoo->read_time; + cycles -= voodoo->read_time; - if (addr & 0x800000) /*Texture*/ - { + if (addr & 0x800000) /*Texture*/ + { + } else if (addr & 0x400000) /*Framebuffer*/ + { + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; + int y = (addr >> 11) & 0x3ff; + + if (y & 1) + voodoo = set->voodoos[1]; + else + voodoo = set->voodoos[0]; } - else if (addr & 0x400000) /*Framebuffer*/ - { - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; - int y = (addr >> 11) & 0x3ff; - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; - } - - voodoo->flush = 1; - while (!FIFO_EMPTY) - { - voodoo_wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - voodoo_wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; - - temp = voodoo_fb_readl(addr, voodoo); + voodoo->flush = 1; + while (!FIFO_EMPTY) { + voodoo_wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); } - else switch (addr & 0x3fc) - { - case SST_status: + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; + + temp = voodoo_fb_readl(addr, voodoo); + } else + switch (addr & 0x3fc) { + case SST_status: { - int fifo_entries = FIFO_ENTRIES; - int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); + int fifo_entries = FIFO_ENTRIES; + int swap_count = voodoo->swap_count; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr); - if (SLI_ENABLED && voodoo->type != VOODOO_2) - { - voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; - int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo; + if (SLI_ENABLED && voodoo->type != VOODOO_2) { + voodoo_t *voodoo_other = (voodoo == voodoo->set->voodoos[0]) ? voodoo->set->voodoos[1] : voodoo->set->voodoos[0]; + int other_written = voodoo_other->cmd_written + voodoo_other->cmd_written_fifo; - if (voodoo_other->swap_count > swap_count) - swap_count = voodoo_other->swap_count; - if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries) - fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx; - if ((other_written - voodoo_other->cmd_read) || - (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) - busy = 1; - if (!voodoo_other->voodoo_busy) - voodoo_wake_fifo_thread(voodoo_other); - } + if (voodoo_other->swap_count > swap_count) + swap_count = voodoo_other->swap_count; + if ((voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx) > fifo_entries) + fifo_entries = voodoo_other->fifo_write_idx - voodoo_other->fifo_read_idx; + if ((other_written - voodoo_other->cmd_read) || (voodoo_other->cmdfifo_depth_rd != voodoo_other->cmdfifo_depth_wr)) + busy = 1; + if (!voodoo_other->voodoo_busy) + voodoo_wake_fifo_thread(voodoo_other); + } - fifo_size = 0xffff - fifo_entries; - temp = fifo_size << 12; - if (fifo_size < 0x40) - temp |= fifo_size; - else - temp |= 0x3f; - if (swap_count < 7) - temp |= (swap_count << 28); - else - temp |= (7 << 28); - if (!voodoo->v_retrace) - temp |= 0x40; + fifo_size = 0xffff - fifo_entries; + temp = fifo_size << 12; + if (fifo_size < 0x40) + temp |= fifo_size; + else + temp |= 0x3f; + if (swap_count < 7) + temp |= (swap_count << 28); + else + temp |= (7 << 28); + if (!voodoo->v_retrace) + temp |= 0x40; - if (busy) - temp |= 0x380; /*Busy*/ + if (busy) + temp |= 0x380; /*Busy*/ - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_thread(voodoo); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_thread(voodoo); } break; - case SST_fbzColorPath: + case SST_fbzColorPath: voodoo_flush(voodoo); temp = voodoo->params.fbzColorPath; break; - case SST_fogMode: + case SST_fogMode: voodoo_flush(voodoo); temp = voodoo->params.fogMode; break; - case SST_alphaMode: + case SST_alphaMode: voodoo_flush(voodoo); temp = voodoo->params.alphaMode; break; - case SST_fbzMode: + case SST_fbzMode: voodoo_flush(voodoo); temp = voodoo->params.fbzMode; break; - case SST_lfbMode: + case SST_lfbMode: voodoo_flush(voodoo); temp = voodoo->lfbMode; break; - case SST_clipLeftRight: + case SST_clipLeftRight: voodoo_flush(voodoo); temp = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); break; - case SST_clipLowYHighY: + case SST_clipLowYHighY: voodoo_flush(voodoo); temp = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); break; - case SST_stipple: + case SST_stipple: voodoo_flush(voodoo); temp = voodoo->params.stipple; break; - case SST_color0: + case SST_color0: voodoo_flush(voodoo); temp = voodoo->params.color0; break; - case SST_color1: + case SST_color1: voodoo_flush(voodoo); temp = voodoo->params.color1; break; - case SST_fbiPixelsIn: + case SST_fbiPixelsIn: temp = voodoo->fbiPixelsIn & 0xffffff; break; - case SST_fbiChromaFail: + case SST_fbiChromaFail: temp = voodoo->fbiChromaFail & 0xffffff; break; - case SST_fbiZFuncFail: + case SST_fbiZFuncFail: temp = voodoo->fbiZFuncFail & 0xffffff; break; - case SST_fbiAFuncFail: + case SST_fbiAFuncFail: temp = voodoo->fbiAFuncFail & 0xffffff; break; - case SST_fbiPixelsOut: + case SST_fbiPixelsOut: temp = voodoo->fbiPixelsOut & 0xffffff; break; - case SST_fbiInit4: + case SST_fbiInit4: temp = voodoo->fbiInit4; break; - case SST_fbiInit0: + case SST_fbiInit0: temp = voodoo->fbiInit0; break; - case SST_fbiInit1: + case SST_fbiInit1: temp = voodoo->fbiInit1; break; - case SST_fbiInit2: + case SST_fbiInit2: if (voodoo->initEnable & 0x04) - temp = voodoo->dac_readdata; + temp = voodoo->dac_readdata; else - temp = voodoo->fbiInit2; + temp = voodoo->fbiInit2; break; - case SST_fbiInit3: + case SST_fbiInit3: temp = voodoo->fbiInit3 | (1 << 10) | (2 << 8); break; - case SST_vRetrace: + case SST_vRetrace: temp = voodoo->line & 0x1fff; break; - case SST_hvRetrace: + case SST_hvRetrace: { - uint32_t line_time = (uint32_t)(voodoo->line_time >> 32); - uint32_t diff = (timer_get_ts_int(&voodoo->timer) > (tsc & 0xffffffff)) ? (timer_get_ts_int(&voodoo->timer) - (tsc & 0xffffffff)) : 0; - uint32_t pre_div = diff * voodoo->h_total; - uint32_t post_div = pre_div / line_time; - uint32_t h_pos = (voodoo->h_total - 1) - post_div; + uint32_t line_time = (uint32_t) (voodoo->line_time >> 32); + uint32_t diff = (timer_get_ts_int(&voodoo->timer) > (tsc & 0xffffffff)) ? (timer_get_ts_int(&voodoo->timer) - (tsc & 0xffffffff)) : 0; + uint32_t pre_div = diff * voodoo->h_total; + uint32_t post_div = pre_div / line_time; + uint32_t h_pos = (voodoo->h_total - 1) - post_div; - if (h_pos >= voodoo->h_total) - h_pos = 0; + if (h_pos >= voodoo->h_total) + h_pos = 0; - temp = voodoo->line & 0x1fff; - temp |= (h_pos << 16); + temp = voodoo->line & 0x1fff; + temp |= (h_pos << 16); } break; - case SST_fbiInit5: + case SST_fbiInit5: temp = voodoo->fbiInit5 & ~0x1ff; break; - case SST_fbiInit6: + case SST_fbiInit6: temp = voodoo->fbiInit6; break; - case SST_fbiInit7: + case SST_fbiInit7: temp = voodoo->fbiInit7 & ~0xff; break; - case SST_cmdFifoBaseAddr: + case SST_cmdFifoBaseAddr: temp = voodoo->cmdfifo_base >> 12; temp |= (voodoo->cmdfifo_end >> 12) << 16; break; - case SST_cmdFifoRdPtr: + case SST_cmdFifoRdPtr: temp = voodoo->cmdfifo_rp; break; - case SST_cmdFifoAMin: + case SST_cmdFifoAMin: temp = voodoo->cmdfifo_amin; break; - case SST_cmdFifoAMax: + case SST_cmdFifoAMax: temp = voodoo->cmdfifo_amax; break; - case SST_cmdFifoDepth: + case SST_cmdFifoDepth: temp = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; break; - default: + default: voodoo_log("voodoo_readl : bad addr %08X\n", addr); temp = 0xffffffff; } - return temp; + return temp; } -static void voodoo_writew(uint32_t addr, uint16_t val, void *p) +static void +voodoo_writew(uint32_t addr, uint16_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - voodoo->wr_count++; - addr &= 0xffffff; + voodoo_t *voodoo = (voodoo_t *) p; + voodoo->wr_count++; + addr &= 0xffffff; + cycles -= voodoo->write_time; + + if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ + voodoo_queue_command(voodoo, addr | FIFO_WRITEW_FB, val); +} + +static void +voodoo_writel(uint32_t addr, uint32_t val, void *p) +{ + voodoo_t *voodoo = (voodoo_t *) p; + + voodoo->wr_count++; + + addr &= 0xffffff; + + if (addr == voodoo->last_write_addr + 4) + cycles -= voodoo->burst_time; + else cycles -= voodoo->write_time; + voodoo->last_write_addr = addr; - if ((addr & 0xc00000) == 0x400000) /*Framebuffer*/ - voodoo_queue_command(voodoo, addr | FIFO_WRITEW_FB, val); -} - -static void voodoo_writel(uint32_t addr, uint32_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - voodoo->wr_count++; - - addr &= 0xffffff; - - if (addr == voodoo->last_write_addr+4) - cycles -= voodoo->burst_time; - else - cycles -= voodoo->write_time; - voodoo->last_write_addr = addr; - - if (addr & 0x800000) /*Texture*/ - { - voodoo->tex_count++; - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_TEX, val); - } - else if (addr & 0x400000) /*Framebuffer*/ - { - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); - } - else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) - { -// voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); - *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; - voodoo->cmdfifo_depth_wr++; - if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) - voodoo_wake_fifo_thread(voodoo); - } - else switch (addr & 0x3fc) - { - case SST_intrCtrl: + if (addr & 0x800000) /*Texture*/ + { + voodoo->tex_count++; + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_TEX, val); + } else if (addr & 0x400000) /*Framebuffer*/ + { + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_FB, val); + } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { + // voodoo_log("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); + *(uint32_t *) &voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; + voodoo->cmdfifo_depth_wr++; + if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) + voodoo_wake_fifo_thread(voodoo); + } else + switch (addr & 0x3fc) { + case SST_intrCtrl: fatal("intrCtrl write %08x\n", val); break; - case SST_userIntrCMD: + case SST_userIntrCMD: fatal("userIntrCMD write %08x\n", val); break; - case SST_swapbufferCMD: + case SST_swapbufferCMD: voodoo->cmd_written++; thread_wait_mutex(voodoo->swap_mutex); voodoo->swap_count++; thread_release_mutex(voodoo->swap_mutex); if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; + return; voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; - case SST_triangleCMD: + case SST_triangleCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; + return; voodoo->cmd_written++; voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; - case SST_ftriangleCMD: + case SST_ftriangleCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; + return; voodoo->cmd_written++; voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; - case SST_fastfillCMD: + case SST_fastfillCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; + return; voodoo->cmd_written++; voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; - case SST_nopCMD: + case SST_nopCMD: if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - return; + return; voodoo->cmd_written++; voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); + voodoo_wake_fifo_threads(voodoo->set, voodoo); break; - case SST_fbiInit4: - if (voodoo->initEnable & 0x01) - { - voodoo->fbiInit4 = val; - voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); -// voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); + case SST_fbiInit4: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit4 = val; + voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); + // voodoo_log("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); } break; - case SST_backPorch: + case SST_backPorch: voodoo->backPorch = val; break; - case SST_videoDimensions: + case SST_videoDimensions: voodoo->videoDimensions = val; - voodoo->h_disp = (val & 0xfff) + 1; - voodoo->v_disp = (val >> 16) & 0xfff; + voodoo->h_disp = (val & 0xfff) + 1; + voodoo->v_disp = (val >> 16) & 0xfff; break; - case SST_fbiInit0: - if (voodoo->initEnable & 0x01) - { - voodoo->fbiInit0 = val; - thread_wait_mutex(voodoo->force_blit_mutex); - voodoo->can_blit = (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) ? 1 : 0; - if (!voodoo->can_blit) - voodoo->force_blit_count = 0; - thread_release_mutex(voodoo->force_blit_mutex); + case SST_fbiInit0: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit0 = val; + thread_wait_mutex(voodoo->force_blit_mutex); + voodoo->can_blit = (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) ? 1 : 0; + if (!voodoo->can_blit) + voodoo->force_blit_count = 0; + thread_release_mutex(voodoo->force_blit_mutex); - if (voodoo->set->nr_cards == 2) - svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1); - else - svga_set_override(voodoo->svga, val & 1); - if (val & FBIINIT0_GRAPHICS_RESET) - { - /*Reset display/draw buffer selection. This may not actually - happen here on a real Voodoo*/ - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; - voodoo_recalc(voodoo); - voodoo->front_offset = voodoo->params.front_offset; - } - } - break; - case SST_fbiInit1: - if (voodoo->initEnable & 0x01) - { - if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) - { - voodoo->line = 0; - thread_wait_mutex(voodoo->swap_mutex); - voodoo->swap_count = 0; - thread_release_mutex(voodoo->swap_mutex); - voodoo->retrace_count = 0; - } - voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); - voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); - voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); -// voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); - } - break; - case SST_fbiInit2: - if (voodoo->initEnable & 0x01) - { - voodoo->fbiInit2 = val; + if (voodoo->set->nr_cards == 2) + svga_set_override(voodoo->svga, (voodoo->set->voodoos[0]->fbiInit0 | voodoo->set->voodoos[1]->fbiInit0) & 1); + else + svga_set_override(voodoo->svga, val & 1); + if (val & FBIINIT0_GRAPHICS_RESET) { + /*Reset display/draw buffer selection. This may not actually + happen here on a real Voodoo*/ + voodoo->disp_buffer = 0; + voodoo->draw_buffer = 1; voodoo_recalc(voodoo); + voodoo->front_offset = voodoo->params.front_offset; + } } break; - case SST_fbiInit3: + case SST_fbiInit1: + if (voodoo->initEnable & 0x01) { + if ((voodoo->fbiInit1 & FBIINIT1_VIDEO_RESET) && !(val & FBIINIT1_VIDEO_RESET)) { + voodoo->line = 0; + thread_wait_mutex(voodoo->swap_mutex); + voodoo->swap_count = 0; + thread_release_mutex(voodoo->swap_mutex); + voodoo->retrace_count = 0; + } + voodoo->fbiInit1 = (val & ~5) | (voodoo->fbiInit1 & 5); + voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); + voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); + // voodoo_log("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); + } + break; + case SST_fbiInit2: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit2 = val; + voodoo_recalc(voodoo); + } + break; + case SST_fbiInit3: if (voodoo->initEnable & 0x01) - voodoo->fbiInit3 = val; + voodoo->fbiInit3 = val; break; - case SST_hSync: - voodoo->hSync = val; + case SST_hSync: + voodoo->hSync = val; voodoo->h_total = (val & 0xffff) + (val >> 16); voodoo_pixelclock_update(voodoo); break; - case SST_vSync: - voodoo->vSync = val; + case SST_vSync: + voodoo->vSync = val; voodoo->v_total = (val & 0xffff) + (val >> 16); break; - case SST_clutData: + case SST_clutData: voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; - if (val & 0x20000000) - { - voodoo->clutData[(val >> 24) & 0x3f].b = 255; - voodoo->clutData[(val >> 24) & 0x3f].g = 255; - voodoo->clutData[(val >> 24) & 0x3f].r = 255; + if (val & 0x20000000) { + voodoo->clutData[(val >> 24) & 0x3f].b = 255; + voodoo->clutData[(val >> 24) & 0x3f].g = 255; + voodoo->clutData[(val >> 24) & 0x3f].r = 255; } voodoo->clutData_dirty = 1; break; - case SST_dacData: - voodoo->dac_reg = (val >> 8) & 7; + case SST_dacData: + voodoo->dac_reg = (val >> 8) & 7; voodoo->dac_readdata = 0xff; - if (val & 0x800) - { -// voodoo_log(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]); - if (voodoo->dac_reg == 5) - { - switch (voodoo->dac_data[7]) - { - case 0x01: voodoo->dac_readdata = 0x55; break; - case 0x07: voodoo->dac_readdata = 0x71; break; - case 0x0b: voodoo->dac_readdata = 0x79; break; - } + if (val & 0x800) { + // voodoo_log(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]); + if (voodoo->dac_reg == 5) { + switch (voodoo->dac_data[7]) { + case 0x01: + voodoo->dac_readdata = 0x55; + break; + case 0x07: + voodoo->dac_readdata = 0x71; + break; + case 0x0b: + voodoo->dac_readdata = 0x79; + break; } + } else + voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; + } else { + if (voodoo->dac_reg == 5) { + if (!voodoo->dac_reg_ff) + voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; else - voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; - } - else - { - if (voodoo->dac_reg == 5) - { - if (!voodoo->dac_reg_ff) - voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; - else - voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); -// voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); - voodoo->dac_reg_ff = !voodoo->dac_reg_ff; - if (!voodoo->dac_reg_ff) - voodoo->dac_data[4]++; + voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); + // voodoo_log("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); + voodoo->dac_reg_ff = !voodoo->dac_reg_ff; + if (!voodoo->dac_reg_ff) + voodoo->dac_data[4]++; - } - else - { - voodoo->dac_data[voodoo->dac_reg] = val & 0xff; - voodoo->dac_reg_ff = 0; - } - voodoo_pixelclock_update(voodoo); + } else { + voodoo->dac_data[voodoo->dac_reg] = val & 0xff; + voodoo->dac_reg_ff = 0; + } + voodoo_pixelclock_update(voodoo); } break; - case SST_scrFilter: - if (voodoo->initEnable & 0x01) - { - voodoo->scrfilterEnabled = 1; - voodoo->scrfilterThreshold = val; /* update the threshold values and generate a new lookup table if necessary */ + case SST_scrFilter: + if (voodoo->initEnable & 0x01) { + voodoo->scrfilterEnabled = 1; + voodoo->scrfilterThreshold = val; /* update the threshold values and generate a new lookup table if necessary */ - if (val < 1) - voodoo->scrfilterEnabled = 0; - voodoo_threshold_check(voodoo); - voodoo_log("Voodoo Filter: %06x\n", val); - } - break; - - case SST_fbiInit5: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit5 = (val & ~0x41e6) | (voodoo->fbiInit5 & 0x41e6); - break; - case SST_fbiInit6: - if (voodoo->initEnable & 0x01) - voodoo->fbiInit6 = val; - break; - case SST_fbiInit7: - if (voodoo->initEnable & 0x01) - { - voodoo->fbiInit7 = val; - voodoo->cmdfifo_enabled = val & 0x100; + if (val < 1) + voodoo->scrfilterEnabled = 0; + voodoo_threshold_check(voodoo); + voodoo_log("Voodoo Filter: %06x\n", val); } break; - case SST_cmdFifoBaseAddr: + case SST_fbiInit5: + if (voodoo->initEnable & 0x01) + voodoo->fbiInit5 = (val & ~0x41e6) | (voodoo->fbiInit5 & 0x41e6); + break; + case SST_fbiInit6: + if (voodoo->initEnable & 0x01) + voodoo->fbiInit6 = val; + break; + case SST_fbiInit7: + if (voodoo->initEnable & 0x01) { + voodoo->fbiInit7 = val; + voodoo->cmdfifo_enabled = val & 0x100; + } + break; + + case SST_cmdFifoBaseAddr: voodoo->cmdfifo_base = (val & 0x3ff) << 12; - voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; -// voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; + // voodoo_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); break; - case SST_cmdFifoRdPtr: + case SST_cmdFifoRdPtr: voodoo->cmdfifo_rp = val; break; - case SST_cmdFifoAMin: + case SST_cmdFifoAMin: voodoo->cmdfifo_amin = val; break; - case SST_cmdFifoAMax: + case SST_cmdFifoAMax: voodoo->cmdfifo_amax = val; break; - case SST_cmdFifoDepth: + case SST_cmdFifoDepth: voodoo->cmdfifo_depth_rd = 0; voodoo->cmdfifo_depth_wr = val & 0xffff; break; - default: - if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) - { - voodoo_log("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); - } - else - { - voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); + default: + if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE) { + voodoo_log("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val); + } else { + voodoo_queue_command(voodoo, addr | FIFO_WRITEL_REG, val); } break; } } -static uint16_t voodoo_snoop_readw(uint32_t addr, void *p) +static uint16_t +voodoo_snoop_readw(uint32_t addr, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *) p; - return voodoo_readw(addr, set->voodoos[0]); + return voodoo_readw(addr, set->voodoos[0]); } -static uint32_t voodoo_snoop_readl(uint32_t addr, void *p) +static uint32_t +voodoo_snoop_readl(uint32_t addr, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *) p; - return voodoo_readl(addr, set->voodoos[0]); + return voodoo_readl(addr, set->voodoos[0]); } -static void voodoo_snoop_writew(uint32_t addr, uint16_t val, void *p) +static void +voodoo_snoop_writew(uint32_t addr, uint16_t val, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *) p; - voodoo_writew(addr, val, set->voodoos[0]); - voodoo_writew(addr, val, set->voodoos[1]); + voodoo_writew(addr, val, set->voodoos[0]); + voodoo_writew(addr, val, set->voodoos[1]); } -static void voodoo_snoop_writel(uint32_t addr, uint32_t val, void *p) +static void +voodoo_snoop_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_set_t *set = (voodoo_set_t *)p; + voodoo_set_t *set = (voodoo_set_t *) p; - voodoo_writel(addr, val, set->voodoos[0]); - voodoo_writel(addr, val, set->voodoos[1]); + voodoo_writel(addr, val, set->voodoos[0]); + voodoo_writel(addr, val, set->voodoos[1]); } -static void voodoo_recalcmapping(voodoo_set_t *set) +static void +voodoo_recalcmapping(voodoo_set_t *set) { - if (set->nr_cards == 2) - { - if (set->voodoos[0]->pci_enable && set->voodoos[0]->memBaseAddr) - { - if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23)) - { - voodoo_log("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->voodoos[0]->mapping); - mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - } - else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr)) - { - voodoo_log("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->voodoos[0]->mapping); - mem_mapping_disable(&set->voodoos[1]->mapping); - mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - return; - } - else - { - voodoo_log("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); - mem_mapping_disable(&set->snoop_mapping); - mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000); - } - } - else - { - voodoo_log("voodoo_recalcmapping (pri) : disabled\n"); - mem_mapping_disable(&set->voodoos[0]->mapping); - } - - if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr) - { - voodoo_log("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr); - mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000); - } - else - { - voodoo_log("voodoo_recalcmapping (sec) : disabled\n"); - mem_mapping_disable(&set->voodoos[1]->mapping); - } - } - else - { - voodoo_t *voodoo = set->voodoos[0]; - - if (voodoo->pci_enable && voodoo->memBaseAddr) - { - voodoo_log("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr); - mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000); - } - else - { - voodoo_log("voodoo_recalcmapping : disabled\n"); - mem_mapping_disable(&voodoo->mapping); - } - } -} - -uint8_t voodoo_pci_read(int func, int addr, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - if (func) - return 0; - -// voodoo_log("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); - - switch (addr) - { - case 0x00: return 0x1a; /*3dfx*/ - case 0x01: return 0x12; - - case 0x02: - if (voodoo->type == VOODOO_2) - return 0x02; /*Voodoo 2*/ - else - return 0x01; /*SST-1 (Voodoo Graphics)*/ - case 0x03: return 0x00; - - case 0x04: return voodoo->pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/ - - case 0x08: return 2; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ - case 0x0a: return 0; - case 0x0b: return 0x04; - - case 0x10: return 0x00; /*memBaseAddr*/ - case 0x11: return 0x00; - case 0x12: return 0x00; - case 0x13: return voodoo->memBaseAddr >> 24; - - case 0x40: - return voodoo->initEnable & 0xff; - case 0x41: - if (voodoo->type == VOODOO_2) - return 0x50 | ((voodoo->initEnable >> 8) & 0x0f); - return (voodoo->initEnable >> 8) & 0x0f; - case 0x42: - return (voodoo->initEnable >> 16) & 0xff; - case 0x43: - return (voodoo->initEnable >> 24) & 0xff; - } - return 0; -} - -void voodoo_pci_write(int func, int addr, uint8_t val, void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - if (func) + if (set->nr_cards == 2) { + if (set->voodoos[0]->pci_enable && set->voodoos[0]->memBaseAddr) { + if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23)) { + voodoo_log("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->voodoos[0]->mapping); + mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); + } else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr)) { + voodoo_log("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->voodoos[0]->mapping); + mem_mapping_disable(&set->voodoos[1]->mapping); + mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000); return; - -// voodoo_log("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); - - switch (addr) - { - case 0x04: - voodoo->pci_enable = val & 2; - voodoo_recalcmapping(voodoo->set); - break; - - case 0x13: - voodoo->memBaseAddr = val << 24; - voodoo_recalcmapping(voodoo->set); - break; - - case 0x40: - voodoo->initEnable = (voodoo->initEnable & ~0x000000ff) | val; - break; - case 0x41: - voodoo->initEnable = (voodoo->initEnable & ~0x0000ff00) | (val << 8); - break; - case 0x42: - voodoo->initEnable = (voodoo->initEnable & ~0x00ff0000) | (val << 16); - voodoo_recalcmapping(voodoo->set); - break; - case 0x43: - voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); - voodoo_recalcmapping(voodoo->set); - break; - } -} - - -static void voodoo_speed_changed(void *p) -{ - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - - voodoo_pixelclock_update(voodoo_set->voodoos[0]); - voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); - voodoo_set->voodoos[0]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 1 : 0); - voodoo_set->voodoos[0]->burst_time = pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 2 : 1); - if (voodoo_set->nr_cards == 2) - { - voodoo_pixelclock_update(voodoo_set->voodoos[1]); - voodoo_set->voodoos[1]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit4 & 1) ? 2 : 1); - voodoo_set->voodoos[1]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0); - voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1); - } -// voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); -} - -static void voodoo_force_blit(void *p) -{ - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; - - thread_wait_mutex(voodoo_set->voodoos[0]->force_blit_mutex); - if(voodoo_set->voodoos[0]->can_blit) { - voodoo_set->voodoos[0]->force_blit_count++; - } - thread_release_mutex(voodoo_set->voodoos[0]->force_blit_mutex); - if(voodoo_set->nr_cards == 2) { - thread_wait_mutex(voodoo_set->voodoos[1]->force_blit_mutex); - if(voodoo_set->voodoos[1]->can_blit) { - voodoo_set->voodoos[1]->force_blit_count++; + } else { + voodoo_log("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr); + mem_mapping_disable(&set->snoop_mapping); + mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000); } - thread_release_mutex(voodoo_set->voodoos[1]->force_blit_mutex); + } else { + voodoo_log("voodoo_recalcmapping (pri) : disabled\n"); + mem_mapping_disable(&set->voodoos[0]->mapping); } + + if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr) { + voodoo_log("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr); + mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000); + } else { + voodoo_log("voodoo_recalcmapping (sec) : disabled\n"); + mem_mapping_disable(&set->voodoos[1]->mapping); + } + } else { + voodoo_t *voodoo = set->voodoos[0]; + + if (voodoo->pci_enable && voodoo->memBaseAddr) { + voodoo_log("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr); + mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000); + } else { + voodoo_log("voodoo_recalcmapping : disabled\n"); + mem_mapping_disable(&voodoo->mapping); + } + } } -void *voodoo_card_init() +uint8_t +voodoo_pci_read(int func, int addr, void *p) { - int c; - voodoo_t *voodoo = malloc(sizeof(voodoo_t)); - memset(voodoo, 0, sizeof(voodoo_t)); + voodoo_t *voodoo = (voodoo_t *) p; - voodoo->bilinear_enabled = device_get_config_int("bilinear"); - voodoo->dithersub_enabled = device_get_config_int("dithersub"); - voodoo->scrfilter = device_get_config_int("dacfilter"); - voodoo->texture_size = device_get_config_int("texture_memory"); - voodoo->texture_mask = (voodoo->texture_size << 20) - 1; - voodoo->fb_size = device_get_config_int("framebuffer_memory"); - voodoo->fb_mask = (voodoo->fb_size << 20) - 1; - voodoo->render_threads = device_get_config_int("render_threads"); - voodoo->odd_even_mask = voodoo->render_threads - 1; -#ifndef NO_CODEGEN - voodoo->use_recompiler = device_get_config_int("recompiler"); -#endif - voodoo->type = device_get_config_int("type"); - switch (voodoo->type) { - case VOODOO_1: - voodoo->dual_tmus = 0; - break; - case VOODOO_SB50: - voodoo->dual_tmus = 1; - break; - case VOODOO_2: - voodoo->dual_tmus = 1; - break; - } + if (func) + return 0; - if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ - voodoo_generate_filter_v2(voodoo); - else - voodoo_generate_filter_v1(voodoo); + // voodoo_log("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); - pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo); + switch (addr) { + case 0x00: + return 0x1a; /*3dfx*/ + case 0x01: + return 0x12; - mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo); + case 0x02: + if (voodoo->type == VOODOO_2) + return 0x02; /*Voodoo 2*/ + else + return 0x01; /*SST-1 (Voodoo Graphics)*/ + case 0x03: + return 0x00; - voodoo->fb_mem = malloc(4 * 1024 * 1024); - voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024); - if (voodoo->dual_tmus) - voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024); - voodoo->tex_mem_w[0] = (uint16_t *)voodoo->tex_mem[0]; - voodoo->tex_mem_w[1] = (uint16_t *)voodoo->tex_mem[1]; + case 0x04: + return voodoo->pci_enable ? 0x02 : 0x00; /*Respond to memory accesses*/ - for (c = 0; c < TEX_CACHE_MAX; c++) { - voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); - voodoo->texture_cache[0][c].base = -1; /*invalid*/ - voodoo->texture_cache[0][c].refcount = 0; - if (voodoo->dual_tmus) - { - voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); - voodoo->texture_cache[1][c].base = -1; /*invalid*/ - voodoo->texture_cache[1][c].refcount = 0; - } - } + case 0x08: + return 2; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0a: + return 0; + case 0x0b: + return 0x04; - timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); + case 0x10: + return 0x00; /*memBaseAddr*/ + case 0x11: + return 0x00; + case 0x12: + return 0x00; + case 0x13: + return voodoo->memBaseAddr >> 24; - voodoo->svga = svga_get_pri(); - voodoo->fbiInit0 = 0; - - voodoo->wake_fifo_thread = thread_create_event(); - voodoo->wake_render_thread[0] = thread_create_event(); - voodoo->wake_render_thread[1] = thread_create_event(); - voodoo->wake_render_thread[2] = thread_create_event(); - voodoo->wake_render_thread[3] = thread_create_event(); - voodoo->wake_main_thread = thread_create_event(); - voodoo->fifo_not_full_event = thread_create_event(); - voodoo->render_not_full_event[0] = thread_create_event(); - voodoo->render_not_full_event[1] = thread_create_event(); - voodoo->render_not_full_event[2] = thread_create_event(); - voodoo->render_not_full_event[3] = thread_create_event(); - voodoo->fifo_thread_run = 1; - voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); - voodoo->render_thread_run[0] = 1; - voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads >= 2) { - voodoo->render_thread_run[1] = 1; - voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); - } - if (voodoo->render_threads == 4) { - voodoo->render_thread_run[2] = 1; - voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); - voodoo->render_thread_run[3] = 1; - voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); - } - voodoo->swap_mutex = thread_create_mutex(); - timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); - - for (c = 0; c < 0x100; c++) { - rgb332[c].r = c & 0xe0; - rgb332[c].g = (c << 3) & 0xe0; - rgb332[c].b = (c << 6) & 0xc0; - rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); - rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); - rgb332[c].a = 0xff; - - ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); - ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); - ai44[c].g = ai44[c].b = ai44[c].r; - } - - for (c = 0; c < 0x10000; c++) { - rgb565[c].r = (c >> 8) & 0xf8; - rgb565[c].g = (c >> 3) & 0xfc; - rgb565[c].b = (c << 3) & 0xf8; - rgb565[c].r |= (rgb565[c].r >> 5); - rgb565[c].g |= (rgb565[c].g >> 6); - rgb565[c].b |= (rgb565[c].b >> 5); - rgb565[c].a = 0xff; - - argb1555[c].r = (c >> 7) & 0xf8; - argb1555[c].g = (c >> 2) & 0xf8; - argb1555[c].b = (c << 3) & 0xf8; - argb1555[c].r |= (argb1555[c].r >> 5); - argb1555[c].g |= (argb1555[c].g >> 5); - argb1555[c].b |= (argb1555[c].b >> 5); - argb1555[c].a = (c & 0x8000) ? 0xff : 0; - - argb4444[c].a = (c >> 8) & 0xf0; - argb4444[c].r = (c >> 4) & 0xf0; - argb4444[c].g = c & 0xf0; - argb4444[c].b = (c << 4) & 0xf0; - argb4444[c].a |= (argb4444[c].a >> 4); - argb4444[c].r |= (argb4444[c].r >> 4); - argb4444[c].g |= (argb4444[c].g >> 4); - argb4444[c].b |= (argb4444[c].b >> 4); - - ai88[c].a = (c >> 8); - ai88[c].r = c & 0xff; - ai88[c].g = c & 0xff; - ai88[c].b = c & 0xff; - } -#ifndef NO_CODEGEN - voodoo_codegen_init(voodoo); -#endif - - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; - - voodoo->force_blit_count = 0; - voodoo->can_blit = 0; - voodoo->force_blit_mutex = thread_create_mutex(); - - return voodoo; + case 0x40: + return voodoo->initEnable & 0xff; + case 0x41: + if (voodoo->type == VOODOO_2) + return 0x50 | ((voodoo->initEnable >> 8) & 0x0f); + return (voodoo->initEnable >> 8) & 0x0f; + case 0x42: + return (voodoo->initEnable >> 16) & 0xff; + case 0x43: + return (voodoo->initEnable >> 24) & 0xff; + } + return 0; } -void *voodoo_2d3d_card_init(int type) +void +voodoo_pci_write(int func, int addr, uint8_t val, void *p) { - int c; - voodoo_t *voodoo = malloc(sizeof(voodoo_t)); - memset(voodoo, 0, sizeof(voodoo_t)); + voodoo_t *voodoo = (voodoo_t *) p; - voodoo->bilinear_enabled = device_get_config_int("bilinear"); - voodoo->dithersub_enabled = device_get_config_int("dithersub"); - voodoo->scrfilter = device_get_config_int("dacfilter"); - voodoo->render_threads = device_get_config_int("render_threads"); - voodoo->odd_even_mask = voodoo->render_threads - 1; -#ifndef NO_CODEGEN - voodoo->use_recompiler = device_get_config_int("recompiler"); -#endif - voodoo->type = type; - voodoo->dual_tmus = (type == VOODOO_3) ? 1 : 0; + if (func) + return; - /*generate filter lookup tables*/ - voodoo_generate_filter_v2(voodoo); + // voodoo_log("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); - for (c = 0; c < TEX_CACHE_MAX; c++) { - voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); - voodoo->texture_cache[0][c].base = -1; /*invalid*/ - voodoo->texture_cache[0][c].refcount = 0; - if (voodoo->dual_tmus) - { - voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4); - voodoo->texture_cache[1][c].base = -1; /*invalid*/ - voodoo->texture_cache[1][c].refcount = 0; - } - } + switch (addr) { + case 0x04: + voodoo->pci_enable = val & 2; + voodoo_recalcmapping(voodoo->set); + break; - timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); + case 0x13: + voodoo->memBaseAddr = val << 24; + voodoo_recalcmapping(voodoo->set); + break; - voodoo->fbiInit0 = 0; - - voodoo->wake_fifo_thread = thread_create_event(); - voodoo->wake_render_thread[0] = thread_create_event(); - voodoo->wake_render_thread[1] = thread_create_event(); - voodoo->wake_render_thread[2] = thread_create_event(); - voodoo->wake_render_thread[3] = thread_create_event(); - voodoo->wake_main_thread = thread_create_event(); - voodoo->fifo_not_full_event = thread_create_event(); - voodoo->render_not_full_event[0] = thread_create_event(); - voodoo->render_not_full_event[1] = thread_create_event(); - voodoo->render_not_full_event[2] = thread_create_event(); - voodoo->render_not_full_event[3] = thread_create_event(); - voodoo->fifo_thread_run = 1; - voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); - voodoo->render_thread_run[0] = 1; - voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); - if (voodoo->render_threads >= 2) { - voodoo->render_thread_run[1] = 1; - voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); - } - if (voodoo->render_threads == 4) { - voodoo->render_thread_run[2] = 1; - voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); - voodoo->render_thread_run[3] = 1; - voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); - } - voodoo->swap_mutex = thread_create_mutex(); - timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0); - - for (c = 0; c < 0x100; c++) { - rgb332[c].r = c & 0xe0; - rgb332[c].g = (c << 3) & 0xe0; - rgb332[c].b = (c << 6) & 0xc0; - rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); - rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); - rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); - rgb332[c].a = 0xff; - - ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); - ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); - ai44[c].g = ai44[c].b = ai44[c].r; - } - - for (c = 0; c < 0x10000; c++) { - rgb565[c].r = (c >> 8) & 0xf8; - rgb565[c].g = (c >> 3) & 0xfc; - rgb565[c].b = (c << 3) & 0xf8; - rgb565[c].r |= (rgb565[c].r >> 5); - rgb565[c].g |= (rgb565[c].g >> 6); - rgb565[c].b |= (rgb565[c].b >> 5); - rgb565[c].a = 0xff; - - argb1555[c].r = (c >> 7) & 0xf8; - argb1555[c].g = (c >> 2) & 0xf8; - argb1555[c].b = (c << 3) & 0xf8; - argb1555[c].r |= (argb1555[c].r >> 5); - argb1555[c].g |= (argb1555[c].g >> 5); - argb1555[c].b |= (argb1555[c].b >> 5); - argb1555[c].a = (c & 0x8000) ? 0xff : 0; - - argb4444[c].a = (c >> 8) & 0xf0; - argb4444[c].r = (c >> 4) & 0xf0; - argb4444[c].g = c & 0xf0; - argb4444[c].b = (c << 4) & 0xf0; - argb4444[c].a |= (argb4444[c].a >> 4); - argb4444[c].r |= (argb4444[c].r >> 4); - argb4444[c].g |= (argb4444[c].g >> 4); - argb4444[c].b |= (argb4444[c].b >> 4); - - ai88[c].a = (c >> 8); - ai88[c].r = c & 0xff; - ai88[c].g = c & 0xff; - ai88[c].b = c & 0xff; - } -#ifndef NO_CODEGEN - voodoo_codegen_init(voodoo); -#endif - - voodoo->disp_buffer = 0; - voodoo->draw_buffer = 1; - - voodoo->force_blit_count = 0; - voodoo->can_blit = 0; - voodoo->force_blit_mutex = thread_create_mutex(); - - return voodoo; + case 0x40: + voodoo->initEnable = (voodoo->initEnable & ~0x000000ff) | val; + break; + case 0x41: + voodoo->initEnable = (voodoo->initEnable & ~0x0000ff00) | (val << 8); + break; + case 0x42: + voodoo->initEnable = (voodoo->initEnable & ~0x00ff0000) | (val << 16); + voodoo_recalcmapping(voodoo->set); + break; + case 0x43: + voodoo->initEnable = (voodoo->initEnable & ~0xff000000) | (val << 24); + voodoo_recalcmapping(voodoo->set); + break; + } } -void *voodoo_init() +static void +voodoo_speed_changed(void *p) { - voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); - uint32_t tmuConfig = 1; - int type; - memset(voodoo_set, 0, sizeof(voodoo_set_t)); + voodoo_set_t *voodoo_set = (voodoo_set_t *) p; - type = device_get_config_int("type"); + voodoo_pixelclock_update(voodoo_set->voodoos[0]); + voodoo_set->voodoos[0]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit4 & 1) ? 2 : 1); + voodoo_set->voodoos[0]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 1 : 0); + voodoo_set->voodoos[0]->burst_time = pci_burst_time * ((voodoo_set->voodoos[0]->fbiInit1 & 2) ? 2 : 1); + if (voodoo_set->nr_cards == 2) { + voodoo_pixelclock_update(voodoo_set->voodoos[1]); + voodoo_set->voodoos[1]->read_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit4 & 1) ? 2 : 1); + voodoo_set->voodoos[1]->write_time = pci_nonburst_time + pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 1 : 0); + voodoo_set->voodoos[1]->burst_time = pci_burst_time * ((voodoo_set->voodoos[1]->fbiInit1 & 2) ? 2 : 1); + } + // voodoo_log("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); +} - voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1; - voodoo_set->voodoos[0] = voodoo_card_init(); - voodoo_set->voodoos[0]->set = voodoo_set; - if (voodoo_set->nr_cards == 2) - { - voodoo_set->voodoos[1] = voodoo_card_init(); +static void +voodoo_force_blit(void *p) +{ + voodoo_set_t *voodoo_set = (voodoo_set_t *) p; - voodoo_set->voodoos[1]->set = voodoo_set; - - if (type == VOODOO_2) - { - voodoo_set->voodoos[0]->fbiInit5 |= FBIINIT5_MULTI_CVG; - voodoo_set->voodoos[1]->fbiInit5 |= FBIINIT5_MULTI_CVG; - } - else - { - voodoo_set->voodoos[0]->fbiInit1 |= FBIINIT1_MULTI_SST; - voodoo_set->voodoos[1]->fbiInit1 |= FBIINIT1_MULTI_SST; - } + thread_wait_mutex(voodoo_set->voodoos[0]->force_blit_mutex); + if (voodoo_set->voodoos[0]->can_blit) { + voodoo_set->voodoos[0]->force_blit_count++; + } + thread_release_mutex(voodoo_set->voodoos[0]->force_blit_mutex); + if (voodoo_set->nr_cards == 2) { + thread_wait_mutex(voodoo_set->voodoos[1]->force_blit_mutex); + if (voodoo_set->voodoos[1]->can_blit) { + voodoo_set->voodoos[1]->force_blit_count++; } + thread_release_mutex(voodoo_set->voodoos[1]->force_blit_mutex); + } +} - switch (type) - { - case VOODOO_1: - if (voodoo_set->nr_cards == 2) - tmuConfig = 1 | (3 << 3); - else - tmuConfig = 1; - break; - case VOODOO_SB50: - if (voodoo_set->nr_cards == 2) - tmuConfig = 1 | (3 << 3) | (3 << 6) | (2 << 9); - else - tmuConfig = 1 | (3 << 6); - break; - case VOODOO_2: +void * +voodoo_card_init() +{ + int c; + voodoo_t *voodoo = malloc(sizeof(voodoo_t)); + memset(voodoo, 0, sizeof(voodoo_t)); + + voodoo->bilinear_enabled = device_get_config_int("bilinear"); + voodoo->dithersub_enabled = device_get_config_int("dithersub"); + voodoo->scrfilter = device_get_config_int("dacfilter"); + voodoo->texture_size = device_get_config_int("texture_memory"); + voodoo->texture_mask = (voodoo->texture_size << 20) - 1; + voodoo->fb_size = device_get_config_int("framebuffer_memory"); + voodoo->fb_mask = (voodoo->fb_size << 20) - 1; + voodoo->render_threads = device_get_config_int("render_threads"); + voodoo->odd_even_mask = voodoo->render_threads - 1; +#ifndef NO_CODEGEN + voodoo->use_recompiler = device_get_config_int("recompiler"); +#endif + voodoo->type = device_get_config_int("type"); + switch (voodoo->type) { + case VOODOO_1: + voodoo->dual_tmus = 0; + break; + case VOODOO_SB50: + voodoo->dual_tmus = 1; + break; + case VOODOO_2: + voodoo->dual_tmus = 1; + break; + } + + if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ + voodoo_generate_filter_v2(voodoo); + else + voodoo_generate_filter_v1(voodoo); + + pci_add_card(PCI_ADD_NORMAL, voodoo_pci_read, voodoo_pci_write, voodoo); + + mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo); + + voodoo->fb_mem = malloc(4 * 1024 * 1024); + voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024); + if (voodoo->dual_tmus) + voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024); + voodoo->tex_mem_w[0] = (uint16_t *) voodoo->tex_mem[0]; + voodoo->tex_mem_w[1] = (uint16_t *) voodoo->tex_mem[1]; + + for (c = 0; c < TEX_CACHE_MAX; c++) { + voodoo->texture_cache[0][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[0][c].base = -1; /*invalid*/ + voodoo->texture_cache[0][c].refcount = 0; + if (voodoo->dual_tmus) { + voodoo->texture_cache[1][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[1][c].base = -1; /*invalid*/ + voodoo->texture_cache[1][c].refcount = 0; + } + } + + timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); + + voodoo->svga = svga_get_pri(); + voodoo->fbiInit0 = 0; + + voodoo->wake_fifo_thread = thread_create_event(); + voodoo->wake_render_thread[0] = thread_create_event(); + voodoo->wake_render_thread[1] = thread_create_event(); + voodoo->wake_render_thread[2] = thread_create_event(); + voodoo->wake_render_thread[3] = thread_create_event(); + voodoo->wake_main_thread = thread_create_event(); + voodoo->fifo_not_full_event = thread_create_event(); + voodoo->render_not_full_event[0] = thread_create_event(); + voodoo->render_not_full_event[1] = thread_create_event(); + voodoo->render_not_full_event[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); + voodoo->fifo_thread_run = 1; + voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread_run[0] = 1; + voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); + if (voodoo->render_threads >= 2) { + voodoo->render_thread_run[1] = 1; + voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + } + if (voodoo->render_threads == 4) { + voodoo->render_thread_run[2] = 1; + voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread_run[3] = 1; + voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); + } + voodoo->swap_mutex = thread_create_mutex(); + timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *) voodoo, 0); + + for (c = 0; c < 0x100; c++) { + rgb332[c].r = c & 0xe0; + rgb332[c].g = (c << 3) & 0xe0; + rgb332[c].b = (c << 6) & 0xc0; + rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); + rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); + rgb332[c].a = 0xff; + + ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); + ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); + ai44[c].g = ai44[c].b = ai44[c].r; + } + + for (c = 0; c < 0x10000; c++) { + rgb565[c].r = (c >> 8) & 0xf8; + rgb565[c].g = (c >> 3) & 0xfc; + rgb565[c].b = (c << 3) & 0xf8; + rgb565[c].r |= (rgb565[c].r >> 5); + rgb565[c].g |= (rgb565[c].g >> 6); + rgb565[c].b |= (rgb565[c].b >> 5); + rgb565[c].a = 0xff; + + argb1555[c].r = (c >> 7) & 0xf8; + argb1555[c].g = (c >> 2) & 0xf8; + argb1555[c].b = (c << 3) & 0xf8; + argb1555[c].r |= (argb1555[c].r >> 5); + argb1555[c].g |= (argb1555[c].g >> 5); + argb1555[c].b |= (argb1555[c].b >> 5); + argb1555[c].a = (c & 0x8000) ? 0xff : 0; + + argb4444[c].a = (c >> 8) & 0xf0; + argb4444[c].r = (c >> 4) & 0xf0; + argb4444[c].g = c & 0xf0; + argb4444[c].b = (c << 4) & 0xf0; + argb4444[c].a |= (argb4444[c].a >> 4); + argb4444[c].r |= (argb4444[c].r >> 4); + argb4444[c].g |= (argb4444[c].g >> 4); + argb4444[c].b |= (argb4444[c].b >> 4); + + ai88[c].a = (c >> 8); + ai88[c].r = c & 0xff; + ai88[c].g = c & 0xff; + ai88[c].b = c & 0xff; + } +#ifndef NO_CODEGEN + voodoo_codegen_init(voodoo); +#endif + + voodoo->disp_buffer = 0; + voodoo->draw_buffer = 1; + + voodoo->force_blit_count = 0; + voodoo->can_blit = 0; + voodoo->force_blit_mutex = thread_create_mutex(); + + return voodoo; +} + +void * +voodoo_2d3d_card_init(int type) +{ + int c; + voodoo_t *voodoo = malloc(sizeof(voodoo_t)); + memset(voodoo, 0, sizeof(voodoo_t)); + + voodoo->bilinear_enabled = device_get_config_int("bilinear"); + voodoo->dithersub_enabled = device_get_config_int("dithersub"); + voodoo->scrfilter = device_get_config_int("dacfilter"); + voodoo->render_threads = device_get_config_int("render_threads"); + voodoo->odd_even_mask = voodoo->render_threads - 1; +#ifndef NO_CODEGEN + voodoo->use_recompiler = device_get_config_int("recompiler"); +#endif + voodoo->type = type; + voodoo->dual_tmus = (type == VOODOO_3) ? 1 : 0; + + /*generate filter lookup tables*/ + voodoo_generate_filter_v2(voodoo); + + for (c = 0; c < TEX_CACHE_MAX; c++) { + voodoo->texture_cache[0][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[0][c].base = -1; /*invalid*/ + voodoo->texture_cache[0][c].refcount = 0; + if (voodoo->dual_tmus) { + voodoo->texture_cache[1][c].data = malloc((256 * 256 + 256 * 256 + 128 * 128 + 64 * 64 + 32 * 32 + 16 * 16 + 8 * 8 + 4 * 4 + 2 * 2) * 4); + voodoo->texture_cache[1][c].base = -1; /*invalid*/ + voodoo->texture_cache[1][c].refcount = 0; + } + } + + timer_add(&voodoo->timer, voodoo_callback, voodoo, 1); + + voodoo->fbiInit0 = 0; + + voodoo->wake_fifo_thread = thread_create_event(); + voodoo->wake_render_thread[0] = thread_create_event(); + voodoo->wake_render_thread[1] = thread_create_event(); + voodoo->wake_render_thread[2] = thread_create_event(); + voodoo->wake_render_thread[3] = thread_create_event(); + voodoo->wake_main_thread = thread_create_event(); + voodoo->fifo_not_full_event = thread_create_event(); + voodoo->render_not_full_event[0] = thread_create_event(); + voodoo->render_not_full_event[1] = thread_create_event(); + voodoo->render_not_full_event[2] = thread_create_event(); + voodoo->render_not_full_event[3] = thread_create_event(); + voodoo->fifo_thread_run = 1; + voodoo->fifo_thread = thread_create(voodoo_fifo_thread, voodoo); + voodoo->render_thread_run[0] = 1; + voodoo->render_thread[0] = thread_create(voodoo_render_thread_1, voodoo); + if (voodoo->render_threads >= 2) { + voodoo->render_thread_run[1] = 1; + voodoo->render_thread[1] = thread_create(voodoo_render_thread_2, voodoo); + } + if (voodoo->render_threads == 4) { + voodoo->render_thread_run[2] = 1; + voodoo->render_thread[2] = thread_create(voodoo_render_thread_3, voodoo); + voodoo->render_thread_run[3] = 1; + voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo); + } + voodoo->swap_mutex = thread_create_mutex(); + timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *) voodoo, 0); + + for (c = 0; c < 0x100; c++) { + rgb332[c].r = c & 0xe0; + rgb332[c].g = (c << 3) & 0xe0; + rgb332[c].b = (c << 6) & 0xc0; + rgb332[c].r = rgb332[c].r | (rgb332[c].r >> 3) | (rgb332[c].r >> 6); + rgb332[c].g = rgb332[c].g | (rgb332[c].g >> 3) | (rgb332[c].g >> 6); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 2); + rgb332[c].b = rgb332[c].b | (rgb332[c].b >> 4); + rgb332[c].a = 0xff; + + ai44[c].a = (c & 0xf0) | ((c & 0xf0) >> 4); + ai44[c].r = (c & 0x0f) | ((c & 0x0f) << 4); + ai44[c].g = ai44[c].b = ai44[c].r; + } + + for (c = 0; c < 0x10000; c++) { + rgb565[c].r = (c >> 8) & 0xf8; + rgb565[c].g = (c >> 3) & 0xfc; + rgb565[c].b = (c << 3) & 0xf8; + rgb565[c].r |= (rgb565[c].r >> 5); + rgb565[c].g |= (rgb565[c].g >> 6); + rgb565[c].b |= (rgb565[c].b >> 5); + rgb565[c].a = 0xff; + + argb1555[c].r = (c >> 7) & 0xf8; + argb1555[c].g = (c >> 2) & 0xf8; + argb1555[c].b = (c << 3) & 0xf8; + argb1555[c].r |= (argb1555[c].r >> 5); + argb1555[c].g |= (argb1555[c].g >> 5); + argb1555[c].b |= (argb1555[c].b >> 5); + argb1555[c].a = (c & 0x8000) ? 0xff : 0; + + argb4444[c].a = (c >> 8) & 0xf0; + argb4444[c].r = (c >> 4) & 0xf0; + argb4444[c].g = c & 0xf0; + argb4444[c].b = (c << 4) & 0xf0; + argb4444[c].a |= (argb4444[c].a >> 4); + argb4444[c].r |= (argb4444[c].r >> 4); + argb4444[c].g |= (argb4444[c].g >> 4); + argb4444[c].b |= (argb4444[c].b >> 4); + + ai88[c].a = (c >> 8); + ai88[c].r = c & 0xff; + ai88[c].g = c & 0xff; + ai88[c].b = c & 0xff; + } +#ifndef NO_CODEGEN + voodoo_codegen_init(voodoo); +#endif + + voodoo->disp_buffer = 0; + voodoo->draw_buffer = 1; + + voodoo->force_blit_count = 0; + voodoo->can_blit = 0; + voodoo->force_blit_mutex = thread_create_mutex(); + + return voodoo; +} + +void * +voodoo_init() +{ + voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t)); + uint32_t tmuConfig = 1; + int type; + memset(voodoo_set, 0, sizeof(voodoo_set_t)); + + type = device_get_config_int("type"); + + voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1; + voodoo_set->voodoos[0] = voodoo_card_init(); + voodoo_set->voodoos[0]->set = voodoo_set; + if (voodoo_set->nr_cards == 2) { + voodoo_set->voodoos[1] = voodoo_card_init(); + + voodoo_set->voodoos[1]->set = voodoo_set; + + if (type == VOODOO_2) { + voodoo_set->voodoos[0]->fbiInit5 |= FBIINIT5_MULTI_CVG; + voodoo_set->voodoos[1]->fbiInit5 |= FBIINIT5_MULTI_CVG; + } else { + voodoo_set->voodoos[0]->fbiInit1 |= FBIINIT1_MULTI_SST; + voodoo_set->voodoos[1]->fbiInit1 |= FBIINIT1_MULTI_SST; + } + } + + switch (type) { + case VOODOO_1: + if (voodoo_set->nr_cards == 2) + tmuConfig = 1 | (3 << 3); + else + tmuConfig = 1; + break; + case VOODOO_SB50: + if (voodoo_set->nr_cards == 2) + tmuConfig = 1 | (3 << 3) | (3 << 6) | (2 << 9); + else tmuConfig = 1 | (3 << 6); - break; - } + break; + case VOODOO_2: + tmuConfig = 1 | (3 << 6); + break; + } - voodoo_set->voodoos[0]->tmuConfig = tmuConfig; - if (voodoo_set->nr_cards == 2) - voodoo_set->voodoos[1]->tmuConfig = tmuConfig; + voodoo_set->voodoos[0]->tmuConfig = tmuConfig; + if (voodoo_set->nr_cards == 2) + voodoo_set->voodoos[1]->tmuConfig = tmuConfig; - mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set); + mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set); - return voodoo_set; + return voodoo_set; } -void voodoo_card_close(voodoo_t *voodoo) +void +voodoo_card_close(voodoo_t *voodoo) { - int c; + int c; - voodoo->fifo_thread_run = 0; - thread_set_event(voodoo->wake_fifo_thread); - thread_wait(voodoo->fifo_thread); - voodoo->render_thread_run[0] = 0; - thread_set_event(voodoo->wake_render_thread[0]); - thread_wait(voodoo->render_thread[0]); - if (voodoo->render_threads >= 2) { - voodoo->render_thread_run[1] = 0; - thread_set_event(voodoo->wake_render_thread[1]); - thread_wait(voodoo->render_thread[1]); - } - if (voodoo->render_threads == 4) { - voodoo->render_thread_run[2] = 0; - thread_set_event(voodoo->wake_render_thread[2]); - thread_wait(voodoo->render_thread[2]); - voodoo->render_thread_run[3] = 0; - thread_set_event(voodoo->wake_render_thread[3]); - thread_wait(voodoo->render_thread[3]); - } - thread_destroy_event(voodoo->fifo_not_full_event); - thread_destroy_event(voodoo->wake_main_thread); - thread_destroy_event(voodoo->wake_fifo_thread); - thread_destroy_event(voodoo->wake_render_thread[0]); - thread_destroy_event(voodoo->wake_render_thread[1]); - thread_destroy_event(voodoo->render_not_full_event[0]); - thread_destroy_event(voodoo->render_not_full_event[1]); + voodoo->fifo_thread_run = 0; + thread_set_event(voodoo->wake_fifo_thread); + thread_wait(voodoo->fifo_thread); + voodoo->render_thread_run[0] = 0; + thread_set_event(voodoo->wake_render_thread[0]); + thread_wait(voodoo->render_thread[0]); + if (voodoo->render_threads >= 2) { + voodoo->render_thread_run[1] = 0; + thread_set_event(voodoo->wake_render_thread[1]); + thread_wait(voodoo->render_thread[1]); + } + if (voodoo->render_threads == 4) { + voodoo->render_thread_run[2] = 0; + thread_set_event(voodoo->wake_render_thread[2]); + thread_wait(voodoo->render_thread[2]); + voodoo->render_thread_run[3] = 0; + thread_set_event(voodoo->wake_render_thread[3]); + thread_wait(voodoo->render_thread[3]); + } + thread_destroy_event(voodoo->fifo_not_full_event); + thread_destroy_event(voodoo->wake_main_thread); + thread_destroy_event(voodoo->wake_fifo_thread); + thread_destroy_event(voodoo->wake_render_thread[0]); + thread_destroy_event(voodoo->wake_render_thread[1]); + thread_destroy_event(voodoo->render_not_full_event[0]); + thread_destroy_event(voodoo->render_not_full_event[1]); - for (c = 0; c < TEX_CACHE_MAX; c++) - { - if (voodoo->dual_tmus) - free(voodoo->texture_cache[1][c].data); - free(voodoo->texture_cache[0][c].data); - } + for (c = 0; c < TEX_CACHE_MAX; c++) { + if (voodoo->dual_tmus) + free(voodoo->texture_cache[1][c].data); + free(voodoo->texture_cache[0][c].data); + } #ifndef NO_CODEGEN - voodoo_codegen_close(voodoo); + voodoo_codegen_close(voodoo); #endif - if (voodoo->type < VOODOO_BANSHEE && voodoo->fb_mem) - { - free(voodoo->fb_mem); - if (voodoo->dual_tmus) - free(voodoo->tex_mem[1]); - free(voodoo->tex_mem[0]); - } + if (voodoo->type < VOODOO_BANSHEE && voodoo->fb_mem) { + free(voodoo->fb_mem); + if (voodoo->dual_tmus) + free(voodoo->tex_mem[1]); + free(voodoo->tex_mem[0]); + } - thread_close_mutex(voodoo->force_blit_mutex); + thread_close_mutex(voodoo->force_blit_mutex); - free(voodoo); + free(voodoo); } -void voodoo_close(void *p) +void +voodoo_close(void *p) { - voodoo_set_t *voodoo_set = (voodoo_set_t *)p; + voodoo_set_t *voodoo_set = (voodoo_set_t *) p; - if (voodoo_set->nr_cards == 2) - voodoo_card_close(voodoo_set->voodoos[1]); - voodoo_card_close(voodoo_set->voodoos[0]); + if (voodoo_set->nr_cards == 2) + voodoo_card_close(voodoo_set->voodoos[1]); + voodoo_card_close(voodoo_set->voodoos[0]); - free(voodoo_set); + free(voodoo_set); } static const device_config_t voodoo_config[] = { -// clang-format off + // clang-format off { .name = "type", .description = "Voodoo type", @@ -1424,17 +1391,16 @@ static const device_config_t voodoo_config[] = { // clang-format on }; -const device_t voodoo_device = -{ - .name = "3DFX Voodoo Graphics", +const device_t voodoo_device = { + .name = "3DFX Voodoo Graphics", .internal_name = "voodoo", - .flags = DEVICE_PCI, - .local = 0, - .init = voodoo_init, - .close = voodoo_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = voodoo_init, + .close = voodoo_close, + .reset = NULL, { .available = NULL }, .speed_changed = voodoo_speed_changed, - .force_redraw = voodoo_force_blit, - .config = voodoo_config + .force_redraw = voodoo_force_blit, + .config = voodoo_config }; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 42b06eb4b..b0ac32035 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -44,237 +44,232 @@ #include <86box/vid_voodoo_regs.h> #include <86box/vid_voodoo_render.h> - -static video_timings_t timing_banshee = {VIDEO_PCI, 2, 2, 1, 20, 20, 21}; -static video_timings_t timing_banshee_agp = {VIDEO_AGP, 2, 2, 1, 20, 20, 21}; - +static video_timings_t timing_banshee = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; +static video_timings_t timing_banshee_agp = { .type = VIDEO_AGP, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; #ifdef CLAMP -#undef CLAMP +# undef CLAMP #endif static uint8_t vb_filter_v1_rb[256][256]; -static uint8_t vb_filter_v1_g [256][256]; +static uint8_t vb_filter_v1_g[256][256]; static uint8_t vb_filter_bx_rb[256][256]; -static uint8_t vb_filter_bx_g [256][256]; +static uint8_t vb_filter_bx_g[256][256]; -enum -{ - TYPE_BANSHEE = 0, - TYPE_V3_2000, - TYPE_V3_3000, - TYPE_VELOCITY100 +enum { + TYPE_BANSHEE = 0, + TYPE_V3_2000, + TYPE_V3_3000, + TYPE_VELOCITY100 }; -typedef struct banshee_t -{ - svga_t svga; +typedef struct banshee_t { + svga_t svga; - rom_t bios_rom; + rom_t bios_rom; - uint8_t pci_regs[256]; + uint8_t pci_regs[256]; - uint32_t memBaseAddr0; - uint32_t memBaseAddr1; - uint32_t ioBaseAddr; + uint32_t memBaseAddr0; + uint32_t memBaseAddr1; + uint32_t ioBaseAddr; - uint32_t agpInit0; - uint32_t dramInit0, dramInit1; - uint32_t lfbMemoryConfig; - uint32_t miscInit0, miscInit1; - uint32_t pciInit0; - uint32_t vgaInit0, vgaInit1; + uint32_t agpInit0; + uint32_t dramInit0, dramInit1; + uint32_t lfbMemoryConfig; + uint32_t miscInit0, miscInit1; + uint32_t pciInit0; + uint32_t vgaInit0, vgaInit1; - uint32_t command_2d; - uint32_t srcBaseAddr_2d; + uint32_t command_2d; + uint32_t srcBaseAddr_2d; - uint32_t pllCtrl0, pllCtrl1, pllCtrl2; + uint32_t pllCtrl0, pllCtrl1, pllCtrl2; - uint32_t dacMode; - int dacAddr; + uint32_t dacMode; + int dacAddr; - uint32_t vidDesktopOverlayStride; - uint32_t vidDesktopStartAddr; - uint32_t vidProcCfg; - uint32_t vidScreenSize; - uint32_t vidSerialParallelPort; + uint32_t vidDesktopOverlayStride; + uint32_t vidDesktopStartAddr; + uint32_t vidProcCfg; + uint32_t vidScreenSize; + uint32_t vidSerialParallelPort; - int overlay_pix_fmt; + int overlay_pix_fmt; - uint32_t hwCurPatAddr, hwCurLoc, hwCurC0, hwCurC1; + uint32_t hwCurPatAddr, hwCurLoc, hwCurC0, hwCurC1; - uint32_t intrCtrl; + uint32_t intrCtrl; - uint32_t overlay_buffer[2][4096]; + uint32_t overlay_buffer[2][4096]; - mem_mapping_t linear_mapping; + mem_mapping_t linear_mapping; - mem_mapping_t reg_mapping_low; /*0000000-07fffff*/ - mem_mapping_t reg_mapping_high; /*0c00000-1ffffff - Windows 2000 puts the BIOS ROM in between these two areas*/ + mem_mapping_t reg_mapping_low; /*0000000-07fffff*/ + mem_mapping_t reg_mapping_high; /*0c00000-1ffffff - Windows 2000 puts the BIOS ROM in between these two areas*/ - voodoo_t *voodoo; + voodoo_t *voodoo; - uint32_t desktop_addr; - int desktop_y; - uint32_t desktop_stride_tiled; + uint32_t desktop_addr; + int desktop_y; + uint32_t desktop_stride_tiled; - int type, card, agp, has_bios; - int vblank_irq; + int type, card, agp, has_bios; + int vblank_irq; - void *i2c, *i2c_ddc, *ddc; + void *i2c, *i2c_ddc, *ddc; } banshee_t; -enum -{ - Init_status = 0x00, - Init_pciInit0 = 0x04, - Init_lfbMemoryConfig = 0x0c, - Init_miscInit0 = 0x10, - Init_miscInit1 = 0x14, - Init_dramInit0 = 0x18, - Init_dramInit1 = 0x1c, - Init_agpInit0 = 0x20, - Init_vgaInit0 = 0x28, - Init_vgaInit1 = 0x2c, - Init_2dCommand = 0x30, - Init_2dSrcBaseAddr = 0x34, - Init_strapInfo = 0x38, +enum { + Init_status = 0x00, + Init_pciInit0 = 0x04, + Init_lfbMemoryConfig = 0x0c, + Init_miscInit0 = 0x10, + Init_miscInit1 = 0x14, + Init_dramInit0 = 0x18, + Init_dramInit1 = 0x1c, + Init_agpInit0 = 0x20, + Init_vgaInit0 = 0x28, + Init_vgaInit1 = 0x2c, + Init_2dCommand = 0x30, + Init_2dSrcBaseAddr = 0x34, + Init_strapInfo = 0x38, - PLL_pllCtrl0 = 0x40, - PLL_pllCtrl1 = 0x44, - PLL_pllCtrl2 = 0x48, + PLL_pllCtrl0 = 0x40, + PLL_pllCtrl1 = 0x44, + PLL_pllCtrl2 = 0x48, - DAC_dacMode = 0x4c, - DAC_dacAddr = 0x50, - DAC_dacData = 0x54, + DAC_dacMode = 0x4c, + DAC_dacAddr = 0x50, + DAC_dacData = 0x54, - Video_vidProcCfg = 0x5c, - Video_maxRgbDelta = 0x58, - Video_hwCurPatAddr = 0x60, - Video_hwCurLoc = 0x64, - Video_hwCurC0 = 0x68, - Video_hwCurC1 = 0x6c, - Video_vidSerialParallelPort = 0x78, - Video_vidScreenSize = 0x98, - Video_vidOverlayStartCoords = 0x9c, - Video_vidOverlayEndScreenCoords = 0xa0, - Video_vidOverlayDudx = 0xa4, - Video_vidOverlayDudxOffsetSrcWidth = 0xa8, - Video_vidOverlayDvdy = 0xac, - Video_vidOverlayDvdyOffset = 0xe0, - Video_vidDesktopStartAddr = 0xe4, - Video_vidDesktopOverlayStride = 0xe8 + Video_vidProcCfg = 0x5c, + Video_maxRgbDelta = 0x58, + Video_hwCurPatAddr = 0x60, + Video_hwCurLoc = 0x64, + Video_hwCurC0 = 0x68, + Video_hwCurC1 = 0x6c, + Video_vidSerialParallelPort = 0x78, + Video_vidScreenSize = 0x98, + Video_vidOverlayStartCoords = 0x9c, + Video_vidOverlayEndScreenCoords = 0xa0, + Video_vidOverlayDudx = 0xa4, + Video_vidOverlayDudxOffsetSrcWidth = 0xa8, + Video_vidOverlayDvdy = 0xac, + Video_vidOverlayDvdyOffset = 0xe0, + Video_vidDesktopStartAddr = 0xe4, + Video_vidDesktopOverlayStride = 0xe8 }; -enum -{ - cmdBaseAddr0 = 0x20, - cmdBaseSize0 = 0x24, - cmdBump0 = 0x28, - cmdRdPtrL0 = 0x2c, - cmdRdPtrH0 = 0x30, - cmdAMin0 = 0x34, - cmdAMax0 = 0x3c, - cmdFifoDepth0 = 0x44, - cmdHoleCnt0 = 0x48 +enum { + cmdBaseAddr0 = 0x20, + cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48 }; -#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) +#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) -#define VIDPROCCFG_VIDPROC_ENABLE (1 << 0) -#define VIDPROCCFG_CURSOR_MODE (1 << 1) -#define VIDPROCCFG_INTERLACE (1 << 3) -#define VIDPROCCFG_HALF_MODE (1 << 4) -#define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) -#define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11) -#define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13) -#define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) -#define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) -#define VIDPROCCFG_FILTER_MODE_MASK (3 << 16) -#define VIDPROCCFG_FILTER_MODE_POINT (0 << 16) -#define VIDPROCCFG_FILTER_MODE_DITHER_2X2 (1 << 16) -#define VIDPROCCFG_FILTER_MODE_DITHER_4X4 (2 << 16) -#define VIDPROCCFG_FILTER_MODE_BILINEAR (3 << 16) -#define VIDPROCCFG_DESKTOP_PIX_FORMAT ((banshee->vidProcCfg >> 18) & 7) -#define VIDPROCCFG_OVERLAY_PIX_FORMAT ((banshee->vidProcCfg >> 21) & 7) +#define VIDPROCCFG_VIDPROC_ENABLE (1 << 0) +#define VIDPROCCFG_CURSOR_MODE (1 << 1) +#define VIDPROCCFG_INTERLACE (1 << 3) +#define VIDPROCCFG_HALF_MODE (1 << 4) +#define VIDPROCCFG_OVERLAY_ENABLE (1 << 8) +#define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11) +#define VIDPROCCFG_OVERLAY_CLUT_SEL (1 << 13) +#define VIDPROCCFG_H_SCALE_ENABLE (1 << 14) +#define VIDPROCCFG_V_SCALE_ENABLE (1 << 15) +#define VIDPROCCFG_FILTER_MODE_MASK (3 << 16) +#define VIDPROCCFG_FILTER_MODE_POINT (0 << 16) +#define VIDPROCCFG_FILTER_MODE_DITHER_2X2 (1 << 16) +#define VIDPROCCFG_FILTER_MODE_DITHER_4X4 (2 << 16) +#define VIDPROCCFG_FILTER_MODE_BILINEAR (3 << 16) +#define VIDPROCCFG_DESKTOP_PIX_FORMAT ((banshee->vidProcCfg >> 18) & 7) +#define VIDPROCCFG_OVERLAY_PIX_FORMAT ((banshee->vidProcCfg >> 21) & 7) #define VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT (21) -#define VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK (7 << VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT) -#define VIDPROCCFG_DESKTOP_TILE (1 << 24) -#define VIDPROCCFG_OVERLAY_TILE (1 << 25) -#define VIDPROCCFG_2X_MODE (1 << 26) -#define VIDPROCCFG_HWCURSOR_ENA (1 << 27) +#define VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK (7 << VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT) +#define VIDPROCCFG_DESKTOP_TILE (1 << 24) +#define VIDPROCCFG_OVERLAY_TILE (1 << 25) +#define VIDPROCCFG_2X_MODE (1 << 26) +#define VIDPROCCFG_HWCURSOR_ENA (1 << 27) -#define OVERLAY_FMT_565 (1) -#define OVERLAY_FMT_YUYV422 (5) -#define OVERLAY_FMT_UYVY422 (6) -#define OVERLAY_FMT_565_DITHER (7) +#define OVERLAY_FMT_565 (1) +#define OVERLAY_FMT_YUYV422 (5) +#define OVERLAY_FMT_UYVY422 (6) +#define OVERLAY_FMT_565_DITHER (7) -#define OVERLAY_START_X_MASK (0xfff) -#define OVERLAY_START_Y_SHIFT (12) -#define OVERLAY_START_Y_MASK (0xfff << OVERLAY_START_Y_SHIFT) +#define OVERLAY_START_X_MASK (0xfff) +#define OVERLAY_START_Y_SHIFT (12) +#define OVERLAY_START_Y_MASK (0xfff << OVERLAY_START_Y_SHIFT) -#define OVERLAY_END_X_MASK (0xfff) -#define OVERLAY_END_Y_SHIFT (12) -#define OVERLAY_END_Y_MASK (0xfff << OVERLAY_END_Y_SHIFT) +#define OVERLAY_END_X_MASK (0xfff) +#define OVERLAY_END_Y_SHIFT (12) +#define OVERLAY_END_Y_MASK (0xfff << OVERLAY_END_Y_SHIFT) -#define OVERLAY_SRC_WIDTH_SHIFT (19) -#define OVERLAY_SRC_WIDTH_MASK (0x1fff << OVERLAY_SRC_WIDTH_SHIFT) +#define OVERLAY_SRC_WIDTH_SHIFT (19) +#define OVERLAY_SRC_WIDTH_MASK (0x1fff << OVERLAY_SRC_WIDTH_SHIFT) -#define VID_STRIDE_OVERLAY_SHIFT (16) -#define VID_STRIDE_OVERLAY_MASK (0x7fff << VID_STRIDE_OVERLAY_SHIFT) +#define VID_STRIDE_OVERLAY_SHIFT (16) +#define VID_STRIDE_OVERLAY_MASK (0x7fff << VID_STRIDE_OVERLAY_SHIFT) -#define VID_DUDX_MASK (0xffffff) -#define VID_DVDY_MASK (0xffffff) +#define VID_DUDX_MASK (0xffffff) +#define VID_DVDY_MASK (0xffffff) -#define PIX_FORMAT_8 0 -#define PIX_FORMAT_RGB565 1 -#define PIX_FORMAT_RGB24 2 -#define PIX_FORMAT_RGB32 3 +#define PIX_FORMAT_8 0 +#define PIX_FORMAT_RGB565 1 +#define PIX_FORMAT_RGB24 2 +#define PIX_FORMAT_RGB32 3 -#define VIDSERIAL_DDC_EN (1 << 18) -#define VIDSERIAL_DDC_DCK_W (1 << 19) -#define VIDSERIAL_DDC_DDA_W (1 << 20) -#define VIDSERIAL_DDC_DCK_R (1 << 21) -#define VIDSERIAL_DDC_DDA_R (1 << 22) -#define VIDSERIAL_I2C_EN (1 << 23) -#define VIDSERIAL_I2C_SCK_W (1 << 24) -#define VIDSERIAL_I2C_SDA_W (1 << 25) -#define VIDSERIAL_I2C_SCK_R (1 << 26) -#define VIDSERIAL_I2C_SDA_R (1 << 27) +#define VIDSERIAL_DDC_EN (1 << 18) +#define VIDSERIAL_DDC_DCK_W (1 << 19) +#define VIDSERIAL_DDC_DDA_W (1 << 20) +#define VIDSERIAL_DDC_DCK_R (1 << 21) +#define VIDSERIAL_DDC_DDA_R (1 << 22) +#define VIDSERIAL_I2C_EN (1 << 23) +#define VIDSERIAL_I2C_SCK_W (1 << 24) +#define VIDSERIAL_I2C_SDA_W (1 << 25) +#define VIDSERIAL_I2C_SCK_R (1 << 26) +#define VIDSERIAL_I2C_SDA_R (1 << 27) -#define MISCINIT0_Y_ORIGIN_SWAP_SHIFT (18) -#define MISCINIT0_Y_ORIGIN_SWAP_MASK (0xfff << MISCINIT0_Y_ORIGIN_SWAP_SHIFT) +#define MISCINIT0_Y_ORIGIN_SWAP_SHIFT (18) +#define MISCINIT0_Y_ORIGIN_SWAP_MASK (0xfff << MISCINIT0_Y_ORIGIN_SWAP_SHIFT) #ifdef ENABLE_BANSHEE_LOG int banshee_do_log = ENABLE_BANSHEE_LOG; - static void banshee_log(const char *fmt, ...) { va_list ap; if (banshee_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define banshee_log(fmt, ...) +# define banshee_log(fmt, ...) #endif static uint32_t banshee_status(banshee_t *banshee); -static int banshee_vga_vsync_enabled(banshee_t *banshee) +static int +banshee_vga_vsync_enabled(banshee_t *banshee) { if (!(banshee->svga.crtc[0x11] & 0x20) && (banshee->svga.crtc[0x11] & 0x10) && ((banshee->pciInit0 >> 18) & 1) != 0) return 1; return 0; } -static void banshee_update_irqs(banshee_t *banshee) +static void +banshee_update_irqs(banshee_t *banshee) { if (banshee->vblank_irq > 0 && banshee_vga_vsync_enabled(banshee)) { pci_set_irq(banshee->card, PCI_INTA); @@ -283,2322 +278,2433 @@ static void banshee_update_irqs(banshee_t *banshee) } } -static void banshee_vblank_start(svga_t* svga) +static void +banshee_vblank_start(svga_t *svga) { - banshee_t *banshee = (banshee_t*)svga->p; + banshee_t *banshee = (banshee_t *) svga->p; if (banshee->vblank_irq >= 0) { banshee->vblank_irq = 1; banshee_update_irqs(banshee); } } - -static void banshee_out(uint16_t addr, uint8_t val, void *p) +static void +banshee_out(uint16_t addr, uint8_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - svga_t *svga = &banshee->svga; - uint8_t old; + banshee_t *banshee = (banshee_t *) p; + svga_t *svga = &banshee->svga; + uint8_t old; -// /*if (addr != 0x3c9) */banshee_log("banshee_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); + // /*if (addr != 0x3c9) */banshee_log("banshee_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3D4: - svga->crtcreg = val & 0x3f; + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - if (old != val) - { - if (svga->crtcreg == 0x11) { - if (!(val & 0x10)) { - if (banshee->vblank_irq > 0) - banshee->vblank_irq = -1; - } else if (banshee->vblank_irq < 0) { - banshee->vblank_irq = 0; - } - banshee_update_irqs(banshee); - if ((val & ~0x30) == (old & ~0x30)) - old = val; - } - if (svga->crtcreg < 0xe || svga->crtcreg > 0x11 || (svga->crtcreg == 0x11 && old != val)) - { - if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { - svga->fullchange = 3; - svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); - } else { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg == 0x11) { + if (!(val & 0x10)) { + if (banshee->vblank_irq > 0) + banshee->vblank_irq = -1; + } else if (banshee->vblank_irq < 0) { + banshee->vblank_irq = 0; + } + banshee_update_irqs(banshee); + if ((val & ~0x30) == (old & ~0x30)) + old = val; } - break; - } - svga_out(addr, val, svga); + if (svga->crtcreg < 0xe || svga->crtcreg > 0x11 || (svga->crtcreg == 0x11 && old != val)) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + } + svga_out(addr, val, svga); } -static uint8_t banshee_in(uint16_t addr, void *p) +static uint8_t +banshee_in(uint16_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - svga_t *svga = &banshee->svga; - uint8_t temp; + banshee_t *banshee = (banshee_t *) p; + svga_t *svga = &banshee->svga; + uint8_t temp; -// if (addr != 0x3da) banshee_log("banshee_in : %04X ", addr); + // if (addr != 0x3da) banshee_log("banshee_in : %04X ", addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - switch (addr) - { - case 0x3c2: - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x40) - temp = 0; - else - temp = 0x10; - if (banshee->vblank_irq > 0) - temp |= 0x80; - break; - case 0x3D4: - temp = svga->crtcreg; - break; - case 0x3D5: - temp = svga->crtc[svga->crtcreg]; - break; - default: - temp = svga_in(addr, svga); - break; - } -// if (addr != 0x3da) banshee_log("%02X %04X:%04X %i\n", temp, CS,cpu_state.pc, ins); - return temp; + switch (addr) { + case 0x3c2: + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x40) + temp = 0; + else + temp = 0x10; + if (banshee->vblank_irq > 0) + temp |= 0x80; + break; + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) banshee_log("%02X %04X:%04X %i\n", temp, CS,cpu_state.pc, ins); + return temp; } -static void banshee_updatemapping(banshee_t *banshee) +static void +banshee_updatemapping(banshee_t *banshee) { - svga_t *svga = &banshee->svga; + svga_t *svga = &banshee->svga; - if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) - { -// banshee_log("Update mapping - PCI disabled\n"); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&banshee->linear_mapping); - mem_mapping_disable(&banshee->reg_mapping_low); - mem_mapping_disable(&banshee->reg_mapping_high); - return; - } + if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + // banshee_log("Update mapping - PCI disabled\n"); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&banshee->linear_mapping); + mem_mapping_disable(&banshee->reg_mapping_low); + mem_mapping_disable(&banshee->reg_mapping_high); + return; + } - banshee_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + banshee_log("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } - banshee_log("Linear framebuffer %08X ", banshee->memBaseAddr1); - mem_mapping_set_addr(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20); - banshee_log("registers %08X\n", banshee->memBaseAddr0); - mem_mapping_set_addr(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20); - mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); + banshee_log("Linear framebuffer %08X ", banshee->memBaseAddr1); + mem_mapping_set_addr(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20); + banshee_log("registers %08X\n", banshee->memBaseAddr0); + mem_mapping_set_addr(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20); + mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20); } -static void banshee_render_16bpp_tiled(svga_t *svga) +static void +banshee_render_16bpp_tiled(svga_t *svga) { - banshee_t *banshee = (banshee_t *)svga->p; - int x; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + svga->y_add])[svga->x_add]; - uint32_t addr; - int drawn = 0; + banshee_t *banshee = (banshee_t *) svga->p; + int x; + uint32_t *p = &((uint32_t *) buffer32->line[svga->displine + svga->y_add])[svga->x_add]; + uint32_t addr; + int drawn = 0; - if ((svga->displine + svga->y_add) < 0) - return; + if ((svga->displine + svga->y_add) < 0) + return; - if (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE) - addr = banshee->desktop_addr + ((banshee->desktop_y >> 1) & 31) * 128 + ((banshee->desktop_y >> 6) * banshee->desktop_stride_tiled); + if (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE) + addr = banshee->desktop_addr + ((banshee->desktop_y >> 1) & 31) * 128 + ((banshee->desktop_y >> 6) * banshee->desktop_stride_tiled); + else + addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); + + for (x = 0; x <= svga->hdisp; x += 64) { + if (svga->hwcursor_on || svga->overlay_on) + svga->changedvram[addr >> 12] = 2; + if (svga->changedvram[addr >> 12] || svga->fullchange) { + uint16_t *vram_p = (uint16_t *) &svga->vram[addr & svga->vram_display_mask]; + int xx; + + for (xx = 0; xx < 64; xx++) + *p++ = video_16to32[*vram_p++]; + + drawn = 1; + } else + p += 64; + addr += 128 * 32; + } + + if (drawn) { + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + } + + banshee->desktop_y++; +} + +static void +banshee_recalctimings(svga_t *svga) +{ + banshee_t *banshee = (banshee_t *) svga->p; + voodoo_t *voodoo = banshee->voodoo; + + /*7 R/W Horizontal Retrace End bit 5. - + 6 R/W Horizontal Retrace Start bit 8 0x4 + 5 R/W Horizontal Blank End bit 6. - + 4 R/W Horizontal Blank Start bit 8. 0x3 + 3 R/W Reserved. - + 2 R/W Horizontal Display Enable End bit 8. 0x1 + 1 R/W Reserved. - + 0 R/W Horizontal Total bit 8. 0x0*/ + if (svga->crtc[0x1a] & 0x01) + svga->htotal += 0x100; + if (svga->crtc[0x1a] & 0x04) + svga->hdisp += 0x100; + /*6 R/W Vertical Retrace Start bit 10 0x10 + 5 R/W Reserved. - + 4 R/W Vertical Blank Start bit 10. 0x15 + 3 R/W Reserved. - + 2 R/W Vertical Display Enable End bit 10 0x12 + 1 R/W Reserved. - + 0 R/W Vertical Total bit 10. 0x6*/ + if (svga->crtc[0x1b] & 0x01) + svga->vtotal += 0x400; + if (svga->crtc[0x1b] & 0x04) + svga->dispend += 0x400; + if (svga->crtc[0x1b] & 0x10) + svga->vblankstart += 0x400; + if (svga->crtc[0x1b] & 0x40) + svga->vsyncstart += 0x400; + // banshee_log("svga->hdisp=%i\n", svga->hdisp); + + svga->interlace = 0; + + if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) { + switch (VIDPROCCFG_DESKTOP_PIX_FORMAT) { + case PIX_FORMAT_8: + svga->render = svga_render_8bpp_highres; + svga->bpp = 8; + break; + case PIX_FORMAT_RGB565: + svga->render = (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) ? banshee_render_16bpp_tiled : svga_render_16bpp_highres; + svga->bpp = 16; + break; + case PIX_FORMAT_RGB24: + svga->render = svga_render_24bpp_highres; + svga->bpp = 24; + break; + case PIX_FORMAT_RGB32: + svga->render = svga_render_32bpp_highres; + svga->bpp = 32; + break; + default: + fatal("Unknown pixel format %08x\n", banshee->vgaInit0); + } + if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) + svga->rowcount = 1; else - addr = banshee->desktop_addr + (banshee->desktop_y & 31) * 128 + ((banshee->desktop_y >> 5) * banshee->desktop_stride_tiled); - - for (x = 0; x <= svga->hdisp; x += 64) - { - if (svga->hwcursor_on || svga->overlay_on) - svga->changedvram[addr >> 12] = 2; - if (svga->changedvram[addr >> 12] || svga->fullchange) - { - uint16_t *vram_p = (uint16_t *)&svga->vram[addr & svga->vram_display_mask]; - int xx; - - for (xx = 0; xx < 64; xx++) - *p++ = video_16to32[*vram_p++]; - - drawn = 1; - } - else - p += 64; - addr += 128*32; - } - - if (drawn) - { - if (svga->firstline_draw == 2000) - svga->firstline_draw = svga->displine; - svga->lastline_draw = svga->displine; - } - - banshee->desktop_y++; -} - -static void banshee_recalctimings(svga_t *svga) -{ - banshee_t *banshee = (banshee_t *)svga->p; - voodoo_t *voodoo = banshee->voodoo; - -/*7 R/W Horizontal Retrace End bit 5. - - 6 R/W Horizontal Retrace Start bit 8 0x4 - 5 R/W Horizontal Blank End bit 6. - - 4 R/W Horizontal Blank Start bit 8. 0x3 - 3 R/W Reserved. - - 2 R/W Horizontal Display Enable End bit 8. 0x1 - 1 R/W Reserved. - - 0 R/W Horizontal Total bit 8. 0x0*/ - if (svga->crtc[0x1a] & 0x01) svga->htotal += 0x100; - if (svga->crtc[0x1a] & 0x04) svga->hdisp += 0x100; -/*6 R/W Vertical Retrace Start bit 10 0x10 - 5 R/W Reserved. - - 4 R/W Vertical Blank Start bit 10. 0x15 - 3 R/W Reserved. - - 2 R/W Vertical Display Enable End bit 10 0x12 - 1 R/W Reserved. - - 0 R/W Vertical Total bit 10. 0x6*/ - if (svga->crtc[0x1b] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x1b] & 0x04) svga->dispend += 0x400; - if (svga->crtc[0x1b] & 0x10) svga->vblankstart += 0x400; - if (svga->crtc[0x1b] & 0x40) svga->vsyncstart += 0x400; -// banshee_log("svga->hdisp=%i\n", svga->hdisp); - - svga->interlace = 0; - - if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT) - { - switch (VIDPROCCFG_DESKTOP_PIX_FORMAT) - { - case PIX_FORMAT_8: - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - break; - case PIX_FORMAT_RGB565: - svga->render = (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) ? banshee_render_16bpp_tiled : svga_render_16bpp_highres; - svga->bpp = 16; - break; - case PIX_FORMAT_RGB24: - svga->render = svga_render_24bpp_highres; - svga->bpp = 24; - break; - case PIX_FORMAT_RGB32: - svga->render = svga_render_32bpp_highres; - svga->bpp = 32; - break; - default: - fatal("Unknown pixel format %08x\n", banshee->vgaInit0); - } - if (!(banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) && (banshee->vidProcCfg & VIDPROCCFG_HALF_MODE)) - svga->rowcount = 1; - else - svga->rowcount = 0; - if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) - svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; - else - svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; - svga->ma_latch = banshee->vidDesktopStartAddr >> 2; - banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; -// banshee_log("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); - - svga->char_width = 8; - svga->split = 99999; - - if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) - { - svga->hdisp *= 2; - svga->htotal *= 2; - } - - svga->interlace = !!(banshee->vidProcCfg & VIDPROCCFG_INTERLACE); - - svga->overlay.ena = banshee->vidProcCfg & VIDPROCCFG_OVERLAY_ENABLE; - - svga->overlay.x = voodoo->overlay.start_x; - svga->overlay.y = voodoo->overlay.start_y; - svga->overlay.cur_xsize = voodoo->overlay.size_x; - svga->overlay.cur_ysize = voodoo->overlay.size_y; - svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) - svga->overlay.pitch *= 128*32; - if (svga->overlay.cur_xsize <= 0 || svga->overlay.cur_ysize <= 0) - svga->overlay.ena = 0; - if (svga->overlay.ena) - { -/* banshee_log("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", - voodoo->overlay.start_x, voodoo->overlay.start_y, - voodoo->overlay.end_x, voodoo->overlay.end_y, - voodoo->overlay.size_x, voodoo->overlay.size_y, - svga->overlay.pitch);*/ - if (!voodoo->overlay.start_x && !voodoo->overlay.start_y && - svga->hdisp == voodoo->overlay.size_x && svga->dispend == voodoo->overlay.size_y) - { - /*Overlay is full screen, so don't bother rendering the desktop - behind it*/ - svga->render = svga_render_null; - svga->bpp = 0; - } - } - } + svga->rowcount = 0; + if (banshee->vidProcCfg & VIDPROCCFG_DESKTOP_TILE) + svga->rowoffset = ((banshee->vidDesktopOverlayStride & 0x3fff) * 128) >> 3; else - { -// banshee_log("Normal shift out\n"); - svga->bpp = 8; + svga->rowoffset = (banshee->vidDesktopOverlayStride & 0x3fff) >> 3; + svga->ma_latch = banshee->vidDesktopStartAddr >> 2; + banshee->desktop_stride_tiled = (banshee->vidDesktopOverlayStride & 0x3fff) * 128 * 32; + // banshee_log("Extended shift out %i rowoffset=%i %02x\n", VIDPROCCFG_DESKTOP_PIX_FORMAT, svga->rowoffset, svga->crtc[1]); + + svga->char_width = 8; + svga->split = 99999; + + if (banshee->vidProcCfg & VIDPROCCFG_2X_MODE) { + svga->hdisp *= 2; + svga->htotal *= 2; } - svga->fb_only = (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE); + svga->interlace = !!(banshee->vidProcCfg & VIDPROCCFG_INTERLACE); - if (((svga->miscout >> 2) & 3) == 3) - { - int k = banshee->pllCtrl0 & 3; - int m = (banshee->pllCtrl0 >> 2) & 0x3f; - int n = (banshee->pllCtrl0 >> 8) & 0xff; - double freq = (((double)n + 2) / (((double)m + 2) * (double)(1 << k))) * 14318184.0; + svga->overlay.ena = banshee->vidProcCfg & VIDPROCCFG_OVERLAY_ENABLE; - svga->clock = (cpuclock * (float)(1ull << 32)) / freq; -// svga->clock = cpuclock / freq; - -// banshee_log("svga->clock = %g %g m=%i k=%i n=%i\n", freq, freq / 1000000.0, m, k, n); + svga->overlay.x = voodoo->overlay.start_x; + svga->overlay.y = voodoo->overlay.start_y; + svga->overlay.cur_xsize = voodoo->overlay.size_x; + svga->overlay.cur_ysize = voodoo->overlay.size_y; + svga->overlay.pitch = (banshee->vidDesktopOverlayStride & VID_STRIDE_OVERLAY_MASK) >> VID_STRIDE_OVERLAY_SHIFT; + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) + svga->overlay.pitch *= 128 * 32; + if (svga->overlay.cur_xsize <= 0 || svga->overlay.cur_ysize <= 0) + svga->overlay.ena = 0; + if (svga->overlay.ena) { + /* banshee_log("Overlay enabled : start=%i,%i end=%i,%i size=%i,%i pitch=%x\n", + voodoo->overlay.start_x, voodoo->overlay.start_y, + voodoo->overlay.end_x, voodoo->overlay.end_y, + voodoo->overlay.size_x, voodoo->overlay.size_y, + svga->overlay.pitch);*/ + if (!voodoo->overlay.start_x && !voodoo->overlay.start_y && svga->hdisp == voodoo->overlay.size_x && svga->dispend == voodoo->overlay.size_y) { + /*Overlay is full screen, so don't bother rendering the desktop + behind it*/ + svga->render = svga_render_null; + svga->bpp = 0; + } } + } else { + // banshee_log("Normal shift out\n"); + svga->bpp = 8; + } + + svga->fb_only = (banshee->vidProcCfg & VIDPROCCFG_VIDPROC_ENABLE); + + if (((svga->miscout >> 2) & 3) == 3) { + int k = banshee->pllCtrl0 & 3; + int m = (banshee->pllCtrl0 >> 2) & 0x3f; + int n = (banshee->pllCtrl0 >> 8) & 0xff; + double freq = (((double) n + 2) / (((double) m + 2) * (double) (1 << k))) * 14318184.0; + + svga->clock = (cpuclock * (float) (1ull << 32)) / freq; + // svga->clock = cpuclock / freq; + + // banshee_log("svga->clock = %g %g m=%i k=%i n=%i\n", freq, freq / 1000000.0, m, k, n); + } } -static void banshee_ext_out(uint16_t addr, uint8_t val, void *p) +static void +banshee_ext_out(uint16_t addr, uint8_t val, void *p) { -// banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; + // banshee_t *banshee = (banshee_t *)p; + // svga_t *svga = &banshee->svga; -// banshee_log("banshee_ext_out: addr=%04x val=%02x\n", addr, val); + // banshee_log("banshee_ext_out: addr=%04x val=%02x\n", addr, val); - switch (addr & 0xff) - { - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - banshee_out((addr & 0xff)+0x300, val, p); - break; + switch (addr & 0xff) { + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + banshee_out((addr & 0xff) + 0x300, val, p); + break; - default: - banshee_log("bad banshee_ext_out: addr=%04x val=%02x\n", addr, val); - } + default: + banshee_log("bad banshee_ext_out: addr=%04x val=%02x\n", addr, val); + } } -static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) +static void +banshee_ext_outl(uint16_t addr, uint32_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; -// banshee_log("banshee_ext_outl: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); + // banshee_log("banshee_ext_outl: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); - switch (addr & 0xff) - { - case Init_pciInit0: - banshee->pciInit0 = val; - voodoo->read_time = (banshee->agp ? agp_nonburst_time : pci_nonburst_time) + (banshee->agp ? agp_burst_time : pci_burst_time) * ((val & 0x100) ? 2 : 1); - voodoo->burst_time = (banshee->agp ? agp_burst_time : pci_burst_time) * ((val & 0x200) ? 1 : 0); - voodoo->write_time = (banshee->agp ? agp_nonburst_time : pci_nonburst_time) + voodoo->burst_time; - break; + switch (addr & 0xff) { + case Init_pciInit0: + banshee->pciInit0 = val; + voodoo->read_time = (banshee->agp ? agp_nonburst_time : pci_nonburst_time) + (banshee->agp ? agp_burst_time : pci_burst_time) * ((val & 0x100) ? 2 : 1); + voodoo->burst_time = (banshee->agp ? agp_burst_time : pci_burst_time) * ((val & 0x200) ? 1 : 0); + voodoo->write_time = (banshee->agp ? agp_nonburst_time : pci_nonburst_time) + voodoo->burst_time; + break; - case Init_lfbMemoryConfig: - banshee->lfbMemoryConfig = val; -// banshee_log("lfbMemoryConfig=%08x\n", val); - voodoo->tile_base = (val & 0x1fff) << 12; - voodoo->tile_stride = 1024 << ((val >> 13) & 7); - voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); - voodoo->tile_x = ((val >> 16) & 0x7f) * 128; - voodoo->tile_x_real = ((val >> 16) & 0x7f) * 128*32; - break; + case Init_lfbMemoryConfig: + banshee->lfbMemoryConfig = val; + // banshee_log("lfbMemoryConfig=%08x\n", val); + voodoo->tile_base = (val & 0x1fff) << 12; + voodoo->tile_stride = 1024 << ((val >> 13) & 7); + voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); + voodoo->tile_x = ((val >> 16) & 0x7f) * 128; + voodoo->tile_x_real = ((val >> 16) & 0x7f) * 128 * 32; + break; - case Init_miscInit0: - banshee->miscInit0 = val; - voodoo->y_origin_swap = (val & MISCINIT0_Y_ORIGIN_SWAP_MASK) >> MISCINIT0_Y_ORIGIN_SWAP_SHIFT; - break; - case Init_miscInit1: - banshee->miscInit1 = val; - break; - case Init_dramInit0: - banshee->dramInit0 = val; - break; - case Init_dramInit1: - banshee->dramInit1 = val; - break; - case Init_agpInit0: - banshee->agpInit0 = val; - break; + case Init_miscInit0: + banshee->miscInit0 = val; + voodoo->y_origin_swap = (val & MISCINIT0_Y_ORIGIN_SWAP_MASK) >> MISCINIT0_Y_ORIGIN_SWAP_SHIFT; + break; + case Init_miscInit1: + banshee->miscInit1 = val; + break; + case Init_dramInit0: + banshee->dramInit0 = val; + break; + case Init_dramInit1: + banshee->dramInit1 = val; + break; + case Init_agpInit0: + banshee->agpInit0 = val; + break; - case Init_2dCommand: - banshee->command_2d = val; - break; - case Init_2dSrcBaseAddr: - banshee->srcBaseAddr_2d = val; - break; - case Init_vgaInit0: - banshee->vgaInit0 = val; - break; - case Init_vgaInit1: - banshee->vgaInit1 = val; - svga->write_bank = (val & 0x3ff) << 15; - svga->read_bank = ((val >> 10) & 0x3ff) << 15; - svga->packed_chain4 = !!(val & 0x00100000); - break; + case Init_2dCommand: + banshee->command_2d = val; + break; + case Init_2dSrcBaseAddr: + banshee->srcBaseAddr_2d = val; + break; + case Init_vgaInit0: + banshee->vgaInit0 = val; + break; + case Init_vgaInit1: + banshee->vgaInit1 = val; + svga->write_bank = (val & 0x3ff) << 15; + svga->read_bank = ((val >> 10) & 0x3ff) << 15; + svga->packed_chain4 = !!(val & 0x00100000); + break; - case PLL_pllCtrl0: - banshee->pllCtrl0 = val; - break; - case PLL_pllCtrl1: - banshee->pllCtrl1 = val; - break; - case PLL_pllCtrl2: - banshee->pllCtrl2 = val; - break; + case PLL_pllCtrl0: + banshee->pllCtrl0 = val; + break; + case PLL_pllCtrl1: + banshee->pllCtrl1 = val; + break; + case PLL_pllCtrl2: + banshee->pllCtrl2 = val; + break; - case DAC_dacMode: - banshee->dacMode = val; - svga->dpms = !!(val & 0x0a); - svga_recalctimings(svga); - break; - case DAC_dacAddr: - banshee->dacAddr = val & 0x1ff; - break; - case DAC_dacData: - svga->pallook[banshee->dacAddr] = val & 0xffffff; - svga->fullchange = changeframecount; - break; + case DAC_dacMode: + banshee->dacMode = val; + svga->dpms = !!(val & 0x0a); + svga_recalctimings(svga); + break; + case DAC_dacAddr: + banshee->dacAddr = val & 0x1ff; + break; + case DAC_dacData: + svga->pallook[banshee->dacAddr] = val & 0xffffff; + svga->fullchange = changeframecount; + break; - case Video_vidProcCfg: - banshee->vidProcCfg = val; -// banshee_log("vidProcCfg=%08x\n", val); - banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; - svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; + case Video_vidProcCfg: + banshee->vidProcCfg = val; + // banshee_log("vidProcCfg=%08x\n", val); + banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT; + svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA; + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; - case Video_maxRgbDelta: - banshee->voodoo->scrfilterThreshold = val; - if (val > 0x00) - banshee->voodoo->scrfilterEnabled = 1; - else - banshee->voodoo->scrfilterEnabled = 0; - voodoo_threshold_check(banshee->voodoo); - banshee_log("Banshee Filter: %06x\n", val); - break; + case Video_maxRgbDelta: + banshee->voodoo->scrfilterThreshold = val; + if (val > 0x00) + banshee->voodoo->scrfilterEnabled = 1; + else + banshee->voodoo->scrfilterEnabled = 0; + voodoo_threshold_check(banshee->voodoo); + banshee_log("Banshee Filter: %06x\n", val); + break; - case Video_hwCurPatAddr: - banshee->hwCurPatAddr = val; - svga->hwcursor.addr = (val & 0xfffff0) + (svga->hwcursor.yoff * 16); - break; - case Video_hwCurLoc: - banshee->hwCurLoc = val; - svga->hwcursor.x = (val & 0x7ff) - 64; - svga->hwcursor.y = ((val >> 16) & 0x7ff) - 64; - if (svga->hwcursor.y < 0) - { - svga->hwcursor.yoff = -svga->hwcursor.y; - svga->hwcursor.y = 0; - } - else - svga->hwcursor.yoff = 0; - svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); - svga->hwcursor.cur_xsize = 64; - svga->hwcursor.cur_ysize = 64; -// banshee_log("hwCurLoc %08x %i\n", val, svga->hwcursor.y); - break; - case Video_hwCurC0: - banshee->hwCurC0 = val; - break; - case Video_hwCurC1: - banshee->hwCurC1 = val; - break; + case Video_hwCurPatAddr: + banshee->hwCurPatAddr = val; + svga->hwcursor.addr = (val & 0xfffff0) + (svga->hwcursor.yoff * 16); + break; + case Video_hwCurLoc: + banshee->hwCurLoc = val; + svga->hwcursor.x = (val & 0x7ff) - 64; + svga->hwcursor.y = ((val >> 16) & 0x7ff) - 64; + if (svga->hwcursor.y < 0) { + svga->hwcursor.yoff = -svga->hwcursor.y; + svga->hwcursor.y = 0; + } else + svga->hwcursor.yoff = 0; + svga->hwcursor.addr = (banshee->hwCurPatAddr & 0xfffff0) + (svga->hwcursor.yoff * 16); + svga->hwcursor.cur_xsize = 64; + svga->hwcursor.cur_ysize = 64; + // banshee_log("hwCurLoc %08x %i\n", val, svga->hwcursor.y); + break; + case Video_hwCurC0: + banshee->hwCurC0 = val; + break; + case Video_hwCurC1: + banshee->hwCurC1 = val; + break; - case Video_vidSerialParallelPort: - banshee->vidSerialParallelPort = val; -// banshee_log("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc); - i2c_gpio_set(banshee->i2c_ddc, !!(val & VIDSERIAL_DDC_DCK_W), !!(val & VIDSERIAL_DDC_DDA_W)); - i2c_gpio_set(banshee->i2c, !!(val & VIDSERIAL_I2C_SCK_W), !!(val & VIDSERIAL_I2C_SDA_W)); - break; + case Video_vidSerialParallelPort: + banshee->vidSerialParallelPort = val; + // banshee_log("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc); + i2c_gpio_set(banshee->i2c_ddc, !!(val & VIDSERIAL_DDC_DCK_W), !!(val & VIDSERIAL_DDC_DDA_W)); + i2c_gpio_set(banshee->i2c, !!(val & VIDSERIAL_I2C_SCK_W), !!(val & VIDSERIAL_I2C_SDA_W)); + break; - case Video_vidScreenSize: - banshee->vidScreenSize = val; - voodoo->h_disp = (val & 0xfff) + 1; - voodoo->v_disp = (val >> 12) & 0xfff; - break; - case Video_vidOverlayStartCoords: - voodoo->overlay.vidOverlayStartCoords = val; - voodoo->overlay.start_x = val & OVERLAY_START_X_MASK; - voodoo->overlay.start_y = (val & OVERLAY_START_Y_MASK) >> OVERLAY_START_Y_SHIFT; - voodoo->overlay.size_x = voodoo->overlay.end_x - voodoo->overlay.start_x; - voodoo->overlay.size_y = voodoo->overlay.end_y - voodoo->overlay.start_y; - svga_recalctimings(svga); - break; - case Video_vidOverlayEndScreenCoords: - voodoo->overlay.vidOverlayEndScreenCoords = val; - voodoo->overlay.end_x = val & OVERLAY_END_X_MASK; - voodoo->overlay.end_y = (val & OVERLAY_END_Y_MASK) >> OVERLAY_END_Y_SHIFT; - voodoo->overlay.size_x = (voodoo->overlay.end_x - voodoo->overlay.start_x) + 1; - voodoo->overlay.size_y = (voodoo->overlay.end_y - voodoo->overlay.start_y) + 1; - svga_recalctimings(svga); - break; - case Video_vidOverlayDudx: - voodoo->overlay.vidOverlayDudx = val & VID_DUDX_MASK; -// banshee_log("vidOverlayDudx=%08x\n", val); - break; - case Video_vidOverlayDudxOffsetSrcWidth: - voodoo->overlay.vidOverlayDudxOffsetSrcWidth = val; - voodoo->overlay.overlay_bytes = (val & OVERLAY_SRC_WIDTH_MASK) >> OVERLAY_SRC_WIDTH_SHIFT; -// banshee_log("vidOverlayDudxOffsetSrcWidth=%08x\n", val); - break; - case Video_vidOverlayDvdy: - voodoo->overlay.vidOverlayDvdy = val & VID_DVDY_MASK; -// banshee_log("vidOverlayDvdy=%08x\n", val); - break; - case Video_vidOverlayDvdyOffset: - voodoo->overlay.vidOverlayDvdyOffset = val; - break; + case Video_vidScreenSize: + banshee->vidScreenSize = val; + voodoo->h_disp = (val & 0xfff) + 1; + voodoo->v_disp = (val >> 12) & 0xfff; + break; + case Video_vidOverlayStartCoords: + voodoo->overlay.vidOverlayStartCoords = val; + voodoo->overlay.start_x = val & OVERLAY_START_X_MASK; + voodoo->overlay.start_y = (val & OVERLAY_START_Y_MASK) >> OVERLAY_START_Y_SHIFT; + voodoo->overlay.size_x = voodoo->overlay.end_x - voodoo->overlay.start_x; + voodoo->overlay.size_y = voodoo->overlay.end_y - voodoo->overlay.start_y; + svga_recalctimings(svga); + break; + case Video_vidOverlayEndScreenCoords: + voodoo->overlay.vidOverlayEndScreenCoords = val; + voodoo->overlay.end_x = val & OVERLAY_END_X_MASK; + voodoo->overlay.end_y = (val & OVERLAY_END_Y_MASK) >> OVERLAY_END_Y_SHIFT; + voodoo->overlay.size_x = (voodoo->overlay.end_x - voodoo->overlay.start_x) + 1; + voodoo->overlay.size_y = (voodoo->overlay.end_y - voodoo->overlay.start_y) + 1; + svga_recalctimings(svga); + break; + case Video_vidOverlayDudx: + voodoo->overlay.vidOverlayDudx = val & VID_DUDX_MASK; + // banshee_log("vidOverlayDudx=%08x\n", val); + break; + case Video_vidOverlayDudxOffsetSrcWidth: + voodoo->overlay.vidOverlayDudxOffsetSrcWidth = val; + voodoo->overlay.overlay_bytes = (val & OVERLAY_SRC_WIDTH_MASK) >> OVERLAY_SRC_WIDTH_SHIFT; + // banshee_log("vidOverlayDudxOffsetSrcWidth=%08x\n", val); + break; + case Video_vidOverlayDvdy: + voodoo->overlay.vidOverlayDvdy = val & VID_DVDY_MASK; + // banshee_log("vidOverlayDvdy=%08x\n", val); + break; + case Video_vidOverlayDvdyOffset: + voodoo->overlay.vidOverlayDvdyOffset = val; + break; - - case Video_vidDesktopStartAddr: - banshee->vidDesktopStartAddr = val & 0xffffff; -// banshee_log("vidDesktopStartAddr=%08x\n", val); - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; - case Video_vidDesktopOverlayStride: - banshee->vidDesktopOverlayStride = val; -// banshee_log("vidDesktopOverlayStride=%08x\n", val); - svga->fullchange = changeframecount; - svga_recalctimings(svga); - break; -// default: -// fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); - } + case Video_vidDesktopStartAddr: + banshee->vidDesktopStartAddr = val & 0xffffff; + // banshee_log("vidDesktopStartAddr=%08x\n", val); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + case Video_vidDesktopOverlayStride: + banshee->vidDesktopOverlayStride = val; + // banshee_log("vidDesktopOverlayStride=%08x\n", val); + svga->fullchange = changeframecount; + svga_recalctimings(svga); + break; + // default: + // fatal("bad banshee_ext_outl: addr=%04x val=%08x\n", addr, val); + } } -static uint8_t banshee_ext_in(uint16_t addr, void *p) +static uint8_t +banshee_ext_in(uint16_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; - uint8_t ret = 0xff; + banshee_t *banshee = (banshee_t *) p; + // svga_t *svga = &banshee->svga; + uint8_t ret = 0xff; - switch (addr & 0xff) - { - case Init_status: case Init_status+1: case Init_status+2: case Init_status+3: - ret = (banshee_status(banshee) >> ((addr & 3) * 8)) & 0xff; -// banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); - break; + switch (addr & 0xff) { + case Init_status: + case Init_status + 1: + case Init_status + 2: + case Init_status + 3: + ret = (banshee_status(banshee) >> ((addr & 3) * 8)) & 0xff; + // banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); + break; - case 0xb0: case 0xb1: case 0xb2: case 0xb3: - case 0xb4: case 0xb5: case 0xb6: case 0xb7: - case 0xb8: case 0xb9: case 0xba: case 0xbb: - case 0xbc: case 0xbd: case 0xbe: case 0xbf: - case 0xc0: case 0xc1: case 0xc2: case 0xc3: - case 0xc4: case 0xc5: case 0xc6: case 0xc7: - case 0xc8: case 0xc9: case 0xca: case 0xcb: - case 0xcc: case 0xcd: case 0xce: case 0xcf: - case 0xd0: case 0xd1: case 0xd2: case 0xd3: - case 0xd4: case 0xd5: case 0xd6: case 0xd7: - case 0xd8: case 0xd9: case 0xda: case 0xdb: - case 0xdc: case 0xdd: case 0xde: case 0xdf: - ret = banshee_in((addr & 0xff)+0x300, p); - break; + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + ret = banshee_in((addr & 0xff) + 0x300, p); + break; - default: - banshee_log("bad banshee_ext_in: addr=%04x\n", addr); - break; - } + default: + banshee_log("bad banshee_ext_in: addr=%04x\n", addr); + break; + } -// banshee_log("banshee_ext_in: addr=%04x val=%02x\n", addr, ret); + // banshee_log("banshee_ext_in: addr=%04x val=%02x\n", addr, ret); - return ret; + return ret; } -static uint32_t banshee_status(banshee_t *banshee) +static uint32_t +banshee_status(banshee_t *banshee) { - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - int fifo_entries = FIFO_ENTRIES; - int swap_count = voodoo->swap_count; - int written = voodoo->cmd_written + voodoo->cmd_written_fifo; - int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || - voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || - voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || - voodoo->voodoo_busy; - uint32_t ret; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + int fifo_entries = FIFO_ENTRIES; + int swap_count = voodoo->swap_count; + int written = voodoo->cmd_written + voodoo->cmd_written_fifo; + int busy = (written - voodoo->cmd_read) || (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) || voodoo->render_voodoo_busy[0] || voodoo->render_voodoo_busy[1] || voodoo->render_voodoo_busy[2] || voodoo->render_voodoo_busy[3] || voodoo->voodoo_busy; + uint32_t ret; - ret = 0; - if (fifo_entries < 0x20) - ret |= 0x1f - fifo_entries; - else - ret |= 0x1f; - if (fifo_entries) - ret |= 0x20; - if (swap_count < 7) - ret |= (swap_count << 28); - else - ret |= (7 << 28); - if (!(svga->cgastat & 8)) - ret |= 0x40; + ret = 0; + if (fifo_entries < 0x20) + ret |= 0x1f - fifo_entries; + else + ret |= 0x1f; + if (fifo_entries) + ret |= 0x20; + if (swap_count < 7) + ret |= (swap_count << 28); + else + ret |= (7 << 28); + if (!(svga->cgastat & 8)) + ret |= 0x40; - if (busy) - ret |= 0x780; /*Busy*/ + if (busy) + ret |= 0x780; /*Busy*/ - if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) - ret |= (1 << 11); + if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) + ret |= (1 << 11); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_thread(voodoo); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_thread(voodoo); -// banshee_log("banshee_status: busy %i %i (%i %i) %i %i %i %04x(%08x):%08x %08x\n", busy, written, voodoo->cmd_written, voodoo->cmd_written_fifo, voodoo->cmd_read, voodoo->cmdfifo_depth_rd, voodoo->cmdfifo_depth_wr, CS,cs,cpu_state.pc, ret); + // banshee_log("banshee_status: busy %i %i (%i %i) %i %i %i %04x(%08x):%08x %08x\n", busy, written, voodoo->cmd_written, voodoo->cmd_written_fifo, voodoo->cmd_read, voodoo->cmdfifo_depth_rd, voodoo->cmdfifo_depth_wr, CS,cs,cpu_state.pc, ret); - return ret; + return ret; } -static uint32_t banshee_ext_inl(uint16_t addr, void *p) +static uint32_t +banshee_ext_inl(uint16_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - uint32_t ret = 0xffffffff; + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + uint32_t ret = 0xffffffff; - cycles -= voodoo->read_time; + cycles -= voodoo->read_time; - switch (addr & 0xff) - { - case Init_status: - ret = banshee_status(banshee); -// banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); - break; - case Init_pciInit0: - ret = banshee->pciInit0; - break; - case Init_lfbMemoryConfig: - ret = banshee->lfbMemoryConfig; - break; + switch (addr & 0xff) { + case Init_status: + ret = banshee_status(banshee); + // banshee_log("Read status reg! %04x(%08x):%08x\n", CS, cs, cpu_state.pc); + break; + case Init_pciInit0: + ret = banshee->pciInit0; + break; + case Init_lfbMemoryConfig: + ret = banshee->lfbMemoryConfig; + break; - case Init_miscInit0: - ret = banshee->miscInit0; - break; - case Init_miscInit1: - ret = banshee->miscInit1; - break; - case Init_dramInit0: - ret = banshee->dramInit0; - break; - case Init_dramInit1: - ret = banshee->dramInit1; - break; - case Init_agpInit0: - ret = banshee->agpInit0; - break; + case Init_miscInit0: + ret = banshee->miscInit0; + break; + case Init_miscInit1: + ret = banshee->miscInit1; + break; + case Init_dramInit0: + ret = banshee->dramInit0; + break; + case Init_dramInit1: + ret = banshee->dramInit1; + break; + case Init_agpInit0: + ret = banshee->agpInit0; + break; - case Init_vgaInit0: - ret = banshee->vgaInit0; - break; - case Init_vgaInit1: - ret = banshee->vgaInit1; - break; + case Init_vgaInit0: + ret = banshee->vgaInit0; + break; + case Init_vgaInit1: + ret = banshee->vgaInit1; + break; - case Init_2dCommand: - ret = banshee->command_2d; - break; - case Init_2dSrcBaseAddr: - ret = banshee->srcBaseAddr_2d; - break; - case Init_strapInfo: - ret = 0x00000040; /*8 MB SGRAM, PCI, IRQ enabled, 32kB BIOS*/ - break; + case Init_2dCommand: + ret = banshee->command_2d; + break; + case Init_2dSrcBaseAddr: + ret = banshee->srcBaseAddr_2d; + break; + case Init_strapInfo: + ret = 0x00000040; /*8 MB SGRAM, PCI, IRQ enabled, 32kB BIOS*/ + break; - case PLL_pllCtrl0: - ret = banshee->pllCtrl0; - break; - case PLL_pllCtrl1: - ret = banshee->pllCtrl1; - break; - case PLL_pllCtrl2: - ret = banshee->pllCtrl2; - break; + case PLL_pllCtrl0: + ret = banshee->pllCtrl0; + break; + case PLL_pllCtrl1: + ret = banshee->pllCtrl1; + break; + case PLL_pllCtrl2: + ret = banshee->pllCtrl2; + break; - case DAC_dacMode: - ret = banshee->dacMode; - break; - case DAC_dacAddr: - ret = banshee->dacAddr; - break; - case DAC_dacData: - ret = svga->pallook[banshee->dacAddr]; - break; + case DAC_dacMode: + ret = banshee->dacMode; + break; + case DAC_dacAddr: + ret = banshee->dacAddr; + break; + case DAC_dacData: + ret = svga->pallook[banshee->dacAddr]; + break; - case Video_vidProcCfg: - ret = banshee->vidProcCfg; - break; + case Video_vidProcCfg: + ret = banshee->vidProcCfg; + break; - case Video_hwCurPatAddr: - ret = banshee->hwCurPatAddr; - break; - case Video_hwCurLoc: - ret = banshee->hwCurLoc; - break; - case Video_hwCurC0: - ret = banshee->hwCurC0; - break; - case Video_hwCurC1: - ret = banshee->hwCurC1; - break; + case Video_hwCurPatAddr: + ret = banshee->hwCurPatAddr; + break; + case Video_hwCurLoc: + ret = banshee->hwCurLoc; + break; + case Video_hwCurC0: + ret = banshee->hwCurC0; + break; + case Video_hwCurC1: + ret = banshee->hwCurC1; + break; - case Video_vidSerialParallelPort: - ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R | VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R); - if (banshee->vidSerialParallelPort & VIDSERIAL_DDC_EN) { - if (i2c_gpio_get_scl(banshee->i2c_ddc)) - ret |= VIDSERIAL_DDC_DCK_R; - if (i2c_gpio_get_sda(banshee->i2c_ddc)) - ret |= VIDSERIAL_DDC_DDA_R; - } - if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_EN) { - if (i2c_gpio_get_scl(banshee->i2c)) - ret |= VIDSERIAL_I2C_SCK_R; - if (i2c_gpio_get_sda(banshee->i2c)) - ret |= VIDSERIAL_I2C_SDA_R; - } -// banshee_log("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); - break; + case Video_vidSerialParallelPort: + ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R | VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R); + if (banshee->vidSerialParallelPort & VIDSERIAL_DDC_EN) { + if (i2c_gpio_get_scl(banshee->i2c_ddc)) + ret |= VIDSERIAL_DDC_DCK_R; + if (i2c_gpio_get_sda(banshee->i2c_ddc)) + ret |= VIDSERIAL_DDC_DDA_R; + } + if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_EN) { + if (i2c_gpio_get_scl(banshee->i2c)) + ret |= VIDSERIAL_I2C_SCK_R; + if (i2c_gpio_get_sda(banshee->i2c)) + ret |= VIDSERIAL_I2C_SDA_R; + } + // banshee_log("vidSerialParallelPort: read %08x %08x %04x(%08x):%08x\n", ret, ret & (VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R), CS,cs,cpu_state.pc); + break; - case Video_vidScreenSize: - ret = banshee->vidScreenSize; - break; - case Video_vidOverlayStartCoords: - ret = voodoo->overlay.vidOverlayStartCoords; - break; - case Video_vidOverlayEndScreenCoords: - ret = voodoo->overlay.vidOverlayEndScreenCoords; - break; - case Video_vidOverlayDudx: - ret = voodoo->overlay.vidOverlayDudx; - break; - case Video_vidOverlayDudxOffsetSrcWidth: - ret = voodoo->overlay.vidOverlayDudxOffsetSrcWidth; - break; - case Video_vidOverlayDvdy: - ret = voodoo->overlay.vidOverlayDvdy; - break; - case Video_vidOverlayDvdyOffset: - ret = voodoo->overlay.vidOverlayDvdyOffset; - break; + case Video_vidScreenSize: + ret = banshee->vidScreenSize; + break; + case Video_vidOverlayStartCoords: + ret = voodoo->overlay.vidOverlayStartCoords; + break; + case Video_vidOverlayEndScreenCoords: + ret = voodoo->overlay.vidOverlayEndScreenCoords; + break; + case Video_vidOverlayDudx: + ret = voodoo->overlay.vidOverlayDudx; + break; + case Video_vidOverlayDudxOffsetSrcWidth: + ret = voodoo->overlay.vidOverlayDudxOffsetSrcWidth; + break; + case Video_vidOverlayDvdy: + ret = voodoo->overlay.vidOverlayDvdy; + break; + case Video_vidOverlayDvdyOffset: + ret = voodoo->overlay.vidOverlayDvdyOffset; + break; - case Video_vidDesktopStartAddr: - ret = banshee->vidDesktopStartAddr; - break; - case Video_vidDesktopOverlayStride: - ret = banshee->vidDesktopOverlayStride; - break; + case Video_vidDesktopStartAddr: + ret = banshee->vidDesktopStartAddr; + break; + case Video_vidDesktopOverlayStride: + ret = banshee->vidDesktopOverlayStride; + break; - default: -// fatal("bad banshee_ext_inl: addr=%04x\n", addr); - break; - } + default: + // fatal("bad banshee_ext_inl: addr=%04x\n", addr); + break; + } -// /*if (addr) */banshee_log("banshee_ext_inl: addr=%04x val=%08x\n", addr, ret); + // /*if (addr) */banshee_log("banshee_ext_inl: addr=%04x val=%08x\n", addr, ret); - return ret; + return ret; } - static uint32_t banshee_reg_readl(uint32_t addr, void *p); -static uint8_t banshee_reg_read(uint32_t addr, void *p) +static uint8_t +banshee_reg_read(uint32_t addr, void *p) { -// banshee_log("banshee_reg_read: addr=%08x\n", addr); - return banshee_reg_readl(addr & ~3, p) >> (8*(addr & 3)); + // banshee_log("banshee_reg_read: addr=%08x\n", addr); + return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 3)); } -static uint16_t banshee_reg_readw(uint32_t addr, void *p) +static uint16_t +banshee_reg_readw(uint32_t addr, void *p) { -// banshee_log("banshee_reg_readw: addr=%08x\n", addr); - return banshee_reg_readl(addr & ~3, p) >> (8*(addr & 2)); + // banshee_log("banshee_reg_readw: addr=%08x\n", addr); + return banshee_reg_readl(addr & ~3, p) >> (8 * (addr & 2)); } -static uint32_t banshee_cmd_read(banshee_t *banshee, uint32_t addr) +static uint32_t +banshee_cmd_read(banshee_t *banshee, uint32_t addr) { - voodoo_t *voodoo = banshee->voodoo; - uint32_t ret = 0xffffffff; + voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; - switch (addr & 0x1fc) - { - case cmdBaseAddr0: - ret = voodoo->cmdfifo_base >> 12; -// banshee_log("Read cmdfifo_base %08x\n", ret); - break; + switch (addr & 0x1fc) { + case cmdBaseAddr0: + ret = voodoo->cmdfifo_base >> 12; + // banshee_log("Read cmdfifo_base %08x\n", ret); + break; - case cmdRdPtrL0: - ret = voodoo->cmdfifo_rp; -// banshee_log("Read cmdfifo_rp %08x\n", ret); - break; + case cmdRdPtrL0: + ret = voodoo->cmdfifo_rp; + // banshee_log("Read cmdfifo_rp %08x\n", ret); + break; - case cmdFifoDepth0: - ret = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; -// banshee_log("Read cmdfifo_depth %08x\n", ret); - break; + case cmdFifoDepth0: + ret = voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd; + // banshee_log("Read cmdfifo_depth %08x\n", ret); + break; - case 0x108: - break; + case 0x108: + break; + + default: + fatal("Unknown banshee_cmd_read %08x\n", addr); + } + + return ret; +} + +static uint32_t +banshee_reg_readl(uint32_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + uint32_t ret = 0xffffffff; + + cycles -= voodoo->read_time; + + switch (addr & 0x1f00000) { + case 0x0000000: /*IO remap*/ + if (!(addr & 0x80000)) + ret = banshee_ext_inl(addr & 0xff, banshee); + else + ret = banshee_cmd_read(banshee, addr); + break; + + case 0x0100000: /*2D registers*/ + voodoo_flush(voodoo); + switch (addr & 0x1fc) { + case SST_status: + ret = banshee_status(banshee); + break; + + case SST_intrCtrl: + ret = banshee->intrCtrl & 0x0030003f; + break; + + case 0x08: + ret = voodoo->banshee_blt.clip0Min; + break; + case 0x0c: + ret = voodoo->banshee_blt.clip0Max; + break; + case 0x10: + ret = voodoo->banshee_blt.dstBaseAddr; + break; + case 0x14: + ret = voodoo->banshee_blt.dstFormat; + break; + case 0x34: + ret = voodoo->banshee_blt.srcBaseAddr; + break; + case 0x38: + ret = voodoo->banshee_blt.commandExtra; + break; + case 0x5c: + ret = voodoo->banshee_blt.srcXY; + break; + case 0x60: + ret = voodoo->banshee_blt.colorBack; + break; + case 0x64: + ret = voodoo->banshee_blt.colorFore; + break; + case 0x68: + ret = voodoo->banshee_blt.dstSize; + break; + case 0x6c: + ret = voodoo->banshee_blt.dstXY; + break; + case 0x70: + ret = voodoo->banshee_blt.command; + break; + default: + banshee_log("banshee_reg_readl: addr=%08x\n", addr); + } + break; + + case 0x0200000: + case 0x0300000: + case 0x0400000: + case 0x0500000: /*3D registers*/ + switch (addr & 0x3fc) { + case SST_status: + ret = banshee_status(banshee); + break; + + case SST_intrCtrl: + ret = banshee->intrCtrl & 0x0030003f; + break; + + case SST_fbzColorPath: + voodoo_flush(voodoo); + ret = voodoo->params.fbzColorPath; + break; + case SST_fogMode: + voodoo_flush(voodoo); + ret = voodoo->params.fogMode; + break; + case SST_alphaMode: + voodoo_flush(voodoo); + ret = voodoo->params.alphaMode; + break; + case SST_fbzMode: + voodoo_flush(voodoo); + ret = voodoo->params.fbzMode; + break; + case SST_lfbMode: + voodoo_flush(voodoo); + ret = voodoo->lfbMode; + break; + case SST_clipLeftRight: + ret = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); + break; + case SST_clipLowYHighY: + ret = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); + break; + + case SST_clipLeftRight1: + ret = voodoo->params.clipRight1 | (voodoo->params.clipLeft1 << 16); + break; + case SST_clipTopBottom1: + ret = voodoo->params.clipHighY1 | (voodoo->params.clipLowY1 << 16); + break; + + case SST_stipple: + voodoo_flush(voodoo); + ret = voodoo->params.stipple; + break; + case SST_color0: + voodoo_flush(voodoo); + ret = voodoo->params.color0; + break; + case SST_color1: + voodoo_flush(voodoo); + ret = voodoo->params.color1; + break; + + case SST_fbiPixelsIn: + ret = voodoo->fbiPixelsIn & 0xffffff; + break; + case SST_fbiChromaFail: + ret = voodoo->fbiChromaFail & 0xffffff; + break; + case SST_fbiZFuncFail: + ret = voodoo->fbiZFuncFail & 0xffffff; + break; + case SST_fbiAFuncFail: + ret = voodoo->fbiAFuncFail & 0xffffff; + break; + case SST_fbiPixelsOut: + ret = voodoo->fbiPixelsOut & 0xffffff; + break; default: - fatal("Unknown banshee_cmd_read %08x\n", addr); - } + banshee_log("banshee_reg_readl: 3D addr=%08x\n", addr); + break; + } + break; + } - return ret; + // /*if (addr != 0xe0000000) */banshee_log("banshee_reg_readl: addr=%08x ret=%08x %04x(%08x):%08x\n", addr, ret, CS,cs,cpu_state.pc); + + return ret; } -static uint32_t banshee_reg_readl(uint32_t addr, void *p) +static void +banshee_reg_write(uint32_t addr, uint8_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - uint32_t ret = 0xffffffff; - - cycles -= voodoo->read_time; - - switch (addr & 0x1f00000) - { - case 0x0000000: /*IO remap*/ - if (!(addr & 0x80000)) - ret = banshee_ext_inl(addr & 0xff, banshee); - else - ret = banshee_cmd_read(banshee, addr); - break; - - case 0x0100000: /*2D registers*/ - voodoo_flush(voodoo); - switch (addr & 0x1fc) - { - case SST_status: - ret = banshee_status(banshee); - break; - - case SST_intrCtrl: - ret = banshee->intrCtrl & 0x0030003f; - break; - - case 0x08: - ret = voodoo->banshee_blt.clip0Min; - break; - case 0x0c: - ret = voodoo->banshee_blt.clip0Max; - break; - case 0x10: - ret = voodoo->banshee_blt.dstBaseAddr; - break; - case 0x14: - ret = voodoo->banshee_blt.dstFormat; - break; - case 0x34: - ret = voodoo->banshee_blt.srcBaseAddr; - break; - case 0x38: - ret = voodoo->banshee_blt.commandExtra; - break; - case 0x5c: - ret = voodoo->banshee_blt.srcXY; - break; - case 0x60: - ret = voodoo->banshee_blt.colorBack; - break; - case 0x64: - ret = voodoo->banshee_blt.colorFore; - break; - case 0x68: - ret = voodoo->banshee_blt.dstSize; - break; - case 0x6c: - ret = voodoo->banshee_blt.dstXY; - break; - case 0x70: - ret = voodoo->banshee_blt.command; - break; - default: - banshee_log("banshee_reg_readl: addr=%08x\n", addr); - } - break; - - case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/ - switch (addr & 0x3fc) - { - case SST_status: - ret = banshee_status(banshee); - break; - - case SST_intrCtrl: - ret = banshee->intrCtrl & 0x0030003f; - break; - - case SST_fbzColorPath: - voodoo_flush(voodoo); - ret = voodoo->params.fbzColorPath; - break; - case SST_fogMode: - voodoo_flush(voodoo); - ret = voodoo->params.fogMode; - break; - case SST_alphaMode: - voodoo_flush(voodoo); - ret = voodoo->params.alphaMode; - break; - case SST_fbzMode: - voodoo_flush(voodoo); - ret = voodoo->params.fbzMode; - break; - case SST_lfbMode: - voodoo_flush(voodoo); - ret = voodoo->lfbMode; - break; - case SST_clipLeftRight: - ret = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); - break; - case SST_clipLowYHighY: - ret = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); - break; - - case SST_clipLeftRight1: - ret = voodoo->params.clipRight1 | (voodoo->params.clipLeft1 << 16); - break; - case SST_clipTopBottom1: - ret = voodoo->params.clipHighY1 | (voodoo->params.clipLowY1 << 16); - break; - - case SST_stipple: - voodoo_flush(voodoo); - ret = voodoo->params.stipple; - break; - case SST_color0: - voodoo_flush(voodoo); - ret = voodoo->params.color0; - break; - case SST_color1: - voodoo_flush(voodoo); - ret = voodoo->params.color1; - break; - - case SST_fbiPixelsIn: - ret = voodoo->fbiPixelsIn & 0xffffff; - break; - case SST_fbiChromaFail: - ret = voodoo->fbiChromaFail & 0xffffff; - break; - case SST_fbiZFuncFail: - ret = voodoo->fbiZFuncFail & 0xffffff; - break; - case SST_fbiAFuncFail: - ret = voodoo->fbiAFuncFail & 0xffffff; - break; - case SST_fbiPixelsOut: - ret = voodoo->fbiPixelsOut & 0xffffff; - break; - - default: - banshee_log("banshee_reg_readl: 3D addr=%08x\n", addr); - break; - } - break; - } - -// /*if (addr != 0xe0000000) */banshee_log("banshee_reg_readl: addr=%08x ret=%08x %04x(%08x):%08x\n", addr, ret, CS,cs,cpu_state.pc); - - return ret; + // banshee_log("banshee_reg_writeb: addr=%08x val=%02x\n", addr, val); } -static void banshee_reg_write(uint32_t addr, uint8_t val, void *p) +static void +banshee_reg_writew(uint32_t addr, uint16_t val, void *p) { -// banshee_log("banshee_reg_writeb: addr=%08x val=%02x\n", addr, val); + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + + cycles -= voodoo->write_time; + + // banshee_log("banshee_reg_writew: addr=%08x val=%04x\n", addr, val); + switch (addr & 0x1f00000) { + case 0x1000000: + case 0x1100000: + case 0x1200000: + case 0x1300000: /*3D LFB*/ + case 0x1400000: + case 0x1500000: + case 0x1600000: + case 0x1700000: + case 0x1800000: + case 0x1900000: + case 0x1a00000: + case 0x1b00000: + case 0x1c00000: + case 0x1d00000: + case 0x1e00000: + case 0x1f00000: + voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); + break; + } } -static void banshee_reg_writew(uint32_t addr, uint16_t val, void *p) +static void +banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; + voodoo_t *voodoo = banshee->voodoo; + // banshee_log("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); + switch (addr & 0x1fc) { + case cmdBaseAddr0: + voodoo->cmdfifo_base = (val & 0xfff) << 12; + voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); + // banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, val); + break; + case cmdBaseSize0: + voodoo->cmdfifo_size = val; + voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); + voodoo->cmdfifo_enabled = val & 0x100; + if (!voodoo->cmdfifo_enabled) + voodoo->cmdfifo_in_sub = 0; /*Not sure exactly when this should be reset*/ + // banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + break; + + // voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; + // banshee_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); + // break; + + case cmdRdPtrL0: + voodoo->cmdfifo_rp = val; + break; + case cmdAMin0: + voodoo->cmdfifo_amin = val; + break; + case cmdAMax0: + voodoo->cmdfifo_amax = val; + break; + case cmdFifoDepth0: + voodoo->cmdfifo_depth_rd = 0; + voodoo->cmdfifo_depth_wr = val & 0xffff; + break; + + default: + banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x\n", addr, val); + break; + } + + /* cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48 + }*/ +} + +static void +banshee_reg_writel(uint32_t addr, uint32_t val, void *p) +{ + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + + if (addr == voodoo->last_write_addr + 4) + cycles -= voodoo->burst_time; + else cycles -= voodoo->write_time; + voodoo->last_write_addr = addr; -// banshee_log("banshee_reg_writew: addr=%08x val=%04x\n", addr, val); - switch (addr & 0x1f00000) - { - case 0x1000000: case 0x1100000: case 0x1200000: case 0x1300000: /*3D LFB*/ - case 0x1400000: case 0x1500000: case 0x1600000: case 0x1700000: - case 0x1800000: case 0x1900000: case 0x1a00000: case 0x1b00000: - case 0x1c00000: case 0x1d00000: case 0x1e00000: case 0x1f00000: - voodoo_queue_command(voodoo, (addr & 0xffffff) | FIFO_WRITEW_FB, val); - break; - } -} + // banshee_log("banshee_reg_writel: addr=%08x val=%08x\n", addr, val); -static void banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) -{ - voodoo_t *voodoo = banshee->voodoo; -// banshee_log("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); - switch (addr & 0x1fc) - { - case cmdBaseAddr0: - voodoo->cmdfifo_base = (val & 0xfff) << 12; - voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); -// banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x %08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end, val); - break; + switch (addr & 0x1f00000) { + case 0x0000000: /*IO remap*/ + if (!(addr & 0x80000)) + banshee_ext_outl(addr & 0xff, val, banshee); + else + banshee_cmd_write(banshee, addr, val); + // banshee_log("CMD!!! write %08x %08x\n", addr, val); + break; - case cmdBaseSize0: - voodoo->cmdfifo_size = val; - voodoo->cmdfifo_end = voodoo->cmdfifo_base + (((voodoo->cmdfifo_size & 0xff) + 1) << 12); - voodoo->cmdfifo_enabled = val & 0x100; - if (!voodoo->cmdfifo_enabled) - voodoo->cmdfifo_in_sub = 0; /*Not sure exactly when this should be reset*/ -// banshee_log("cmdfifo_base=%08x cmdfifo_end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); - break; + case 0x0100000: /*2D registers*/ + if ((addr & 0x3fc) == SST_intrCtrl) { + banshee->intrCtrl = val & 0x0030003f; + } else { + voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val); + } + break; -// voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; -// banshee_log("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); -// break; + case 0x0200000: + case 0x0300000: + case 0x0400000: + case 0x0500000: /*3D registers*/ + switch (addr & 0x3fc) { + case SST_intrCtrl: + banshee->intrCtrl = val & 0x0030003f; + // banshee_log("intrCtrl=%08x\n", val); + break; - case cmdRdPtrL0: - voodoo->cmdfifo_rp = val; - break; - case cmdAMin0: - voodoo->cmdfifo_amin = val; - break; - case cmdAMax0: - voodoo->cmdfifo_amax = val; - break; - case cmdFifoDepth0: - voodoo->cmdfifo_depth_rd = 0; - voodoo->cmdfifo_depth_wr = val & 0xffff; - break; + case SST_userIntrCMD: + fatal("userIntrCMD write %08x\n", val); + break; + + case SST_swapbufferCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + // banshee_log("SST_swapbufferCMD write: %i %i\n", voodoo->cmd_written, voodoo->cmd_written_fifo); + break; + case SST_triangleCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_ftriangleCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_fastfillCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + case SST_nopCMD: + voodoo->cmd_written++; + voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); + if (!voodoo->voodoo_busy) + voodoo_wake_fifo_threads(voodoo->set, voodoo); + break; + + case SST_swapPending: + thread_wait_mutex(voodoo->swap_mutex); + voodoo->swap_count++; + thread_release_mutex(voodoo->swap_mutex); + // voodoo->cmd_written++; + break; default: - banshee_log("Unknown banshee_cmd_write: addr=%08x val=%08x\n", addr, val); - break; - } + voodoo_queue_command(voodoo, (addr & 0x3ffffc) | FIFO_WRITEL_REG, val); + break; + } + break; -/* cmdBaseSize0 = 0x24, - cmdBump0 = 0x28, - cmdRdPtrL0 = 0x2c, - cmdRdPtrH0 = 0x30, - cmdAMin0 = 0x34, - cmdAMax0 = 0x3c, - cmdFifoDepth0 = 0x44, - cmdHoleCnt0 = 0x48 - }*/ + case 0x0600000: + case 0x0700000: /*Texture download*/ + voodoo->tex_count++; + voodoo_queue_command(voodoo, (addr & 0x1ffffc) | FIFO_WRITEL_TEX, val); + break; + + case 0x1000000: + case 0x1100000: + case 0x1200000: + case 0x1300000: /*3D LFB*/ + case 0x1400000: + case 0x1500000: + case 0x1600000: + case 0x1700000: + case 0x1800000: + case 0x1900000: + case 0x1a00000: + case 0x1b00000: + case 0x1c00000: + case 0x1d00000: + case 0x1e00000: + case 0x1f00000: + voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val); + break; + } } -static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p) +static uint8_t +banshee_read_linear(uint32_t addr, void *p) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; - if (addr == voodoo->last_write_addr+4) - cycles -= voodoo->burst_time; - else - cycles -= voodoo->write_time; - voodoo->last_write_addr = addr; + cycles -= voodoo->read_time; -// banshee_log("banshee_reg_writel: addr=%08x val=%08x\n", addr, val); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; - switch (addr & 0x1f00000) - { - case 0x0000000: /*IO remap*/ - if (!(addr & 0x80000)) - banshee_ext_outl(addr & 0xff, val, banshee); - else - banshee_cmd_write(banshee, addr, val); -// banshee_log("CMD!!! write %08x %08x\n", addr, val); - break; + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; - case 0x0100000: /*2D registers*/ - if ((addr & 0x3fc) == SST_intrCtrl) { - banshee->intrCtrl = val & 0x0030003f; - } else { - voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val); - } - break; + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // banshee_log(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; - case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/ - switch (addr & 0x3fc) - { - case SST_intrCtrl: - banshee->intrCtrl = val & 0x0030003f; -// banshee_log("intrCtrl=%08x\n", val); - break; + cycles -= video_timing_read_b; - case SST_userIntrCMD: - fatal("userIntrCMD write %08x\n", val); - break; + // banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); - case SST_swapbufferCMD: - voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); -// banshee_log("SST_swapbufferCMD write: %i %i\n", voodoo->cmd_written, voodoo->cmd_written_fifo); - break; - case SST_triangleCMD: - voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_ftriangleCMD: - voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_fastfillCMD: - voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; - case SST_nopCMD: - voodoo->cmd_written++; - voodoo_queue_command(voodoo, (addr & 0x3fc) | FIFO_WRITEL_REG, val); - if (!voodoo->voodoo_busy) - voodoo_wake_fifo_threads(voodoo->set, voodoo); - break; + return svga->vram[addr & svga->vram_mask]; +} - case SST_swapPending: - thread_wait_mutex(voodoo->swap_mutex); - voodoo->swap_count++; - thread_release_mutex(voodoo->swap_mutex); -// voodoo->cmd_written++; - break; +static uint16_t +banshee_read_linear_w(uint32_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; - default: - voodoo_queue_command(voodoo, (addr & 0x3ffffc) | FIFO_WRITEL_REG, val); - break; + if (addr & 1) + return banshee_read_linear(addr, p) | (banshee_read_linear(addr + 1, p) << 8); + + cycles -= voodoo->read_time; + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // banshee_log(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; + + cycles -= video_timing_read_w; + + // banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + + return *(uint16_t *) &svga->vram[addr & svga->vram_mask]; +} + +static uint32_t +banshee_read_linear_l(uint32_t addr, void *p) +{ + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + if (addr & 3) + return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr + 2, p) << 16); + + cycles -= voodoo->read_time; + + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // banshee_log(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return 0xff; + + cycles -= video_timing_read_l; + + // banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); + + return *(uint32_t *) &svga->vram[addr & svga->vram_mask]; +} + +static void +banshee_write_linear(uint32_t addr, uint8_t val, void *p) +{ + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + cycles -= voodoo->write_time; + + // banshee_log("write_linear: addr=%08x val=%02x\n", addr, val); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // banshee_log(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return; + + cycles -= video_timing_write_b; + + svga->changedvram[addr >> 12] = changeframecount; + svga->vram[addr & svga->vram_mask] = val; +} + +static void +banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) +{ + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + + if (addr & 1) { + banshee_write_linear(addr, val, p); + banshee_write_linear(addr + 1, val >> 8, p); + return; + } + + cycles -= voodoo->write_time; + // banshee_log("write_linear: addr=%08x val=%02x\n", addr, val); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // banshee_log(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); + } + if (addr >= svga->vram_max) + return; + + cycles -= video_timing_write_w; + + svga->changedvram[addr >> 12] = changeframecount; + *(uint16_t *) &svga->vram[addr & svga->vram_mask] = val; +} + +static void +banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) +{ + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + svga_t *svga = &banshee->svga; + int timing; + + if (addr & 3) { + banshee_write_linear_w(addr, val, p); + banshee_write_linear_w(addr + 2, val >> 16, p); + return; + } + + if (addr == voodoo->last_write_addr + 4) + timing = voodoo->burst_time; + else + timing = voodoo->write_time; + cycles -= timing; + voodoo->last_write_addr = addr; + + // /*if (val) */banshee_log("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base); + addr &= svga->decode_mask; + if (addr >= voodoo->tile_base) { + int x, y; + + addr -= voodoo->tile_base; + x = addr & (voodoo->tile_stride - 1); + y = addr >> voodoo->tile_stride_shift; + + addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * voodoo->tile_x_real; + // banshee_log(" Tile %08x->%08x->%08x->%08x %i %i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_x_real); + } + + if (addr >= svga->vram_max) + return; + + cycles -= video_timing_write_l; + + svga->changedvram[addr >> 12] = changeframecount; + *(uint32_t *) &svga->vram[addr & svga->vram_mask] = val; + if (voodoo->cmdfifo_enabled && addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) { + // banshee_log("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); + if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount) { + // if (voodoo->cmdfifo_holecount) + // fatal("CMDFIFO reset pointers while outstanding holes\n"); + /*Reset pointers*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base; + voodoo->cmdfifo_amax = voodoo->cmdfifo_base; + voodoo->cmdfifo_depth_wr++; + voodoo_wake_fifo_thread(voodoo); + } else if (voodoo->cmdfifo_holecount) { + // if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax) + // fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); + // banshee_log("holecount %i\n", voodoo->cmdfifo_holecount); + voodoo->cmdfifo_holecount--; + if (!voodoo->cmdfifo_holecount) { + /*Filled in holes, resume normal operation*/ + voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2); + voodoo->cmdfifo_amin = voodoo->cmdfifo_amax; + voodoo_wake_fifo_thread(voodoo); + // banshee_log("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add); + } + } else if (addr == voodoo->cmdfifo_amax + 4) { + /*In-order write*/ + voodoo->cmdfifo_amin = addr; + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_depth_wr++; + voodoo_wake_fifo_thread(voodoo); + } else { + /*Out-of-order write*/ + if (addr < voodoo->cmdfifo_amin) { + /*Reset back to start. Note that write is still out of order!*/ + voodoo->cmdfifo_amin = voodoo->cmdfifo_base - 4; + } + // else if (addr < voodoo->cmdfifo_amax) + // fatal("Out-of-order write really out of order\n"); + voodoo->cmdfifo_amax = addr; + voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1; + // banshee_log("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); + } + } +} + +void +banshee_hwcursor_draw(svga_t *svga, int displine) +{ + banshee_t *banshee = (banshee_t *) svga->p; + int x, c; + int x_off; + int xx; + uint32_t col0 = banshee->hwCurC0; + uint32_t col1 = banshee->hwCurC1; + uint8_t plane0[8], plane1[8]; + + for (c = 0; c < 8; c++) + plane0[c] = svga->vram[svga->hwcursor_latch.addr + c]; + for (c = 0; c < 8; c++) + plane1[c] = svga->vram[svga->hwcursor_latch.addr + c + 8]; + svga->hwcursor_latch.addr += 16; + + x_off = svga->hwcursor_latch.x; + + if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE) { + /*X11 mode*/ + for (x = 0; x < 64; x += 8) { + if (x_off > -8) { + for (xx = 0; xx < 8; xx++) { + if (plane0[x >> 3] & (1 << 7)) + ((uint32_t *) buffer32->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + + plane0[x >> 3] <<= 1; + plane1[x >> 3] <<= 1; } - break; + } - case 0x0600000: case 0x0700000: /*Texture download*/ - voodoo->tex_count++; - voodoo_queue_command(voodoo, (addr & 0x1ffffc) | FIFO_WRITEL_TEX, val); - break; - - case 0x1000000: case 0x1100000: case 0x1200000: case 0x1300000: /*3D LFB*/ - case 0x1400000: case 0x1500000: case 0x1600000: case 0x1700000: - case 0x1800000: case 0x1900000: case 0x1a00000: case 0x1b00000: - case 0x1c00000: case 0x1d00000: case 0x1e00000: case 0x1f00000: - voodoo_queue_command(voodoo, (addr & 0xfffffc) | FIFO_WRITEL_FB, val); - break; + x_off += 8; } -} + } else { + /*Windows mode*/ + for (x = 0; x < 64; x += 8) { + if (x_off > -8) { + for (xx = 0; xx < 8; xx++) { + if (!(plane0[x >> 3] & (1 << 7))) + ((uint32_t *) buffer32->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; + else if (plane1[x >> 3] & (1 << 7)) + ((uint32_t *) buffer32->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; -static uint8_t banshee_read_linear(uint32_t addr, void *p) -{ - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - - cycles -= voodoo->read_time; - - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) - { - int x, y; - - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride-1); - y = addr >> voodoo->tile_stride_shift; - - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; -// banshee_log(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return 0xff; - - cycles -= video_timing_read_b; - -// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); - - return svga->vram[addr & svga->vram_mask]; -} - -static uint16_t banshee_read_linear_w(uint32_t addr, void *p) -{ - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - - if (addr & 1) - return banshee_read_linear(addr, p) | (banshee_read_linear(addr+1, p) << 8); - - cycles -= voodoo->read_time; - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) - { - int x, y; - - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride-1); - y = addr >> voodoo->tile_stride_shift; - - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; -// banshee_log(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return 0xff; - - cycles -= video_timing_read_w; - -// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); - - return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; -} - -static uint32_t banshee_read_linear_l(uint32_t addr, void *p) -{ - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - - if (addr & 3) - return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr+2, p) << 16); - - cycles -= voodoo->read_time; - - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) - { - int x, y; - - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride-1); - y = addr >> voodoo->tile_stride_shift; - - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; -// banshee_log(" Tile rb %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return 0xff; - - cycles -= video_timing_read_l; - -// banshee_log("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]); - - return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; -} - -static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) -{ - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - - cycles -= voodoo->write_time; - -// banshee_log("write_linear: addr=%08x val=%02x\n", addr, val); - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) - { - int x, y; - - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride-1); - y = addr >> voodoo->tile_stride_shift; - - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; -// banshee_log(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return; - - cycles -= video_timing_write_b; - - svga->changedvram[addr >> 12] = changeframecount; - svga->vram[addr & svga->vram_mask] = val; -} - -static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p) -{ - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - - if (addr & 1) - { - banshee_write_linear(addr, val, p); - banshee_write_linear(addr + 1, val >> 8, p); - return; - } - - cycles -= voodoo->write_time; -// banshee_log("write_linear: addr=%08x val=%02x\n", addr, val); - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) - { - int x, y; - - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride-1); - y = addr >> voodoo->tile_stride_shift; - - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; -// banshee_log(" Tile b %08x->%08x %i %i\n", old_addr, addr, x, y); - } - if (addr >= svga->vram_max) - return; - - cycles -= video_timing_write_w; - - svga->changedvram[addr >> 12] = changeframecount; - *(uint16_t *)&svga->vram[addr & svga->vram_mask] = val; -} - -static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p) -{ - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; - svga_t *svga = &banshee->svga; - int timing; - - if (addr & 3) - { - banshee_write_linear_w(addr, val, p); - banshee_write_linear_w(addr + 2, val >> 16, p); - return; - } - - if (addr == voodoo->last_write_addr+4) - timing = voodoo->burst_time; - else - timing = voodoo->write_time; - cycles -= timing; - voodoo->last_write_addr = addr; - -// /*if (val) */banshee_log("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base); - addr &= svga->decode_mask; - if (addr >= voodoo->tile_base) - { - int x, y; - - addr -= voodoo->tile_base; - x = addr & (voodoo->tile_stride-1); - y = addr >> voodoo->tile_stride_shift; - - addr = voodoo->tile_base + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*voodoo->tile_x_real; -// banshee_log(" Tile %08x->%08x->%08x->%08x %i %i tile_x=%i\n", old_addr, addr_off, addr2, addr, x, y, voodoo->tile_x_real); - } - - if (addr >= svga->vram_max) - return; - - cycles -= video_timing_write_l; - - svga->changedvram[addr >> 12] = changeframecount; - *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val; - if (voodoo->cmdfifo_enabled && addr >= voodoo->cmdfifo_base && addr < voodoo->cmdfifo_end) - { -// banshee_log("CMDFIFO write %08x %08x old amin=%08x amax=%08x hlcnt=%i depth_wr=%i rp=%08x\n", addr, val, voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount, voodoo->cmdfifo_depth_wr, voodoo->cmdfifo_rp); - if (addr == voodoo->cmdfifo_base && !voodoo->cmdfifo_holecount) - { -// if (voodoo->cmdfifo_holecount) -// fatal("CMDFIFO reset pointers while outstanding holes\n"); - /*Reset pointers*/ - voodoo->cmdfifo_amin = voodoo->cmdfifo_base; - voodoo->cmdfifo_amax = voodoo->cmdfifo_base; - voodoo->cmdfifo_depth_wr++; - voodoo_wake_fifo_thread(voodoo); + plane0[x >> 3] <<= 1; + plane1[x >> 3] <<= 1; } - else if (voodoo->cmdfifo_holecount) - { -// if ((addr <= voodoo->cmdfifo_amin && voodoo->cmdfifo_amin != -4) || addr >= voodoo->cmdfifo_amax) -// fatal("CMDFIFO holecount write outside of amin/amax - amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); -// banshee_log("holecount %i\n", voodoo->cmdfifo_holecount); - voodoo->cmdfifo_holecount--; - if (!voodoo->cmdfifo_holecount) - { - /*Filled in holes, resume normal operation*/ - voodoo->cmdfifo_depth_wr += ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2); - voodoo->cmdfifo_amin = voodoo->cmdfifo_amax; - voodoo_wake_fifo_thread(voodoo); -// banshee_log("hole filled! amin=%08x amax=%08x added %i words\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, words_to_add); - } - } - else if (addr == voodoo->cmdfifo_amax+4) - { - /*In-order write*/ - voodoo->cmdfifo_amin = addr; - voodoo->cmdfifo_amax = addr; - voodoo->cmdfifo_depth_wr++; - voodoo_wake_fifo_thread(voodoo); - } - else - { - /*Out-of-order write*/ - if (addr < voodoo->cmdfifo_amin) - { - /*Reset back to start. Note that write is still out of order!*/ - voodoo->cmdfifo_amin = voodoo->cmdfifo_base-4; + } - } -// else if (addr < voodoo->cmdfifo_amax) -// fatal("Out-of-order write really out of order\n"); - voodoo->cmdfifo_amax = addr; - voodoo->cmdfifo_holecount = ((voodoo->cmdfifo_amax - voodoo->cmdfifo_amin) >> 2) - 1; -// banshee_log("CMDFIFO out of order: amin=%08x amax=%08x holecount=%i\n", voodoo->cmdfifo_amin, voodoo->cmdfifo_amax, voodoo->cmdfifo_holecount); - } + x_off += 8; } + } } -void banshee_hwcursor_draw(svga_t *svga, int displine) -{ - banshee_t *banshee = (banshee_t *)svga->p; - int x, c; - int x_off; - int xx; - uint32_t col0 = banshee->hwCurC0; - uint32_t col1 = banshee->hwCurC1; - uint8_t plane0[8], plane1[8]; +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) - for (c = 0; c < 8; c++) - plane0[c] = svga->vram[svga->hwcursor_latch.addr + c]; - for (c = 0; c < 8; c++) - plane1[c] = svga->vram[svga->hwcursor_latch.addr + c + 8]; - svga->hwcursor_latch.addr += 16; +#define DECODE_RGB565(buf) \ + do { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) { \ + uint16_t data = *(uint16_t *) src; \ + int r = data & 0x1f; \ + int g = (data >> 5) & 0x3f; \ + int b = data >> 11; \ + \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + else \ + buf[wp++] = (clut[r << 3] & 0x0000ff) | (clut[g << 2] & 0x00ff00) | (clut[b << 3] & 0xff0000); \ + src += 2; \ + } \ + } while (0) - x_off = svga->hwcursor_latch.x; +#define DECODE_RGB565_TILED(buf) \ + do { \ + int c; \ + int wp = 0; \ + uint32_t base_addr = (buf == banshee->overlay_buffer[1]) ? src_addr2 : src_addr; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) { \ + uint16_t data = *(uint16_t *) &svga->vram[(base_addr + (c & 127) + (c >> 7) * 128 * 32) & svga->vram_mask]; \ + int r = data & 0x1f; \ + int g = (data >> 5) & 0x3f; \ + int b = data >> 11; \ + \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ + buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ + else \ + buf[wp++] = (clut[r << 3] & 0x0000ff) | (clut[g << 2] & 0x00ff00) | (clut[b << 3] & 0xff0000); \ + } \ + } while (0) - if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE) - { - /*X11 mode*/ - for (x = 0; x < 64; x += 8) - { - if (x_off > -8) - { - for (xx = 0; xx < 8; xx++) - { - if (plane0[x >> 3] & (1 << 7)) - ((uint32_t *)buffer32->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; +#define DECODE_YUYV422(buf) \ + do { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + y1 = src[0]; \ + Cr = src[1] - 0x80; \ + y2 = src[2]; \ + Cb = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + } \ + } while (0) - plane0[x >> 3] <<= 1; - plane1[x >> 3] <<= 1; - } - } +#define DECODE_UYUV422(buf) \ + do { \ + int c; \ + int wp = 0; \ + \ + for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) { \ + uint8_t y1, y2; \ + int8_t Cr, Cb; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + Cr = src[0] - 0x80; \ + y1 = src[1]; \ + Cb = src[2] - 0x80; \ + y2 = src[3]; \ + src += 4; \ + \ + dR = (359 * Cr) >> 8; \ + dG = (88 * Cb + 183 * Cr) >> 8; \ + dB = (453 * Cb) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + buf[wp++] = r | (g << 8) | (b << 16); \ + } \ + } while (0) - x_off += 8; - } - } - else - { - /*Windows mode*/ - for (x = 0; x < 64; x += 8) - { - if (x_off > -8) - { - for (xx = 0; xx < 8; xx++) - { - if (!(plane0[x >> 3] & (1 << 7))) - ((uint32_t *)buffer32->line[displine])[x_off + xx + svga->x_add] = (plane1[x >> 3] & (1 << 7)) ? col1 : col0; - else if (plane1[x >> 3] & (1 << 7)) - ((uint32_t *)buffer32->line[displine])[x_off + xx + svga->x_add] ^= 0xffffff; - - plane0[x >> 3] <<= 1; - plane1[x >> 3] <<= 1; - } - } - - x_off += 8; - } - } -} - -#define CLAMP(x) do \ - { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } \ - while (0) - -#define DECODE_RGB565(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ - { \ - uint16_t data = *(uint16_t *)src; \ - int r = data & 0x1f; \ - int g = (data >> 5) & 0x3f; \ - int b = data >> 11; \ - \ - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ - buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ - else \ - buf[wp++] = (clut[r << 3] & 0x0000ff) | \ - (clut[g << 2] & 0x00ff00) | \ - (clut[b << 3] & 0xff0000); \ - src += 2; \ - } \ - } while (0) - -#define DECODE_RGB565_TILED(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - uint32_t base_addr = (buf == banshee->overlay_buffer[1]) ? src_addr2 : src_addr; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 2) \ - { \ - uint16_t data = *(uint16_t *)&svga->vram[(base_addr + (c & 127) + (c >> 7)*128*32) & svga->vram_mask]; \ - int r = data & 0x1f; \ - int g = (data >> 5) & 0x3f; \ - int b = data >> 11; \ - \ - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_BYPASS) \ - buf[wp++] = (r << 3) | (g << 10) | (b << 19); \ - else \ - buf[wp++] = (clut[r << 3] & 0x0000ff) | \ - (clut[g << 2] & 0x00ff00) | \ - (clut[b << 3] & 0xff0000); \ - } \ - } while (0) - -#define DECODE_YUYV422(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - y1 = src[0]; \ - Cr = src[1] - 0x80; \ - y2 = src[2]; \ - Cb = src[3] - 0x80; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - } \ - } while (0) - -#define DECODE_UYUV422(buf) \ - do \ - { \ - int c; \ - int wp = 0; \ - \ - for (c = 0; c < voodoo->overlay.overlay_bytes; c += 4) \ - { \ - uint8_t y1, y2; \ - int8_t Cr, Cb; \ - int dR, dG, dB; \ - int r, g, b; \ - \ - Cr = src[0] - 0x80; \ - y1 = src[1]; \ - Cb = src[2] - 0x80; \ - y2 = src[3]; \ - src += 4; \ - \ - dR = (359*Cr) >> 8; \ - dG = (88*Cb + 183*Cr) >> 8; \ - dB = (453*Cb) >> 8; \ - \ - r = y1 + dR; \ - CLAMP(r); \ - g = y1 - dG; \ - CLAMP(g); \ - b = y1 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - \ - r = y2 + dR; \ - CLAMP(r); \ - g = y2 - dG; \ - CLAMP(g); \ - b = y2 + dB; \ - CLAMP(b); \ - buf[wp++] = r | (g << 8) | (b << 16); \ - } \ - } while (0) - - -#define OVERLAY_SAMPLE(buf) \ - do \ - { \ - switch (banshee->overlay_pix_fmt) \ - { \ - case 0: \ - break; \ - \ - case OVERLAY_FMT_YUYV422: \ - DECODE_YUYV422(buf); \ - break; \ - \ - case OVERLAY_FMT_UYVY422: \ - DECODE_UYUV422(buf); \ - break; \ - \ - case OVERLAY_FMT_565: \ - case OVERLAY_FMT_565_DITHER: \ - if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ - DECODE_RGB565_TILED(buf); \ - else \ - DECODE_RGB565(buf); \ - break; \ - \ - default: \ - fatal("Unknown overlay pix fmt %i\n", banshee->overlay_pix_fmt); \ - } \ - } while (0) +#define OVERLAY_SAMPLE(buf) \ + do { \ + switch (banshee->overlay_pix_fmt) { \ + case 0: \ + break; \ + \ + case OVERLAY_FMT_YUYV422: \ + DECODE_YUYV422(buf); \ + break; \ + \ + case OVERLAY_FMT_UYVY422: \ + DECODE_UYUV422(buf); \ + break; \ + \ + case OVERLAY_FMT_565: \ + case OVERLAY_FMT_565_DITHER: \ + if (banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) \ + DECODE_RGB565_TILED(buf); \ + else \ + DECODE_RGB565(buf); \ + break; \ + \ + default: \ + fatal("Unknown overlay pix fmt %i\n", banshee->overlay_pix_fmt); \ + } \ + } while (0) /* generate both filters for the static table here */ -void voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) +void +voodoo_generate_vb_filters(voodoo_t *voodoo, int fcr, int fcg) { - int g, h; - float difference, diffg; - float thiscol, thiscolg; - float clr, clg = 0; - float hack = 1.0f; - // pre-clamping + int g, h; + float difference, diffg; + float thiscol, thiscolg; + float clr, clg = 0; + float hack = 1.0f; + // pre-clamping - fcr *= hack; - fcg *= hack; + fcr *= hack; + fcg *= hack; - - /* box prefilter */ - for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into + /* box prefilter */ + for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into + { + for (h = 0; h < 256; h++) // pixel 2 - our main pixel { - for (h=0;h<256;h++) // pixel 2 - our main pixel - { - float avg; - float avgdiff; + float avg; + float avgdiff; - difference = (float)(g - h); - avg = g; - avgdiff = avg - h; + difference = (float) (g - h); + avg = g; + avgdiff = avg - h; - avgdiff = avgdiff * 0.75f; - if (avgdiff < 0) avgdiff *= -1; - if (difference < 0) difference *= -1; + avgdiff = avgdiff * 0.75f; + if (avgdiff < 0) + avgdiff *= -1; + if (difference < 0) + difference *= -1; - thiscol = thiscolg = g; + thiscol = thiscolg = g; - if (h > g) - { - clr = clg = avgdiff; + if (h > g) { + clr = clg = avgdiff; - if (clr>fcr) clr=fcr; - if (clg>fcg) clg=fcg; + if (clr > fcr) + clr = fcr; + if (clg > fcg) + clg = fcg; - thiscol = g; - thiscolg = g; + thiscol = g; + thiscolg = g; - if (thiscol>g+fcr) - thiscol=g+fcr; - if (thiscolg>g+fcg) - thiscolg=g+fcg; + if (thiscol > g + fcr) + thiscol = g + fcr; + if (thiscolg > g + fcg) + thiscolg = g + fcg; - if (thiscol>g+difference) - thiscol=g+difference; - if (thiscolg>g+difference) - thiscolg=g+difference; + if (thiscol > g + difference) + thiscol = g + difference; + if (thiscolg > g + difference) + thiscolg = g + difference; - // hmm this might not be working out.. - int ugh = g - h; - if (ugh < fcr) - thiscol = h; - if (ugh < fcg) - thiscolg = h; - } + // hmm this might not be working out.. + int ugh = g - h; + if (ugh < fcr) + thiscol = h; + if (ugh < fcg) + thiscolg = h; + } - if (difference > fcr) - thiscol = g; - if (difference > fcg) - thiscolg = g; + if (difference > fcr) + thiscol = g; + if (difference > fcg) + thiscolg = g; - // clamp - if (thiscol < 0) thiscol = 0; - if (thiscolg < 0) thiscolg = 0; + // clamp + if (thiscol < 0) + thiscol = 0; + if (thiscolg < 0) + thiscolg = 0; - if (thiscol > 255) thiscol = 255; - if (thiscolg > 255) thiscolg = 255; + if (thiscol > 255) + thiscol = 255; + if (thiscolg > 255) + thiscolg = 255; - vb_filter_bx_rb[g][h] = (thiscol); - vb_filter_bx_g [g][h] = (thiscolg); - - } - float lined = g + 4; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][0] = lined; - voodoo->purpleline[g][2] = lined; - - lined = g + 0; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][1] = lined; + vb_filter_bx_rb[g][h] = (thiscol); + vb_filter_bx_g[g][h] = (thiscolg); } + float lined = g + 4; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][0] = lined; + voodoo->purpleline[g][2] = lined; - /* 4x1 and 2x2 filter */ - //fcr *= 5; - //fcg *= 6; + lined = g + 0; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][1] = lined; + } - for (g=0;g<256;g++) // pixel 1 + /* 4x1 and 2x2 filter */ + // fcr *= 5; + // fcg *= 6; + + for (g = 0; g < 256; g++) // pixel 1 + { + for (h = 0; h < 256; h++) // pixel 2 { - for (h=0;h<256;h++) // pixel 2 - { - difference = (float)(h - g); - diffg = difference; + difference = (float) (h - g); + diffg = difference; - thiscol = thiscolg = g; + thiscol = thiscolg = g; - if (difference > fcr) - difference = fcr; - if (difference < -fcr) - difference = -fcr; + if (difference > fcr) + difference = fcr; + if (difference < -fcr) + difference = -fcr; - if (diffg > fcg) - diffg = fcg; - if (diffg < -fcg) - diffg = -fcg; + if (diffg > fcg) + diffg = fcg; + if (diffg < -fcg) + diffg = -fcg; - if ((difference < fcr) || (-difference > -fcr)) - thiscol = g + (difference / 2); - if ((diffg < fcg) || (-diffg > -fcg)) - thiscolg = g + (diffg / 2); + if ((difference < fcr) || (-difference > -fcr)) + thiscol = g + (difference / 2); + if ((diffg < fcg) || (-diffg > -fcg)) + thiscolg = g + (diffg / 2); - if (thiscol < 0) - thiscol = 0; - if (thiscol > 255) - thiscol = 255; + if (thiscol < 0) + thiscol = 0; + if (thiscol > 255) + thiscol = 255; - if (thiscolg < 0) - thiscolg = 0; - if (thiscolg > 255) - thiscolg = 255; + if (thiscolg < 0) + thiscolg = 0; + if (thiscolg > 255) + thiscolg = 255; - vb_filter_v1_rb[g][h] = thiscol; - vb_filter_v1_g [g][h] = thiscolg; - - } + vb_filter_v1_rb[g][h] = thiscol; + vb_filter_v1_g[g][h] = thiscolg; } - + } } - -static void banshee_overlay_draw(svga_t *svga, int displine) +static void +banshee_overlay_draw(svga_t *svga, int displine) { - banshee_t *banshee = (banshee_t *)svga->p; - voodoo_t *voodoo = banshee->voodoo; - uint32_t *p; - int x; - int y = voodoo->overlay.src_y >> 20; - uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? - ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : - y * svga->overlay_latch.pitch); - uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? - (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : - (y + 1) * svga->overlay_latch.pitch); - uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; - uint32_t src_x = 0; - unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; - int skip_filtering; - uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; + banshee_t *banshee = (banshee_t *) svga->p; + voodoo_t *voodoo = banshee->voodoo; + uint32_t *p; + int x; + int y = voodoo->overlay.src_y >> 20; + uint32_t src_addr = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? ((y & 31) * 128 + (y >> 5) * svga->overlay_latch.pitch) : y * svga->overlay_latch.pitch); + uint32_t src_addr2 = svga->overlay_latch.addr + ((banshee->vidProcCfg & VIDPROCCFG_OVERLAY_TILE) ? (((y + 1) & 31) * 128 + ((y + 1) >> 5) * svga->overlay_latch.pitch) : (y + 1) * svga->overlay_latch.pitch); + uint8_t *src = &svga->vram[src_addr & svga->vram_mask]; + uint32_t src_x = 0; + unsigned int y_coeff = (voodoo->overlay.src_y & 0xfffff) >> 4; + int skip_filtering; + uint32_t *clut = &svga->pallook[(banshee->vidProcCfg & VIDPROCCFG_OVERLAY_CLUT_SEL) ? 256 : 0]; - if (svga->render == svga_render_null && - !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && - !svga->fullchange && - ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && - !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) - { - voodoo->overlay.src_y += (1 << 20); - return; - } + if (svga->render == svga_render_null && !svga->changedvram[src_addr >> 12] && !svga->changedvram[src_addr2 >> 12] && !svga->fullchange && ((voodoo->overlay.src_y >> 20) < 2048 && !voodoo->dirty_line[voodoo->overlay.src_y >> 20]) && !(banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE)) { + voodoo->overlay.src_y += (1 << 20); + return; + } - if ((voodoo->overlay.src_y >> 20) < 2048) - voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; -// pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); -// if (src_addr >= 0x800000) -// fatal("overlay out of range!\n"); - p = &((uint32_t *)buffer32->line[displine])[svga->overlay_latch.x + svga->x_add]; + if ((voodoo->overlay.src_y >> 20) < 2048) + voodoo->dirty_line[voodoo->overlay.src_y >> 20] = 0; + // pclog("displine=%i addr=%08x %08x %08x %08x\n", displine, svga->overlay_latch.addr, src_addr, voodoo->overlay.vidOverlayDvdy, *(uint32_t *)src); + // if (src_addr >= 0x800000) + // fatal("overlay out of range!\n"); + p = &((uint32_t *) buffer32->line[displine])[svga->overlay_latch.x + svga->x_add]; - if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) - skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && - !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && - !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); - else - skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && - !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)); + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) + skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_4X4) && !(banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_DITHER_2X2)); + else + skip_filtering = ((banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) != VIDPROCCFG_FILTER_MODE_BILINEAR && !(banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE)); - if (skip_filtering) - { - /*No scaling or filtering required, just write straight to output buffer*/ - OVERLAY_SAMPLE(p); - } - else - { - OVERLAY_SAMPLE(banshee->overlay_buffer[0]); + if (skip_filtering) { + /*No scaling or filtering required, just write straight to output buffer*/ + OVERLAY_SAMPLE(p); + } else { + OVERLAY_SAMPLE(banshee->overlay_buffer[0]); - switch (banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) - { - case VIDPROCCFG_FILTER_MODE_BILINEAR: - src = &svga->vram[src_addr2 & svga->vram_mask]; - OVERLAY_SAMPLE(banshee->overlay_buffer[1]); - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - { - unsigned int x_coeff = (src_x & 0xfffff) >> 4; - unsigned int coeffs[4] = { - ((0x10000 - x_coeff) * (0x10000 - y_coeff)) >> 16, - ( x_coeff * (0x10000 - y_coeff)) >> 16, - ((0x10000 - x_coeff) * y_coeff) >> 16, - ( x_coeff * y_coeff) >> 16 - }; - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; - uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; - uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; - int r = (((samp0 >> 16) & 0xff) * coeffs[0] + - ((samp1 >> 16) & 0xff) * coeffs[1] + - ((samp2 >> 16) & 0xff) * coeffs[2] + - ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; - int g = (((samp0 >> 8) & 0xff) * coeffs[0] + - ((samp1 >> 8) & 0xff) * coeffs[1] + - ((samp2 >> 8) & 0xff) * coeffs[2] + - ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; - int b = ((samp0 & 0xff) * coeffs[0] + - (samp1 & 0xff) * coeffs[1] + - (samp2 & 0xff) * coeffs[2] + - (samp3 & 0xff) * coeffs[3]) >> 16; - p[x] = (r << 16) | (g << 8) | b; + switch (banshee->vidProcCfg & VIDPROCCFG_FILTER_MODE_MASK) { + case VIDPROCCFG_FILTER_MODE_BILINEAR: + src = &svga->vram[src_addr2 & svga->vram_mask]; + OVERLAY_SAMPLE(banshee->overlay_buffer[1]); + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + unsigned int x_coeff = (src_x & 0xfffff) >> 4; + unsigned int coeffs[4] = { + ((0x10000 - x_coeff) * (0x10000 - y_coeff)) >> 16, + (x_coeff * (0x10000 - y_coeff)) >> 16, + ((0x10000 - x_coeff) * y_coeff) >> 16, + (x_coeff * y_coeff) >> 16 + }; + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[0][(src_x >> 20) + 1]; + uint32_t samp2 = banshee->overlay_buffer[1][src_x >> 20]; + uint32_t samp3 = banshee->overlay_buffer[1][(src_x >> 20) + 1]; + int r = (((samp0 >> 16) & 0xff) * coeffs[0] + ((samp1 >> 16) & 0xff) * coeffs[1] + ((samp2 >> 16) & 0xff) * coeffs[2] + ((samp3 >> 16) & 0xff) * coeffs[3]) >> 16; + int g = (((samp0 >> 8) & 0xff) * coeffs[0] + ((samp1 >> 8) & 0xff) * coeffs[1] + ((samp2 >> 8) & 0xff) * coeffs[2] + ((samp3 >> 8) & 0xff) * coeffs[3]) >> 16; + int b = ((samp0 & 0xff) * coeffs[0] + (samp1 & 0xff) * coeffs[1] + (samp2 & 0xff) * coeffs[2] + (samp3 & 0xff) * coeffs[3]) >> 16; + p[x] = (r << 16) | (g << 8) | b; - src_x += voodoo->overlay.vidOverlayDudx; - } - } - else - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - { - uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; - uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; - int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + - ((samp1 >> 16) & 0xff) * y_coeff) >> 16; - int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + - ((samp1 >> 8) & 0xff) * y_coeff) >> 16; - int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + - (samp1 & 0xff) * y_coeff) >> 16; - p[x] = (r << 16) | (g << 8) | b; - } - } - break; - - case VIDPROCCFG_FILTER_MODE_DITHER_4X4: - if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) - { - uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3); - uint8_t *fil3 = malloc((svga->overlay_latch.cur_xsize) * 3); - - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */ - { - for (x=0; xoverlay_latch.cur_xsize;x++) - { - fil[x*3] = ((banshee->overlay_buffer[0][src_x >> 20])); - fil[x*3+1] = ((banshee->overlay_buffer[0][src_x >> 20] >> 8)); - fil[x*3+2] = ((banshee->overlay_buffer[0][src_x >> 20] >> 16)); - fil3[x*3+0] = fil[x*3+0]; - fil3[x*3+1] = fil[x*3+1]; - fil3[x*3+2] = fil[x*3+2]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } - else - { - for (x=0; xoverlay_latch.cur_xsize;x++) - { - fil[x*3] = ((banshee->overlay_buffer[0][x])); - fil[x*3+1] = ((banshee->overlay_buffer[0][x] >> 8)); - fil[x*3+2] = ((banshee->overlay_buffer[0][x] >> 16)); - fil3[x*3+0] = fil[x*3+0]; - fil3[x*3+1] = fil[x*3+1]; - fil3[x*3+2] = fil[x*3+2]; - } - } - if (y % 2 == 0) - { - for (x=0; xoverlay_latch.cur_xsize;x++) - { - fil[x*3] = banshee->voodoo->purpleline[fil[x*3+0]][0]; - fil[x*3+1] = banshee->voodoo->purpleline[fil[x*3+1]][1]; - fil[x*3+2] = banshee->voodoo->purpleline[fil[x*3+2]][2]; - } - } - - for (x=1; xoverlay_latch.cur_xsize;x++) - { - fil3[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil[(x-1) *3]]; - fil3[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil[(x-1) *3+1]]; - fil3[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil[(x-1) *3+2]]; - } - for (x=1; xoverlay_latch.cur_xsize;x++) - { - fil[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil3[(x-1) *3]]; - fil[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil3[(x-1) *3+1]]; - fil[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil3[(x-1) *3+2]]; - } - for (x=1; xoverlay_latch.cur_xsize;x++) - { - fil3[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil[(x-1) *3]]; - fil3[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil[(x-1) *3+1]]; - fil3[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil[(x-1) *3+2]]; - } - for (x=0; xoverlay_latch.cur_xsize;x++) - { - fil[(x)*3] = vb_filter_v1_rb [fil[x*3]] [fil3[(x+1) *3]]; - fil[(x)*3+1] = vb_filter_v1_g [fil[x*3+1]][fil3[(x+1) *3+1]]; - fil[(x)*3+2] = vb_filter_v1_rb [fil[x*3+2]] [fil3[(x+1) *3+2]]; - p[x] = (fil[x*3+2] << 16) | (fil[x*3+1] << 8) | fil[x*3]; - } - - free(fil); - free(fil3); - } - else /* filter disabled by emulator option */ - { - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } - else - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; - } - } - break; - - case VIDPROCCFG_FILTER_MODE_DITHER_2X2: - if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) - { - uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3); - uint8_t *soak = malloc((svga->overlay_latch.cur_xsize) * 3); - uint8_t *soak2 = malloc((svga->overlay_latch.cur_xsize) * 3); - - uint8_t *samp1 = malloc((svga->overlay_latch.cur_xsize) * 3); - uint8_t *samp2 = malloc((svga->overlay_latch.cur_xsize) * 3); - uint8_t *samp3 = malloc((svga->overlay_latch.cur_xsize) * 3); - uint8_t *samp4 = malloc((svga->overlay_latch.cur_xsize) * 3); - - src = &svga->vram[src_addr2 & svga->vram_mask]; - OVERLAY_SAMPLE(banshee->overlay_buffer[1]); - for (x=0; xoverlay_latch.cur_xsize;x++) - { - samp1[x*3] = ((banshee->overlay_buffer[0][x])); - samp1[x*3+1] = ((banshee->overlay_buffer[0][x] >> 8)); - samp1[x*3+2] = ((banshee->overlay_buffer[0][x] >> 16)); - - samp2[x*3+0] = ((banshee->overlay_buffer[0][x+1])); - samp2[x*3+1] = ((banshee->overlay_buffer[0][x+1] >> 8)); - samp2[x*3+2] = ((banshee->overlay_buffer[0][x+1] >> 16)); - - samp3[x*3+0] = ((banshee->overlay_buffer[1][x])); - samp3[x*3+1] = ((banshee->overlay_buffer[1][x] >> 8)); - samp3[x*3+2] = ((banshee->overlay_buffer[1][x] >> 16)); - - samp4[x*3+0] = ((banshee->overlay_buffer[1][x+1])); - samp4[x*3+1] = ((banshee->overlay_buffer[1][x+1] >> 8)); - samp4[x*3+2] = ((banshee->overlay_buffer[1][x+1] >> 16)); - - /* sample two lines */ - - soak[x*3+0] = vb_filter_bx_rb [samp1[x*3+0]] [samp2[x*3+0]]; - soak[x*3+1] = vb_filter_bx_g [samp1[x*3+1]] [samp2[x*3+1]]; - soak[x*3+2] = vb_filter_bx_rb [samp1[x*3+2]] [samp2[x*3+2]]; - - soak2[x*3+0] = vb_filter_bx_rb[samp3[x*3+0]] [samp4[x*3+0]]; - soak2[x*3+1] = vb_filter_bx_g [samp3[x*3+1]] [samp4[x*3+1]]; - soak2[x*3+2] = vb_filter_bx_rb[samp3[x*3+2]] [samp4[x*3+2]]; - - /* then pour it on the rest */ - - fil[x*3+0] = vb_filter_v1_rb[soak[x*3+0]] [soak2[x*3+0]]; - fil[x*3+1] = vb_filter_v1_g [soak[x*3+1]] [soak2[x*3+1]]; - fil[x*3+2] = vb_filter_v1_rb[soak[x*3+2]] [soak2[x*3+2]]; - } - - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */ - { - for (x=0; xoverlay_latch.cur_xsize;x++) - { - p[x] = (fil[(src_x >> 20)*3+2] << 16) | (fil[(src_x >> 20)*3+1] << 8) | fil[(src_x >> 20)*3]; - src_x += voodoo->overlay.vidOverlayDudx; - } - } - else - { - for (x=0; xoverlay_latch.cur_xsize;x++) - { - p[x] = (fil[x*3+2] << 16) | (fil[x*3+1] << 8) | fil[x*3]; - } - } - - free(fil); - free(soak); - free(soak2); - free(samp1); - free(samp2); - free(samp3); - free(samp4); - } - else /* filter disabled by emulator option */ - { - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; - - src_x += voodoo->overlay.vidOverlayDudx; - } - } - else - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; - } - } - break; - - case VIDPROCCFG_FILTER_MODE_POINT: - default: - if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - { - p[x] = banshee->overlay_buffer[0][src_x >> 20]; - - src_x += voodoo->overlay.vidOverlayDudx; - } - } - else - { - for (x = 0; x < svga->overlay_latch.cur_xsize; x++) - p[x] = banshee->overlay_buffer[0][x]; - } - break; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + uint32_t samp0 = banshee->overlay_buffer[0][src_x >> 20]; + uint32_t samp1 = banshee->overlay_buffer[1][src_x >> 20]; + int r = (((samp0 >> 16) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 16) & 0xff) * y_coeff) >> 16; + int g = (((samp0 >> 8) & 0xff) * (0x10000 - y_coeff) + ((samp1 >> 8) & 0xff) * y_coeff) >> 16; + int b = ((samp0 & 0xff) * (0x10000 - y_coeff) + (samp1 & 0xff) * y_coeff) >> 16; + p[x] = (r << 16) | (g << 8) | b; + } } - } + break; - if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) - voodoo->overlay.src_y += voodoo->overlay.vidOverlayDvdy; - else - voodoo->overlay.src_y += (1 << 20); + case VIDPROCCFG_FILTER_MODE_DITHER_4X4: + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { + uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *fil3 = malloc((svga->overlay_latch.cur_xsize) * 3); + + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */ + { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + fil[x * 3] = ((banshee->overlay_buffer[0][src_x >> 20])); + fil[x * 3 + 1] = ((banshee->overlay_buffer[0][src_x >> 20] >> 8)); + fil[x * 3 + 2] = ((banshee->overlay_buffer[0][src_x >> 20] >> 16)); + fil3[x * 3 + 0] = fil[x * 3 + 0]; + fil3[x * 3 + 1] = fil[x * 3 + 1]; + fil3[x * 3 + 2] = fil[x * 3 + 2]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + fil[x * 3] = ((banshee->overlay_buffer[0][x])); + fil[x * 3 + 1] = ((banshee->overlay_buffer[0][x] >> 8)); + fil[x * 3 + 2] = ((banshee->overlay_buffer[0][x] >> 16)); + fil3[x * 3 + 0] = fil[x * 3 + 0]; + fil3[x * 3 + 1] = fil[x * 3 + 1]; + fil3[x * 3 + 2] = fil[x * 3 + 2]; + } + } + if (y % 2 == 0) { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + fil[x * 3] = banshee->voodoo->purpleline[fil[x * 3 + 0]][0]; + fil[x * 3 + 1] = banshee->voodoo->purpleline[fil[x * 3 + 1]][1]; + fil[x * 3 + 2] = banshee->voodoo->purpleline[fil[x * 3 + 2]][2]; + } + } + + for (x = 1; x < svga->overlay_latch.cur_xsize; x++) { + fil3[(x) *3] = vb_filter_v1_rb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x) *3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x) *3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } + for (x = 1; x < svga->overlay_latch.cur_xsize; x++) { + fil[(x) *3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x - 1) * 3]]; + fil[(x) *3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x - 1) * 3 + 1]]; + fil[(x) *3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x - 1) * 3 + 2]]; + } + for (x = 1; x < svga->overlay_latch.cur_xsize; x++) { + fil3[(x) *3] = vb_filter_v1_rb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x) *3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x) *3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + fil[(x) *3] = vb_filter_v1_rb[fil[x * 3]][fil3[(x + 1) * 3]]; + fil[(x) *3 + 1] = vb_filter_v1_g[fil[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; + fil[(x) *3 + 2] = vb_filter_v1_rb[fil[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; + p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; + } + + free(fil); + free(fil3); + } else /* filter disabled by emulator option */ + { + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + } + break; + + case VIDPROCCFG_FILTER_MODE_DITHER_2X2: + if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled) { + uint8_t *fil = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *soak = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *soak2 = malloc((svga->overlay_latch.cur_xsize) * 3); + + uint8_t *samp1 = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *samp2 = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *samp3 = malloc((svga->overlay_latch.cur_xsize) * 3); + uint8_t *samp4 = malloc((svga->overlay_latch.cur_xsize) * 3); + + src = &svga->vram[src_addr2 & svga->vram_mask]; + OVERLAY_SAMPLE(banshee->overlay_buffer[1]); + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + samp1[x * 3] = ((banshee->overlay_buffer[0][x])); + samp1[x * 3 + 1] = ((banshee->overlay_buffer[0][x] >> 8)); + samp1[x * 3 + 2] = ((banshee->overlay_buffer[0][x] >> 16)); + + samp2[x * 3 + 0] = ((banshee->overlay_buffer[0][x + 1])); + samp2[x * 3 + 1] = ((banshee->overlay_buffer[0][x + 1] >> 8)); + samp2[x * 3 + 2] = ((banshee->overlay_buffer[0][x + 1] >> 16)); + + samp3[x * 3 + 0] = ((banshee->overlay_buffer[1][x])); + samp3[x * 3 + 1] = ((banshee->overlay_buffer[1][x] >> 8)); + samp3[x * 3 + 2] = ((banshee->overlay_buffer[1][x] >> 16)); + + samp4[x * 3 + 0] = ((banshee->overlay_buffer[1][x + 1])); + samp4[x * 3 + 1] = ((banshee->overlay_buffer[1][x + 1] >> 8)); + samp4[x * 3 + 2] = ((banshee->overlay_buffer[1][x + 1] >> 16)); + + /* sample two lines */ + + soak[x * 3 + 0] = vb_filter_bx_rb[samp1[x * 3 + 0]][samp2[x * 3 + 0]]; + soak[x * 3 + 1] = vb_filter_bx_g[samp1[x * 3 + 1]][samp2[x * 3 + 1]]; + soak[x * 3 + 2] = vb_filter_bx_rb[samp1[x * 3 + 2]][samp2[x * 3 + 2]]; + + soak2[x * 3 + 0] = vb_filter_bx_rb[samp3[x * 3 + 0]][samp4[x * 3 + 0]]; + soak2[x * 3 + 1] = vb_filter_bx_g[samp3[x * 3 + 1]][samp4[x * 3 + 1]]; + soak2[x * 3 + 2] = vb_filter_bx_rb[samp3[x * 3 + 2]][samp4[x * 3 + 2]]; + + /* then pour it on the rest */ + + fil[x * 3 + 0] = vb_filter_v1_rb[soak[x * 3 + 0]][soak2[x * 3 + 0]]; + fil[x * 3 + 1] = vb_filter_v1_g[soak[x * 3 + 1]][soak2[x * 3 + 1]]; + fil[x * 3 + 2] = vb_filter_v1_rb[soak[x * 3 + 2]][soak2[x * 3 + 2]]; + } + + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* 2x2 on a scaled low res */ + { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + p[x] = (fil[(src_x >> 20) * 3 + 2] << 16) | (fil[(src_x >> 20) * 3 + 1] << 8) | fil[(src_x >> 20) * 3]; + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + p[x] = (fil[x * 3 + 2] << 16) | (fil[x * 3 + 1] << 8) | fil[x * 3]; + } + } + + free(fil); + free(soak); + free(soak2); + free(samp1); + free(samp2); + free(samp3); + free(samp4); + } else /* filter disabled by emulator option */ + { + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + } + break; + + case VIDPROCCFG_FILTER_MODE_POINT: + default: + if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) { + p[x] = banshee->overlay_buffer[0][src_x >> 20]; + + src_x += voodoo->overlay.vidOverlayDudx; + } + } else { + for (x = 0; x < svga->overlay_latch.cur_xsize; x++) + p[x] = banshee->overlay_buffer[0][x]; + } + break; + } + } + + if (banshee->vidProcCfg & VIDPROCCFG_V_SCALE_ENABLE) + voodoo->overlay.src_y += voodoo->overlay.vidOverlayDvdy; + else + voodoo->overlay.src_y += (1 << 20); } -void banshee_set_overlay_addr(void *p, uint32_t addr) +void +banshee_set_overlay_addr(void *p, uint32_t addr) { - banshee_t *banshee = (banshee_t *)p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *) p; + voodoo_t *voodoo = banshee->voodoo; + + banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; + banshee->svga.overlay_latch.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); +} + +static void +banshee_vsync_callback(svga_t *svga) +{ + banshee_t *banshee = (banshee_t *) svga->p; + voodoo_t *voodoo = banshee->voodoo; + + voodoo->retrace_count++; + thread_wait_mutex(voodoo->swap_mutex); + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_release_mutex(voodoo->swap_mutex); - banshee->svga.overlay.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; - banshee->svga.overlay_latch.addr = banshee->voodoo->leftOverlayBuf & 0xfffffff; memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); + voodoo->retrace_count = 0; + banshee_set_overlay_addr(banshee, voodoo->swap_offset); + thread_set_event(voodoo->wake_fifo_thread); + voodoo->frame_count++; + } else + thread_release_mutex(voodoo->swap_mutex); + + voodoo->overlay.src_y = 0; + banshee->desktop_addr = banshee->vidDesktopStartAddr; + banshee->desktop_y = 0; } -static void banshee_vsync_callback(svga_t *svga) +static uint8_t +banshee_pci_read(int func, int addr, void *p) { - banshee_t *banshee = (banshee_t *)svga->p; - voodoo_t *voodoo = banshee->voodoo; + banshee_t *banshee = (banshee_t *) p; + // svga_t *svga = &banshee->svga; + uint8_t ret = 0; - voodoo->retrace_count++; - thread_wait_mutex(voodoo->swap_mutex); - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) - { - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_release_mutex(voodoo->swap_mutex); + if (func) + return 0xff; + // banshee_log("Banshee PCI read %08X ", addr); + switch (addr) { + case 0x00: + ret = 0x1a; + break; /*3DFX*/ + case 0x01: + ret = 0x12; + break; - memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); - voodoo->retrace_count = 0; - banshee_set_overlay_addr(banshee, voodoo->swap_offset); - thread_set_event(voodoo->wake_fifo_thread); - voodoo->frame_count++; - } - else - thread_release_mutex(voodoo->swap_mutex); + case 0x02: + ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : 0x05; + break; + case 0x03: + ret = 0x00; + break; - voodoo->overlay.src_y = 0; - banshee->desktop_addr = banshee->vidDesktopStartAddr; - banshee->desktop_y = 0; + case 0x04: + ret = banshee->pci_regs[0x04] & 0x27; + break; + + case 0x07: + ret = banshee->pci_regs[0x07] & 0x36; + break; + + case 0x08: + ret = (banshee->type == TYPE_BANSHEE) ? 3 : 1; + break; /*Revision ID*/ + case 0x09: + ret = 0; + break; /*Programming interface*/ + + case 0x0a: + ret = 0x00; + break; /*Supports VGA interface*/ + case 0x0b: + ret = 0x03; + break; + + case 0x0d: + ret = banshee->pci_regs[0x0d] & 0xf8; + break; + + case 0x10: + ret = 0x00; + break; /*memBaseAddr0*/ + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = 0x00; + break; + case 0x13: + ret = banshee->memBaseAddr0 >> 24; + break; + + case 0x14: + ret = 0x00; + break; /*memBaseAddr1*/ + case 0x15: + ret = 0x00; + break; + case 0x16: + ret = 0x00; + break; + case 0x17: + ret = banshee->memBaseAddr1 >> 24; + break; + + case 0x18: + ret = 0x01; + break; /*ioBaseAddr*/ + case 0x19: + ret = banshee->ioBaseAddr >> 8; + break; + case 0x1a: + ret = banshee->ioBaseAddr >> 16; + break; + case 0x1b: + ret = banshee->ioBaseAddr >> 24; + break; + + /*Subsystem vendor ID*/ + case 0x2c: + ret = banshee->pci_regs[0x2c]; + break; + case 0x2d: + ret = banshee->pci_regs[0x2d]; + break; + case 0x2e: + ret = banshee->pci_regs[0x2e]; + break; + case 0x2f: + ret = banshee->pci_regs[0x2f]; + break; + + case 0x30: + ret = banshee->pci_regs[0x30] & 0x01; + break; /*BIOS ROM address*/ + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = banshee->pci_regs[0x32]; + break; + case 0x33: + ret = banshee->pci_regs[0x33]; + break; + + case 0x34: + ret = banshee->agp ? 0x54 : 0x60; + break; + + case 0x3c: + ret = banshee->pci_regs[0x3c]; + break; + + case 0x3d: + ret = 0x01; + break; /*INTA*/ + + case 0x3e: + ret = 0x04; + break; + case 0x3f: + ret = 0xff; + break; + + case 0x40: + ret = 0x01; + break; + + case 0x50: + ret = banshee->pci_regs[0x50]; + break; + + case 0x54: + ret = 0x02; + break; + case 0x55: + ret = 0x60; + break; + case 0x56: + ret = 0x10; + break; /* assumed AGP 1.0 */ + + case 0x58: + ret = (banshee->type == TYPE_BANSHEE) ? 0x21 : 0x23; + break; + case 0x59: + ret = 0x02; + break; + case 0x5b: + ret = 0x07; + break; + + case 0x5c: + ret = banshee->pci_regs[0x5c]; + break; + case 0x5d: + ret = banshee->pci_regs[0x5d]; + break; + case 0x5e: + ret = banshee->pci_regs[0x5e]; + break; + case 0x5f: + ret = banshee->pci_regs[0x5f]; + break; + + case 0x60: + ret = 0x01; + break; + case 0x62: + ret = 0x21; + break; + + case 0x64: + ret = banshee->pci_regs[0x64]; + break; + case 0x65: + ret = banshee->pci_regs[0x65]; + break; + case 0x66: + ret = banshee->pci_regs[0x66]; + break; + case 0x67: + ret = banshee->pci_regs[0x67]; + break; + } + // banshee_log("%02X\n", ret); + return ret; } -static uint8_t banshee_pci_read(int func, int addr, void *p) +static void +banshee_pci_write(int func, int addr, uint8_t val, void *p) { - banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; - uint8_t ret = 0; + banshee_t *banshee = (banshee_t *) p; + // svga_t *svga = &banshee->svga; - if (func) - return 0xff; -// banshee_log("Banshee PCI read %08X ", addr); - switch (addr) - { - case 0x00: ret = 0x1a; break; /*3DFX*/ - case 0x01: ret = 0x12; break; + if (func) + return; + // banshee_log("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + switch (addr) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x3d: + case 0x3e: + case 0x3f: + return; - case 0x02: ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : 0x05; break; - case 0x03: ret = 0x00; break; + case PCI_REG_COMMAND: + if (val & PCI_COMMAND_IO) { + io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + if (banshee->ioBaseAddr) + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - case 0x04: ret = banshee->pci_regs[0x04] & 0x27; break; + io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + if (banshee->ioBaseAddr) + io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + } else { + io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + } + banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27; + banshee_updatemapping(banshee); + return; + case 0x07: + banshee->pci_regs[0x07] = val & 0x3e; + return; + case 0x0d: + banshee->pci_regs[0x0d] = val & 0xf8; + return; - case 0x07: ret = banshee->pci_regs[0x07] & 0x36; break; + case 0x13: + banshee->memBaseAddr0 = (val & 0xfe) << 24; + banshee_updatemapping(banshee); + return; - case 0x08: ret = (banshee->type == TYPE_BANSHEE) ? 3 : 1; break; /*Revision ID*/ - case 0x09: ret = 0; break; /*Programming interface*/ + case 0x17: + banshee->memBaseAddr1 = (val & 0xfe) << 24; + banshee_updatemapping(banshee); + return; - case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ - case 0x0b: ret = 0x03; break; + case 0x19: + if (banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + banshee->ioBaseAddr &= 0xffff00ff; + banshee->ioBaseAddr |= val << 8; + if ((banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && banshee->ioBaseAddr) + io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + banshee_log("Banshee ioBaseAddr=%08x\n", banshee->ioBaseAddr); + return; - case 0x0d: ret = banshee->pci_regs[0x0d] & 0xf8; break; + case 0x1a: + banshee->ioBaseAddr &= 0xff00ffff; + banshee->ioBaseAddr |= val << 16; + break; - case 0x10: ret = 0x00; break; /*memBaseAddr0*/ - case 0x11: ret = 0x00; break; - case 0x12: ret = 0x00; break; - case 0x13: ret = banshee->memBaseAddr0 >> 24; break; + case 0x1b: + banshee->ioBaseAddr &= 0x00ffffff; + banshee->ioBaseAddr |= val << 24; + break; - case 0x14: ret = 0x00; break; /*memBaseAddr1*/ - case 0x15: ret = 0x00; break; - case 0x16: ret = 0x00; break; - case 0x17: ret = banshee->memBaseAddr1 >> 24; break; - - case 0x18: ret = 0x01; break; /*ioBaseAddr*/ - case 0x19: ret = banshee->ioBaseAddr >> 8; break; - case 0x1a: ret = banshee->ioBaseAddr >> 16; break; - case 0x1b: ret = banshee->ioBaseAddr >> 24; break; - - /*Subsystem vendor ID*/ - case 0x2c: ret = banshee->pci_regs[0x2c]; break; - case 0x2d: ret = banshee->pci_regs[0x2d]; break; - case 0x2e: ret = banshee->pci_regs[0x2e]; break; - case 0x2f: ret = banshee->pci_regs[0x2f]; break; - - case 0x30: ret = banshee->pci_regs[0x30] & 0x01; break; /*BIOS ROM address*/ - case 0x31: ret = 0x00; break; - case 0x32: ret = banshee->pci_regs[0x32]; break; - case 0x33: ret = banshee->pci_regs[0x33]; break; - - case 0x34: ret = banshee->agp ? 0x54 : 0x60; break; - - case 0x3c: ret = banshee->pci_regs[0x3c]; break; - - case 0x3d: ret = 0x01; break; /*INTA*/ - - case 0x3e: ret = 0x04; break; - case 0x3f: ret = 0xff; break; - - case 0x40: ret = 0x01; break; - - case 0x50: ret = banshee->pci_regs[0x50]; break; - - case 0x54: ret = 0x02; break; - case 0x55: ret = 0x60; break; - case 0x56: ret = 0x10; break; /* assumed AGP 1.0 */ - - case 0x58: ret = (banshee->type == TYPE_BANSHEE) ? 0x21 : 0x23; break; - case 0x59: ret = 0x02; break; - case 0x5b: ret = 0x07; break; - - case 0x5c: ret = banshee->pci_regs[0x5c]; break; - case 0x5d: ret = banshee->pci_regs[0x5d]; break; - case 0x5e: ret = banshee->pci_regs[0x5e]; break; - case 0x5f: ret = banshee->pci_regs[0x5f]; break; - - case 0x60: ret = 0x01; break; - case 0x62: ret = 0x21; break; - - case 0x64: ret = banshee->pci_regs[0x64]; break; - case 0x65: ret = banshee->pci_regs[0x65]; break; - case 0x66: ret = banshee->pci_regs[0x66]; break; - case 0x67: ret = banshee->pci_regs[0x67]; break; - } -// banshee_log("%02X\n", ret); - return ret; -} - -static void banshee_pci_write(int func, int addr, uint8_t val, void *p) -{ - banshee_t *banshee = (banshee_t *)p; -// svga_t *svga = &banshee->svga; - - if (func) - return; -// banshee_log("Banshee write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x3d: case 0x3e: case 0x3f: + case 0x30: + case 0x32: + case 0x33: + if (!banshee->has_bios) return; + banshee->pci_regs[addr] = val; + if (banshee->pci_regs[0x30] & 0x01) { + uint32_t biosaddr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24); + banshee_log("Banshee bios_rom enabled at %08x\n", biosaddr); + mem_mapping_set_addr(&banshee->bios_rom.mapping, biosaddr, 0x10000); + mem_mapping_enable(&banshee->bios_rom.mapping); + } else { + banshee_log("Banshee bios_rom disabled\n"); + mem_mapping_disable(&banshee->bios_rom.mapping); + } + return; + case 0x3c: + case 0x50: + case 0x65: + case 0x67: + banshee->pci_regs[addr] = val; + return; - case PCI_REG_COMMAND: - if (val & PCI_COMMAND_IO) - { - io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - if (banshee->ioBaseAddr) - io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); + case 0x5c: + banshee->pci_regs[0x5c] = val & 0x27; + return; - io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - if (banshee->ioBaseAddr) - io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - } - else - { - io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - } - banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27; - banshee_updatemapping(banshee); - return; - case 0x07: - banshee->pci_regs[0x07] = val & 0x3e; - return; - case 0x0d: - banshee->pci_regs[0x0d] = val & 0xf8; - return; + case 0x5d: + banshee->pci_regs[0x5d] = val & 0x03; + return; - case 0x13: - banshee->memBaseAddr0 = (val & 0xfe) << 24; - banshee_updatemapping(banshee); - return; + case 0x5f: + banshee->pci_regs[0x5e] = val; + return; - case 0x17: - banshee->memBaseAddr1 = (val & 0xfe) << 24; - banshee_updatemapping(banshee); - return; + case 0x64: + banshee->pci_regs[0x64] = val & 0x03; + return; - case 0x19: - if (banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) - io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - banshee->ioBaseAddr &= 0xffff00ff; - banshee->ioBaseAddr |= val << 8; - if ((banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && banshee->ioBaseAddr) - io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee); - banshee_log("Banshee ioBaseAddr=%08x\n", banshee->ioBaseAddr); - return; - - case 0x1a: - banshee->ioBaseAddr &= 0xff00ffff; - banshee->ioBaseAddr |= val << 16; - break; - - case 0x1b: - banshee->ioBaseAddr &= 0x00ffffff; - banshee->ioBaseAddr |= val << 24; - break; - - case 0x30: case 0x32: case 0x33: - if (!banshee->has_bios) - return; - banshee->pci_regs[addr] = val; - if (banshee->pci_regs[0x30] & 0x01) - { - uint32_t biosaddr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24); - banshee_log("Banshee bios_rom enabled at %08x\n", biosaddr); - mem_mapping_set_addr(&banshee->bios_rom.mapping, biosaddr, 0x10000); - mem_mapping_enable(&banshee->bios_rom.mapping); - } - else - { - banshee_log("Banshee bios_rom disabled\n"); - mem_mapping_disable(&banshee->bios_rom.mapping); - } - return; - case 0x3c: case 0x50: case 0x65: case 0x67: - banshee->pci_regs[addr] = val; - return; - - case 0x5c: - banshee->pci_regs[0x5c] = val & 0x27; - return; - - case 0x5d: - banshee->pci_regs[0x5d] = val & 0x03; - return; - - case 0x5f: - banshee->pci_regs[0x5e] = val; - return; - - case 0x64: - banshee->pci_regs[0x64] = val & 0x03; - return; - - case 0x66: - banshee->pci_regs[0x66] = val & 0xc0; - return; - } + case 0x66: + banshee->pci_regs[0x66] = val & 0xc0; + return; + } } // clang-format off @@ -2732,335 +2838,351 @@ static const device_config_t banshee_sdram_config[] = { }; // clang-format on -static void *banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int voodoo_type, int agp) +static void * +banshee_init_common(const device_t *info, char *fn, int has_sgram, int type, int voodoo_type, int agp) { - int mem_size; - banshee_t *banshee = malloc(sizeof(banshee_t)); - memset(banshee, 0, sizeof(banshee_t)); + int mem_size; + banshee_t *banshee = malloc(sizeof(banshee_t)); + memset(banshee, 0, sizeof(banshee_t)); - banshee->type = type; - banshee->agp = agp; - banshee->has_bios = !!fn; + banshee->type = type; + banshee->agp = agp; + banshee->has_bios = !!fn; - if (banshee->has_bios) { - rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - mem_mapping_disable(&banshee->bios_rom.mapping); - } + if (banshee->has_bios) { + rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&banshee->bios_rom.mapping); + } - if (!banshee->has_bios) - mem_size = info->local; /* fixed size for on-board chips */ - else if (has_sgram) { - if (banshee->type == TYPE_VELOCITY100) - mem_size = 8; /* Velocity 100 only supports 8 MB */ - else - mem_size = device_get_config_int("memory"); - } else - mem_size = 16; /* SDRAM Banshee only supports 16 MB */ + if (!banshee->has_bios) + mem_size = info->local; /* fixed size for on-board chips */ + else if (has_sgram) { + if (banshee->type == TYPE_VELOCITY100) + mem_size = 8; /* Velocity 100 only supports 8 MB */ + else + mem_size = device_get_config_int("memory"); + } else + mem_size = 16; /* SDRAM Banshee only supports 16 MB */ - svga_init(info, &banshee->svga, banshee, mem_size << 20, - banshee_recalctimings, - banshee_in, banshee_out, - banshee_hwcursor_draw, - banshee_overlay_draw); - banshee->svga.vsync_callback = banshee_vsync_callback; + svga_init(info, &banshee->svga, banshee, mem_size << 20, + banshee_recalctimings, + banshee_in, banshee_out, + banshee_hwcursor_draw, + banshee_overlay_draw); + banshee->svga.vsync_callback = banshee_vsync_callback; - mem_mapping_add(&banshee->linear_mapping, 0, 0, banshee_read_linear, - banshee_read_linear_w, - banshee_read_linear_l, - banshee_write_linear, - banshee_write_linear_w, - banshee_write_linear_l, - NULL, - MEM_MAPPING_EXTERNAL, - &banshee->svga); - mem_mapping_add(&banshee->reg_mapping_low, 0, 0,banshee_reg_read, - banshee_reg_readw, - banshee_reg_readl, - banshee_reg_write, - banshee_reg_writew, - banshee_reg_writel, - NULL, - MEM_MAPPING_EXTERNAL, - banshee); - mem_mapping_add(&banshee->reg_mapping_high, 0,0,banshee_reg_read, - banshee_reg_readw, - banshee_reg_readl, - banshee_reg_write, - banshee_reg_writew, - banshee_reg_writel, - NULL, - MEM_MAPPING_EXTERNAL, - banshee); + mem_mapping_add(&banshee->linear_mapping, 0, 0, banshee_read_linear, + banshee_read_linear_w, + banshee_read_linear_l, + banshee_write_linear, + banshee_write_linear_w, + banshee_write_linear_l, + NULL, + MEM_MAPPING_EXTERNAL, + &banshee->svga); + mem_mapping_add(&banshee->reg_mapping_low, 0, 0, banshee_reg_read, + banshee_reg_readw, + banshee_reg_readl, + banshee_reg_write, + banshee_reg_writew, + banshee_reg_writel, + NULL, + MEM_MAPPING_EXTERNAL, + banshee); + mem_mapping_add(&banshee->reg_mapping_high, 0, 0, banshee_reg_read, + banshee_reg_readw, + banshee_reg_readl, + banshee_reg_write, + banshee_reg_writew, + banshee_reg_writel, + NULL, + MEM_MAPPING_EXTERNAL, + banshee); - banshee->svga.vblank_start = banshee_vblank_start; + banshee->svga.vblank_start = banshee_vblank_start; -// io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); + // io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee); - banshee->svga.bpp = 8; - banshee->svga.miscout = 1; + banshee->svga.bpp = 8; + banshee->svga.miscout = 1; - banshee->dramInit0 = 1 << 27; - if (has_sgram && mem_size == 16) - banshee->dramInit0 |= (1 << 26); /*2xSGRAM = 16 MB*/ - if (!has_sgram) - banshee->dramInit1 = 1 << 30; /*SDRAM*/ - banshee->svga.decode_mask = 0x1ffffff; + banshee->dramInit0 = 1 << 27; + if (has_sgram && mem_size == 16) + banshee->dramInit0 |= (1 << 26); /*2xSGRAM = 16 MB*/ + if (!has_sgram) + banshee->dramInit1 = 1 << 30; /*SDRAM*/ + banshee->svga.decode_mask = 0x1ffffff; - banshee->card = pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee); + banshee->card = pci_add_card(banshee->agp ? PCI_ADD_AGP : PCI_ADD_VIDEO, banshee_pci_read, banshee_pci_write, banshee); - banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); - banshee->voodoo->p = banshee; - banshee->voodoo->vram = banshee->svga.vram; - banshee->voodoo->changedvram = banshee->svga.changedvram; - banshee->voodoo->fb_mem = banshee->svga.vram; - banshee->voodoo->fb_mask = banshee->svga.vram_mask; - banshee->voodoo->tex_mem[0] = banshee->svga.vram; - banshee->voodoo->tex_mem_w[0] = (uint16_t *)banshee->svga.vram; - banshee->voodoo->tex_mem[1] = banshee->svga.vram; - banshee->voodoo->tex_mem_w[1] = (uint16_t *)banshee->svga.vram; - banshee->voodoo->texture_mask = banshee->svga.vram_mask; - voodoo_generate_filter_v1(banshee->voodoo); + banshee->voodoo = voodoo_2d3d_card_init(voodoo_type); + banshee->voodoo->p = banshee; + banshee->voodoo->vram = banshee->svga.vram; + banshee->voodoo->changedvram = banshee->svga.changedvram; + banshee->voodoo->fb_mem = banshee->svga.vram; + banshee->voodoo->fb_mask = banshee->svga.vram_mask; + banshee->voodoo->tex_mem[0] = banshee->svga.vram; + banshee->voodoo->tex_mem_w[0] = (uint16_t *) banshee->svga.vram; + banshee->voodoo->tex_mem[1] = banshee->svga.vram; + banshee->voodoo->tex_mem_w[1] = (uint16_t *) banshee->svga.vram; + banshee->voodoo->texture_mask = banshee->svga.vram_mask; + voodoo_generate_filter_v1(banshee->voodoo); - banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W; + banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W; - banshee->i2c = i2c_gpio_init("i2c_voodoo_banshee"); - banshee->i2c_ddc = i2c_gpio_init("ddc_voodoo_banshee"); - banshee->ddc = ddc_init(i2c_gpio_get_bus(banshee->i2c_ddc)); + banshee->i2c = i2c_gpio_init("i2c_voodoo_banshee"); + banshee->i2c_ddc = i2c_gpio_init("ddc_voodoo_banshee"); + banshee->ddc = ddc_init(i2c_gpio_get_bus(banshee->i2c_ddc)); - switch (type) - { - case TYPE_BANSHEE: - if (has_sgram) { - banshee->pci_regs[0x2c] = 0x1a; - banshee->pci_regs[0x2d] = 0x12; - banshee->pci_regs[0x2e] = 0x04; - banshee->pci_regs[0x2f] = 0x00; - } else { - banshee->pci_regs[0x2c] = 0x02; - banshee->pci_regs[0x2d] = 0x11; - banshee->pci_regs[0x2e] = 0x17; - banshee->pci_regs[0x2f] = 0x10; - } - break; + switch (type) { + case TYPE_BANSHEE: + if (has_sgram) { + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x04; + banshee->pci_regs[0x2f] = 0x00; + } else { + banshee->pci_regs[0x2c] = 0x02; + banshee->pci_regs[0x2d] = 0x11; + banshee->pci_regs[0x2e] = 0x17; + banshee->pci_regs[0x2f] = 0x10; + } + break; - case TYPE_V3_2000: - banshee->pci_regs[0x2c] = 0x1a; - banshee->pci_regs[0x2d] = 0x12; - banshee->pci_regs[0x2e] = 0x30; - banshee->pci_regs[0x2f] = 0x00; - break; + case TYPE_V3_2000: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x30; + banshee->pci_regs[0x2f] = 0x00; + break; - case TYPE_V3_3000: - banshee->pci_regs[0x2c] = 0x1a; - banshee->pci_regs[0x2d] = 0x12; - banshee->pci_regs[0x2e] = 0x3a; - banshee->pci_regs[0x2f] = 0x00; - break; + case TYPE_V3_3000: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x3a; + banshee->pci_regs[0x2f] = 0x00; + break; - case TYPE_VELOCITY100: - banshee->pci_regs[0x2c] = 0x1a; - banshee->pci_regs[0x2d] = 0x12; - banshee->pci_regs[0x2e] = 0x4b; - banshee->pci_regs[0x2f] = 0x00; - break; - } + case TYPE_VELOCITY100: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x4b; + banshee->pci_regs[0x2f] = 0x00; + break; + } - video_inform(VIDEO_FLAG_TYPE_SPECIAL, banshee->agp ? &timing_banshee_agp : &timing_banshee); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, banshee->agp ? &timing_banshee_agp : &timing_banshee); - return banshee; + return banshee; } -static void *banshee_init(const device_t *info) +static void * +banshee_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/Pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE, 0); + return banshee_init_common(info, "roms/video/voodoo/Pci_sg.rom", 1, TYPE_BANSHEE, VOODOO_BANSHEE, 0); } -static void *creative_banshee_init(const device_t *info) +static void * +creative_banshee_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/BlasterPCI.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE, 0); + return banshee_init_common(info, "roms/video/voodoo/BlasterPCI.rom", 0, TYPE_BANSHEE, VOODOO_BANSHEE, 0); } -static void *v3_2000_init(const device_t *info) +static void * +v3_2000_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 0); + return banshee_init_common(info, "roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 0); } -static void *v3_2000_agp_init(const device_t *info) +static void * +v3_2000_agp_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 1); + return banshee_init_common(info, "roms/video/voodoo/2k11sd.rom", 0, TYPE_V3_2000, VOODOO_3, 1); } -static void *v3_2000_agp_onboard_init(const device_t *info) +static void * +v3_2000_agp_onboard_init(const device_t *info) { - return banshee_init_common(info, NULL, 0, TYPE_V3_2000, VOODOO_3, 1); + return banshee_init_common(info, NULL, 0, TYPE_V3_2000, VOODOO_3, 1); } -static void *v3_3000_init(const device_t *info) +static void * +v3_3000_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 0); + return banshee_init_common(info, "roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 0); } -static void *v3_3000_agp_init(const device_t *info) +static void * +v3_3000_agp_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 1); + return banshee_init_common(info, "roms/video/voodoo/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3, 1); } -static void *velocity_100_agp_init(const device_t *info) +static void * +velocity_100_agp_init(const device_t *info) { - return banshee_init_common(info, "roms/video/voodoo/Velocity100.VBI", 1, TYPE_VELOCITY100, VOODOO_3, 1); + return banshee_init_common(info, "roms/video/voodoo/Velocity100.VBI", 1, TYPE_VELOCITY100, VOODOO_3, 1); } -static int banshee_available(void) +static int +banshee_available(void) { - return rom_present("roms/video/voodoo/Pci_sg.rom"); + return rom_present("roms/video/voodoo/Pci_sg.rom"); } -static int creative_banshee_available(void) +static int +creative_banshee_available(void) { - return rom_present("roms/video/voodoo/BlasterPCI.rom"); + return rom_present("roms/video/voodoo/BlasterPCI.rom"); } -static int v3_2000_available(void) +static int +v3_2000_available(void) { - return rom_present("roms/video/voodoo/2k11sd.rom"); + return rom_present("roms/video/voodoo/2k11sd.rom"); } #define v3_2000_agp_available v3_2000_available -static int v3_3000_available(void) +static int +v3_3000_available(void) { - return rom_present("roms/video/voodoo/3k12sd.rom"); + return rom_present("roms/video/voodoo/3k12sd.rom"); } #define v3_3000_agp_available v3_3000_available -static int velocity_100_available(void) +static int +velocity_100_available(void) { - return rom_present("roms/video/voodoo/Velocity100.VBI"); + return rom_present("roms/video/voodoo/Velocity100.VBI"); } -static void banshee_close(void *p) +static void +banshee_close(void *p) { - banshee_t *banshee = (banshee_t *)p; + banshee_t *banshee = (banshee_t *) p; - voodoo_card_close(banshee->voodoo); - svga_close(&banshee->svga); - ddc_close(banshee->ddc); - i2c_gpio_close(banshee->i2c_ddc); - i2c_gpio_close(banshee->i2c); + voodoo_card_close(banshee->voodoo); + svga_close(&banshee->svga); + ddc_close(banshee->ddc); + i2c_gpio_close(banshee->i2c_ddc); + i2c_gpio_close(banshee->i2c); - free(banshee); + free(banshee); } -static void banshee_speed_changed(void *p) +static void +banshee_speed_changed(void *p) { - banshee_t *banshee = (banshee_t *)p; + banshee_t *banshee = (banshee_t *) p; - svga_recalctimings(&banshee->svga); + svga_recalctimings(&banshee->svga); } -static void banshee_force_redraw(void *p) +static void +banshee_force_redraw(void *p) { - banshee_t *banshee = (banshee_t *)p; + banshee_t *banshee = (banshee_t *) p; - banshee->svga.fullchange = changeframecount; + banshee->svga.fullchange = changeframecount; } const device_t voodoo_banshee_device = { - .name = "3dfx Voodoo Banshee", + .name = "3dfx Voodoo Banshee", .internal_name = "voodoo_banshee_pci", - .flags = DEVICE_PCI, - .local = 0, - .init = banshee_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = banshee_init, + .close = banshee_close, + .reset = NULL, { .available = banshee_available }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sgram_config }; const device_t creative_voodoo_banshee_device = { - .name = "Creative 3D Blaster Banshee", + .name = "Creative 3D Blaster Banshee", .internal_name = "ctl3d_banshee_pci", - .flags = DEVICE_PCI, - .local = 0, - .init = creative_banshee_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = creative_banshee_init, + .close = banshee_close, + .reset = NULL, { .available = creative_banshee_available }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sdram_config }; const device_t voodoo_3_2000_device = { - .name = "3dfx Voodoo3 2000", + .name = "3dfx Voodoo3 2000", .internal_name = "voodoo3_2k_pci", - .flags = DEVICE_PCI, - .local = 0, - .init = v3_2000_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = v3_2000_init, + .close = banshee_close, + .reset = NULL, { .available = v3_2000_available }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sdram_config }; const device_t voodoo_3_2000_agp_device = { - .name = "3dfx Voodoo3 2000", + .name = "3dfx Voodoo3 2000", .internal_name = "voodoo3_2k_agp", - .flags = DEVICE_AGP, - .local = 0, - .init = v3_2000_agp_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_AGP, + .local = 0, + .init = v3_2000_agp_init, + .close = banshee_close, + .reset = NULL, { .available = v3_2000_agp_available }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sdram_config }; const device_t voodoo_3_2000_agp_onboard_8m_device = { - .name = "3dfx Voodoo3 2000 (On-Board 8MB SGRAM)", + .name = "3dfx Voodoo3 2000 (On-Board 8MB SGRAM)", .internal_name = "voodoo3_2k_agp_onboard_8m", - .flags = DEVICE_AGP, - .local = 8, - .init = v3_2000_agp_onboard_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_AGP, + .local = 8, + .init = v3_2000_agp_onboard_init, + .close = banshee_close, + .reset = NULL, { .available = NULL }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sdram_config }; const device_t voodoo_3_3000_device = { - .name = "3dfx Voodoo3 3000", + .name = "3dfx Voodoo3 3000", .internal_name = "voodoo3_3k_pci", - .flags = DEVICE_PCI, - .local = 0, - .init = v3_3000_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_PCI, + .local = 0, + .init = v3_3000_init, + .close = banshee_close, + .reset = NULL, { .available = v3_3000_available }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sdram_config }; const device_t voodoo_3_3000_agp_device = { - .name = "3dfx Voodoo3 3000", + .name = "3dfx Voodoo3 3000", .internal_name = "voodoo3_3k_agp", - .flags = DEVICE_AGP, - .local = 0, - .init = v3_3000_agp_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_AGP, + .local = 0, + .init = v3_3000_agp_init, + .close = banshee_close, + .reset = NULL, { .available = v3_3000_agp_available }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sdram_config }; const device_t velocity_100_agp_device = { - .name = "3dfx Velocity 100", + .name = "3dfx Velocity 100", .internal_name = "velocity100_agp", - .flags = DEVICE_AGP, - .local = 0, - .init = velocity_100_agp_init, - .close = banshee_close, - .reset = NULL, + .flags = DEVICE_AGP, + .local = 0, + .init = velocity_100_agp_init, + .close = banshee_close, + .reset = NULL, { .available = velocity_100_available }, .speed_changed = banshee_speed_changed, - .force_redraw = banshee_force_redraw, + .force_redraw = banshee_force_redraw, banshee_sdram_config }; diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index 4062acb3a..548ec0f6e 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -41,56 +41,55 @@ #define COMMAND_CMD_LINE (6 << 0) #define COMMAND_CMD_POLYLINE (7 << 0) #define COMMAND_CMD_POLYFILL (8 << 0) -#define COMMAND_INITIATE (1 << 8) -#define COMMAND_INC_X_START (1 << 10) -#define COMMAND_INC_Y_START (1 << 11) -#define COMMAND_STIPPLE_LINE (1 << 12) -#define COMMAND_PATTERN_MONO (1 << 13) -#define COMMAND_DX (1 << 14) -#define COMMAND_DY (1 << 15) -#define COMMAND_TRANS_MONO (1 << 16) -#define COMMAND_PATOFF_X_MASK (7 << 17) -#define COMMAND_PATOFF_X_SHIFT (17) -#define COMMAND_PATOFF_Y_MASK (7 << 20) -#define COMMAND_PATOFF_Y_SHIFT (20) -#define COMMAND_CLIP_SEL (1 << 23) +#define COMMAND_INITIATE (1 << 8) +#define COMMAND_INC_X_START (1 << 10) +#define COMMAND_INC_Y_START (1 << 11) +#define COMMAND_STIPPLE_LINE (1 << 12) +#define COMMAND_PATTERN_MONO (1 << 13) +#define COMMAND_DX (1 << 14) +#define COMMAND_DY (1 << 15) +#define COMMAND_TRANS_MONO (1 << 16) +#define COMMAND_PATOFF_X_MASK (7 << 17) +#define COMMAND_PATOFF_X_SHIFT (17) +#define COMMAND_PATOFF_Y_MASK (7 << 20) +#define COMMAND_PATOFF_Y_SHIFT (20) +#define COMMAND_CLIP_SEL (1 << 23) -#define CMDEXTRA_SRC_COLORKEY (1 << 0) -#define CMDEXTRA_DST_COLORKEY (1 << 1) -#define CMDEXTRA_FORCE_PAT_ROW0 (1 << 3) +#define CMDEXTRA_SRC_COLORKEY (1 << 0) +#define CMDEXTRA_DST_COLORKEY (1 << 1) +#define CMDEXTRA_FORCE_PAT_ROW0 (1 << 3) -#define SRC_FORMAT_STRIDE_MASK (0x1fff) -#define SRC_FORMAT_COL_MASK (0xf << 16) -#define SRC_FORMAT_COL_1_BPP (0 << 16) -#define SRC_FORMAT_COL_8_BPP (1 << 16) -#define SRC_FORMAT_COL_16_BPP (3 << 16) -#define SRC_FORMAT_COL_24_BPP (4 << 16) -#define SRC_FORMAT_COL_32_BPP (5 << 16) -#define SRC_FORMAT_COL_YUYV (8 << 16) -#define SRC_FORMAT_COL_UYVY (9 << 16) -#define SRC_FORMAT_BYTE_SWIZZLE (1 << 20) -#define SRC_FORMAT_WORD_SWIZZLE (1 << 21) -#define SRC_FORMAT_PACKING_MASK (3 << 22) -#define SRC_FORMAT_PACKING_STRIDE (0 << 22) -#define SRC_FORMAT_PACKING_BYTE (1 << 22) -#define SRC_FORMAT_PACKING_WORD (2 << 22) -#define SRC_FORMAT_PACKING_DWORD (3 << 22) +#define SRC_FORMAT_STRIDE_MASK (0x1fff) +#define SRC_FORMAT_COL_MASK (0xf << 16) +#define SRC_FORMAT_COL_1_BPP (0 << 16) +#define SRC_FORMAT_COL_8_BPP (1 << 16) +#define SRC_FORMAT_COL_16_BPP (3 << 16) +#define SRC_FORMAT_COL_24_BPP (4 << 16) +#define SRC_FORMAT_COL_32_BPP (5 << 16) +#define SRC_FORMAT_COL_YUYV (8 << 16) +#define SRC_FORMAT_COL_UYVY (9 << 16) +#define SRC_FORMAT_BYTE_SWIZZLE (1 << 20) +#define SRC_FORMAT_WORD_SWIZZLE (1 << 21) +#define SRC_FORMAT_PACKING_MASK (3 << 22) +#define SRC_FORMAT_PACKING_STRIDE (0 << 22) +#define SRC_FORMAT_PACKING_BYTE (1 << 22) +#define SRC_FORMAT_PACKING_WORD (2 << 22) +#define SRC_FORMAT_PACKING_DWORD (3 << 22) -#define DST_FORMAT_STRIDE_MASK (0x1fff) -#define DST_FORMAT_COL_MASK (0xf << 16) -#define DST_FORMAT_COL_8_BPP (1 << 16) -#define DST_FORMAT_COL_16_BPP (3 << 16) -#define DST_FORMAT_COL_24_BPP (4 << 16) -#define DST_FORMAT_COL_32_BPP (5 << 16) +#define DST_FORMAT_STRIDE_MASK (0x1fff) +#define DST_FORMAT_COL_MASK (0xf << 16) +#define DST_FORMAT_COL_8_BPP (1 << 16) +#define DST_FORMAT_COL_16_BPP (3 << 16) +#define DST_FORMAT_COL_24_BPP (4 << 16) +#define DST_FORMAT_COL_32_BPP (5 << 16) -#define BRES_ERROR_MASK (0xffff) -#define BRES_ERROR_USE (1 << 31) +#define BRES_ERROR_MASK (0xffff) +#define BRES_ERROR_USE (1 << 31) -enum -{ - COLORKEY_8, - COLORKEY_16, - COLORKEY_32 +enum { + COLORKEY_8, + COLORKEY_16, + COLORKEY_32 }; #ifdef ENABLE_BANSHEEBLT_LOG @@ -102,1371 +101,1345 @@ bansheeblt_log(const char *fmt, ...) va_list ap; if (bansheeblt_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define banshee_log(fmt, ...) +# define banshee_log(fmt, ...) #endif -static int colorkey(voodoo_t *voodoo, uint32_t src, int src_notdst, int color_format) +static int +colorkey(voodoo_t *voodoo, uint32_t src, int src_notdst, int color_format) { - uint32_t min = src_notdst ? voodoo->banshee_blt.srcColorkeyMin : voodoo->banshee_blt.dstColorkeyMin; - uint32_t max = src_notdst ? voodoo->banshee_blt.srcColorkeyMax : voodoo->banshee_blt.dstColorkeyMax; + uint32_t min = src_notdst ? voodoo->banshee_blt.srcColorkeyMin : voodoo->banshee_blt.dstColorkeyMin; + uint32_t max = src_notdst ? voodoo->banshee_blt.srcColorkeyMax : voodoo->banshee_blt.dstColorkeyMax; - if (!(voodoo->banshee_blt.commandExtra & (src_notdst ? CMDEXTRA_SRC_COLORKEY : CMDEXTRA_DST_COLORKEY))) - return 0; + if (!(voodoo->banshee_blt.commandExtra & (src_notdst ? CMDEXTRA_SRC_COLORKEY : CMDEXTRA_DST_COLORKEY))) + return 0; - switch (color_format) - { - case COLORKEY_8: - return ((src & 0xff) >= (min & 0xff)) && ((src & 0xff) <= (max & 0xff)); + switch (color_format) { + case COLORKEY_8: + return ((src & 0xff) >= (min & 0xff)) && ((src & 0xff) <= (max & 0xff)); - case COLORKEY_16: - { - int r = (src >> 11) & 0x1f, r_min = (min >> 11) & 0x1f, r_max = (max >> 11) & 0x1f; - int g = (src >> 5) & 0x3f, g_min = (min >> 5) & 0x3f, g_max = (max >> 5) & 0x3f; - int b = src & 0x1f, b_min = min & 0x1f, b_max = max & 0x1f; + case COLORKEY_16: + { + int r = (src >> 11) & 0x1f, r_min = (min >> 11) & 0x1f, r_max = (max >> 11) & 0x1f; + int g = (src >> 5) & 0x3f, g_min = (min >> 5) & 0x3f, g_max = (max >> 5) & 0x3f; + int b = src & 0x1f, b_min = min & 0x1f, b_max = max & 0x1f; - return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && - (b >= b_min) && (b <= b_max); - } + return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && (b >= b_min) && (b <= b_max); + } - case COLORKEY_32: - { - int r = (src >> 16) & 0xff, r_min = (min >> 16) & 0xff, r_max = (max >> 16) & 0xff; - int g = (src >> 8) & 0xff, g_min = (min >> 8) & 0xff, g_max = (max >> 8) & 0xff; - int b = src & 0xff, b_min = min & 0xff, b_max = max & 0xff; + case COLORKEY_32: + { + int r = (src >> 16) & 0xff, r_min = (min >> 16) & 0xff, r_max = (max >> 16) & 0xff; + int g = (src >> 8) & 0xff, g_min = (min >> 8) & 0xff, g_max = (max >> 8) & 0xff; + int b = src & 0xff, b_min = min & 0xff, b_max = max & 0xff; - return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && - (b >= b_min) && (b <= b_max); - } + return (r >= r_min) && (r <= r_max) && (g >= g_min) && (g <= g_max) && (b >= b_min) && (b <= b_max); + } - default: - return 0; - } + default: + return 0; + } } -static uint32_t MIX(voodoo_t *voodoo, uint32_t dest, uint32_t src, uint32_t pattern, int colour_format_src, int colour_format_dest) +static uint32_t +MIX(voodoo_t *voodoo, uint32_t dest, uint32_t src, uint32_t pattern, int colour_format_src, int colour_format_dest) { - int rop_nr = 0; - uint32_t result = 0; - uint32_t rop; + int rop_nr = 0; + uint32_t result = 0; + uint32_t rop; - if (colorkey(voodoo, src, 1, colour_format_src)) - rop_nr |= 2; - if (colorkey(voodoo, dest, 0, colour_format_dest)) - rop_nr |= 1; + if (colorkey(voodoo, src, 1, colour_format_src)) + rop_nr |= 2; + if (colorkey(voodoo, dest, 0, colour_format_dest)) + rop_nr |= 1; - rop = voodoo->banshee_blt.rops[rop_nr]; + rop = voodoo->banshee_blt.rops[rop_nr]; - if (rop & 0x01) - result |= (~pattern & ~src & ~dest); - if (rop & 0x02) - result |= (~pattern & ~src & dest); - if (rop & 0x04) - result |= (~pattern & src & ~dest); - if (rop & 0x08) - result |= (~pattern & src & dest); - if (rop & 0x10) - result |= ( pattern & ~src & ~dest); - if (rop & 0x20) - result |= ( pattern & ~src & dest); - if (rop & 0x40) - result |= ( pattern & src & ~dest); - if (rop & 0x80) - result |= ( pattern & src & dest); + if (rop & 0x01) + result |= (~pattern & ~src & ~dest); + if (rop & 0x02) + result |= (~pattern & ~src & dest); + if (rop & 0x04) + result |= (~pattern & src & ~dest); + if (rop & 0x08) + result |= (~pattern & src & dest); + if (rop & 0x10) + result |= (pattern & ~src & ~dest); + if (rop & 0x20) + result |= (pattern & ~src & dest); + if (rop & 0x40) + result |= (pattern & src & ~dest); + if (rop & 0x80) + result |= (pattern & src & dest); - return result; + return result; } -static uint32_t get_addr(voodoo_t *voodoo, int x, int y, int src_notdst, uint32_t src_stride) +static uint32_t +get_addr(voodoo_t *voodoo, int x, int y, int src_notdst, uint32_t src_stride) { - uint32_t stride = src_notdst ? src_stride : voodoo->banshee_blt.dst_stride; - uint32_t base_addr = src_notdst ? voodoo->banshee_blt.srcBaseAddr : voodoo->banshee_blt.dstBaseAddr; + uint32_t stride = src_notdst ? src_stride : voodoo->banshee_blt.dst_stride; + uint32_t base_addr = src_notdst ? voodoo->banshee_blt.srcBaseAddr : voodoo->banshee_blt.dstBaseAddr; - if (src_notdst ? voodoo->banshee_blt.srcBaseAddr_tiled : voodoo->banshee_blt.dstBaseAddr_tiled) - return (base_addr + (x & 127) + ((x >> 7) * 128*32) + ((y & 31) * 128) + (y >> 5)*stride) & voodoo->fb_mask; - else - return (base_addr + x + y*stride) & voodoo->fb_mask; + if (src_notdst ? voodoo->banshee_blt.srcBaseAddr_tiled : voodoo->banshee_blt.dstBaseAddr_tiled) + return (base_addr + (x & 127) + ((x >> 7) * 128 * 32) + ((y & 31) * 128) + (y >> 5) * stride) & voodoo->fb_mask; + else + return (base_addr + x + y * stride) & voodoo->fb_mask; } -static void PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, int src_colorkey) +static void +PLOT(voodoo_t *voodoo, int x, int y, int pat_x, int pat_y, uint8_t pattern_mask, uint8_t rop, uint32_t src, int src_colorkey) { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) - { - case DST_FORMAT_COL_8_BPP: - { - uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7)*8]; + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: + { + uint32_t addr = get_addr(voodoo, x, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; - voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_8); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: - { - uint32_t addr = get_addr(voodoo, x*2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7)*8]; + voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_8); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t addr = get_addr(voodoo, x * 2, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint16_t *) &voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_16); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: - { - uint32_t addr = get_addr(voodoo, x*3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7)*8]; + *(uint16_t *) &voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_16); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t addr = get_addr(voodoo, x * 3, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[addr] = (MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: - { - uint32_t addr = get_addr(voodoo, x*4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + *(uint32_t *) &voodoo->vram[addr] = (MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t addr = get_addr(voodoo, x * 4, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - } + *(uint32_t *) &voodoo->vram[addr] = MIX(voodoo, dest, src, pattern, src_colorkey, COLORKEY_32); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + } } -static void PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src_colorkey) +static void +PLOT_LINE(voodoo_t *voodoo, int x, int y, uint8_t rop, uint32_t pattern, int src_colorkey) { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) - { - case DST_FORMAT_COL_8_BPP: - { - uint32_t addr = get_addr(voodoo, x, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = voodoo->vram[addr]; + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: + { + uint32_t addr = get_addr(voodoo, x, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = voodoo->vram[addr]; - voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: - { - uint32_t addr = get_addr(voodoo, x*2, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint16_t *)&voodoo->vram[addr]; + voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_8); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t addr = get_addr(voodoo, x * 2, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*2 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint16_t *) &voodoo->vram[addr]; - *(uint16_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: - { - uint32_t addr = get_addr(voodoo, x*3, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + *(uint16_t *) &voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_16); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t addr = get_addr(voodoo, x * 3, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*3 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; - *(uint32_t *)&voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: - { - uint32_t addr = get_addr(voodoo, x*4, y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t dest = *(uint32_t *)&voodoo->vram[addr]; + *(uint32_t *) &voodoo->vram[addr] = (MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t addr = get_addr(voodoo, x * 4, y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + x*4 + y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t dest = *(uint32_t *) &voodoo->vram[addr]; - *(uint32_t *)&voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32); - voodoo->changedvram[addr >> 12] = changeframecount; - break; - } - } + *(uint32_t *) &voodoo->vram[addr] = MIX(voodoo, dest, voodoo->banshee_blt.colorFore, pattern, src_colorkey, COLORKEY_32); + voodoo->changedvram[addr >> 12] = changeframecount; + break; + } + } } - -static void update_src_stride(voodoo_t *voodoo) +static void +update_src_stride(voodoo_t *voodoo) { - int bpp; + int bpp; - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) - { - case SRC_FORMAT_COL_1_BPP: - bpp = 1; - break; - case SRC_FORMAT_COL_8_BPP: - bpp = 8; - break; - case SRC_FORMAT_COL_16_BPP: - bpp = 16; - break; - case SRC_FORMAT_COL_24_BPP: - bpp = 24; - break; - case SRC_FORMAT_COL_32_BPP: - bpp = 32; - break; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_1_BPP: + bpp = 1; + break; + case SRC_FORMAT_COL_8_BPP: + bpp = 8; + break; + case SRC_FORMAT_COL_16_BPP: + bpp = 16; + break; + case SRC_FORMAT_COL_24_BPP: + bpp = 24; + break; + case SRC_FORMAT_COL_32_BPP: + bpp = 32; + break; - default: - bpp = 16; - break; - } + default: + bpp = 16; + break; + } - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) - { - case SRC_FORMAT_PACKING_STRIDE: - voodoo->banshee_blt.src_stride_src = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - voodoo->banshee_blt.src_stride_dest = voodoo->banshee_blt.src_stride; //voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - voodoo->banshee_blt.host_data_size_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; - voodoo->banshee_blt.host_data_size_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; -// bansheeblt_log("Stride packing %08x %08x bpp=%i dstSizeX=%i\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest, bpp, voodoo->banshee_blt.dstSizeX); - break; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) { + case SRC_FORMAT_PACKING_STRIDE: + voodoo->banshee_blt.src_stride_src = voodoo->banshee_blt.src_stride; // voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + voodoo->banshee_blt.src_stride_dest = voodoo->banshee_blt.src_stride; // voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + voodoo->banshee_blt.host_data_size_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.host_data_size_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; + // bansheeblt_log("Stride packing %08x %08x bpp=%i dstSizeX=%i\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest, bpp, voodoo->banshee_blt.dstSizeX); + break; - case SRC_FORMAT_PACKING_BYTE: - voodoo->banshee_blt.src_stride_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; - voodoo->banshee_blt.src_stride_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; - voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; - voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; -// bansheeblt_log("Byte packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - break; + case SRC_FORMAT_PACKING_BYTE: + voodoo->banshee_blt.src_stride_src = (voodoo->banshee_blt.srcSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.src_stride_dest = (voodoo->banshee_blt.dstSizeX * bpp + 7) >> 3; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; + // bansheeblt_log("Byte packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + break; - case SRC_FORMAT_PACKING_WORD: - voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 15) >> 4) * 2; - voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 15) >> 4) * 2; - voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; - voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; -// bansheeblt_log("Word packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - break; + case SRC_FORMAT_PACKING_WORD: + voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 15) >> 4) * 2; + voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 15) >> 4) * 2; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; + // bansheeblt_log("Word packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + break; - case SRC_FORMAT_PACKING_DWORD: - voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 31) >> 5) * 4; - voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 31) >> 5) * 4; - voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; - voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; -// bansheeblt_log("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - break; - } + case SRC_FORMAT_PACKING_DWORD: + voodoo->banshee_blt.src_stride_src = ((voodoo->banshee_blt.srcSizeX * bpp + 31) >> 5) * 4; + voodoo->banshee_blt.src_stride_dest = ((voodoo->banshee_blt.dstSizeX * bpp + 31) >> 5) * 4; + voodoo->banshee_blt.host_data_size_src = voodoo->banshee_blt.src_stride_src; + voodoo->banshee_blt.host_data_size_dest = voodoo->banshee_blt.src_stride_dest; + // bansheeblt_log("Dword packing %08x %08x\n", voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + break; + } } -static void end_command(voodoo_t *voodoo) +static void +end_command(voodoo_t *voodoo) { - /*Update dest coordinates if required*/ - if (voodoo->banshee_blt.command & COMMAND_INC_X_START) - { - voodoo->banshee_blt.dstXY &= ~0x0000ffff; - voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstX & 0xffff); - } + /*Update dest coordinates if required*/ + if (voodoo->banshee_blt.command & COMMAND_INC_X_START) { + voodoo->banshee_blt.dstXY &= ~0x0000ffff; + voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstX & 0xffff); + } - if (voodoo->banshee_blt.command & COMMAND_INC_Y_START) - { - voodoo->banshee_blt.dstXY &= ~0xffff0000; - voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstY << 16); - } + if (voodoo->banshee_blt.command & COMMAND_INC_Y_START) { + voodoo->banshee_blt.dstXY &= ~0xffff0000; + voodoo->banshee_blt.dstXY |= (voodoo->banshee_blt.dstY << 16); + } } -static void banshee_do_rectfill(voodoo_t *voodoo) +static void +banshee_do_rectfill(voodoo_t *voodoo) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; -// bansheeblt_log("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY); -// bansheeblt_log("clipping: %i,%i -> %i,%i\n", clip->x_min, clip->y_min, clip->x_max, clip->y_max); -// bansheeblt_log("colorFore=%08x\n", voodoo->banshee_blt.colorFore); - for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) - { - int dst_x = voodoo->banshee_blt.dstX; + // bansheeblt_log("banshee_do_rectfill: size=%i,%i dst=%i,%i\n", voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY); + // bansheeblt_log("clipping: %i,%i -> %i,%i\n", clip->x_min, clip->y_min, clip->x_max, clip->y_max); + // bansheeblt_log("colorFore=%08x\n", voodoo->banshee_blt.colorFore); + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { + int dst_x = voodoo->banshee_blt.dstX; - if (dst_y >= clip->y_min && dst_y < clip->y_max) - { - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) - { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) - PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); - dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - } - } - dst_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - if (!(voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0)) - pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } } + dst_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + if (!(voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0)) + pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } - end_command(voodoo); + end_command(voodoo); } -static void do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) +static void +do_screen_to_screen_line(voodoo_t *voodoo, uint8_t *src_p, int use_x_dir, int src_x, int src_tiled) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int src_colorkey; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int src_colorkey; - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) - { - case SRC_FORMAT_COL_8_BPP: - src_colorkey = COLORKEY_8; - break; - case SRC_FORMAT_COL_16_BPP: - src_colorkey = COLORKEY_16; - break; - default: - src_colorkey = COLORKEY_32; - break; - } -// bansheeblt_log("do_screen_to_screen_line: srcFormat=%08x dst=%08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.dstFormat); - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == - (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)) - { - /*No conversion required*/ - if (dst_y >= clip->y_min && dst_y < clip->y_max) - { - int dst_x = voodoo->banshee_blt.dstX; - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_8_BPP: + src_colorkey = COLORKEY_8; + break; + case SRC_FORMAT_COL_16_BPP: + src_colorkey = COLORKEY_16; + break; + default: + src_colorkey = COLORKEY_32; + break; + } + // bansheeblt_log("do_screen_to_screen_line: srcFormat=%08x dst=%08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.dstFormat); + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK)) { + /*No conversion required*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) - { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; - int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; - if (src_tiled) - src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128*32); + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128 * 32); - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) - { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) - { - case DST_FORMAT_COL_8_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = src_p[src_x_real]; - uint32_t dest = voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7)*8]; + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x_real]; + uint32_t dest = voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern8[(pat_x & 7) + (pat_y & 7) * 8]; - voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x*2, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint16_t *)&src_p[src_x_real]; - uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7)*8]; + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_16_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x * 2, dst_y, 0, 0); // dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *) &src_p[src_x_real]; + uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern16[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint16_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x*3, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x_real]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7)*8]; + *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_24_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x * 3, dst_y, 0, 0); // dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *) &src_p[src_x_real]; + uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern24[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x*4, dst_y, 0, 0);//dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x_real]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7)*8]; + *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (dest & 0xff000000); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x * 4, dst_y, 0, 0); // dst_addr = (voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *) &src_p[src_x_real]; + uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : voodoo->banshee_blt.colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - *(uint32_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - } - } - if (use_x_dir) - { - src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - } - else - { - src_x++; - dst_x++; - pat_x++; - } - } + *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + } } - voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - } - else - { - /*Conversion required*/ - if (dst_y >= clip->y_min && dst_y < clip->y_max) - { -// int src_x = voodoo->banshee_blt.srcX; - int dst_x = voodoo->banshee_blt.dstX; - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; - - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) - { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; - int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; - - if (src_tiled) - src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128*32); - - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) - { - uint32_t src_data = 0; - int transparent = 0; - - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) - { - case SRC_FORMAT_COL_1_BPP: - { - uint8_t src_byte = src_p[src_x_real]; - src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack; - if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) - transparent = !(src_byte & (0x80 >> (src_x & 7))); -// bansheeblt_log(" 1bpp src_byte=%02x src_x=%i src_data=%x transparent=%i\n", src_byte, src_x, src_data, transparent); - break; - } - case SRC_FORMAT_COL_8_BPP: - { - src_data = src_p[src_x_real]; - break; - } - case SRC_FORMAT_COL_16_BPP: - { - uint16_t src_16 = *(uint16_t *)&src_p[src_x_real]; - int r = (src_16 >> 11); - int g = (src_16 >> 5) & 0x3f; - int b = src_16 & 0x1f; - - r = (r << 3) | (r >> 2); - g = (g << 2) | (g >> 4); - b = (b << 3) | (b >> 2); - src_data = (r << 16) | (g << 8) | b; - break; - } - case SRC_FORMAT_COL_24_BPP: - { - src_data = *(uint32_t *)&src_p[src_x_real]; - break; - } - case SRC_FORMAT_COL_32_BPP: - { - src_data = *(uint32_t *)&src_p[src_x_real]; - break; - } - - default: - fatal("banshee_do_screen_to_screen_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat); - } - - if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && - (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) != SRC_FORMAT_COL_1_BPP) - { - int r = src_data >> 16; - int g = (src_data >> 8) & 0xff; - int b = src_data & 0xff; - - src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); - } - - if (!transparent) - PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, src_data, src_colorkey); - } - if (use_x_dir) - { - src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; - } - else - { - src_x++; - dst_x++; - pat_x++; - } - } + if (use_x_dir) { + src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } else { + src_x++; + dst_x++; + pat_x++; } - voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; - } -} - -static void banshee_do_screen_to_screen_blt(voodoo_t *voodoo) -{ -// bansheeblt_log("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); -// return; - for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) - { - uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_dest); -// if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) -// bansheeblt_log(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); - do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcBaseAddr_tiled); - } - end_command(voodoo); -} - -static void banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) -{ -// if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) -// bansheeblt_log("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); - - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) - data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) - data = (data >> 16) | (data << 16); - - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) - { - int last_byte; - - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - last_byte = ((voodoo->banshee_blt.srcX & 31) + voodoo->banshee_blt.dstSizeX + 7) >> 3; - else - last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; - - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - if (voodoo->banshee_blt.host_data_count >= last_byte) - { -// bansheeblt_log(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) - { - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7, 0); - else - do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0, 0); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } - - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; - else - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); - - voodoo->banshee_blt.host_data_count = 0; - } - } - else - { - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_dest) - { - voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_dest; - -// bansheeblt_log(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) - { - do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0, 0); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } - - if (voodoo->banshee_blt.host_data_count) - { -// bansheeblt_log(" remaining=%i\n", voodoo->banshee_blt.host_data_count); - *(uint32_t *)&voodoo->banshee_blt.host_data[0] = data >> (4-voodoo->banshee_blt.host_data_count)*8; - } - } - } -} - -static void do_screen_to_screen_stretch_line(voodoo_t *voodoo,uint8_t *src_p, int src_x, int *src_y) -{ - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; -// int src_y = voodoo->banshee_blt.srcY; - int dst_y = voodoo->banshee_blt.dstY; - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; - - //int error_y = voodoo->banshee_blt.dstSizeY / 2; - -/* bansheeblt_log("banshee_do_screen_to_screen_stretch_blt:\n"); - bansheeblt_log(" srcXY=%i,%i srcsizeXY=%i,%i\n", voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcY, voodoo->banshee_blt.srcSizeX, voodoo->banshee_blt.srcSizeY); - bansheeblt_log(" dstXY=%i,%i dstsizeXY=%i,%i\n", voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY, voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY);*/ - if (dst_y >= clip->y_min && dst_y < clip->y_max) - { -// int src_x = voodoo->banshee_blt.srcX; - int dst_x = voodoo->banshee_blt.dstX; - int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; - uint8_t pattern_mask = pattern_mono[pat_y & 7]; - int error_x = voodoo->banshee_blt.dstSizeX / 2; - -// bansheeblt_log(" Plot dest line %03i : src line %03i\n", dst_y, src_y); - for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) - { - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; - - if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) - { - switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) - { - case DST_FORMAT_COL_8_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = src_p[src_x]; - uint32_t dest = voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7)*8]; - - voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); -// bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_16_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x*2, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint16_t *)&src_p[src_x*2]; - uint32_t dest = *(uint16_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7)*8]; - - *(uint16_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); -// bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, *(uint16_t *)&voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_24_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x*3, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x*3]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7)*8]; - - *(uint32_t *)&voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *)&voodoo->vram[dst_addr] & 0xff000000); -// bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - case DST_FORMAT_COL_32_BPP: - { - uint32_t dst_addr = get_addr(voodoo, dst_x*4, dst_y, 0, 0);//(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; - uint32_t src = *(uint32_t *)&src_p[src_x*4]; - uint32_t dest = *(uint32_t *)&voodoo->vram[dst_addr]; - uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? - ((pattern_mask & (1 << (7-(pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : - colorPattern[(pat_x & 7) + (pat_y & 7)*8]; - - *(uint32_t *)&voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); -// bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); - voodoo->changedvram[dst_addr >> 12] = changeframecount; - break; - } - } - } - - error_x -= voodoo->banshee_blt.srcSizeX; - while (error_x < 0) - { - error_x += voodoo->banshee_blt.dstSizeX; - src_x++; - } - dst_x++; - pat_x++; - } - } - - voodoo->banshee_blt.bres_error_0 -= voodoo->banshee_blt.srcSizeY; - while (voodoo->banshee_blt.bres_error_0 < 0) - { - voodoo->banshee_blt.bres_error_0 += voodoo->banshee_blt.dstSizeY; - if (src_y) - (*src_y) += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } } + voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; -// pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; -} + } else { + /*Conversion required*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + // int src_x = voodoo->banshee_blt.srcX; + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; -static void banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) -{ -// bansheeblt_log("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); -// return; - for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) - { - uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_src);//(voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; -// bansheeblt_log("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); -// if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) -// bansheeblt_log(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); - do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, &voodoo->banshee_blt.srcY); - } - end_command(voodoo); -} + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + int src_x_real = (src_x * voodoo->banshee_blt.src_bpp) >> 3; -static void banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, uint32_t data) -{ -// if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) -// bansheeblt_log("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + if (src_tiled) + src_x_real = (src_x_real & 127) + ((src_x_real >> 7) * 128 * 32); - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) - data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); - if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) - data = (data >> 16) | (data << 16); + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + uint32_t src_data = 0; + int transparent = 0; - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) - { - int last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_src; + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_1_BPP: + { + uint8_t src_byte = src_p[src_x_real]; + src_data = (src_byte & (0x80 >> (src_x & 7))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack; + if (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) + transparent = !(src_byte & (0x80 >> (src_x & 7))); + // bansheeblt_log(" 1bpp src_byte=%02x src_x=%i src_data=%x transparent=%i\n", src_byte, src_x, src_data, transparent); + break; + } + case SRC_FORMAT_COL_8_BPP: + { + src_data = src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_16_BPP: + { + uint16_t src_16 = *(uint16_t *) &src_p[src_x_real]; + int r = (src_16 >> 11); + int g = (src_16 >> 5) & 0x3f; + int b = src_16 & 0x1f; - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - if (voodoo->banshee_blt.host_data_count >= last_byte) - { -// bansheeblt_log(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) - { - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], voodoo->banshee_blt.srcX & 7, NULL); - else - do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, NULL); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } + r = (r << 3) | (r >> 2); + g = (g << 2) | (g >> 4); + b = (b << 3) | (b >> 2); + src_data = (r << 16) | (g << 8) | b; + break; + } + case SRC_FORMAT_COL_24_BPP: + { + src_data = *(uint32_t *) &src_p[src_x_real]; + break; + } + case SRC_FORMAT_COL_32_BPP: + { + src_data = *(uint32_t *) &src_p[src_x_real]; + break; + } - if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; - else - voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); + default: + fatal("banshee_do_screen_to_screen_blt: unknown srcFormat %08x\n", voodoo->banshee_blt.srcFormat); + } - voodoo->banshee_blt.host_data_count = 0; + if ((voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) == DST_FORMAT_COL_16_BPP && (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) != SRC_FORMAT_COL_1_BPP) { + int r = src_data >> 16; + int g = (src_data >> 8) & 0xff; + int b = src_data & 0xff; + + src_data = (b >> 3) | ((g >> 2) << 5) | ((r >> 3) << 11); + } + + if (!transparent) + PLOT(voodoo, dst_x, dst_y, pat_x, pat_y, pattern_mask, rop, src_data, src_colorkey); } + if (use_x_dir) { + src_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + dst_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + pat_x += (voodoo->banshee_blt.command & COMMAND_DX) ? -1 : 1; + } else { + src_x++; + dst_x++; + pat_x++; + } + } } + voodoo->banshee_blt.srcY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } +} + +static void +banshee_do_screen_to_screen_blt(voodoo_t *voodoo) +{ + // bansheeblt_log("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); + // return; + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_dest); + // if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + // bansheeblt_log(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); + do_screen_to_screen_line(voodoo, &voodoo->vram[src_addr], 1, voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcBaseAddr_tiled); + } + end_command(voodoo); +} + +static void +banshee_do_host_to_screen_blt(voodoo_t *voodoo, int count, uint32_t data) +{ + // if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) + // bansheeblt_log("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) + data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) + data = (data >> 16) | (data << 16); + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) { + int last_byte; + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + last_byte = ((voodoo->banshee_blt.srcX & 31) + voodoo->banshee_blt.dstSizeX + 7) >> 3; else - { - *(uint32_t *)&voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; - voodoo->banshee_blt.host_data_count += 4; - while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_src) - { - voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_src; + last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_dest; -// bansheeblt_log(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); - if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) - { - do_screen_to_screen_stretch_line(voodoo, voodoo->banshee_blt.host_data, 0, NULL); - voodoo->banshee_blt.cur_y++; - if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) - end_command(voodoo); - } - - if (voodoo->banshee_blt.host_data_count) - { -// bansheeblt_log(" remaining=%i\n", voodoo->banshee_blt.host_data_count); - *(uint32_t *)&voodoo->banshee_blt.host_data[0] = data >> (4-voodoo->banshee_blt.host_data_count)*8; - } - } - } -} - -static void step_line(voodoo_t *voodoo) -{ - if (voodoo->banshee_blt.line_pix_pos == voodoo->banshee_blt.line_rep_cnt) - { - voodoo->banshee_blt.line_pix_pos = 0; - if (voodoo->banshee_blt.line_bit_pos == voodoo->banshee_blt.line_bit_mask_size) - voodoo->banshee_blt.line_bit_pos = 0; + *(uint32_t *) &voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + if (voodoo->banshee_blt.host_data_count >= last_byte) { + // bansheeblt_log(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], 0, voodoo->banshee_blt.srcX & 7, 0); else - voodoo->banshee_blt.line_bit_pos++; + do_screen_to_screen_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, 0, 0); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; + else + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); + + voodoo->banshee_blt.host_data_count = 0; } - else - voodoo->banshee_blt.line_pix_pos++; + } else { + *(uint32_t *) &voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_dest) { + voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_dest; + + // bansheeblt_log(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + do_screen_to_screen_line(voodoo, voodoo->banshee_blt.host_data, 0, 0, 0); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } + + if (voodoo->banshee_blt.host_data_count) { + // bansheeblt_log(" remaining=%i\n", voodoo->banshee_blt.host_data_count); + *(uint32_t *) &voodoo->banshee_blt.host_data[0] = data >> (4 - voodoo->banshee_blt.host_data_count) * 8; + } + } + } } - -static void banshee_do_line(voodoo_t *voodoo, int draw_last_pixel) +static void +do_screen_to_screen_stretch_line(voodoo_t *voodoo, uint8_t *src_p, int src_x, int *src_y) { - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t rop = voodoo->banshee_blt.command >> 24; - int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); - int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); - int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; - int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; - int x = voodoo->banshee_blt.srcX; - int y = voodoo->banshee_blt.srcY; - int error; - uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? - voodoo->banshee_blt.lineStipple : ~0; + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + // int src_y = voodoo->banshee_blt.srcY; + int dst_y = voodoo->banshee_blt.dstY; + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + voodoo->banshee_blt.dstY); + uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint32_t *colorPattern = voodoo->banshee_blt.colorPattern; - if (dx > dy) /*X major*/ - { - error = dx/2; - while (x != voodoo->banshee_blt.dstX) - { - int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); - int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + // int error_y = voodoo->banshee_blt.dstSizeY / 2; - if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); + /* bansheeblt_log("banshee_do_screen_to_screen_stretch_blt:\n"); + bansheeblt_log(" srcXY=%i,%i srcsizeXY=%i,%i\n", voodoo->banshee_blt.srcX, voodoo->banshee_blt.srcY, voodoo->banshee_blt.srcSizeX, voodoo->banshee_blt.srcSizeY); + bansheeblt_log(" dstXY=%i,%i dstsizeXY=%i,%i\n", voodoo->banshee_blt.dstX, voodoo->banshee_blt.dstY, voodoo->banshee_blt.dstSizeX, voodoo->banshee_blt.dstSizeY);*/ + if (dst_y >= clip->y_min && dst_y < clip->y_max) { + // int src_x = voodoo->banshee_blt.srcX; + int dst_x = voodoo->banshee_blt.dstX; + int pat_x = voodoo->banshee_blt.patoff_x + voodoo->banshee_blt.dstX; + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int error_x = voodoo->banshee_blt.dstSizeX / 2; - error -= dy; - if (error < 0) + // bansheeblt_log(" Plot dest line %03i : src line %03i\n", dst_y, src_y); + for (voodoo->banshee_blt.cur_x = 0; voodoo->banshee_blt.cur_x < voodoo->banshee_blt.dstSizeX; voodoo->banshee_blt.cur_x++) { + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + + if (dst_x >= clip->x_min && dst_x < clip->x_max && pattern_trans) { + switch (voodoo->banshee_blt.dstFormat & DST_FORMAT_COL_MASK) { + case DST_FORMAT_COL_8_BPP: { - error += dx; - y += y_inc; + uint32_t dst_addr = get_addr(voodoo, dst_x, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = src_p[src_x]; + uint32_t dest = voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + + voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_8, COLORKEY_8); + // bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; } - x += x_inc; - step_line(voodoo); - } - } - else /*Y major*/ - { - error = dy/2; - while (y != voodoo->banshee_blt.dstY) - { - int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); - int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; - - if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); - - error -= dx; - if (error < 0) + case DST_FORMAT_COL_16_BPP: { - error += dy; - x += x_inc; + uint32_t dst_addr = get_addr(voodoo, dst_x * 2, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*2 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint16_t *) &src_p[src_x * 2]; + uint32_t dest = *(uint16_t *) &voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + + *(uint16_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_16, COLORKEY_16); + // bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, *(uint16_t *)&voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; } - y += y_inc; - step_line(voodoo); - } - } - - if (draw_last_pixel) - { - int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); - int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; - - if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); - } - - voodoo->banshee_blt.srcXY = (x & 0xffff) | (y << 16); - voodoo->banshee_blt.srcX = x; - voodoo->banshee_blt.srcY = y; -} - -static void banshee_polyfill_start(voodoo_t *voodoo) -{ - voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.srcY; - voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.dstX; - voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.dstY; - voodoo->banshee_blt.lx[1] = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.ly[1] = voodoo->banshee_blt.srcY; - voodoo->banshee_blt.rx[1] = voodoo->banshee_blt.dstX; - voodoo->banshee_blt.ry[1] = voodoo->banshee_blt.dstY; - voodoo->banshee_blt.lx_cur = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.rx_cur = voodoo->banshee_blt.dstX; -} - -static void banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data) -{ - clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; - uint8_t *pattern_mono = (uint8_t *)voodoo->banshee_blt.colorPattern; - int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == - (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); - uint8_t rop = voodoo->banshee_blt.command >> 24; - int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); - int y_end; - -// bansheeblt_log("Polyfill : data %08x\n", data); - - /*if r1.y>=l1.y, next vertex is left*/ - if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) - { - voodoo->banshee_blt.lx[1] = ((int32_t)(data << 19)) >> 19; - voodoo->banshee_blt.ly[1] = ((int32_t)(data << 3)) >> 19; - voodoo->banshee_blt.dx[0] = ABS(voodoo->banshee_blt.lx[1] - voodoo->banshee_blt.lx[0]); - voodoo->banshee_blt.dy[0] = ABS(voodoo->banshee_blt.ly[1] - voodoo->banshee_blt.ly[0]); - voodoo->banshee_blt.x_inc[0] = (voodoo->banshee_blt.lx[1] > voodoo->banshee_blt.lx[0]) ? 1 : -1; - voodoo->banshee_blt.error[0] = voodoo->banshee_blt.dy[0] / 2; - } - else - { - voodoo->banshee_blt.rx[1] = ((int32_t)(data << 19)) >> 19; - voodoo->banshee_blt.ry[1] = ((int32_t)(data << 3)) >> 19; - voodoo->banshee_blt.dx[1] = ABS(voodoo->banshee_blt.rx[1] - voodoo->banshee_blt.rx[0]); - voodoo->banshee_blt.dy[1] = ABS(voodoo->banshee_blt.ry[1] - voodoo->banshee_blt.ry[0]); - voodoo->banshee_blt.x_inc[1] = (voodoo->banshee_blt.rx[1] > voodoo->banshee_blt.rx[0]) ? 1 : -1; - voodoo->banshee_blt.error[1] = voodoo->banshee_blt.dy[1] / 2; - } - -/* bansheeblt_log(" verts now : %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[0], voodoo->banshee_blt.ly[0], voodoo->banshee_blt.rx[0], voodoo->banshee_blt.ry[0]); - bansheeblt_log(" %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[1], voodoo->banshee_blt.ly[1], voodoo->banshee_blt.rx[1], voodoo->banshee_blt.ry[1]); - bansheeblt_log(" left dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[0],voodoo->banshee_blt.dy[0],voodoo->banshee_blt.x_inc[0],voodoo->banshee_blt.error[0]); - bansheeblt_log(" right dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[1],voodoo->banshee_blt.dy[1],voodoo->banshee_blt.x_inc[1],voodoo->banshee_blt.error[1]);*/ - y_end = MIN(voodoo->banshee_blt.ly[1], voodoo->banshee_blt.ry[1]); -// bansheeblt_log("Polyfill : draw spans from %i-%i\n", y, y_end); - for (; y < y_end; y++) - { -// bansheeblt_log(" %i: %i %i\n", y, voodoo->banshee_blt.lx_cur, voodoo->banshee_blt.rx_cur); - /*Draw span from lx_cur to rx_cur*/ - if (y >= clip->y_min && y < clip->y_max) - { - int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + y); - uint8_t pattern_mask = pattern_mono[pat_y & 7]; - int x; - - for (x = voodoo->banshee_blt.lx_cur; x < voodoo->banshee_blt.rx_cur; x++) + case DST_FORMAT_COL_24_BPP: { - int pat_x = voodoo->banshee_blt.patoff_x + x; - int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7-(pat_x & 7)))) : 1; + uint32_t dst_addr = get_addr(voodoo, dst_x * 3, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*3 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *) &src_p[src_x * 3]; + uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; - if (x >= clip->x_min && x < clip->x_max && pattern_trans) - PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + *(uint32_t *) &voodoo->vram[dst_addr] = (MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32) & 0xffffff) | (*(uint32_t *) &voodoo->vram[dst_addr] & 0xff000000); + // bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; + } + case DST_FORMAT_COL_32_BPP: + { + uint32_t dst_addr = get_addr(voodoo, dst_x * 4, dst_y, 0, 0); //(voodoo->banshee_blt.dstBaseAddr + dst_x*4 + dst_y*voodoo->banshee_blt.dst_stride) & voodoo->fb_mask; + uint32_t src = *(uint32_t *) &src_p[src_x * 4]; + uint32_t dest = *(uint32_t *) &voodoo->vram[dst_addr]; + uint32_t pattern = (voodoo->banshee_blt.command & COMMAND_PATTERN_MONO) ? ((pattern_mask & (1 << (7 - (pat_x & 7)))) ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack) : colorPattern[(pat_x & 7) + (pat_y & 7) * 8]; + + *(uint32_t *) &voodoo->vram[dst_addr] = MIX(voodoo, dest, src, pattern, COLORKEY_32, COLORKEY_32); + // bansheeblt_log("%i,%i : sdp=%02x,%02x,%02x res=%02x\n", voodoo->banshee_blt.cur_x, voodoo->banshee_blt.cur_y, src, dest, pattern, voodoo->vram[dst_addr]); + voodoo->changedvram[dst_addr >> 12] = changeframecount; + break; } } + } - voodoo->banshee_blt.error[0] -= voodoo->banshee_blt.dx[0]; - while (voodoo->banshee_blt.error[0] < 0) - { - voodoo->banshee_blt.error[0] += voodoo->banshee_blt.dy[0]; - voodoo->banshee_blt.lx_cur += voodoo->banshee_blt.x_inc[0]; - } - voodoo->banshee_blt.error[1] -= voodoo->banshee_blt.dx[1]; - while (voodoo->banshee_blt.error[1] < 0) - { - voodoo->banshee_blt.error[1] += voodoo->banshee_blt.dy[1]; - voodoo->banshee_blt.rx_cur += voodoo->banshee_blt.x_inc[1]; - } + error_x -= voodoo->banshee_blt.srcSizeX; + while (error_x < 0) { + error_x += voodoo->banshee_blt.dstSizeX; + src_x++; + } + dst_x++; + pat_x++; } + } - if (voodoo->banshee_blt.ry[1] == voodoo->banshee_blt.ly[1]) - { - voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; - voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; - voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; - voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; - } - else if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) - { - voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; - voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; - } - else - { - voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; - voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; - } + voodoo->banshee_blt.bres_error_0 -= voodoo->banshee_blt.srcSizeY; + while (voodoo->banshee_blt.bres_error_0 < 0) { + voodoo->banshee_blt.bres_error_0 += voodoo->banshee_blt.dstSizeY; + if (src_y) + (*src_y) += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + } + voodoo->banshee_blt.dstY += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; + // pat_y += (voodoo->banshee_blt.command & COMMAND_DY) ? -1 : 1; } -static void banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data) +static void +banshee_do_screen_to_screen_stretch_blt(voodoo_t *voodoo) { - switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) - { - case COMMAND_CMD_NOP: - break; + // bansheeblt_log("screen_to_screen: %08x %08x %08x\n", voodoo->banshee_blt.srcFormat, voodoo->banshee_blt.src_stride, voodoo->banshee_blt.src_stride_dest); + // return; + for (voodoo->banshee_blt.cur_y = 0; voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY; voodoo->banshee_blt.cur_y++) { + uint32_t src_addr = get_addr(voodoo, 0, voodoo->banshee_blt.srcY, 1, voodoo->banshee_blt.src_stride_src); //(voodoo->banshee_blt.srcBaseAddr + voodoo->banshee_blt.srcY*voodoo->banshee_blt.src_stride_src) & voodoo->fb_mask; + // bansheeblt_log("scale_blit %i %08x %08x\n", voodoo->banshee_blt.cur_y, src_addr, voodoo->banshee_blt.command); + // if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + // bansheeblt_log(" srcY=%i src_addr=%08x\n", voodoo->banshee_blt.srcY, src_addr); + do_screen_to_screen_stretch_line(voodoo, &voodoo->vram[src_addr], voodoo->banshee_blt.srcX, &voodoo->banshee_blt.srcY); + } + end_command(voodoo); +} +static void +banshee_do_host_to_screen_stretch_blt(voodoo_t *voodoo, int count, uint32_t data) +{ + // if (voodoo->banshee_blt.dstBaseAddr == 0xee5194) + // bansheeblt_log("banshee_do_host_to_screen_blt: data=%08x host_data_count=%i src_stride_dest=%i host_data_size_dest=%i\n", data, voodoo->banshee_blt.host_data_count, voodoo->banshee_blt.src_stride_dest, voodoo->banshee_blt.host_data_size_dest); + + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_BYTE_SWIZZLE) + data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); + if (voodoo->banshee_blt.srcFormat & SRC_FORMAT_WORD_SWIZZLE) + data = (data >> 16) | (data << 16); + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_PACKING_MASK) == SRC_FORMAT_PACKING_STRIDE) { + int last_byte = (voodoo->banshee_blt.srcX & 3) + voodoo->banshee_blt.host_data_size_src; + + *(uint32_t *) &voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + if (voodoo->banshee_blt.host_data_count >= last_byte) { + // bansheeblt_log(" %i %i srcX=%i srcFormat=%08x\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY, voodoo->banshee_blt.srcX); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[(voodoo->banshee_blt.srcX >> 3) & 3], voodoo->banshee_blt.srcX & 7, NULL); + else + do_screen_to_screen_stretch_line(voodoo, &voodoo->banshee_blt.host_data[voodoo->banshee_blt.srcX & 3], 0, NULL); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } + + if ((voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) == SRC_FORMAT_COL_1_BPP) + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) << 3; + else + voodoo->banshee_blt.srcX += (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK); + + voodoo->banshee_blt.host_data_count = 0; + } + } else { + *(uint32_t *) &voodoo->banshee_blt.host_data[voodoo->banshee_blt.host_data_count] = data; + voodoo->banshee_blt.host_data_count += 4; + while (voodoo->banshee_blt.host_data_count >= voodoo->banshee_blt.src_stride_src) { + voodoo->banshee_blt.host_data_count -= voodoo->banshee_blt.src_stride_src; + + // bansheeblt_log(" %i %i\n", voodoo->banshee_blt.cur_y, voodoo->banshee_blt.dstSizeY); + if (voodoo->banshee_blt.cur_y < voodoo->banshee_blt.dstSizeY) { + do_screen_to_screen_stretch_line(voodoo, voodoo->banshee_blt.host_data, 0, NULL); + voodoo->banshee_blt.cur_y++; + if (voodoo->banshee_blt.cur_y == voodoo->banshee_blt.dstSizeY) + end_command(voodoo); + } + + if (voodoo->banshee_blt.host_data_count) { + // bansheeblt_log(" remaining=%i\n", voodoo->banshee_blt.host_data_count); + *(uint32_t *) &voodoo->banshee_blt.host_data[0] = data >> (4 - voodoo->banshee_blt.host_data_count) * 8; + } + } + } +} + +static void +step_line(voodoo_t *voodoo) +{ + if (voodoo->banshee_blt.line_pix_pos == voodoo->banshee_blt.line_rep_cnt) { + voodoo->banshee_blt.line_pix_pos = 0; + if (voodoo->banshee_blt.line_bit_pos == voodoo->banshee_blt.line_bit_mask_size) + voodoo->banshee_blt.line_bit_pos = 0; + else + voodoo->banshee_blt.line_bit_pos++; + } else + voodoo->banshee_blt.line_pix_pos++; +} + +static void +banshee_do_line(voodoo_t *voodoo, int draw_last_pixel) +{ + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t rop = voodoo->banshee_blt.command >> 24; + int dx = ABS(voodoo->banshee_blt.dstX - voodoo->banshee_blt.srcX); + int dy = ABS(voodoo->banshee_blt.dstY - voodoo->banshee_blt.srcY); + int x_inc = (voodoo->banshee_blt.dstX > voodoo->banshee_blt.srcX) ? 1 : -1; + int y_inc = (voodoo->banshee_blt.dstY > voodoo->banshee_blt.srcY) ? 1 : -1; + int x = voodoo->banshee_blt.srcX; + int y = voodoo->banshee_blt.srcY; + int error; + uint32_t stipple = (voodoo->banshee_blt.command & COMMAND_STIPPLE_LINE) ? voodoo->banshee_blt.lineStipple : ~0; + + if (dx > dy) /*X major*/ + { + error = dx / 2; + while (x != voodoo->banshee_blt.dstX) { + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); + + error -= dy; + if (error < 0) { + error += dx; + y += y_inc; + } + x += x_inc; + step_line(voodoo); + } + } else /*Y major*/ + { + error = dy / 2; + while (y != voodoo->banshee_blt.dstY) { + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); + + error -= dx; + if (error < 0) { + error += dy; + x += x_inc; + } + y += y_inc; + step_line(voodoo); + } + } + + if (draw_last_pixel) { + int mask = stipple & (1 << voodoo->banshee_blt.line_bit_pos); + int pattern_trans = (voodoo->banshee_blt.command & COMMAND_TRANS_MONO) ? mask : 1; + + if (y >= clip->y_min && y < clip->y_max && x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT_LINE(voodoo, x, y, rop, mask ? voodoo->banshee_blt.colorFore : voodoo->banshee_blt.colorBack, COLORKEY_32); + } + + voodoo->banshee_blt.srcXY = (x & 0xffff) | (y << 16); + voodoo->banshee_blt.srcX = x; + voodoo->banshee_blt.srcY = y; +} + +static void +banshee_polyfill_start(voodoo_t *voodoo) +{ + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.srcY; + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.dstX; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.dstY; + voodoo->banshee_blt.lx[1] = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.ly[1] = voodoo->banshee_blt.srcY; + voodoo->banshee_blt.rx[1] = voodoo->banshee_blt.dstX; + voodoo->banshee_blt.ry[1] = voodoo->banshee_blt.dstY; + voodoo->banshee_blt.lx_cur = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.rx_cur = voodoo->banshee_blt.dstX; +} + +static void +banshee_polyfill_continue(voodoo_t *voodoo, uint32_t data) +{ + clip_t *clip = &voodoo->banshee_blt.clip[(voodoo->banshee_blt.command & COMMAND_CLIP_SEL) ? 1 : 0]; + uint8_t *pattern_mono = (uint8_t *) voodoo->banshee_blt.colorPattern; + int use_pattern_trans = (voodoo->banshee_blt.command & (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO)) == (COMMAND_PATTERN_MONO | COMMAND_TRANS_MONO); + uint8_t rop = voodoo->banshee_blt.command >> 24; + int y = MAX(voodoo->banshee_blt.ly[0], voodoo->banshee_blt.ry[0]); + int y_end; + + // bansheeblt_log("Polyfill : data %08x\n", data); + + /*if r1.y>=l1.y, next vertex is left*/ + if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) { + voodoo->banshee_blt.lx[1] = ((int32_t) (data << 19)) >> 19; + voodoo->banshee_blt.ly[1] = ((int32_t) (data << 3)) >> 19; + voodoo->banshee_blt.dx[0] = ABS(voodoo->banshee_blt.lx[1] - voodoo->banshee_blt.lx[0]); + voodoo->banshee_blt.dy[0] = ABS(voodoo->banshee_blt.ly[1] - voodoo->banshee_blt.ly[0]); + voodoo->banshee_blt.x_inc[0] = (voodoo->banshee_blt.lx[1] > voodoo->banshee_blt.lx[0]) ? 1 : -1; + voodoo->banshee_blt.error[0] = voodoo->banshee_blt.dy[0] / 2; + } else { + voodoo->banshee_blt.rx[1] = ((int32_t) (data << 19)) >> 19; + voodoo->banshee_blt.ry[1] = ((int32_t) (data << 3)) >> 19; + voodoo->banshee_blt.dx[1] = ABS(voodoo->banshee_blt.rx[1] - voodoo->banshee_blt.rx[0]); + voodoo->banshee_blt.dy[1] = ABS(voodoo->banshee_blt.ry[1] - voodoo->banshee_blt.ry[0]); + voodoo->banshee_blt.x_inc[1] = (voodoo->banshee_blt.rx[1] > voodoo->banshee_blt.rx[0]) ? 1 : -1; + voodoo->banshee_blt.error[1] = voodoo->banshee_blt.dy[1] / 2; + } + + /* bansheeblt_log(" verts now : %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[0], voodoo->banshee_blt.ly[0], voodoo->banshee_blt.rx[0], voodoo->banshee_blt.ry[0]); + bansheeblt_log(" %03i,%03i %03i,%03i\n", voodoo->banshee_blt.lx[1], voodoo->banshee_blt.ly[1], voodoo->banshee_blt.rx[1], voodoo->banshee_blt.ry[1]); + bansheeblt_log(" left dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[0],voodoo->banshee_blt.dy[0],voodoo->banshee_blt.x_inc[0],voodoo->banshee_blt.error[0]); + bansheeblt_log(" right dx=%i dy=%i x_inc=%i error=%i\n", voodoo->banshee_blt.dx[1],voodoo->banshee_blt.dy[1],voodoo->banshee_blt.x_inc[1],voodoo->banshee_blt.error[1]);*/ + y_end = MIN(voodoo->banshee_blt.ly[1], voodoo->banshee_blt.ry[1]); + // bansheeblt_log("Polyfill : draw spans from %i-%i\n", y, y_end); + for (; y < y_end; y++) { + // bansheeblt_log(" %i: %i %i\n", y, voodoo->banshee_blt.lx_cur, voodoo->banshee_blt.rx_cur); + /*Draw span from lx_cur to rx_cur*/ + if (y >= clip->y_min && y < clip->y_max) { + int pat_y = (voodoo->banshee_blt.commandExtra & CMDEXTRA_FORCE_PAT_ROW0) ? 0 : (voodoo->banshee_blt.patoff_y + y); + uint8_t pattern_mask = pattern_mono[pat_y & 7]; + int x; + + for (x = voodoo->banshee_blt.lx_cur; x < voodoo->banshee_blt.rx_cur; x++) { + int pat_x = voodoo->banshee_blt.patoff_x + x; + int pattern_trans = use_pattern_trans ? (pattern_mask & (1 << (7 - (pat_x & 7)))) : 1; + + if (x >= clip->x_min && x < clip->x_max && pattern_trans) + PLOT(voodoo, x, y, pat_x, pat_y, pattern_mask, rop, voodoo->banshee_blt.colorFore, COLORKEY_32); + } + } + + voodoo->banshee_blt.error[0] -= voodoo->banshee_blt.dx[0]; + while (voodoo->banshee_blt.error[0] < 0) { + voodoo->banshee_blt.error[0] += voodoo->banshee_blt.dy[0]; + voodoo->banshee_blt.lx_cur += voodoo->banshee_blt.x_inc[0]; + } + voodoo->banshee_blt.error[1] -= voodoo->banshee_blt.dx[1]; + while (voodoo->banshee_blt.error[1] < 0) { + voodoo->banshee_blt.error[1] += voodoo->banshee_blt.dy[1]; + voodoo->banshee_blt.rx_cur += voodoo->banshee_blt.x_inc[1]; + } + } + + if (voodoo->banshee_blt.ry[1] == voodoo->banshee_blt.ly[1]) { + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; + } else if (voodoo->banshee_blt.ry[1] >= voodoo->banshee_blt.ly[1]) { + voodoo->banshee_blt.lx[0] = voodoo->banshee_blt.lx[1]; + voodoo->banshee_blt.ly[0] = voodoo->banshee_blt.ly[1]; + } else { + voodoo->banshee_blt.rx[0] = voodoo->banshee_blt.rx[1]; + voodoo->banshee_blt.ry[0] = voodoo->banshee_blt.ry[1]; + } +} + +static void +banshee_do_2d_blit(voodoo_t *voodoo, int count, uint32_t data) +{ + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { + case COMMAND_CMD_NOP: + break; + + case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: + banshee_do_screen_to_screen_blt(voodoo); + break; + + case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: + banshee_do_screen_to_screen_stretch_blt(voodoo); + break; + + case COMMAND_CMD_HOST_TO_SCREEN_BLT: + banshee_do_host_to_screen_blt(voodoo, count, data); + break; + + case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: + banshee_do_host_to_screen_stretch_blt(voodoo, count, data); + break; + + case COMMAND_CMD_RECTFILL: + banshee_do_rectfill(voodoo); + break; + + case COMMAND_CMD_LINE: + banshee_do_line(voodoo, 1); + break; + + case COMMAND_CMD_POLYLINE: + banshee_do_line(voodoo, 0); + break; + + default: + fatal("banshee_do_2d_blit: unknown command=%08x\n", voodoo->banshee_blt.command); + } +} + +void +voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) +{ + // /*if ((addr & 0x1fc) != 0x80) */bansheeblt_log("2D reg write %03x %08x\n", addr & 0x1fc, val); + switch (addr & 0x1fc) { + case 0x08: + voodoo->banshee_blt.clip0Min = val; + voodoo->banshee_blt.clip[0].x_min = val & 0xfff; + voodoo->banshee_blt.clip[0].y_min = (val >> 16) & 0xfff; + break; + case 0x0c: + voodoo->banshee_blt.clip0Max = val; + voodoo->banshee_blt.clip[0].x_max = val & 0xfff; + voodoo->banshee_blt.clip[0].y_max = (val >> 16) & 0xfff; + break; + case 0x10: + voodoo->banshee_blt.dstBaseAddr = val & 0xffffff; + voodoo->banshee_blt.dstBaseAddr_tiled = val & 0x80000000; + if (voodoo->banshee_blt.dstBaseAddr_tiled) + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; + // bansheeblt_log("dstBaseAddr=%08x\n", val); + break; + case 0x14: + voodoo->banshee_blt.dstFormat = val; + if (voodoo->banshee_blt.dstBaseAddr_tiled) + voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; + // bansheeblt_log("dstFormat=%08x\n", val); + break; + + case 0x18: + voodoo->banshee_blt.srcColorkeyMin = val & 0xffffff; + break; + case 0x1c: + voodoo->banshee_blt.srcColorkeyMax = val & 0xffffff; + break; + case 0x20: + voodoo->banshee_blt.dstColorkeyMin = val & 0xffffff; + break; + case 0x24: + voodoo->banshee_blt.dstColorkeyMax = val & 0xffffff; + break; + + case 0x28: + voodoo->banshee_blt.bresError0 = val; + voodoo->banshee_blt.bres_error_0 = val & 0xffff; + break; + case 0x2c: + voodoo->banshee_blt.bresError1 = val; + voodoo->banshee_blt.bres_error_1 = val & 0xffff; + break; + + case 0x30: + voodoo->banshee_blt.rop = val; + voodoo->banshee_blt.rops[1] = val & 0xff; + voodoo->banshee_blt.rops[2] = (val >> 8) & 0xff; + voodoo->banshee_blt.rops[3] = (val >> 16) & 0xff; + // bansheeblt_log("rop=%08x\n", val); + break; + case 0x34: + voodoo->banshee_blt.srcBaseAddr = val & 0xffffff; + voodoo->banshee_blt.srcBaseAddr_tiled = val & 0x80000000; + if (voodoo->banshee_blt.srcBaseAddr_tiled) + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + update_src_stride(voodoo); + // bansheeblt_log("srcBaseAddr=%08x\n", val); + break; + case 0x38: + voodoo->banshee_blt.commandExtra = val; + // bansheeblt_log("commandExtra=%08x\n", val); + break; + case 0x3c: + voodoo->banshee_blt.lineStipple = val; + break; + case 0x40: + voodoo->banshee_blt.lineStyle = val; + voodoo->banshee_blt.line_rep_cnt = val & 0xff; + voodoo->banshee_blt.line_bit_mask_size = (val >> 8) & 0x1f; + voodoo->banshee_blt.line_pix_pos = (val >> 16) & 0xff; + voodoo->banshee_blt.line_bit_pos = (val >> 24) & 0x1f; + break; + case 0x44: + voodoo->banshee_blt.colorPattern[0] = val; + // bansheeblt_log("colorPattern0=%08x\n", val); + voodoo->banshee_blt.colorPattern24[0] = val & 0xffffff; + voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xffff00) | (val >> 24); + voodoo->banshee_blt.colorPattern16[0] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[1] = (val >> 16) & 0xffff; + voodoo->banshee_blt.colorPattern8[0] = val & 0xff; + voodoo->banshee_blt.colorPattern8[1] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[2] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[3] = (val >> 24) & 0xff; + break; + case 0x48: + voodoo->banshee_blt.colorPattern[1] = val; + // bansheeblt_log("colorPattern1=%08x\n", val); + voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xff) | ((val & 0xffff) << 8); + voodoo->banshee_blt.colorPattern24[2] = (voodoo->banshee_blt.colorPattern24[2] & 0xff0000) | (val >> 16); + voodoo->banshee_blt.colorPattern16[2] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[3] = (val >> 16) & 0xffff; + voodoo->banshee_blt.colorPattern8[4] = val & 0xff; + voodoo->banshee_blt.colorPattern8[5] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[6] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[7] = (val >> 24) & 0xff; + break; + case 0x4c: + voodoo->banshee_blt.clip1Min = val; + voodoo->banshee_blt.clip[1].x_min = val & 0xfff; + voodoo->banshee_blt.clip[1].y_min = (val >> 16) & 0xfff; + break; + case 0x50: + voodoo->banshee_blt.clip1Max = val; + voodoo->banshee_blt.clip[1].x_max = val & 0xfff; + voodoo->banshee_blt.clip[1].y_max = (val >> 16) & 0xfff; + break; + case 0x54: + voodoo->banshee_blt.srcFormat = val; + if (voodoo->banshee_blt.srcBaseAddr_tiled) + voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128 * 32; + else + voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; + update_src_stride(voodoo); + switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) { + case SRC_FORMAT_COL_1_BPP: + voodoo->banshee_blt.src_bpp = 1; + break; + case SRC_FORMAT_COL_8_BPP: + voodoo->banshee_blt.src_bpp = 8; + break; + case SRC_FORMAT_COL_24_BPP: + voodoo->banshee_blt.src_bpp = 24; + break; + case SRC_FORMAT_COL_32_BPP: + voodoo->banshee_blt.src_bpp = 32; + break; + case SRC_FORMAT_COL_16_BPP: + default: + voodoo->banshee_blt.src_bpp = 16; + break; + } + // bansheeblt_log("srcFormat=%08x\n", val); + break; + case 0x58: + voodoo->banshee_blt.srcSize = val; + voodoo->banshee_blt.srcSizeX = voodoo->banshee_blt.srcSize & 0x1fff; + voodoo->banshee_blt.srcSizeY = (voodoo->banshee_blt.srcSize >> 16) & 0x1fff; + update_src_stride(voodoo); + // bansheeblt_log("srcSize=%08x\n", val); + break; + case 0x5c: + voodoo->banshee_blt.srcXY = val; + voodoo->banshee_blt.srcX = ((int32_t) (val << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t) (val << 3)) >> 19; + update_src_stride(voodoo); + // bansheeblt_log("srcXY=%08x\n", val); + break; + case 0x60: + voodoo->banshee_blt.colorBack = val; + break; + case 0x64: + voodoo->banshee_blt.colorFore = val; + break; + case 0x68: + voodoo->banshee_blt.dstSize = val; + voodoo->banshee_blt.dstSizeX = voodoo->banshee_blt.dstSize & 0x1fff; + voodoo->banshee_blt.dstSizeY = (voodoo->banshee_blt.dstSize >> 16) & 0x1fff; + update_src_stride(voodoo); + // bansheeblt_log("dstSize=%08x\n", val); + break; + case 0x6c: + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t) (val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t) (val << 3)) >> 19; + // bansheeblt_log("dstXY=%08x\n", val); + break; + case 0x70: + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->banshee_blt.command = val; + voodoo->banshee_blt.rops[0] = val >> 24; + // bansheeblt_log("command=%x %08x\n", voodoo->banshee_blt.command & COMMAND_CMD_MASK, val); + voodoo->banshee_blt.patoff_x = (val & COMMAND_PATOFF_X_MASK) >> COMMAND_PATOFF_X_SHIFT; + voodoo->banshee_blt.patoff_y = (val & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; + voodoo->banshee_blt.cur_x = 0; + voodoo->banshee_blt.cur_y = 0; + voodoo->banshee_blt.dstX = ((int32_t) (voodoo->banshee_blt.dstXY << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t) (voodoo->banshee_blt.dstXY << 3)) >> 19; + voodoo->banshee_blt.srcX = ((int32_t) (voodoo->banshee_blt.srcXY << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t) (voodoo->banshee_blt.srcXY << 3)) >> 19; + voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.host_data_remainder = 0; + voodoo->banshee_blt.host_data_count = 0; + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { + /* case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: + if (voodoo->banshee_blt.bresError0 & BRES_ERROR_USE) + voodoo->banshee_blt.bres_error_0 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError0 & BRES_ERROR_MASK); + else + voodoo->banshee_blt.bres_error_0 = voodoo->banshee_blt.dstSizeY / 2; + if (voodoo->banshee_blt.bresError1 & BRES_ERROR_USE) + voodoo->banshee_blt.bres_error_1 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError1 & BRES_ERROR_MASK); + else + voodoo->banshee_blt.bres_error_1 = voodoo->banshee_blt.dstSizeX / 2; + + if (val & COMMAND_INITIATE) + banshee_do_2d_blit(voodoo, -1, 0); + break;*/ + + case COMMAND_CMD_POLYFILL: + if (val & COMMAND_INITIATE) { + voodoo->banshee_blt.dstXY = voodoo->banshee_blt.srcXY; + voodoo->banshee_blt.dstX = voodoo->banshee_blt.srcX; + voodoo->banshee_blt.dstY = voodoo->banshee_blt.srcY; + } + banshee_polyfill_start(voodoo); + break; + + default: + if (val & COMMAND_INITIATE) { + banshee_do_2d_blit(voodoo, -1, 0); + // fatal("Initiate command!\n"); + } + break; + } + break; + + case 0x80: + case 0x84: + case 0x88: + case 0x8c: + case 0x90: + case 0x94: + case 0x98: + case 0x9c: + case 0xa0: + case 0xa4: + case 0xa8: + case 0xac: + case 0xb0: + case 0xb4: + case 0xb8: + case 0xbc: + case 0xc0: + case 0xc4: + case 0xc8: + case 0xcc: + case 0xd0: + case 0xd4: + case 0xd8: + case 0xdc: + case 0xe0: + case 0xe4: + case 0xe8: + case 0xec: + case 0xf0: + case 0xf4: + case 0xf8: + case 0xfc: + // bansheeblt_log("launch %08x %08x %08x %08x\n", voodoo->banshee_blt.command, voodoo->banshee_blt.commandExtra, voodoo->banshee_blt.srcColorkeyMin, voodoo->banshee_blt.srcColorkeyMax); + switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) { case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: - banshee_do_screen_to_screen_blt(voodoo); - break; - - case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: - banshee_do_screen_to_screen_stretch_blt(voodoo); - break; + voodoo->banshee_blt.srcXY = val; + voodoo->banshee_blt.srcX = ((int32_t) (val << 19)) >> 19; + voodoo->banshee_blt.srcY = ((int32_t) (val << 3)) >> 19; + banshee_do_screen_to_screen_blt(voodoo); + break; case COMMAND_CMD_HOST_TO_SCREEN_BLT: - banshee_do_host_to_screen_blt(voodoo, count, data); - break; + banshee_do_2d_blit(voodoo, 32, val); + break; case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: - banshee_do_host_to_screen_stretch_blt(voodoo, count, data); - break; + banshee_do_2d_blit(voodoo, 32, val); + break; case COMMAND_CMD_RECTFILL: - banshee_do_rectfill(voodoo); - break; + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t) (val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t) (val << 3)) >> 19; + banshee_do_rectfill(voodoo); + break; case COMMAND_CMD_LINE: - banshee_do_line(voodoo, 1); - break; + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t) (val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t) (val << 3)) >> 19; + banshee_do_line(voodoo, 1); + break; case COMMAND_CMD_POLYLINE: - banshee_do_line(voodoo, 0); - break; + voodoo->banshee_blt.dstXY = val; + voodoo->banshee_blt.dstX = ((int32_t) (val << 19)) >> 19; + voodoo->banshee_blt.dstY = ((int32_t) (val << 3)) >> 19; + banshee_do_line(voodoo, 0); + break; + + case COMMAND_CMD_POLYFILL: + banshee_polyfill_continue(voodoo, val); + break; default: - fatal("banshee_do_2d_blit: unknown command=%08x\n", voodoo->banshee_blt.command); - } -} - -void voodoo_2d_reg_writel(voodoo_t *voodoo, uint32_t addr, uint32_t val) -{ -// /*if ((addr & 0x1fc) != 0x80) */bansheeblt_log("2D reg write %03x %08x\n", addr & 0x1fc, val); - switch (addr & 0x1fc) - { - case 0x08: - voodoo->banshee_blt.clip0Min = val; - voodoo->banshee_blt.clip[0].x_min = val & 0xfff; - voodoo->banshee_blt.clip[0].y_min = (val >> 16) & 0xfff; - break; - case 0x0c: - voodoo->banshee_blt.clip0Max = val; - voodoo->banshee_blt.clip[0].x_max = val & 0xfff; - voodoo->banshee_blt.clip[0].y_max = (val >> 16) & 0xfff; - break; - case 0x10: - voodoo->banshee_blt.dstBaseAddr = val & 0xffffff; - voodoo->banshee_blt.dstBaseAddr_tiled = val & 0x80000000; - if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128*32; - else - voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; -// bansheeblt_log("dstBaseAddr=%08x\n", val); - break; - case 0x14: - voodoo->banshee_blt.dstFormat = val; - if (voodoo->banshee_blt.dstBaseAddr_tiled) - voodoo->banshee_blt.dst_stride = (voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK) * 128*32; - else - voodoo->banshee_blt.dst_stride = voodoo->banshee_blt.dstFormat & DST_FORMAT_STRIDE_MASK; -// bansheeblt_log("dstFormat=%08x\n", val); - break; - - case 0x18: - voodoo->banshee_blt.srcColorkeyMin = val & 0xffffff; - break; - case 0x1c: - voodoo->banshee_blt.srcColorkeyMax = val & 0xffffff; - break; - case 0x20: - voodoo->banshee_blt.dstColorkeyMin = val & 0xffffff; - break; - case 0x24: - voodoo->banshee_blt.dstColorkeyMax = val & 0xffffff; - break; - - case 0x28: - voodoo->banshee_blt.bresError0 = val; - voodoo->banshee_blt.bres_error_0 = val & 0xffff; - break; - case 0x2c: - voodoo->banshee_blt.bresError1 = val; - voodoo->banshee_blt.bres_error_1 = val & 0xffff; - break; - - case 0x30: - voodoo->banshee_blt.rop = val; - voodoo->banshee_blt.rops[1] = val & 0xff; - voodoo->banshee_blt.rops[2] = (val >> 8) & 0xff; - voodoo->banshee_blt.rops[3] = (val >> 16) & 0xff; -// bansheeblt_log("rop=%08x\n", val); - break; - case 0x34: - voodoo->banshee_blt.srcBaseAddr = val & 0xffffff; - voodoo->banshee_blt.srcBaseAddr_tiled = val & 0x80000000; - if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128*32; - else - voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - update_src_stride(voodoo); -// bansheeblt_log("srcBaseAddr=%08x\n", val); - break; - case 0x38: - voodoo->banshee_blt.commandExtra = val; -// bansheeblt_log("commandExtra=%08x\n", val); - break; - case 0x3c: - voodoo->banshee_blt.lineStipple = val; - break; - case 0x40: - voodoo->banshee_blt.lineStyle = val; - voodoo->banshee_blt.line_rep_cnt = val & 0xff; - voodoo->banshee_blt.line_bit_mask_size = (val >> 8) & 0x1f; - voodoo->banshee_blt.line_pix_pos = (val >> 16) & 0xff; - voodoo->banshee_blt.line_bit_pos = (val >> 24) & 0x1f; - break; - case 0x44: - voodoo->banshee_blt.colorPattern[0] = val; -// bansheeblt_log("colorPattern0=%08x\n", val); - voodoo->banshee_blt.colorPattern24[0] = val & 0xffffff; - voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xffff00) | (val >> 24); - voodoo->banshee_blt.colorPattern16[0] = val & 0xffff; - voodoo->banshee_blt.colorPattern16[1] = (val >> 16) & 0xffff; - voodoo->banshee_blt.colorPattern8[0] = val & 0xff; - voodoo->banshee_blt.colorPattern8[1] = (val >> 8) & 0xff; - voodoo->banshee_blt.colorPattern8[2] = (val >> 16) & 0xff; - voodoo->banshee_blt.colorPattern8[3] = (val >> 24) & 0xff; - break; - case 0x48: - voodoo->banshee_blt.colorPattern[1] = val; -// bansheeblt_log("colorPattern1=%08x\n", val); - voodoo->banshee_blt.colorPattern24[1] = (voodoo->banshee_blt.colorPattern24[1] & 0xff) | ((val & 0xffff) << 8); - voodoo->banshee_blt.colorPattern24[2] = (voodoo->banshee_blt.colorPattern24[2] & 0xff0000) | (val >> 16); - voodoo->banshee_blt.colorPattern16[2] = val & 0xffff; - voodoo->banshee_blt.colorPattern16[3] = (val >> 16) & 0xffff; - voodoo->banshee_blt.colorPattern8[4] = val & 0xff; - voodoo->banshee_blt.colorPattern8[5] = (val >> 8) & 0xff; - voodoo->banshee_blt.colorPattern8[6] = (val >> 16) & 0xff; - voodoo->banshee_blt.colorPattern8[7] = (val >> 24) & 0xff; - break; - case 0x4c: - voodoo->banshee_blt.clip1Min = val; - voodoo->banshee_blt.clip[1].x_min = val & 0xfff; - voodoo->banshee_blt.clip[1].y_min = (val >> 16) & 0xfff; - break; - case 0x50: - voodoo->banshee_blt.clip1Max = val; - voodoo->banshee_blt.clip[1].x_max = val & 0xfff; - voodoo->banshee_blt.clip[1].y_max = (val >> 16) & 0xfff; - break; - case 0x54: - voodoo->banshee_blt.srcFormat = val; - if (voodoo->banshee_blt.srcBaseAddr_tiled) - voodoo->banshee_blt.src_stride = (voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK) * 128*32; - else - voodoo->banshee_blt.src_stride = voodoo->banshee_blt.srcFormat & SRC_FORMAT_STRIDE_MASK; - update_src_stride(voodoo); - switch (voodoo->banshee_blt.srcFormat & SRC_FORMAT_COL_MASK) - { - case SRC_FORMAT_COL_1_BPP: - voodoo->banshee_blt.src_bpp = 1; - break; - case SRC_FORMAT_COL_8_BPP: - voodoo->banshee_blt.src_bpp = 8; - break; - case SRC_FORMAT_COL_24_BPP: - voodoo->banshee_blt.src_bpp = 24; - break; - case SRC_FORMAT_COL_32_BPP: - voodoo->banshee_blt.src_bpp = 32; - break; - case SRC_FORMAT_COL_16_BPP: default: - voodoo->banshee_blt.src_bpp = 16; - break; - } -// bansheeblt_log("srcFormat=%08x\n", val); - break; - case 0x58: - voodoo->banshee_blt.srcSize = val; - voodoo->banshee_blt.srcSizeX = voodoo->banshee_blt.srcSize & 0x1fff; - voodoo->banshee_blt.srcSizeY = (voodoo->banshee_blt.srcSize >> 16) & 0x1fff; - update_src_stride(voodoo); -// bansheeblt_log("srcSize=%08x\n", val); - break; - case 0x5c: - voodoo->banshee_blt.srcXY = val; - voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; - update_src_stride(voodoo); -// bansheeblt_log("srcXY=%08x\n", val); - break; - case 0x60: - voodoo->banshee_blt.colorBack = val; - break; - case 0x64: - voodoo->banshee_blt.colorFore = val; - break; - case 0x68: - voodoo->banshee_blt.dstSize = val; - voodoo->banshee_blt.dstSizeX = voodoo->banshee_blt.dstSize & 0x1fff; - voodoo->banshee_blt.dstSizeY = (voodoo->banshee_blt.dstSize >> 16) & 0x1fff; - update_src_stride(voodoo); -// bansheeblt_log("dstSize=%08x\n", val); - break; - case 0x6c: - voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; -// bansheeblt_log("dstXY=%08x\n", val); - break; - case 0x70: - voodoo_wait_for_render_thread_idle(voodoo); - voodoo->banshee_blt.command = val; - voodoo->banshee_blt.rops[0] = val >> 24; -// bansheeblt_log("command=%x %08x\n", voodoo->banshee_blt.command & COMMAND_CMD_MASK, val); - voodoo->banshee_blt.patoff_x = (val & COMMAND_PATOFF_X_MASK) >> COMMAND_PATOFF_X_SHIFT; - voodoo->banshee_blt.patoff_y = (val & COMMAND_PATOFF_Y_MASK) >> COMMAND_PATOFF_Y_SHIFT; - voodoo->banshee_blt.cur_x = 0; - voodoo->banshee_blt.cur_y = 0; - voodoo->banshee_blt.dstX = ((int32_t)(voodoo->banshee_blt.dstXY << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(voodoo->banshee_blt.dstXY << 3)) >> 19; - voodoo->banshee_blt.srcX = ((int32_t)(voodoo->banshee_blt.srcXY << 19)) >> 19; - voodoo->banshee_blt.srcY = ((int32_t)(voodoo->banshee_blt.srcXY << 3)) >> 19; - voodoo->banshee_blt.old_srcX = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.host_data_remainder = 0; - voodoo->banshee_blt.host_data_count = 0; - switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) - { -/* case COMMAND_CMD_SCREEN_TO_SCREEN_STRETCH_BLT: - if (voodoo->banshee_blt.bresError0 & BRES_ERROR_USE) - voodoo->banshee_blt.bres_error_0 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError0 & BRES_ERROR_MASK); - else - voodoo->banshee_blt.bres_error_0 = voodoo->banshee_blt.dstSizeY / 2; - if (voodoo->banshee_blt.bresError1 & BRES_ERROR_USE) - voodoo->banshee_blt.bres_error_1 = (int32_t)(int16_t)(voodoo->banshee_blt.bresError1 & BRES_ERROR_MASK); - else - voodoo->banshee_blt.bres_error_1 = voodoo->banshee_blt.dstSizeX / 2; - - if (val & COMMAND_INITIATE) - banshee_do_2d_blit(voodoo, -1, 0); - break;*/ - - case COMMAND_CMD_POLYFILL: - if (val & COMMAND_INITIATE) - { - voodoo->banshee_blt.dstXY = voodoo->banshee_blt.srcXY; - voodoo->banshee_blt.dstX = voodoo->banshee_blt.srcX; - voodoo->banshee_blt.dstY = voodoo->banshee_blt.srcY; - } - banshee_polyfill_start(voodoo); - break; - - default: - if (val & COMMAND_INITIATE) - { - banshee_do_2d_blit(voodoo, -1, 0); - // fatal("Initiate command!\n"); - } - break; - } - break; - - case 0x80: case 0x84: case 0x88: case 0x8c: - case 0x90: case 0x94: case 0x98: case 0x9c: - case 0xa0: case 0xa4: case 0xa8: case 0xac: - case 0xb0: case 0xb4: case 0xb8: case 0xbc: - case 0xc0: case 0xc4: case 0xc8: case 0xcc: - case 0xd0: case 0xd4: case 0xd8: case 0xdc: - case 0xe0: case 0xe4: case 0xe8: case 0xec: - case 0xf0: case 0xf4: case 0xf8: case 0xfc: -// bansheeblt_log("launch %08x %08x %08x %08x\n", voodoo->banshee_blt.command, voodoo->banshee_blt.commandExtra, voodoo->banshee_blt.srcColorkeyMin, voodoo->banshee_blt.srcColorkeyMax); - switch (voodoo->banshee_blt.command & COMMAND_CMD_MASK) - { - case COMMAND_CMD_SCREEN_TO_SCREEN_BLT: - voodoo->banshee_blt.srcXY = val; - voodoo->banshee_blt.srcX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.srcY = ((int32_t)(val << 3)) >> 19; - banshee_do_screen_to_screen_blt(voodoo); - break; - - case COMMAND_CMD_HOST_TO_SCREEN_BLT: - banshee_do_2d_blit(voodoo, 32, val); - break; - - case COMMAND_CMD_HOST_TO_SCREEN_STRETCH_BLT: - banshee_do_2d_blit(voodoo, 32, val); - break; - - case COMMAND_CMD_RECTFILL: - voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_rectfill(voodoo); - break; - - case COMMAND_CMD_LINE: - voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_line(voodoo, 1); - break; - - case COMMAND_CMD_POLYLINE: - voodoo->banshee_blt.dstXY = val; - voodoo->banshee_blt.dstX = ((int32_t)(val << 19)) >> 19; - voodoo->banshee_blt.dstY = ((int32_t)(val << 3)) >> 19; - banshee_do_line(voodoo, 0); - break; - - case COMMAND_CMD_POLYFILL: - banshee_polyfill_continue(voodoo, val); - break; - - default: - fatal("launch area write, command=%08x\n", voodoo->banshee_blt.command); - } - break; - - case 0x100: case 0x104: case 0x108: case 0x10c: - case 0x110: case 0x114: case 0x118: case 0x11c: - case 0x120: case 0x124: case 0x128: case 0x12c: - case 0x130: case 0x134: case 0x138: case 0x13c: - case 0x140: case 0x144: case 0x148: case 0x14c: - case 0x150: case 0x154: case 0x158: case 0x15c: - case 0x160: case 0x164: case 0x168: case 0x16c: - case 0x170: case 0x174: case 0x178: case 0x17c: - case 0x180: case 0x184: case 0x188: case 0x18c: - case 0x190: case 0x194: case 0x198: case 0x19c: - case 0x1a0: case 0x1a4: case 0x1a8: case 0x1ac: - case 0x1b0: case 0x1b4: case 0x1b8: case 0x1bc: - case 0x1c0: case 0x1c4: case 0x1c8: case 0x1cc: - case 0x1d0: case 0x1d4: case 0x1d8: case 0x1dc: - case 0x1e0: case 0x1e4: case 0x1e8: case 0x1ec: - case 0x1f0: case 0x1f4: case 0x1f8: case 0x1fc: - voodoo->banshee_blt.colorPattern[(addr >> 2) & 63] = val; - if ((addr & 0x1fc) < 0x1c0) - { - int base_addr = (addr & 0xfc) / 0xc; - uintptr_t src_p = (uintptr_t)&voodoo->banshee_blt.colorPattern[base_addr * 3]; - int col24 = base_addr * 4; - - voodoo->banshee_blt.colorPattern24[col24] = *(uint32_t *)src_p & 0xffffff; - voodoo->banshee_blt.colorPattern24[col24 + 1] = *(uint32_t *)(src_p + 3) & 0xffffff; - voodoo->banshee_blt.colorPattern24[col24 + 2] = *(uint32_t *)(src_p + 6) & 0xffffff; - voodoo->banshee_blt.colorPattern24[col24 + 3] = *(uint32_t *)(src_p + 9) & 0xffffff; - } - if ((addr & 0x1fc) < 0x180) - { - voodoo->banshee_blt.colorPattern16[(addr >> 1) & 62] = val & 0xffff; - voodoo->banshee_blt.colorPattern16[((addr >> 1) & 62) + 1] = (val >> 16) & 0xffff; - } - if ((addr & 0x1fc) < 0x140) - { - voodoo->banshee_blt.colorPattern8[addr & 60] = val & 0xff; - voodoo->banshee_blt.colorPattern8[(addr & 60) + 1] = (val >> 8) & 0xff; - voodoo->banshee_blt.colorPattern8[(addr & 60) + 2] = (val >> 16) & 0xff; - voodoo->banshee_blt.colorPattern8[(addr & 60) + 3] = (val >> 24) & 0xff; - } -// bansheeblt_log("colorPattern%02x=%08x\n", (addr >> 2) & 63, val); - break; - - default: - fatal("Unknown 2D reg write %03x %08x\n", addr & 0x1fc, val); - } + fatal("launch area write, command=%08x\n", voodoo->banshee_blt.command); + } + break; + + case 0x100: + case 0x104: + case 0x108: + case 0x10c: + case 0x110: + case 0x114: + case 0x118: + case 0x11c: + case 0x120: + case 0x124: + case 0x128: + case 0x12c: + case 0x130: + case 0x134: + case 0x138: + case 0x13c: + case 0x140: + case 0x144: + case 0x148: + case 0x14c: + case 0x150: + case 0x154: + case 0x158: + case 0x15c: + case 0x160: + case 0x164: + case 0x168: + case 0x16c: + case 0x170: + case 0x174: + case 0x178: + case 0x17c: + case 0x180: + case 0x184: + case 0x188: + case 0x18c: + case 0x190: + case 0x194: + case 0x198: + case 0x19c: + case 0x1a0: + case 0x1a4: + case 0x1a8: + case 0x1ac: + case 0x1b0: + case 0x1b4: + case 0x1b8: + case 0x1bc: + case 0x1c0: + case 0x1c4: + case 0x1c8: + case 0x1cc: + case 0x1d0: + case 0x1d4: + case 0x1d8: + case 0x1dc: + case 0x1e0: + case 0x1e4: + case 0x1e8: + case 0x1ec: + case 0x1f0: + case 0x1f4: + case 0x1f8: + case 0x1fc: + voodoo->banshee_blt.colorPattern[(addr >> 2) & 63] = val; + if ((addr & 0x1fc) < 0x1c0) { + int base_addr = (addr & 0xfc) / 0xc; + uintptr_t src_p = (uintptr_t) &voodoo->banshee_blt.colorPattern[base_addr * 3]; + int col24 = base_addr * 4; + + voodoo->banshee_blt.colorPattern24[col24] = *(uint32_t *) src_p & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 1] = *(uint32_t *) (src_p + 3) & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 2] = *(uint32_t *) (src_p + 6) & 0xffffff; + voodoo->banshee_blt.colorPattern24[col24 + 3] = *(uint32_t *) (src_p + 9) & 0xffffff; + } + if ((addr & 0x1fc) < 0x180) { + voodoo->banshee_blt.colorPattern16[(addr >> 1) & 62] = val & 0xffff; + voodoo->banshee_blt.colorPattern16[((addr >> 1) & 62) + 1] = (val >> 16) & 0xffff; + } + if ((addr & 0x1fc) < 0x140) { + voodoo->banshee_blt.colorPattern8[addr & 60] = val & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 1] = (val >> 8) & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 2] = (val >> 16) & 0xff; + voodoo->banshee_blt.colorPattern8[(addr & 60) + 3] = (val >> 24) & 0xff; + } + // bansheeblt_log("colorPattern%02x=%08x\n", (addr >> 2) & 63, val); + break; + + default: + fatal("Unknown 2D reg write %03x %08x\n", addr & 0x1fc, val); + } } diff --git a/src/video/vid_voodoo_blitter.c b/src/video/vid_voodoo_blitter.c index 94fb9dfa1..9ffeb9553 100644 --- a/src/video/vid_voodoo_blitter.c +++ b/src/video/vid_voodoo_blitter.c @@ -39,519 +39,479 @@ #include <86box/vid_voodoo_regs.h> #include <86box/vid_voodoo_render.h> - -enum -{ - BLIT_COMMAND_SCREEN_TO_SCREEN = 0, - BLIT_COMMAND_CPU_TO_SCREEN = 1, - BLIT_COMMAND_RECT_FILL = 2, - BLIT_COMMAND_SGRAM_FILL = 3 +enum { + BLIT_COMMAND_SCREEN_TO_SCREEN = 0, + BLIT_COMMAND_CPU_TO_SCREEN = 1, + BLIT_COMMAND_RECT_FILL = 2, + BLIT_COMMAND_SGRAM_FILL = 3 }; -enum -{ - BLIT_SRC_1BPP = (0 << 3), - BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3), - BLIT_SRC_16BPP = (2 << 3), - BLIT_SRC_24BPP = (3 << 3), - BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3), - BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3) +enum { + BLIT_SRC_1BPP = (0 << 3), + BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3), + BLIT_SRC_16BPP = (2 << 3), + BLIT_SRC_24BPP = (3 << 3), + BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3), + BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3) }; -enum -{ - BLIT_SRC_RGB_ARGB = (0 << 6), - BLIT_SRC_RGB_ABGR = (1 << 6), - BLIT_SRC_RGB_RGBA = (2 << 6), - BLIT_SRC_RGB_BGRA = (3 << 6) +enum { + BLIT_SRC_RGB_ARGB = (0 << 6), + BLIT_SRC_RGB_ABGR = (1 << 6), + BLIT_SRC_RGB_RGBA = (2 << 6), + BLIT_SRC_RGB_BGRA = (3 << 6) }; -enum -{ - BLIT_COMMAND_MASK = 7, - BLIT_SRC_FORMAT = (7 << 3), - BLIT_SRC_RGB_FORMAT = (3 << 6), - BLIT_SRC_CHROMA = (1 << 10), - BLIT_DST_CHROMA = (1 << 12), - BLIT_CLIPPING_ENABLED = (1 << 16) +enum { + BLIT_COMMAND_MASK = 7, + BLIT_SRC_FORMAT = (7 << 3), + BLIT_SRC_RGB_FORMAT = (3 << 6), + BLIT_SRC_CHROMA = (1 << 10), + BLIT_DST_CHROMA = (1 << 12), + BLIT_CLIPPING_ENABLED = (1 << 16) }; -enum -{ - BLIT_ROP_DST_PASS = (1 << 0), - BLIT_ROP_SRC_PASS = (1 << 1) +enum { + BLIT_ROP_DST_PASS = (1 << 0), + BLIT_ROP_SRC_PASS = (1 << 1) }; - #ifdef ENABLE_VOODOOBLT_LOG int voodooblt_do_log = ENABLE_VOODOOBLT_LOG; - static void voodooblt_log(const char *fmt, ...) { va_list ap; if (voodooblt_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodooblt_log(fmt, ...) +# define voodooblt_log(fmt, ...) #endif +#define MIX(src_dat, dst_dat, rop) \ + switch (rop) { \ + case 0x0: \ + dst_dat = 0; \ + break; \ + case 0x1: \ + dst_dat = ~(src_dat | dst_dat); \ + break; \ + case 0x2: \ + dst_dat = ~src_dat & dst_dat; \ + break; \ + case 0x3: \ + dst_dat = ~src_dat; \ + break; \ + case 0x4: \ + dst_dat = src_dat & ~dst_dat; \ + break; \ + case 0x5: \ + dst_dat = ~dst_dat; \ + break; \ + case 0x6: \ + dst_dat = src_dat ^ dst_dat; \ + break; \ + case 0x7: \ + dst_dat = ~(src_dat & dst_dat); \ + break; \ + case 0x8: \ + dst_dat = src_dat & dst_dat; \ + break; \ + case 0x9: \ + dst_dat = ~(src_dat ^ dst_dat); \ + break; \ + case 0xa: \ + dst_dat = dst_dat; \ + break; \ + case 0xb: \ + dst_dat = ~src_dat | dst_dat; \ + break; \ + case 0xc: \ + dst_dat = src_dat; \ + break; \ + case 0xd: \ + dst_dat = src_dat | ~dst_dat; \ + break; \ + case 0xe: \ + dst_dat = src_dat | dst_dat; \ + break; \ + case 0xf: \ + dst_dat = 0xffff; \ + break; \ + } -#define MIX(src_dat, dst_dat, rop) \ - switch (rop) \ - { \ - case 0x0: dst_dat = 0; break; \ - case 0x1: dst_dat = ~(src_dat | dst_dat); break; \ - case 0x2: dst_dat = ~src_dat & dst_dat; break; \ - case 0x3: dst_dat = ~src_dat; break; \ - case 0x4: dst_dat = src_dat & ~dst_dat; break; \ - case 0x5: dst_dat = ~dst_dat; break; \ - case 0x6: dst_dat = src_dat ^ dst_dat; break; \ - case 0x7: dst_dat = ~(src_dat & dst_dat); break; \ - case 0x8: dst_dat = src_dat & dst_dat; break; \ - case 0x9: dst_dat = ~(src_dat ^ dst_dat); break; \ - case 0xa: dst_dat = dst_dat; break; \ - case 0xb: dst_dat = ~src_dat | dst_dat; break; \ - case 0xc: dst_dat = src_dat; break; \ - case 0xd: dst_dat = src_dat | ~dst_dat; break; \ - case 0xe: dst_dat = src_dat | dst_dat; break; \ - case 0xf: dst_dat = 0xffff; break; \ - } - -void voodoo_v2_blit_start(voodoo_t *voodoo) +void +voodoo_v2_blit_start(voodoo_t *voodoo) { - uint64_t dat64; - int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); - int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; - int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; - int dst_x; - int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; - int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32*2) : (voodoo->bltSrcXYStride & 0xff8); - int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); - uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); - uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - int x, y; + uint64_t dat64; + int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); + int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; + int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; + int dst_x; + int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; + int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32 * 2) : (voodoo->bltSrcXYStride & 0xff8); + int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); + uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8); + uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); + int x, y; -/* voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", - voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ + /* voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n", + voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/ - voodoo_wait_for_render_thread_idle(voodoo); + voodoo_wait_for_render_thread_idle(voodoo); - switch (voodoo->bltCommand & BLIT_COMMAND_MASK) - { - case BLIT_COMMAND_SCREEN_TO_SCREEN: - for (y = 0; y <= size_y; y++) - { - uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y*src_stride]; - uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; - int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX; + switch (voodoo->bltCommand & BLIT_COMMAND_MASK) { + case BLIT_COMMAND_SCREEN_TO_SCREEN: + for (y = 0; y <= size_y; y++) { + uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride]; + uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; + int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX; - for (x = 0; x <= size_x; x++) - { - uint16_t src_dat = src[src_x]; - uint16_t dst_dat = dst[dst_x]; - int rop = 0; + for (x = 0; x <= size_x; x++) { + uint16_t src_dat = src[src_x]; + uint16_t dst_dat = dst[dst_x]; + int rop = 0; - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_blit; - } + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) + goto skip_pixel_blit; + } - if (voodoo->bltCommand & BLIT_SRC_CHROMA) - { - int r = (src_dat >> 11); - int g = (src_dat >> 5) & 0x3f; - int b = src_dat & 0x1f; + if (voodoo->bltCommand & BLIT_SRC_CHROMA) { + int r = (src_dat >> 11); + int g = (src_dat >> 5) & 0x3f; + int b = src_dat & 0x1f; - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) - { - int r = (dst_dat >> 11); - int g = (dst_dat >> 5) & 0x3f; - int b = dst_dat & 0x1f; + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) { + int r = (dst_dat >> 11); + int g = (dst_dat >> 5) & 0x3f; + int b = dst_dat & 0x1f; - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); - dst[dst_x] = dst_dat; + dst[dst_x] = dst_dat; skip_pixel_blit: - src_x += x_dir; - dst_x += x_dir; - } - - src_y += y_dir; - dst_y += y_dir; + src_x += x_dir; + dst_x += x_dir; } - break; - case BLIT_COMMAND_CPU_TO_SCREEN: - voodoo->blt.dst_x = voodoo->bltDstX; - voodoo->blt.dst_y = voodoo->bltDstY; - voodoo->blt.cur_x = 0; - voodoo->blt.size_x = size_x; - voodoo->blt.size_y = size_y; - voodoo->blt.x_dir = x_dir; - voodoo->blt.y_dir = y_dir; - voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); - break; + src_y += y_dir; + dst_y += y_dir; + } + break; - case BLIT_COMMAND_RECT_FILL: - for (y = 0; y <= size_y; y++) - { - uint16_t *dst; - int dst_x = voodoo->bltDstX; + case BLIT_COMMAND_CPU_TO_SCREEN: + voodoo->blt.dst_x = voodoo->bltDstX; + voodoo->blt.dst_y = voodoo->bltDstY; + voodoo->blt.cur_x = 0; + voodoo->blt.size_x = size_x; + voodoo->blt.size_y = size_y; + voodoo->blt.x_dir = x_dir; + voodoo->blt.y_dir = y_dir; + voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8); + break; - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_line_fill; - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; - } - else - dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride]; + case BLIT_COMMAND_RECT_FILL: + for (y = 0; y <= size_y; y++) { + uint16_t *dst; + int dst_x = voodoo->bltDstX; - for (x = 0; x <= size_x; x++) - { - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || - dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) - goto skip_pixel_fill; - } + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_line_fill; + dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride]; + } else + dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride]; - dst[dst_x] = voodoo->bltColorFg; + for (x = 0; x <= size_x; x++) { + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { + if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY) + goto skip_pixel_fill; + } + + dst[dst_x] = voodoo->bltColorFg; skip_pixel_fill: - dst_x += x_dir; - } + dst_x += x_dir; + } skip_line_fill: - dst_y += y_dir; + dst_y += y_dir; + } + break; + + case BLIT_COMMAND_SGRAM_FILL: + /*32x32 tiles - 2kb*/ + dst_y = voodoo->bltDstY & 0x3ff; + size_x = voodoo->bltSizeX & 0x1ff; // 512*8 = 4kb + size_y = voodoo->bltSizeY & 0x3ff; + + dat64 = voodoo->bltColorFg | ((uint64_t) voodoo->bltColorFg << 16) | ((uint64_t) voodoo->bltColorFg << 32) | ((uint64_t) voodoo->bltColorFg << 48); + + for (y = 0; y <= size_y; y++) { + uint64_t *dst; + + /*This may be wrong*/ + if (!y) { + dst_x = voodoo->bltDstX & 0x1ff; + size_x = 511 - dst_x; + } else if (y < size_y) { + dst_x = 0; + size_x = 511; + } else { + dst_x = 0; + size_x = voodoo->bltSizeX & 0x1ff; } - break; - case BLIT_COMMAND_SGRAM_FILL: - /*32x32 tiles - 2kb*/ - dst_y = voodoo->bltDstY & 0x3ff; - size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb - size_y = voodoo->bltSizeY & 0x3ff; + dst = (uint64_t *) &voodoo->fb_mem[(dst_y * 512 * 8 + dst_x * 8) & voodoo->fb_mask]; - dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | - ((uint64_t)voodoo->bltColorFg << 32) | ((uint64_t)voodoo->bltColorFg << 48); + for (x = 0; x <= size_x; x++) + dst[x] = dat64; - for (y = 0; y <= size_y; y++) - { - uint64_t *dst; + dst_y++; + } + break; - /*This may be wrong*/ - if (!y) - { - dst_x = voodoo->bltDstX & 0x1ff; - size_x = 511 - dst_x; - } - else if (y < size_y) - { - dst_x = 0; - size_x = 511; - } - else - { - dst_x = 0; - size_x = voodoo->bltSizeX & 0x1ff; - } - - dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask]; - - for (x = 0; x <= size_x; x++) - dst[x] = dat64; - - dst_y++; - } - break; - - default: - fatal("bad blit command %08x\n", voodoo->bltCommand); - } + default: + fatal("bad blit command %08x\n", voodoo->bltCommand); + } } -void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) +void +voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data) { - int src_bits = 32; - uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); - uint32_t addr; - uint16_t *dst; + int src_bits = 32; + uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); + uint32_t addr; + uint16_t *dst; - if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) - return; + if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN) + return; - if (SLI_ENABLED) - { - addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } - else - { - addr = base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride; - dst = (uint16_t *)&voodoo->fb_mem[addr]; - } + if (SLI_ENABLED) { + addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride; + dst = (uint16_t *) &voodoo->fb_mem[addr]; + } else { + addr = base_addr + voodoo->blt.dst_y * voodoo->blt.dst_stride; + dst = (uint16_t *) &voodoo->fb_mem[addr]; + } - if (addr >= voodoo->front_offset && voodoo->row_width) - { - int y = (addr - voodoo->front_offset) / voodoo->row_width; - if (y < voodoo->v_disp) - voodoo->dirty_line[y] = 2; - } + if (addr >= voodoo->front_offset && voodoo->row_width) { + int y = (addr - voodoo->front_offset) / voodoo->row_width; + if (y < voodoo->v_disp) + voodoo->dirty_line[y] = 2; + } - while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) - { - int r = 0, g = 0, b = 0; - uint16_t src_dat = 0, dst_dat; - int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x); - int rop = 0; + while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) { + int r = 0, g = 0, b = 0; + uint16_t src_dat = 0, dst_dat; + int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x); + int rop = 0; - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) - { - case BLIT_SRC_1BPP: case BLIT_SRC_1BPP_BYTE_PACKED: - src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg; - data >>= 1; - src_bits--; + switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { + case BLIT_SRC_1BPP: + case BLIT_SRC_1BPP_BYTE_PACKED: + src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg; + data >>= 1; + src_bits--; + break; + case BLIT_SRC_16BPP: + switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) { + case BLIT_SRC_RGB_ARGB: + case BLIT_SRC_RGB_RGBA: + src_dat = data & 0xffff; break; - case BLIT_SRC_16BPP: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) - { - case BLIT_SRC_RGB_ARGB: case BLIT_SRC_RGB_RGBA: - src_dat = data & 0xffff; - break; - case BLIT_SRC_RGB_ABGR: case BLIT_SRC_RGB_BGRA: - src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); - break; - } - data >>= 16; - src_bits -= 16; - break; - case BLIT_SRC_24BPP: case BLIT_SRC_24BPP_DITHER_2X2: case BLIT_SRC_24BPP_DITHER_4X4: - switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) - { - case BLIT_SRC_RGB_ARGB: - r = (data >> 16) & 0xff; - g = (data >> 8) & 0xff; - b = data & 0xff; - break; - case BLIT_SRC_RGB_ABGR: - r = data & 0xff; - g = (data >> 8) & 0xff; - b = (data >> 16) & 0xff; - break; - case BLIT_SRC_RGB_RGBA: - r = (data >> 24) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 8) & 0xff; - break; - case BLIT_SRC_RGB_BGRA: - r = (data >> 8) & 0xff; - g = (data >> 16) & 0xff; - b = (data >> 24) & 0xff; - break; - } - switch (voodoo->bltCommand & BLIT_SRC_FORMAT) - { - case BLIT_SRC_24BPP: - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_2X2: - r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1]; - g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1]; - b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - case BLIT_SRC_24BPP_DITHER_4X4: - r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3]; - g = dither_g[g][voodoo->blt.dst_y & 3][x & 3]; - b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; - src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); - break; - } - src_bits = 0; + case BLIT_SRC_RGB_ABGR: + case BLIT_SRC_RGB_BGRA: + src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11); break; } - - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) - goto skip_pixel; + data >>= 16; + src_bits -= 16; + break; + case BLIT_SRC_24BPP: + case BLIT_SRC_24BPP_DITHER_2X2: + case BLIT_SRC_24BPP_DITHER_4X4: + switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) { + case BLIT_SRC_RGB_ARGB: + r = (data >> 16) & 0xff; + g = (data >> 8) & 0xff; + b = data & 0xff; + break; + case BLIT_SRC_RGB_ABGR: + r = data & 0xff; + g = (data >> 8) & 0xff; + b = (data >> 16) & 0xff; + break; + case BLIT_SRC_RGB_RGBA: + r = (data >> 24) & 0xff; + g = (data >> 16) & 0xff; + b = (data >> 8) & 0xff; + break; + case BLIT_SRC_RGB_BGRA: + r = (data >> 8) & 0xff; + g = (data >> 16) & 0xff; + b = (data >> 24) & 0xff; + break; } - - if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) - { - if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || - voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY) - goto skip_pixel; + switch (voodoo->bltCommand & BLIT_SRC_FORMAT) { + case BLIT_SRC_24BPP: + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + case BLIT_SRC_24BPP_DITHER_2X2: + r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1]; + g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1]; + b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1]; + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; + case BLIT_SRC_24BPP_DITHER_4X4: + r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3]; + g = dither_g[g][voodoo->blt.dst_y & 3][x & 3]; + b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3]; + src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8); + break; } + src_bits = 0; + break; + } - dst_dat = dst[x]; + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1))) + goto skip_pixel; + } - if (voodoo->bltCommand & BLIT_SRC_CHROMA) - { - r = (src_dat >> 11); - g = (src_dat >> 5) & 0x3f; - b = src_dat & 0x1f; + if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { + if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY) + goto skip_pixel; + } - if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && - g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && - b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) - rop |= BLIT_ROP_SRC_PASS; - } - if (voodoo->bltCommand & BLIT_DST_CHROMA) - { - r = (dst_dat >> 11); - g = (dst_dat >> 5) & 0x3f; - b = dst_dat & 0x1f; + dst_dat = dst[x]; - if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && - g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && - b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) - rop |= BLIT_ROP_DST_PASS; - } + if (voodoo->bltCommand & BLIT_SRC_CHROMA) { + r = (src_dat >> 11); + g = (src_dat >> 5) & 0x3f; + b = src_dat & 0x1f; - MIX(src_dat, dst_dat, voodoo->bltRop[rop]); + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) { + r = (dst_dat >> 11); + g = (dst_dat >> 5) & 0x3f; + b = dst_dat & 0x1f; - dst[x] = dst_dat; + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } + + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); + + dst[x] = dst_dat; skip_pixel: - voodoo->blt.cur_x++; - } + voodoo->blt.cur_x++; + } - if (voodoo->blt.cur_x > voodoo->blt.size_x) - { - voodoo->blt.size_y--; - if (voodoo->blt.size_y >= 0) - { - voodoo->blt.cur_x = 0; - voodoo->blt.dst_y += voodoo->blt.y_dir; - } + if (voodoo->blt.cur_x > voodoo->blt.size_x) { + voodoo->blt.size_y--; + if (voodoo->blt.size_y >= 0) { + voodoo->blt.cur_x = 0; + voodoo->blt.dst_y += voodoo->blt.y_dir; } + } } - -void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) +void +voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { - int y; - int low_y, high_y; + int y; + int low_y, high_y; - if (params->fbzMode & (1 << 17)) - { - int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap+1) : voodoo->v_disp; + if (params->fbzMode & (1 << 17)) { + int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap + 1) : voodoo->v_disp; - high_y = y_origin - params->clipLowY; - low_y = y_origin - params->clipHighY; - } - else - { - low_y = params->clipLowY; - high_y = params->clipHighY; - } + high_y = y_origin - params->clipLowY; + low_y = y_origin - params->clipHighY; + } else { + low_y = params->clipLowY; + high_y = params->clipHighY; + } - if (params->fbzMode & FBZ_RGB_WMASK) - { - int r, g, b; - uint16_t col; + if (params->fbzMode & FBZ_RGB_WMASK) { + int r, g, b; + uint16_t col; - r = ((params->color1 >> 16) >> 3) & 0x1f; - g = ((params->color1 >> 8) >> 2) & 0x3f; - b = (params->color1 >> 3) & 0x1f; - col = b | (g << 5) | (r << 11); + r = ((params->color1 >> 16) >> 3) & 0x1f; + g = ((params->color1 >> 8) >> 2) & 0x3f; + b = (params->color1 >> 3) & 0x1f; + col = b | (g << 5) | (r << 11); - if (SLI_ENABLED) - { - for (y = low_y; y < high_y; y += 2) - { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; + if (SLI_ENABLED) { + for (y = low_y; y < high_y; y += 2) { + uint16_t *cbuf = (uint16_t *) &voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } - else - { - for (y = low_y; y < high_y; y++) - { - if (voodoo->col_tiled) - { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - { - int x2 = (x & 63) | ((x >> 6) * 128*32/2); - cbuf[x2] = col; - } - } - else - { - uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - cbuf[x] = col; - } - } + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; + } + } else { + for (y = low_y; y < high_y; y++) { + if (voodoo->col_tiled) { + uint16_t *cbuf = (uint16_t *) &voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) { + int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2); + cbuf[x2] = col; + } + } else { + uint16_t *cbuf = (uint16_t *) &voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + cbuf[x] = col; } + } } - if (params->fbzMode & FBZ_DEPTH_WMASK) - { - if (SLI_ENABLED) - { - for (y = low_y; y < high_y; y += 2) - { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; - int x; + } + if (params->fbzMode & FBZ_DEPTH_WMASK) { + if (SLI_ENABLED) { + for (y = low_y; y < high_y; y += 2) { + uint16_t *abuf = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask]; + int x; - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } - else - { - for (y = low_y; y < high_y; y++) - { - if (voodoo->aux_tiled) - { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - { - int x2 = (x & 63) | ((x >> 6) * 128*32/2); - abuf[x2] = params->zaColor & 0xffff; - } - } - else - { - uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask]; - int x; - - for (x = params->clipLeft; x < params->clipRight; x++) - abuf[x] = params->zaColor & 0xffff; - } - } + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; + } + } else { + for (y = low_y; y < high_y; y++) { + if (voodoo->aux_tiled) { + uint16_t *abuf = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) { + int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2); + abuf[x2] = params->zaColor & 0xffff; + } + } else { + uint16_t *abuf = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask]; + int x; + + for (x = params->clipLeft; x < params->clipRight; x++) + abuf[x] = params->zaColor & 0xffff; } + } } + } } diff --git a/src/video/vid_voodoo_display.c b/src/video/vid_voodoo_display.c index 8e4e952d2..071e29df2 100644 --- a/src/video/vid_voodoo_display.c +++ b/src/video/vid_voodoo_display.c @@ -37,643 +37,609 @@ #include <86box/vid_voodoo_regs.h> #include <86box/vid_voodoo_render.h> - #ifdef ENABLE_VOODOODISP_LOG int voodoodisp_do_log = ENABLE_VOODOODISP_LOG; - static void voodoodisp_log(const char *fmt, ...) { va_list ap; if (voodoodisp_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoodisp_log(fmt, ...) +# define voodoodisp_log(fmt, ...) #endif -void voodoo_update_ncc(voodoo_t *voodoo, int tmu) +void +voodoo_update_ncc(voodoo_t *voodoo, int tmu) { - int tbl; + int tbl; - for (tbl = 0; tbl < 2; tbl++) - { - int col; + for (tbl = 0; tbl < 2; tbl++) { + int col; - for (col = 0; col < 256; col++) - { - int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; - int i_r, i_g, i_b; - int q_r, q_g, q_b; + for (col = 0; col < 256; col++) { + int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; + int i_r, i_g, i_b; + int q_r, q_g, q_b; - y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; + y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; - i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff; - if (i_r & 0x100) - i_r |= 0xfffffe00; - i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff; - if (i_g & 0x100) - i_g |= 0xfffffe00; - i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff; - if (i_b & 0x100) - i_b |= 0xfffffe00; + i_r = (voodoo->nccTable[tmu][tbl].i[i] >> 18) & 0x1ff; + if (i_r & 0x100) + i_r |= 0xfffffe00; + i_g = (voodoo->nccTable[tmu][tbl].i[i] >> 9) & 0x1ff; + if (i_g & 0x100) + i_g |= 0xfffffe00; + i_b = voodoo->nccTable[tmu][tbl].i[i] & 0x1ff; + if (i_b & 0x100) + i_b |= 0xfffffe00; - q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff; - if (q_r & 0x100) - q_r |= 0xfffffe00; - q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff; - if (q_g & 0x100) - q_g |= 0xfffffe00; - q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff; - if (q_b & 0x100) - q_b |= 0xfffffe00; + q_r = (voodoo->nccTable[tmu][tbl].q[q] >> 18) & 0x1ff; + if (q_r & 0x100) + q_r |= 0xfffffe00; + q_g = (voodoo->nccTable[tmu][tbl].q[q] >> 9) & 0x1ff; + if (q_g & 0x100) + q_g |= 0xfffffe00; + q_b = voodoo->nccTable[tmu][tbl].q[q] & 0x1ff; + if (q_b & 0x100) + q_b |= 0xfffffe00; - voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r); - voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g); - voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b); - voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff; - } + voodoo->ncc_lookup[tmu][tbl][col].rgba.r = CLAMP(y + i_r + q_r); + voodoo->ncc_lookup[tmu][tbl][col].rgba.g = CLAMP(y + i_g + q_g); + voodoo->ncc_lookup[tmu][tbl][col].rgba.b = CLAMP(y + i_b + q_b); + voodoo->ncc_lookup[tmu][tbl][col].rgba.a = 0xff; } + } } -void voodoo_pixelclock_update(voodoo_t *voodoo) +void +voodoo_pixelclock_update(voodoo_t *voodoo) { - int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2; - int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2; - int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07); - float t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); - double clock_const; - int line_length; + int m = (voodoo->dac_pll_regs[0] & 0x7f) + 2; + int n1 = ((voodoo->dac_pll_regs[0] >> 8) & 0x1f) + 2; + int n2 = ((voodoo->dac_pll_regs[0] >> 13) & 0x07); + float t = (14318184.0 * ((float) m / (float) n1)) / (float) (1 << n2); + double clock_const; + int line_length; - if ((voodoo->dac_data[6] & 0xf0) == 0x20 || - (voodoo->dac_data[6] & 0xf0) == 0x60 || - (voodoo->dac_data[6] & 0xf0) == 0x70) - t /= 2.0f; + if ((voodoo->dac_data[6] & 0xf0) == 0x20 || (voodoo->dac_data[6] & 0xf0) == 0x60 || (voodoo->dac_data[6] & 0xf0) == 0x70) + t /= 2.0f; - line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); + line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); -// voodoodisp_log("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); + // voodoodisp_log("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); - voodoo->pixel_clock = t; + voodoo->pixel_clock = t; - clock_const = cpuclock / t; - voodoo->line_time = (uint64_t)((double)line_length * clock_const * (double)(1ull << 32)); + clock_const = cpuclock / t; + voodoo->line_time = (uint64_t) ((double) line_length * clock_const * (double) (1ull << 32)); } -static void voodoo_calc_clutData(voodoo_t *voodoo) +static void +voodoo_calc_clutData(voodoo_t *voodoo) { - int c; + int c; - for (c = 0; c < 256; c++) - { - voodoo->clutData256[c].r = (voodoo->clutData[c >> 3].r*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].r*(c & 7)) >> 3; - voodoo->clutData256[c].g = (voodoo->clutData[c >> 3].g*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].g*(c & 7)) >> 3; - voodoo->clutData256[c].b = (voodoo->clutData[c >> 3].b*(8-(c & 7)) + - voodoo->clutData[(c >> 3)+1].b*(c & 7)) >> 3; - } + for (c = 0; c < 256; c++) { + voodoo->clutData256[c].r = (voodoo->clutData[c >> 3].r * (8 - (c & 7)) + voodoo->clutData[(c >> 3) + 1].r * (c & 7)) >> 3; + voodoo->clutData256[c].g = (voodoo->clutData[c >> 3].g * (8 - (c & 7)) + voodoo->clutData[(c >> 3) + 1].g * (c & 7)) >> 3; + voodoo->clutData256[c].b = (voodoo->clutData[c >> 3].b * (8 - (c & 7)) + voodoo->clutData[(c >> 3) + 1].b * (c & 7)) >> 3; + } - for (c = 0; c < 65536; c++) - { - int r = (c >> 8) & 0xf8; - int g = (c >> 3) & 0xfc; - int b = (c << 3) & 0xf8; -// r |= (r >> 5); -// g |= (g >> 6); -// b |= (b >> 5); + for (c = 0; c < 65536; c++) { + int r = (c >> 8) & 0xf8; + int g = (c >> 3) & 0xfc; + int b = (c << 3) & 0xf8; + // r |= (r >> 5); + // g |= (g >> 6); + // b |= (b >> 5); - voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; - } + voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; + } } - - #define FILTDIV 256 -static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ +static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ -void voodoo_generate_filter_v1(voodoo_t *voodoo) +void +voodoo_generate_filter_v1(voodoo_t *voodoo) { - int g, h; - float difference, diffg, diffb; - float thiscol, thiscolg, thiscolb, lined; - float fcr, fcg, fcb; + int g, h; + float difference, diffg, diffb; + float thiscol, thiscolg, thiscolb, lined; + float fcr, fcg, fcb; - fcr = FILTCAP * 5; - fcg = FILTCAPG * 6; - fcb = FILTCAPB * 5; + fcr = FILTCAP * 5; + fcg = FILTCAPG * 6; + fcb = FILTCAPB * 5; - for (g=0;g FILTCAP) - difference = FILTCAP; - if (difference < -FILTCAP) - difference = -FILTCAP; + if (difference > FILTCAP) + difference = FILTCAP; + if (difference < -FILTCAP) + difference = -FILTCAP; - if (diffg > FILTCAPG) - diffg = FILTCAPG; - if (diffg < -FILTCAPG) - diffg = -FILTCAPG; + if (diffg > FILTCAPG) + diffg = FILTCAPG; + if (diffg < -FILTCAPG) + diffg = -FILTCAPG; - if (diffb > FILTCAPB) - diffb = FILTCAPB; - if (diffb < -FILTCAPB) - diffb = -FILTCAPB; + if (diffb > FILTCAPB) + diffb = FILTCAPB; + if (diffb < -FILTCAPB) + diffb = -FILTCAPB; - // hack - to make it not bleed onto black - //if (g == 0){ - //difference = diffg = diffb = 0; - //} + // hack - to make it not bleed onto black + // if (g == 0){ + // difference = diffg = diffb = 0; + //} - if ((difference < fcr) || (-difference > -fcr)) - thiscol = g + (difference / 2); - if ((diffg < fcg) || (-diffg > -fcg)) - thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ - if ((diffb < fcb) || (-diffb > -fcb)) - thiscolb = g + (diffb / 2); + if ((difference < fcr) || (-difference > -fcr)) + thiscol = g + (difference / 2); + if ((diffg < fcg) || (-diffg > -fcg)) + thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ + if ((diffb < fcb) || (-diffb > -fcb)) + thiscolb = g + (diffb / 2); - if (thiscol < 0) - thiscol = 0; - if (thiscol > FILTDIV-1) - thiscol = FILTDIV-1; + if (thiscol < 0) + thiscol = 0; + if (thiscol > FILTDIV - 1) + thiscol = FILTDIV - 1; - if (thiscolg < 0) - thiscolg = 0; - if (thiscolg > FILTDIV-1) - thiscolg = FILTDIV-1; + if (thiscolg < 0) + thiscolg = 0; + if (thiscolg > FILTDIV - 1) + thiscolg = FILTDIV - 1; - if (thiscolb < 0) - thiscolb = 0; - if (thiscolb > FILTDIV-1) - thiscolb = FILTDIV-1; + if (thiscolb < 0) + thiscolb = 0; + if (thiscolb > FILTDIV - 1) + thiscolb = FILTDIV - 1; - voodoo->thefilter[g][h] = thiscol; - voodoo->thefilterg[g][h] = thiscolg; - voodoo->thefilterb[g][h] = thiscolb; - } - - lined = g + 4; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][0] = lined; - voodoo->purpleline[g][2] = lined; - - lined = g + 0; - if (lined > 255) - lined = 255; - voodoo->purpleline[g][1] = lined; + voodoo->thefilter[g][h] = thiscol; + voodoo->thefilterg[g][h] = thiscolg; + voodoo->thefilterb[g][h] = thiscolb; } + + lined = g + 4; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][0] = lined; + voodoo->purpleline[g][2] = lined; + + lined = g + 0; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][1] = lined; + } } -void voodoo_generate_filter_v2(voodoo_t *voodoo) +void +voodoo_generate_filter_v2(voodoo_t *voodoo) { - int g, h; - float difference; - float thiscol, thiscolg, thiscolb; - float clr, clg, clb = 0; - float fcr, fcg, fcb = 0; + int g, h; + float difference; + float thiscol, thiscolg, thiscolb; + float clr, clg, clb = 0; + float fcr, fcg, fcb = 0; - // pre-clamping + // pre-clamping - fcr = FILTCAP; - fcg = FILTCAPG; - fcb = FILTCAPB; + fcr = FILTCAP; + fcg = FILTCAPG; + fcb = FILTCAPB; - if (fcr > 32) fcr = 32; - if (fcg > 32) fcg = 32; - if (fcb > 32) fcb = 32; + if (fcr > 32) + fcr = 32; + if (fcg > 32) + fcg = 32; + if (fcb > 32) + fcb = 32; - for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into + for (g = 0; g < 256; g++) // pixel 1 - our target pixel we want to bleed into + { + for (h = 0; h < 256; h++) // pixel 2 - our main pixel { - for (h=0;h<256;h++) // pixel 2 - our main pixel - { - float avg; - float avgdiff; + float avg; + float avgdiff; - difference = (float)(g - h); - avg = (float)((g + g + g + g + h) / 5); - avgdiff = avg - (float)((g + h + h + h + h) / 5); - if (avgdiff < 0) avgdiff *= -1; - if (difference < 0) difference *= -1; + difference = (float) (g - h); + avg = (float) ((g + g + g + g + h) / 5); + avgdiff = avg - (float) ((g + h + h + h + h) / 5); + if (avgdiff < 0) + avgdiff *= -1; + if (difference < 0) + difference *= -1; - thiscol = thiscolg = thiscolb = g; + thiscol = thiscolg = thiscolb = g; - // try lighten - if (h > g) - { - clr = clg = clb = avgdiff; + // try lighten + if (h > g) { + clr = clg = clb = avgdiff; - if (clr>fcr) clr=fcr; - if (clg>fcg) clg=fcg; - if (clb>fcb) clb=fcb; + if (clr > fcr) + clr = fcr; + if (clg > fcg) + clg = fcg; + if (clb > fcb) + clb = fcb; + thiscol = g + clr; + thiscolg = g + clg; + thiscolb = g + clb; - thiscol = g + clr; - thiscolg = g + clg; - thiscolb = g + clb; + if (thiscol > g + FILTCAP) + thiscol = g + FILTCAP; + if (thiscolg > g + FILTCAPG) + thiscolg = g + FILTCAPG; + if (thiscolb > g + FILTCAPB) + thiscolb = g + FILTCAPB; - if (thiscol>g+FILTCAP) - thiscol=g+FILTCAP; - if (thiscolg>g+FILTCAPG) - thiscolg=g+FILTCAPG; - if (thiscolb>g+FILTCAPB) - thiscolb=g+FILTCAPB; + if (thiscol > g + avgdiff) + thiscol = g + avgdiff; + if (thiscolg > g + avgdiff) + thiscolg = g + avgdiff; + if (thiscolb > g + avgdiff) + thiscolb = g + avgdiff; + } + if (difference > FILTCAP) + thiscol = g; + if (difference > FILTCAPG) + thiscolg = g; + if (difference > FILTCAPB) + thiscolb = g; - if (thiscol>g+avgdiff) - thiscol=g+avgdiff; - if (thiscolg>g+avgdiff) - thiscolg=g+avgdiff; - if (thiscolb>g+avgdiff) - thiscolb=g+avgdiff; + // clamp + if (thiscol < 0) + thiscol = 0; + if (thiscolg < 0) + thiscolg = 0; + if (thiscolb < 0) + thiscolb = 0; - } + if (thiscol > 255) + thiscol = 255; + if (thiscolg > 255) + thiscolg = 255; + if (thiscolb > 255) + thiscolb = 255; - if (difference > FILTCAP) - thiscol = g; - if (difference > FILTCAPG) - thiscolg = g; - if (difference > FILTCAPB) - thiscolb = g; - - // clamp - if (thiscol < 0) thiscol = 0; - if (thiscolg < 0) thiscolg = 0; - if (thiscolb < 0) thiscolb = 0; - - if (thiscol > 255) thiscol = 255; - if (thiscolg > 255) thiscolg = 255; - if (thiscolb > 255) thiscolb = 255; - - // add to the table - voodoo->thefilter[g][h] = (thiscol); - voodoo->thefilterg[g][h] = (thiscolg); - voodoo->thefilterb[g][h] = (thiscolb); - - // debug the ones that don't give us much of a difference - //if (difference < FILTCAP) - //voodoodisp_log("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb); - } + // add to the table + voodoo->thefilter[g][h] = (thiscol); + voodoo->thefilterg[g][h] = (thiscolg); + voodoo->thefilterb[g][h] = (thiscolb); + // debug the ones that don't give us much of a difference + // if (difference < FILTCAP) + // voodoodisp_log("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb); } + } } -void voodoo_threshold_check(voodoo_t *voodoo) +void +voodoo_threshold_check(voodoo_t *voodoo) { - int r, g, b; + int r, g, b; - if (!voodoo->scrfilterEnabled) - return; /* considered disabled; don't check and generate */ + if (!voodoo->scrfilterEnabled) + return; /* considered disabled; don't check and generate */ - /* Check for changes, to generate anew table */ - if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld) - { - r = (voodoo->scrfilterThreshold >> 16) & 0xFF; - g = (voodoo->scrfilterThreshold >> 8 ) & 0xFF; - b = voodoo->scrfilterThreshold & 0xFF; + /* Check for changes, to generate anew table */ + if (voodoo->scrfilterThreshold != voodoo->scrfilterThresholdOld) { + r = (voodoo->scrfilterThreshold >> 16) & 0xFF; + g = (voodoo->scrfilterThreshold >> 8) & 0xFF; + b = voodoo->scrfilterThreshold & 0xFF; - FILTCAP = r; - FILTCAPG = g; - FILTCAPB = b; + FILTCAP = r; + FILTCAPG = g; + FILTCAPB = b; - voodoodisp_log("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); + voodoodisp_log("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); - voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; + voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; - if (voodoo->type == VOODOO_2) - voodoo_generate_filter_v2(voodoo); - else - voodoo_generate_filter_v1(voodoo); - - if (voodoo->type >= VOODOO_BANSHEE) - voodoo_generate_vb_filters(voodoo, FILTCAP, FILTCAPG); - } -} - -static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) -{ - int x; - - // Scratchpad for avoiding feedback streaks - uint8_t *fil3 = malloc((voodoo->h_disp) * 3); - - /* 16 to 32-bit */ - for (x=0; x> 5) & 63) << 2); - fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - - // Copy to our scratchpads - fil3[x*3+0] = fil[x*3+0]; - fil3[x*3+1] = fil[x*3+1]; - fil3[x*3+2] = fil[x*3+2]; - } - - - /* lines */ - - if (line & 1) - { - for (x=0; xpurpleline[fil[x*3]][0]; - fil[x*3+1] = voodoo->purpleline[fil[x*3+1]][1]; - fil[x*3+2] = voodoo->purpleline[fil[x*3+2]][2]; - } - } - - - /* filtering time */ - - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - - for (x=1; xthefilterb[fil3[x*3]][fil3[ (x-1) *3]]; - fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x-1) *3+1]]; - fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x-1) *3+2]]; - } - - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - - for (x=0; xthefilterb[fil3[x*3]][fil3[ (x+1) *3]]; - fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x+1) *3+1]]; - fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x+1) *3+2]]; - } - - free(fil3); -} - - -static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) -{ - int x; - - // Scratchpad for blending filter - uint8_t *fil3 = malloc((voodoo->h_disp) * 3); - - /* 16 to 32-bit */ - for (x=0; x> 5) & 63) << 2); - fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - } - - /* filtering time */ - - for (x=1; xthefilterb [((src[x+3] & 31) << 3)] [((src[x] & 31) << 3)]; - fil3[(x+3)*3+1] = voodoo->thefilterg [(((src[x+3] >> 5) & 63) << 2)] [(((src[x] >> 5) & 63) << 2)]; - fil3[(x+3)*3+2] = voodoo->thefilter [(((src[x+3] >> 11) & 31) << 3)] [(((src[x] >> 11) & 31) << 3)]; - - fil[(x+2)*3] = voodoo->thefilterb [fil3[(x+2)*3]][((src[x] & 31) << 3)]; - fil[(x+2)*3+1] = voodoo->thefilterg [fil3[(x+2)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x+2)*3+2] = voodoo->thefilter [fil3[(x+2)*3+2]][(((src[x] >> 11) & 31) << 3)]; - - fil3[(x+1)*3] = voodoo->thefilterb [fil[(x+1)*3]][((src[x] & 31) << 3)]; - fil3[(x+1)*3+1] = voodoo->thefilterg [fil[(x+1)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil3[(x+1)*3+2] = voodoo->thefilter [fil[(x+1)*3+2]][(((src[x] >> 11) & 31) << 3)]; - - fil[(x-1)*3] = voodoo->thefilterb [fil3[(x-1)*3]][((src[x] & 31) << 3)]; - fil[(x-1)*3+1] = voodoo->thefilterg [fil3[(x-1)*3+1]][(((src[x] >> 5) & 63) << 2)]; - fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)]; - } - - // unroll for edge cases - - fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-3)*3+2] = voodoo->thefilter [(((src[column-3] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-2)*3] = voodoo->thefilterb [((src[column-2] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-2)*3+1] = voodoo->thefilterg [(((src[column-2] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-2)*3+2] = voodoo->thefilter [(((src[column-2] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-1)*3] = voodoo->thefilterb [((src[column-1] & 31) << 3)] [((src[column] & 31) << 3)]; - fil3[(column-1)*3+1] = voodoo->thefilterg [(((src[column-1] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; - fil3[(column-1)*3+2] = voodoo->thefilter [(((src[column-1] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; - - fil[(column-2)*3] = voodoo->thefilterb [fil3[(column-2)*3]][((src[column] & 31) << 3)]; - fil[(column-2)*3+1] = voodoo->thefilterg [fil3[(column-2)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column-2)*3+2] = voodoo->thefilter [fil3[(column-2)*3+2]][(((src[column] >> 11) & 31) << 3)]; - - fil[(column-1)*3] = voodoo->thefilterb [fil3[(column-1)*3]][((src[column] & 31) << 3)]; - fil[(column-1)*3+1] = voodoo->thefilterg [fil3[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil[(column-1)*3+2] = voodoo->thefilter [fil3[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; - - fil3[(column-1)*3] = voodoo->thefilterb [fil[(column-1)*3]][((src[column] & 31) << 3)]; - fil3[(column-1)*3+1] = voodoo->thefilterg [fil[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; - fil3[(column-1)*3+2] = voodoo->thefilter [fil[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; - - free(fil3); -} - -void voodoo_callback(void *p) -{ - voodoo_t *voodoo = (voodoo_t *)p; - - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) - { - if (voodoo->line < voodoo->v_disp) - { - voodoo_t *draw_voodoo; - int draw_line; - - if (SLI_ENABLED) - { - if (voodoo == voodoo->set->voodoos[1]) - goto skip_draw; - - if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) - draw_voodoo = voodoo; - else - draw_voodoo = voodoo->set->voodoos[1]; - draw_line = voodoo->line >> 1; - } - else - { - if (!(voodoo->fbiInit0 & 1)) - goto skip_draw; - draw_voodoo = voodoo; - draw_line = voodoo->line; - } - - if (draw_voodoo->dirty_line[draw_line]) - { - uint32_t *p = &buffer32->line[voodoo->line + 8][8]; - uint16_t *src = (uint16_t *)&draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line*draw_voodoo->row_width]; - int x; - - draw_voodoo->dirty_line[draw_line] = 0; - - if (voodoo->line < voodoo->dirty_line_low) - { - voodoo->dirty_line_low = voodoo->line; - video_wait_for_buffer(); - } - if (voodoo->line > voodoo->dirty_line_high) - voodoo->dirty_line_high = voodoo->line; - - /* Draw left overscan. */ - for (x = 0; x < 8; x++) - buffer32->line[voodoo->line + 8][x] = 0x00000000; - - if (voodoo->scrfilter && voodoo->scrfilterEnabled) - { - uint8_t *fil = malloc((voodoo->h_disp) * 3); /* interleaved 24-bit RGB */ - - if (voodoo->type == VOODOO_2) - voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); - else - voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); - - for (x = 0; x < voodoo->h_disp; x++) - { - p[x] = (voodoo->clutData256[fil[x*3]].b << 0 | voodoo->clutData256[fil[x*3+1]].g << 8 | voodoo->clutData256[fil[x*3+2]].r << 16); - } - - free(fil); - } - else - { - for (x = 0; x < voodoo->h_disp; x++) - { - p[x] = draw_voodoo->video_16to32[src[x]]; - } - } - - /* Draw right overscan. */ - for (x = 0; x < 8; x++) - buffer32->line[voodoo->line + 8][voodoo->h_disp + x + 8] = 0x00000000; - } - } - } -skip_draw: - if (voodoo->line == voodoo->v_disp) - { -// voodoodisp_log("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); - voodoo->retrace_count++; - if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) - { - if (voodoo == voodoo->set->voodoos[0]) - { - voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; - - thread_wait_mutex(voodoo->swap_mutex); - /*Only swap if both Voodoos are waiting for buffer swap*/ - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && - voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) - { - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - - memset(voodoo_1->dirty_line, 1, 1024); - voodoo_1->retrace_count = 0; - voodoo_1->front_offset = voodoo_1->swap_offset; - if (voodoo_1->swap_count > 0) - voodoo_1->swap_count--; - voodoo_1->swap_pending = 0; - thread_release_mutex(voodoo->swap_mutex); - - thread_set_event(voodoo->wake_fifo_thread); - thread_set_event(voodoo_1->wake_fifo_thread); - - voodoo->frame_count++; - voodoo_1->frame_count++; - } - else - thread_release_mutex(voodoo->swap_mutex); - } - } - else - { - thread_wait_mutex(voodoo->swap_mutex); - if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) - { - voodoo->front_offset = voodoo->swap_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_release_mutex(voodoo->swap_mutex); - - memset(voodoo->dirty_line, 1, 1024); - voodoo->retrace_count = 0; - thread_set_event(voodoo->wake_fifo_thread); - voodoo->frame_count++; - } - else - thread_release_mutex(voodoo->swap_mutex); - } - voodoo->v_retrace = 1; - } - voodoo->line++; - - if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) - { - if (voodoo->line == voodoo->v_disp) - { - int force_blit = 0; - thread_wait_mutex(voodoo->force_blit_mutex); - if(voodoo->force_blit_count) { - force_blit = 1; - if(--voodoo->force_blit_count < 0) - voodoo->force_blit_count = 0; - } - thread_release_mutex(voodoo->force_blit_mutex); - - if (voodoo->dirty_line_high > voodoo->dirty_line_low || force_blit) - svga_doblit(voodoo->h_disp, voodoo->v_disp-1, voodoo->svga); - if (voodoo->clutData_dirty) - { - voodoo->clutData_dirty = 0; - voodoo_calc_clutData(voodoo); - } - voodoo->dirty_line_high = -1; - voodoo->dirty_line_low = 2000; - } - } - - if (voodoo->line >= voodoo->v_total) - { - voodoo->line = 0; - voodoo->v_retrace = 0; - } - if (voodoo->line_time) - timer_advance_u64(&voodoo->timer, voodoo->line_time); + if (voodoo->type == VOODOO_2) + voodoo_generate_filter_v2(voodoo); else - timer_advance_u64(&voodoo->timer, TIMER_USEC * 32); + voodoo_generate_filter_v1(voodoo); + + if (voodoo->type >= VOODOO_BANSHEE) + voodoo_generate_vb_filters(voodoo, FILTCAP, FILTCAPG); + } +} + +static void +voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) +{ + int x; + + // Scratchpad for avoiding feedback streaks + uint8_t *fil3 = malloc((voodoo->h_disp) * 3); + + /* 16 to 32-bit */ + for (x = 0; x < column; x++) { + fil[x * 3] = ((src[x] & 31) << 3); + fil[x * 3 + 1] = (((src[x] >> 5) & 63) << 2); + fil[x * 3 + 2] = (((src[x] >> 11) & 31) << 3); + + // Copy to our scratchpads + fil3[x * 3 + 0] = fil[x * 3 + 0]; + fil3[x * 3 + 1] = fil[x * 3 + 1]; + fil3[x * 3 + 2] = fil[x * 3 + 2]; + } + + /* lines */ + + if (line & 1) { + for (x = 0; x < column; x++) { + fil[x * 3] = voodoo->purpleline[fil[x * 3]][0]; + fil[x * 3 + 1] = voodoo->purpleline[fil[x * 3 + 1]][1]; + fil[x * 3 + 2] = voodoo->purpleline[fil[x * 3 + 2]][2]; + } + } + + /* filtering time */ + + for (x = 1; x < column; x++) { + fil3[(x) *3] = voodoo->thefilterb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x) *3 + 1] = voodoo->thefilterg[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x) *3 + 2] = voodoo->thefilter[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } + + for (x = 1; x < column; x++) { + fil[(x) *3] = voodoo->thefilterb[fil3[x * 3]][fil3[(x - 1) * 3]]; + fil[(x) *3 + 1] = voodoo->thefilterg[fil3[x * 3 + 1]][fil3[(x - 1) * 3 + 1]]; + fil[(x) *3 + 2] = voodoo->thefilter[fil3[x * 3 + 2]][fil3[(x - 1) * 3 + 2]]; + } + + for (x = 1; x < column; x++) { + fil3[(x) *3] = voodoo->thefilterb[fil[x * 3]][fil[(x - 1) * 3]]; + fil3[(x) *3 + 1] = voodoo->thefilterg[fil[x * 3 + 1]][fil[(x - 1) * 3 + 1]]; + fil3[(x) *3 + 2] = voodoo->thefilter[fil[x * 3 + 2]][fil[(x - 1) * 3 + 2]]; + } + + for (x = 0; x < column - 1; x++) { + fil[(x) *3] = voodoo->thefilterb[fil3[x * 3]][fil3[(x + 1) * 3]]; + fil[(x) *3 + 1] = voodoo->thefilterg[fil3[x * 3 + 1]][fil3[(x + 1) * 3 + 1]]; + fil[(x) *3 + 2] = voodoo->thefilter[fil3[x * 3 + 2]][fil3[(x + 1) * 3 + 2]]; + } + + free(fil3); +} + +static void +voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) +{ + int x; + + // Scratchpad for blending filter + uint8_t *fil3 = malloc((voodoo->h_disp) * 3); + + /* 16 to 32-bit */ + for (x = 0; x < column; x++) { + // Blank scratchpads + fil3[x * 3 + 0] = fil[x * 3 + 0] = ((src[x] & 31) << 3); + fil3[x * 3 + 1] = fil[x * 3 + 1] = (((src[x] >> 5) & 63) << 2); + fil3[x * 3 + 2] = fil[x * 3 + 2] = (((src[x] >> 11) & 31) << 3); + } + + /* filtering time */ + + for (x = 1; x < column - 3; x++) { + fil3[(x + 3) * 3] = voodoo->thefilterb[((src[x + 3] & 31) << 3)][((src[x] & 31) << 3)]; + fil3[(x + 3) * 3 + 1] = voodoo->thefilterg[(((src[x + 3] >> 5) & 63) << 2)][(((src[x] >> 5) & 63) << 2)]; + fil3[(x + 3) * 3 + 2] = voodoo->thefilter[(((src[x + 3] >> 11) & 31) << 3)][(((src[x] >> 11) & 31) << 3)]; + + fil[(x + 2) * 3] = voodoo->thefilterb[fil3[(x + 2) * 3]][((src[x] & 31) << 3)]; + fil[(x + 2) * 3 + 1] = voodoo->thefilterg[fil3[(x + 2) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x + 2) * 3 + 2] = voodoo->thefilter[fil3[(x + 2) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; + + fil3[(x + 1) * 3] = voodoo->thefilterb[fil[(x + 1) * 3]][((src[x] & 31) << 3)]; + fil3[(x + 1) * 3 + 1] = voodoo->thefilterg[fil[(x + 1) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; + fil3[(x + 1) * 3 + 2] = voodoo->thefilter[fil[(x + 1) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; + + fil[(x - 1) * 3] = voodoo->thefilterb[fil3[(x - 1) * 3]][((src[x] & 31) << 3)]; + fil[(x - 1) * 3 + 1] = voodoo->thefilterg[fil3[(x - 1) * 3 + 1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x - 1) * 3 + 2] = voodoo->thefilter[fil3[(x - 1) * 3 + 2]][(((src[x] >> 11) & 31) << 3)]; + } + + // unroll for edge cases + + fil3[(column - 3) * 3] = voodoo->thefilterb[((src[column - 3] & 31) << 3)][((src[column] & 31) << 3)]; + fil3[(column - 3) * 3 + 1] = voodoo->thefilterg[(((src[column - 3] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 3) * 3 + 2] = voodoo->thefilter[(((src[column - 3] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; + + fil3[(column - 2) * 3] = voodoo->thefilterb[((src[column - 2] & 31) << 3)][((src[column] & 31) << 3)]; + fil3[(column - 2) * 3 + 1] = voodoo->thefilterg[(((src[column - 2] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 2) * 3 + 2] = voodoo->thefilter[(((src[column - 2] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; + + fil3[(column - 1) * 3] = voodoo->thefilterb[((src[column - 1] & 31) << 3)][((src[column] & 31) << 3)]; + fil3[(column - 1) * 3 + 1] = voodoo->thefilterg[(((src[column - 1] >> 5) & 63) << 2)][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 1) * 3 + 2] = voodoo->thefilter[(((src[column - 1] >> 11) & 31) << 3)][(((src[column] >> 11) & 31) << 3)]; + + fil[(column - 2) * 3] = voodoo->thefilterb[fil3[(column - 2) * 3]][((src[column] & 31) << 3)]; + fil[(column - 2) * 3 + 1] = voodoo->thefilterg[fil3[(column - 2) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column - 2) * 3 + 2] = voodoo->thefilter[fil3[(column - 2) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; + + fil[(column - 1) * 3] = voodoo->thefilterb[fil3[(column - 1) * 3]][((src[column] & 31) << 3)]; + fil[(column - 1) * 3 + 1] = voodoo->thefilterg[fil3[(column - 1) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column - 1) * 3 + 2] = voodoo->thefilter[fil3[(column - 1) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; + + fil3[(column - 1) * 3] = voodoo->thefilterb[fil[(column - 1) * 3]][((src[column] & 31) << 3)]; + fil3[(column - 1) * 3 + 1] = voodoo->thefilterg[fil[(column - 1) * 3 + 1]][(((src[column] >> 5) & 63) << 2)]; + fil3[(column - 1) * 3 + 2] = voodoo->thefilter[fil[(column - 1) * 3 + 2]][(((src[column] >> 11) & 31) << 3)]; + + free(fil3); +} + +void +voodoo_callback(void *p) +{ + voodoo_t *voodoo = (voodoo_t *) p; + + if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { + if (voodoo->line < voodoo->v_disp) { + voodoo_t *draw_voodoo; + int draw_line; + + if (SLI_ENABLED) { + if (voodoo == voodoo->set->voodoos[1]) + goto skip_draw; + + if (((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) ? 1 : 0) == (voodoo->line & 1)) + draw_voodoo = voodoo; + else + draw_voodoo = voodoo->set->voodoos[1]; + draw_line = voodoo->line >> 1; + } else { + if (!(voodoo->fbiInit0 & 1)) + goto skip_draw; + draw_voodoo = voodoo; + draw_line = voodoo->line; + } + + if (draw_voodoo->dirty_line[draw_line]) { + uint32_t *p = &buffer32->line[voodoo->line + 8][8]; + uint16_t *src = (uint16_t *) &draw_voodoo->fb_mem[draw_voodoo->front_offset + draw_line * draw_voodoo->row_width]; + int x; + + draw_voodoo->dirty_line[draw_line] = 0; + + if (voodoo->line < voodoo->dirty_line_low) { + voodoo->dirty_line_low = voodoo->line; + video_wait_for_buffer(); + } + if (voodoo->line > voodoo->dirty_line_high) + voodoo->dirty_line_high = voodoo->line; + + /* Draw left overscan. */ + for (x = 0; x < 8; x++) + buffer32->line[voodoo->line + 8][x] = 0x00000000; + + if (voodoo->scrfilter && voodoo->scrfilterEnabled) { + uint8_t *fil = malloc((voodoo->h_disp) * 3); /* interleaved 24-bit RGB */ + + if (voodoo->type == VOODOO_2) + voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); + else + voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); + + for (x = 0; x < voodoo->h_disp; x++) { + p[x] = (voodoo->clutData256[fil[x * 3]].b << 0 | voodoo->clutData256[fil[x * 3 + 1]].g << 8 | voodoo->clutData256[fil[x * 3 + 2]].r << 16); + } + + free(fil); + } else { + for (x = 0; x < voodoo->h_disp; x++) { + p[x] = draw_voodoo->video_16to32[src[x]]; + } + } + + /* Draw right overscan. */ + for (x = 0; x < 8; x++) + buffer32->line[voodoo->line + 8][voodoo->h_disp + x + 8] = 0x00000000; + } + } + } +skip_draw: + if (voodoo->line == voodoo->v_disp) { + // voodoodisp_log("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); + voodoo->retrace_count++; + if (SLI_ENABLED && (voodoo->fbiInit2 & FBIINIT2_SWAP_ALGORITHM_MASK) == FBIINIT2_SWAP_ALGORITHM_SLI_SYNC) { + if (voodoo == voodoo->set->voodoos[0]) { + voodoo_t *voodoo_1 = voodoo->set->voodoos[1]; + + thread_wait_mutex(voodoo->swap_mutex); + /*Only swap if both Voodoos are waiting for buffer swap*/ + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval) && voodoo_1->swap_pending && (voodoo_1->retrace_count > voodoo_1->swap_interval)) { + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + + memset(voodoo_1->dirty_line, 1, 1024); + voodoo_1->retrace_count = 0; + voodoo_1->front_offset = voodoo_1->swap_offset; + if (voodoo_1->swap_count > 0) + voodoo_1->swap_count--; + voodoo_1->swap_pending = 0; + thread_release_mutex(voodoo->swap_mutex); + + thread_set_event(voodoo->wake_fifo_thread); + thread_set_event(voodoo_1->wake_fifo_thread); + + voodoo->frame_count++; + voodoo_1->frame_count++; + } else + thread_release_mutex(voodoo->swap_mutex); + } + } else { + thread_wait_mutex(voodoo->swap_mutex); + if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { + voodoo->front_offset = voodoo->swap_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_release_mutex(voodoo->swap_mutex); + + memset(voodoo->dirty_line, 1, 1024); + voodoo->retrace_count = 0; + thread_set_event(voodoo->wake_fifo_thread); + voodoo->frame_count++; + } else + thread_release_mutex(voodoo->swap_mutex); + } + voodoo->v_retrace = 1; + } + voodoo->line++; + + if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { + if (voodoo->line == voodoo->v_disp) { + int force_blit = 0; + thread_wait_mutex(voodoo->force_blit_mutex); + if (voodoo->force_blit_count) { + force_blit = 1; + if (--voodoo->force_blit_count < 0) + voodoo->force_blit_count = 0; + } + thread_release_mutex(voodoo->force_blit_mutex); + + if (voodoo->dirty_line_high > voodoo->dirty_line_low || force_blit) + svga_doblit(voodoo->h_disp, voodoo->v_disp - 1, voodoo->svga); + if (voodoo->clutData_dirty) { + voodoo->clutData_dirty = 0; + voodoo_calc_clutData(voodoo); + } + voodoo->dirty_line_high = -1; + voodoo->dirty_line_low = 2000; + } + } + + if (voodoo->line >= voodoo->v_total) { + voodoo->line = 0; + voodoo->v_retrace = 0; + } + if (voodoo->line_time) + timer_advance_u64(&voodoo->timer, voodoo->line_time); + else + timer_advance_u64(&voodoo->timer, TIMER_USEC * 32); } diff --git a/src/video/vid_voodoo_fb.c b/src/video/vid_voodoo_fb.c index 3ab482bff..76c860239 100644 --- a/src/video/vid_voodoo_fb.c +++ b/src/video/vid_voodoo_fb.c @@ -38,7 +38,6 @@ #include <86box/vid_voodoo_render.h> #include <86box/vid_voodoo_fb.h> - #ifdef ENABLE_VOODOO_FB_LOG int voodoo_fb_do_log = ENABLE_VOODOO_FB_LOG; @@ -48,447 +47,402 @@ voodoo_fb_log(const char *fmt, ...) va_list ap; if (voodoo_fb_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoo_fb_log(fmt, ...) +# define voodoo_fb_log(fmt, ...) #endif - -uint16_t voodoo_fb_readw(uint32_t addr, void *p) +uint16_t +voodoo_fb_readw(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint16_t temp; + voodoo_t *voodoo = (voodoo_t *) p; + int x, y; + uint32_t read_addr; + uint16_t temp; - if (voodoo->type >= VOODOO_BANSHEE) - { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } + + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; + + if (y & 1) + voodoo = set->voodoos[1]; else - { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + voodoo = set->voodoos[0]; - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; + y >>= 1; + } - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; + if (voodoo->col_tiled) + read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); - y >>= 1; - } + if (read_addr > voodoo->fb_mask) + return 0xffff; - if (voodoo->col_tiled) - read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); + temp = *(uint16_t *) (&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - if (read_addr > voodoo->fb_mask) - return 0xffff; - - temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - -// voodoo_fb_log("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++); - return temp; + // voodoo_fb_log("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++); + return temp; } -uint32_t voodoo_fb_readl(uint32_t addr, void *p) +uint32_t +voodoo_fb_readl(uint32_t addr, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - int x, y; - uint32_t read_addr; - uint32_t temp; + voodoo_t *voodoo = (voodoo_t *) p; + int x, y; + uint32_t read_addr; + uint32_t temp; - if (voodoo->type >= VOODOO_BANSHEE) - { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } + + if (SLI_ENABLED) { + voodoo_set_t *set = voodoo->set; + + if (y & 1) + voodoo = set->voodoos[1]; else - { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + voodoo = set->voodoos[0]; - if (SLI_ENABLED) - { - voodoo_set_t *set = voodoo->set; + y >>= 1; + } - if (y & 1) - voodoo = set->voodoos[1]; - else - voodoo = set->voodoos[0]; + if (voodoo->col_tiled) + read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); - y >>= 1; - } + if (read_addr > voodoo->fb_mask) + return 0xffffffff; - if (voodoo->col_tiled) - read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width); + temp = *(uint32_t *) (&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - if (read_addr > voodoo->fb_mask) - return 0xffffffff; - - temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); - -// voodoo_fb_log("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width); - return temp; + // voodoo_fb_log("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width); + return temp; } -static inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) +static inline uint16_t +do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) { - int r, g, b; + int r, g, b; - if (dither) - { - if (dither2x2) - { - r = dither_rb2x2[col.r][y & 1][x & 1]; - g = dither_g2x2[col.g][y & 1][x & 1]; - b = dither_rb2x2[col.b][y & 1][x & 1]; - } - else - { - r = dither_rb[col.r][y & 3][x & 3]; - g = dither_g[col.g][y & 3][x & 3]; - b = dither_rb[col.b][y & 3][x & 3]; - } - } - else - { - r = col.r >> 3; - g = col.g >> 2; - b = col.b >> 3; + if (dither) { + if (dither2x2) { + r = dither_rb2x2[col.r][y & 1][x & 1]; + g = dither_g2x2[col.g][y & 1][x & 1]; + b = dither_rb2x2[col.b][y & 1][x & 1]; + } else { + r = dither_rb[col.r][y & 3][x & 3]; + g = dither_g[col.g][y & 3][x & 3]; + b = dither_rb[col.b][y & 3][x & 3]; } + } else { + r = col.r >> 3; + g = col.g >> 2; + b = col.b >> 3; + } - return b | (g << 5) | (r << 11); + return b | (g << 5) | (r << 11); } -void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) +void +voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data; - uint16_t depth_data; - uint8_t alpha_data; - int write_mask = 0; + voodoo_t *voodoo = (voodoo_t *) p; + voodoo_params_t *params = &voodoo->params; + int x, y; + uint32_t write_addr, write_addr_aux; + rgba8_t colour_data; + uint16_t depth_data; + uint8_t alpha_data; + int write_mask = 0; - colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; + colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; - depth_data = voodoo->params.zaColor & 0xffff; - alpha_data = voodoo->params.zaColor >> 24; + depth_data = voodoo->params.zaColor & 0xffff; + alpha_data = voodoo->params.zaColor >> 24; -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); + // while (!RB_EMPTY) + // thread_reset_event(voodoo->not_full_event); -// voodoo_fb_log("voodoo_fb_writew : %08X %04X\n", addr, val); + // voodoo_fb_log("voodoo_fb_writew : %08X %04X\n", addr, val); + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { + case LFB_FORMAT_RGB565: + colour_data = rgb565[val]; + alpha_data = 0xff; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_RGB555: + colour_data = argb1555[val]; + alpha_data = 0xff; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_ARGB1555: + colour_data = argb1555[val]; + alpha_data = colour_data.a; + write_mask = LFB_WRITE_COLOUR; + break; + case LFB_FORMAT_DEPTH: + depth_data = val; + write_mask = LFB_WRITE_DEPTH; + break; - switch (voodoo->lfbMode & LFB_FORMAT_MASK) + default: + fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); + } + + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } + + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } + + if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) + voodoo->dirty_line[y] = 1; + + if (voodoo->col_tiled) + write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + if (voodoo->aux_tiled) + write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + + // voodoo_fb_log("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); + + if (voodoo->lfbMode & 0x100) { { - case LFB_FORMAT_RGB565: - colour_data = rgb565[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_RGB555: - colour_data = argb1555[val]; - alpha_data = 0xff; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_ARGB1555: - colour_data = argb1555[val]; - alpha_data = colour_data.a; - write_mask = LFB_WRITE_COLOUR; - break; - case LFB_FORMAT_DEPTH: - depth_data = val; - write_mask = LFB_WRITE_DEPTH; - break; + rgba8_t write_data = colour_data; + uint16_t new_depth = depth_data; - default: - fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode); - } + if (params->fbzMode & FBZ_DEPTH_ENABLE) { + uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - if (voodoo->type >= VOODOO_BANSHEE) - { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } - else - { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + DEPTH_TEST(new_depth); + } - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } + if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) + goto skip_pixel; + if (params->fogMode & FOG_ENABLE) { + int32_t z = new_depth << 12; + int64_t w_depth = (int64_t) (int32_t) new_depth; + int32_t ia = alpha_data << 12; - if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) - voodoo->dirty_line[y] = 1; + APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); + } - if (voodoo->col_tiled) - write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - if (voodoo->aux_tiled) - write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + if (params->alphaMode & 1) + ALPHA_TEST(alpha_data); -// voodoo_fb_log("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); + if (params->alphaMode & (1 << 4)) { + uint16_t dat = *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]); + int dest_r, dest_g, dest_b, dest_a; - if (voodoo->lfbMode & 0x100) - { - { - rgba8_t write_data = colour_data; - uint16_t new_depth = depth_data; + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); + ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data); + } - DEPTH_TEST(new_depth); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; - - if (params->fogMode & FOG_ENABLE) - { - int32_t z = new_depth << 12; - int64_t w_depth = (int64_t)(int32_t)new_depth; - int32_t ia = alpha_data << 12; - - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } - - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data); - - if (params->alphaMode & (1 << 4)) - { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; - - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; - - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data); - } - - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; + if (params->fbzMode & FBZ_RGB_WMASK) + *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y); + if (params->fbzMode & FBZ_DEPTH_WMASK) + *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; skip_pixel: - return; - } - } - else - { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data; + return; } + } else { + if (write_mask & LFB_WRITE_COLOUR) + *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y); + if (write_mask & LFB_WRITE_DEPTH) + *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data; + } } - -void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) +void +voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - voodoo_params_t *params = &voodoo->params; - int x, y; - uint32_t write_addr, write_addr_aux; - rgba8_t colour_data[2]; - uint16_t depth_data[2]; - uint8_t alpha_data[2]; - int write_mask = 0, count = 1; + voodoo_t *voodoo = (voodoo_t *) p; + voodoo_params_t *params = &voodoo->params; + int x, y; + uint32_t write_addr, write_addr_aux; + rgba8_t colour_data[2]; + uint16_t depth_data[2]; + uint8_t alpha_data[2]; + int write_mask = 0, count = 1; - depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; - alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); + depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; + alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; + // while (!RB_EMPTY) + // thread_reset_event(voodoo->not_full_event); -// voodoo_fb_log("voodoo_fb_writel : %08X %08X\n", addr, val); + // voodoo_fb_log("voodoo_fb_writel : %08X %08X\n", addr, val); - switch (voodoo->lfbMode & LFB_FORMAT_MASK) - { - case LFB_FORMAT_RGB565: - colour_data[0] = rgb565[val & 0xffff]; - colour_data[1] = rgb565[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_RGB555: - colour_data[0] = argb1555[val & 0xffff]; - colour_data[1] = argb1555[val >> 16]; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; - case LFB_FORMAT_ARGB1555: - colour_data[0] = argb1555[val & 0xffff]; - alpha_data[0] = colour_data[0].a; - colour_data[1] = argb1555[val >> 16]; - alpha_data[1] = colour_data[1].a; - write_mask = LFB_WRITE_COLOUR; - count = 2; - break; + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { + case LFB_FORMAT_RGB565: + colour_data[0] = rgb565[val & 0xffff]; + colour_data[1] = rgb565[val >> 16]; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; + case LFB_FORMAT_RGB555: + colour_data[0] = argb1555[val & 0xffff]; + colour_data[1] = argb1555[val >> 16]; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; + case LFB_FORMAT_ARGB1555: + colour_data[0] = argb1555[val & 0xffff]; + alpha_data[0] = colour_data[0].a; + colour_data[1] = argb1555[val >> 16]; + alpha_data[1] = colour_data[1].a; + write_mask = LFB_WRITE_COLOUR; + count = 2; + break; - case LFB_FORMAT_ARGB8888: - colour_data[0].b = val & 0xff; - colour_data[0].g = (val >> 8) & 0xff; - colour_data[0].r = (val >> 16) & 0xff; - alpha_data[0] = (val >> 24) & 0xff; - write_mask = LFB_WRITE_COLOUR; - addr >>= 1; - break; + case LFB_FORMAT_ARGB8888: + colour_data[0].b = val & 0xff; + colour_data[0].g = (val >> 8) & 0xff; + colour_data[0].r = (val >> 16) & 0xff; + alpha_data[0] = (val >> 24) & 0xff; + write_mask = LFB_WRITE_COLOUR; + addr >>= 1; + break; - case LFB_FORMAT_DEPTH: - depth_data[0] = val; - depth_data[1] = val >> 16; - write_mask = LFB_WRITE_DEPTH; - count = 2; - break; + case LFB_FORMAT_DEPTH: + depth_data[0] = val; + depth_data[1] = val >> 16; + write_mask = LFB_WRITE_DEPTH; + count = 2; + break; - default: - fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); - } + default: + fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode); + } - if (voodoo->type >= VOODOO_BANSHEE) - { - x = addr & 0xffe; - y = (addr >> 12) & 0x3ff; - } - else - { - x = addr & 0x7fe; - y = (addr >> 11) & 0x3ff; - } + if (voodoo->type >= VOODOO_BANSHEE) { + x = addr & 0xffe; + y = (addr >> 12) & 0x3ff; + } else { + x = addr & 0x7fe; + y = (addr >> 11) & 0x3ff; + } - if (SLI_ENABLED) - { - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) - return; - y >>= 1; - } + if (SLI_ENABLED) { + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1))) + return; + y >>= 1; + } - if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) - voodoo->dirty_line[y] = 1; + if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048) + voodoo->dirty_line[y] = 1; - if (voodoo->col_tiled) - write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); - if (voodoo->aux_tiled) - write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; - else - write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + if (voodoo->col_tiled) + write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); + if (voodoo->aux_tiled) + write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width; + else + write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); -// voodoo_fb_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); + // voodoo_fb_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); - if (voodoo->lfbMode & 0x100) - { - int c; + if (voodoo->lfbMode & 0x100) { + int c; - for (c = 0; c < count; c++) - { - rgba8_t write_data = colour_data[c]; - uint16_t new_depth = depth_data[c]; + for (c = 0; c < count; c++) { + rgba8_t write_data = colour_data[c]; + uint16_t new_depth = depth_data[c]; - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); + if (params->fbzMode & FBZ_DEPTH_ENABLE) { + uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]); - DEPTH_TEST(new_depth); - } + DEPTH_TEST(new_depth); + } - if ((params->fbzMode & FBZ_CHROMAKEY) && - write_data.r == params->chromaKey_r && - write_data.g == params->chromaKey_g && - write_data.b == params->chromaKey_b) - goto skip_pixel; + if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b) + goto skip_pixel; - if (params->fogMode & FOG_ENABLE) - { - int32_t z = new_depth << 12; - int64_t w_depth = new_depth; - int32_t ia = alpha_data[c] << 12; + if (params->fogMode & FOG_ENABLE) { + int32_t z = new_depth << 12; + int64_t w_depth = new_depth; + int32_t ia = alpha_data[c] << 12; - APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); - } + APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); + } - if (params->alphaMode & 1) - ALPHA_TEST(alpha_data[c]); + if (params->alphaMode & 1) + ALPHA_TEST(alpha_data[c]); - if (params->alphaMode & (1 << 4)) - { - uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]); - int dest_r, dest_g, dest_b, dest_a; + if (params->alphaMode & (1 << 4)) { + uint16_t dat = *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]); + int dest_r, dest_g, dest_b, dest_a; - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; - ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]); - } + ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]); + } - if (params->fbzMode & FBZ_RGB_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y); - if (params->fbzMode & FBZ_DEPTH_WMASK) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; + if (params->fbzMode & FBZ_RGB_WMASK) + *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y); + if (params->fbzMode & FBZ_DEPTH_WMASK) + *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth; skip_pixel: - write_addr += 2; - write_addr_aux += 2; - } + write_addr += 2; + write_addr_aux += 2; } - else - { - int c; + } else { + int c; - for (c = 0; c < count; c++) - { - if (write_mask & LFB_WRITE_COLOUR) - *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); - if (write_mask & LFB_WRITE_DEPTH) - *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; + for (c = 0; c < count; c++) { + if (write_mask & LFB_WRITE_COLOUR) + *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y); + if (write_mask & LFB_WRITE_DEPTH) + *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c]; - write_addr += 2; - write_addr_aux += 2; - } + write_addr += 2; + write_addr_aux += 2; } + } } diff --git a/src/video/vid_voodoo_fifo.c b/src/video/vid_voodoo_fifo.c index 87260ce54..5ac845e6f 100644 --- a/src/video/vid_voodoo_fifo.c +++ b/src/video/vid_voodoo_fifo.c @@ -41,7 +41,6 @@ #include <86box/vid_voodoo_render.h> #include <86box/vid_voodoo_texture.h> - #ifdef ENABLE_VOODOO_FIFO_LOG int voodoo_fifo_do_log = ENABLE_VOODOO_FIFO_LOG; @@ -51,497 +50,461 @@ voodoo_fifo_log(const char *fmt, ...) va_list ap; if (voodoo_fifo_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoo_fifo_log(fmt, ...) +# define voodoo_fifo_log(fmt, ...) #endif #define WAKE_DELAY (TIMER_USEC * 100) -void voodoo_wake_fifo_thread(voodoo_t *voodoo) +void +voodoo_wake_fifo_thread(voodoo_t *voodoo) { - if (!timer_is_enabled(&voodoo->wake_timer)) - { - /*Don't wake FIFO thread immediately - if we do that it will probably - process one word and go back to sleep, requiring it to be woken on - almost every write. Instead, wait a short while so that the CPU - emulation writes more data so we have more batched-up work.*/ - timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); - } + if (!timer_is_enabled(&voodoo->wake_timer)) { + /*Don't wake FIFO thread immediately - if we do that it will probably + process one word and go back to sleep, requiring it to be woken on + almost every write. Instead, wait a short while so that the CPU + emulation writes more data so we have more batched-up work.*/ + timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY); + } } -void voodoo_wake_fifo_thread_now(voodoo_t *voodoo) +void +voodoo_wake_fifo_thread_now(voodoo_t *voodoo) { - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } -void voodoo_wake_timer(void *p) +void +voodoo_wake_timer(void *p) { - voodoo_t *voodoo = (voodoo_t *)p; + voodoo_t *voodoo = (voodoo_t *) p; - thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ + thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } -void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) +void +voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) { - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; + fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; - while (FIFO_FULL) - { - thread_reset_event(voodoo->fifo_not_full_event); - if (FIFO_FULL) - { - thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ - if (FIFO_FULL) - voodoo_wake_fifo_thread_now(voodoo); - } - } - - fifo->val = val; - fifo->addr_type = addr_type; - - voodoo->fifo_write_idx++; - - if (FIFO_ENTRIES > 0xe000) - voodoo_wake_fifo_thread(voodoo); -} - -void voodoo_flush(voodoo_t *voodoo) -{ - voodoo->flush = 1; - while (!FIFO_EMPTY) - { + while (FIFO_FULL) { + thread_reset_event(voodoo->fifo_not_full_event); + if (FIFO_FULL) { + thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/ + if (FIFO_FULL) voodoo_wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); } - voodoo_wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; -} + } -void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo) -{ + fifo->val = val; + fifo->addr_type = addr_type; + + voodoo->fifo_write_idx++; + + if (FIFO_ENTRIES > 0xe000) voodoo_wake_fifo_thread(voodoo); - if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) - voodoo_wake_fifo_thread(set->voodoos[1]); } -void voodoo_wait_for_swap_complete(voodoo_t *voodoo) +void +voodoo_flush(voodoo_t *voodoo) { - while (voodoo->swap_pending) - { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); + voodoo->flush = 1; + while (!FIFO_EMPTY) { + voodoo_wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); + } + voodoo_wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; +} - thread_wait_mutex(voodoo->swap_mutex); - if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) - { - /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ - memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); - voodoo->front_offset = voodoo->params.front_offset; - if (voodoo->swap_count > 0) - voodoo->swap_count--; - voodoo->swap_pending = 0; - thread_release_mutex(voodoo->swap_mutex);; - break; - } - else - thread_release_mutex(voodoo->swap_mutex);; +void +voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo) +{ + voodoo_wake_fifo_thread(voodoo); + if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo) + voodoo_wake_fifo_thread(set->voodoos[1]); +} + +void +voodoo_wait_for_swap_complete(voodoo_t *voodoo) +{ + while (voodoo->swap_pending) { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + + thread_wait_mutex(voodoo->swap_mutex); + if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) { + /*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/ + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); + voodoo->front_offset = voodoo->params.front_offset; + if (voodoo->swap_count > 0) + voodoo->swap_count--; + voodoo->swap_pending = 0; + thread_release_mutex(voodoo->swap_mutex); + ; + break; + } else + thread_release_mutex(voodoo->swap_mutex); + ; + } +} + +static uint32_t +cmdfifo_get(voodoo_t *voodoo) +{ + uint32_t val; + + if (!voodoo->cmdfifo_in_sub) { + while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) { + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); } + } + + val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; + + if (!voodoo->cmdfifo_in_sub) + voodoo->cmdfifo_depth_rd++; + voodoo->cmdfifo_rp += 4; + + // voodoo_fifo_log(" CMDFIFO get %08x\n", val); + return val; } - -static uint32_t cmdfifo_get(voodoo_t *voodoo) +static inline float +cmdfifo_get_f(voodoo_t *voodoo) { - uint32_t val; + union { + uint32_t i; + float f; + } tempif; - if (!voodoo->cmdfifo_in_sub) { - while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) - { - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - } - } - - val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask]; - - if (!voodoo->cmdfifo_in_sub) - voodoo->cmdfifo_depth_rd++; - voodoo->cmdfifo_rp += 4; - -// voodoo_fifo_log(" CMDFIFO get %08x\n", val); - return val; + tempif.i = cmdfifo_get(voodoo); + return tempif.f; } -static inline float cmdfifo_get_f(voodoo_t *voodoo) -{ - union - { - uint32_t i; - float f; - } tempif; +enum { + CMDFIFO3_PC_MASK_RGB = (1 << 10), + CMDFIFO3_PC_MASK_ALPHA = (1 << 11), + CMDFIFO3_PC_MASK_Z = (1 << 12), + CMDFIFO3_PC_MASK_Wb = (1 << 13), + CMDFIFO3_PC_MASK_W0 = (1 << 14), + CMDFIFO3_PC_MASK_S0_T0 = (1 << 15), + CMDFIFO3_PC_MASK_W1 = (1 << 16), + CMDFIFO3_PC_MASK_S1_T1 = (1 << 17), - tempif.i = cmdfifo_get(voodoo); - return tempif.f; -} - -enum -{ - CMDFIFO3_PC_MASK_RGB = (1 << 10), - CMDFIFO3_PC_MASK_ALPHA = (1 << 11), - CMDFIFO3_PC_MASK_Z = (1 << 12), - CMDFIFO3_PC_MASK_Wb = (1 << 13), - CMDFIFO3_PC_MASK_W0 = (1 << 14), - CMDFIFO3_PC_MASK_S0_T0 = (1 << 15), - CMDFIFO3_PC_MASK_W1 = (1 << 16), - CMDFIFO3_PC_MASK_S1_T1 = (1 << 17), - - CMDFIFO3_PC = (1 << 28) + CMDFIFO3_PC = (1 << 28) }; -void voodoo_fifo_thread(void *param) +void +voodoo_fifo_thread(void *param) { - voodoo_t *voodoo = (voodoo_t *)param; + voodoo_t *voodoo = (voodoo_t *) param; - while (voodoo->fifo_thread_run) - { + while (voodoo->fifo_thread_run) { + thread_set_event(voodoo->fifo_not_full_event); + thread_wait_event(voodoo->wake_fifo_thread, -1); + thread_reset_event(voodoo->wake_fifo_thread); + voodoo->voodoo_busy = 1; + while (!FIFO_EMPTY) { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + + switch (fifo->addr_type & FIFO_TYPE) { + case FIFO_WRITEL_REG: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) { + voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEW_FB: + voodoo_wait_for_render_thread_idle(voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) { + voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_FB: + voodoo_wait_for_render_thread_idle(voodoo); + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) { + voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_TEX: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) { + if (!(fifo->addr_type & 0x400000)) + voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + case FIFO_WRITEL_2DREG: + while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG) { + voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val); + fifo->addr_type = FIFO_INVALID; + voodoo->fifo_read_idx++; + if (FIFO_EMPTY) + break; + fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; + } + break; + + default: + fatal("Unknown fifo entry %08x\n", fifo->addr_type); + } + + if (FIFO_ENTRIES > 0xe000) thread_set_event(voodoo->fifo_not_full_event); - thread_wait_event(voodoo->wake_fifo_thread, -1); - thread_reset_event(voodoo->wake_fifo_thread); - voodoo->voodoo_busy = 1; - while (!FIFO_EMPTY) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - switch (fifo->addr_type & FIFO_TYPE) - { - case FIFO_WRITEL_REG: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) - { - voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEW_FB: - voodoo_wait_for_render_thread_idle(voodoo); - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) - { - voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_FB: - voodoo_wait_for_render_thread_idle(voodoo); - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) - { - voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_TEX: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) - { - if (!(fifo->addr_type & 0x400000)) - voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - case FIFO_WRITEL_2DREG: - while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG) - { - voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val); - fifo->addr_type = FIFO_INVALID; - voodoo->fifo_read_idx++; - if (FIFO_EMPTY) - break; - fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK]; - } - break; - - default: - fatal("Unknown fifo entry %08x\n", fifo->addr_type); - } - - if (FIFO_ENTRIES > 0xe000) - thread_set_event(voodoo->fifo_not_full_event); - - end_time = plat_timer_read(); - voodoo->time += end_time - start_time; - } - - while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - uint32_t header = cmdfifo_get(voodoo); - uint32_t addr; - uint32_t mask; - int smode; - int num; - int num_verticies; - int v_num; - -// voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); - - switch (header & 7) - { - case 0: -// voodoo_fifo_log("CMDFIFO0\n"); - switch ((header >> 3) & 7) - { - case 0: /*NOP*/ - break; - - case 1: /*JSR*/ -// voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc); - voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp; - voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; - voodoo->cmdfifo_in_sub = 1; - break; - - case 2: /*RET*/ - voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr; - voodoo->cmdfifo_in_sub = 0; - break; - - case 3: /*JMP local frame buffer*/ - voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; -// voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); - break; - - default: - fatal("Bad CMDFIFO0 %08x\n", header); - } - break; - - case 1: - num = header >> 16; - addr = (header & 0x7ff8) >> 1; -// voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr); - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) - { -// if (voodoo->type != VOODOO_BANSHEE) -// fatal("CMDFIFO1: Not Banshee\n"); -// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); - voodoo_2d_reg_writel(voodoo, addr, val); - } - else - { - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; - - if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) - voodoo->cmd_written_fifo++; - voodoo_reg_writel(addr, val, voodoo); - } - - if (header & (1 << 15)) - addr += 4; - } - break; - - case 2: - if (voodoo->type < VOODOO_BANSHEE) - fatal("CMDFIFO2: Not Banshee\n"); - mask = (header >> 3); - addr = 8; - while (mask) - { - if (mask & 1) - { - uint32_t val = cmdfifo_get(voodoo); - - voodoo_2d_reg_writel(voodoo, addr, val); - } - - addr += 4; - mask >>= 1; - } - break; - - case 3: - num = (header >> 29) & 7; - mask = header;//(header >> 10) & 0xff; - smode = (header >> 22) & 0xf; - voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); - num_verticies = (header >> 6) & 0xf; - v_num = 0; - if (((header >> 3) & 7) == 2) - v_num = 1; -// voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); -// voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); - - while (num_verticies--) - { - voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); - voodoo->verts[3].sVy = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_RGB) - { - if (header & CMDFIFO3_PC) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo->verts[3].sBlue = (float)(val & 0xff); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - } - else - { - voodoo->verts[3].sRed = cmdfifo_get_f(voodoo); - voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo); - voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo); - } - } - if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) - voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Z) - voodoo->verts[3].sVz = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_Wb) - voodoo->verts[3].sWb = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_W0) - voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S0_T0) - { - voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo); - } - if (mask & CMDFIFO3_PC_MASK_W1) - voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo); - if (mask & CMDFIFO3_PC_MASK_S1_T1) - { - voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo); - voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo); - } - if (v_num) - voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); - else - voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); - v_num++; - if (v_num == 3 && ((header >> 3) & 7) == 0) - v_num = 0; - } - break; - - case 4: - num = (header >> 29) & 7; - mask = (header >> 15) & 0x3fff; - addr = (header & 0x7ff8) >> 1; -// voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr); - while (mask) - { - if (mask & 1) - { - uint32_t val = cmdfifo_get(voodoo); - - if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) - { - if (voodoo->type < VOODOO_BANSHEE) - fatal("CMDFIFO1: Not Banshee\n"); -// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); - voodoo_2d_reg_writel(voodoo, addr, val); - } - else - { - if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || - (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) - voodoo->cmd_written_fifo++; - - if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) - voodoo->cmd_written_fifo++; - voodoo_reg_writel(addr, val, voodoo); - } - } - - addr += 4; - mask >>= 1; - } - while (num--) - cmdfifo_get(voodoo); - break; - - case 5: -// if (header & 0x3fc00000) -// fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); - num = (header >> 3) & 0x7ffff; - addr = cmdfifo_get(voodoo) & 0xffffff; - if (!num) - num = 1; -// voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num); - switch (header >> 30) - { - case 0: /*Linear framebuffer (Banshee)*/ - case 1: /*Planar YUV*/ - if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) - { -// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0); - } - if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) - { -// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1); - } - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - if (addr <= voodoo->fb_mask) - *(uint32_t *)&voodoo->fb_mem[addr] = val; - addr += 4; - } - break; - case 2: /*Framebuffer*/ - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo_fb_writel(addr, val, voodoo); - addr += 4; - } - break; - case 3: /*Texture*/ - while (num--) - { - uint32_t val = cmdfifo_get(voodoo); - voodoo_tex_writel(addr, val, voodoo); - addr += 4; - } - break; - - default: - fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); - } - break; - - default: - fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); - } - - end_time = plat_timer_read(); - voodoo->time += end_time - start_time; - } - voodoo->voodoo_busy = 0; + end_time = plat_timer_read(); + voodoo->time += end_time - start_time; } + + while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + uint32_t header = cmdfifo_get(voodoo); + uint32_t addr; + uint32_t mask; + int smode; + int num; + int num_verticies; + int v_num; + + // voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); + + switch (header & 7) { + case 0: + // voodoo_fifo_log("CMDFIFO0\n"); + switch ((header >> 3) & 7) { + case 0: /*NOP*/ + break; + + case 1: /*JSR*/ + // voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc); + voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp; + voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; + voodoo->cmdfifo_in_sub = 1; + break; + + case 2: /*RET*/ + voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr; + voodoo->cmdfifo_in_sub = 0; + break; + + case 3: /*JMP local frame buffer*/ + voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; + // voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); + break; + + default: + fatal("Bad CMDFIFO0 %08x\n", header); + } + break; + + case 1: + num = header >> 16; + addr = (header & 0x7ff8) >> 1; + // voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr); + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { + // if (voodoo->type != VOODOO_BANSHEE) + // fatal("CMDFIFO1: Not Banshee\n"); + // voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); + voodoo_2d_reg_writel(voodoo, addr, val); + } else { + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; + + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo++; + voodoo_reg_writel(addr, val, voodoo); + } + + if (header & (1 << 15)) + addr += 4; + } + break; + + case 2: + if (voodoo->type < VOODOO_BANSHEE) + fatal("CMDFIFO2: Not Banshee\n"); + mask = (header >> 3); + addr = 8; + while (mask) { + if (mask & 1) { + uint32_t val = cmdfifo_get(voodoo); + + voodoo_2d_reg_writel(voodoo, addr, val); + } + + addr += 4; + mask >>= 1; + } + break; + + case 3: + num = (header >> 29) & 7; + mask = header; //(header >> 10) & 0xff; + smode = (header >> 22) & 0xf; + voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); + num_verticies = (header >> 6) & 0xf; + v_num = 0; + if (((header >> 3) & 7) == 2) + v_num = 1; + // voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); + // voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); + + while (num_verticies--) { + voodoo->verts[3].sVx = cmdfifo_get_f(voodoo); + voodoo->verts[3].sVy = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_RGB) { + if (header & CMDFIFO3_PC) { + uint32_t val = cmdfifo_get(voodoo); + voodoo->verts[3].sBlue = (float) (val & 0xff); + voodoo->verts[3].sGreen = (float) ((val >> 8) & 0xff); + voodoo->verts[3].sRed = (float) ((val >> 16) & 0xff); + voodoo->verts[3].sAlpha = (float) ((val >> 24) & 0xff); + } else { + voodoo->verts[3].sRed = cmdfifo_get_f(voodoo); + voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo); + voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo); + } + } + if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC)) + voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_Z) + voodoo->verts[3].sVz = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_Wb) + voodoo->verts[3].sWb = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_W0) + voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_S0_T0) { + voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo); + voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo); + } + if (mask & CMDFIFO3_PC_MASK_W1) + voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo); + if (mask & CMDFIFO3_PC_MASK_S1_T1) { + voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo); + voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo); + } + if (v_num) + voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo); + else + voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo); + v_num++; + if (v_num == 3 && ((header >> 3) & 7) == 0) + v_num = 0; + } + break; + + case 4: + num = (header >> 29) & 7; + mask = (header >> 15) & 0x3fff; + addr = (header & 0x7ff8) >> 1; + // voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr); + while (mask) { + if (mask & 1) { + uint32_t val = cmdfifo_get(voodoo); + + if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) { + if (voodoo->type < VOODOO_BANSHEE) + fatal("CMDFIFO1: Not Banshee\n"); + // voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val); + voodoo_2d_reg_writel(voodoo, addr, val); + } else { + if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD) + voodoo->cmd_written_fifo++; + + if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD) + voodoo->cmd_written_fifo++; + voodoo_reg_writel(addr, val, voodoo); + } + } + + addr += 4; + mask >>= 1; + } + while (num--) + cmdfifo_get(voodoo); + break; + + case 5: + // if (header & 0x3fc00000) + // fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); + num = (header >> 3) & 0x7ffff; + addr = cmdfifo_get(voodoo) & 0xffffff; + if (!num) + num = 1; + // voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num); + switch (header >> 30) { + case 0: /*Linear framebuffer (Banshee)*/ + case 1: /*Planar YUV*/ + if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0); + } + if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1); + } + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + if (addr <= voodoo->fb_mask) + *(uint32_t *) &voodoo->fb_mem[addr] = val; + addr += 4; + } + break; + case 2: /*Framebuffer*/ + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + voodoo_fb_writel(addr, val, voodoo); + addr += 4; + } + break; + case 3: /*Texture*/ + while (num--) { + uint32_t val = cmdfifo_get(voodoo); + voodoo_tex_writel(addr, val, voodoo); + addr += 4; + } + break; + + default: + fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp); + } + break; + + default: + fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); + } + + end_time = plat_timer_read(); + voodoo->time += end_time - start_time; + } + voodoo->voodoo_busy = 0; + } } diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 797fa130f..84f56e726 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -42,16 +42,13 @@ #include <86box/vid_voodoo_setup.h> #include <86box/vid_voodoo_texture.h> - -enum -{ - CHIP_FBI = 0x1, - CHIP_TREX0 = 0x2, - CHIP_TREX1 = 0x4, - CHIP_TREX2 = 0x8 +enum { + CHIP_FBI = 0x1, + CHIP_TREX0 = 0x2, + CHIP_TREX1 = 0x4, + CHIP_TREX2 = 0x8 }; - #ifdef ENABLE_VOODOO_REG_LOG int voodoo_reg_do_log = ENABLE_VOODOO_REG_LOG; @@ -61,1306 +58,1266 @@ voodoo_reg_log(const char *fmt, ...) va_list ap; if (voodoo_reg_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoo_reg_log(fmt, ...) +# define voodoo_reg_log(fmt, ...) #endif - -void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) +void +voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *)p; - union - { - uint32_t i; - float f; - } tempif; - int ad21 = addr & (1 << 21); - int chip = (addr >> 10) & 0xf; - if (!chip) - chip = 0xf; + voodoo_t *voodoo = (voodoo_t *) p; + union { + uint32_t i; + float f; + } tempif; + int ad21 = addr & (1 << 21); + int chip = (addr >> 10) & 0xf; + if (!chip) + chip = 0xf; - tempif.i = val; -//voodoo_reg_log("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); - addr &= 0x3fc; + tempif.i = val; + // voodoo_reg_log("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); + addr &= 0x3fc; - if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) - addr |= 0x400; - switch (addr) - { - case SST_swapbufferCMD: - if (voodoo->type >= VOODOO_BANSHEE) - { -// voodoo_reg_log("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); + if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) + addr |= 0x400; + switch (addr) { + case SST_swapbufferCMD: + if (voodoo->type >= VOODOO_BANSHEE) { + // voodoo_reg_log("swapbufferCMD %08x %08x\n", val, voodoo->leftOverlayBuf); - voodoo_wait_for_render_thread_idle(voodoo); - if (!(val & 1)) - { - banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf); - thread_wait_mutex(voodoo->swap_mutex); - if (voodoo->swap_count > 0) - voodoo->swap_count--; - thread_release_mutex(voodoo->swap_mutex); - voodoo->frame_count++; - } - else if (TRIPLE_BUFFER) - { - if (voodoo->swap_pending) - voodoo_wait_for_swap_complete(voodoo); - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->leftOverlayBuf; - voodoo->swap_pending = 1; - } - else - { - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->leftOverlayBuf; - voodoo->swap_pending = 1; - - voodoo_wait_for_swap_complete(voodoo); - } - - voodoo->cmd_read++; - break; - } - - if (TRIPLE_BUFFER) - { - voodoo->disp_buffer = (voodoo->disp_buffer + 1) % 3; - voodoo->draw_buffer = (voodoo->draw_buffer + 1) % 3; - } - else - { - voodoo->disp_buffer = !voodoo->disp_buffer; - voodoo->draw_buffer = !voodoo->draw_buffer; - } - voodoo_recalc(voodoo); - - voodoo->params.swapbufferCMD = val; - -// voodoo_reg_log("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); -// voodoo->front_offset = params->front_offset; voodoo_wait_for_render_thread_idle(voodoo); - if (!(val & 1)) - { - memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); - voodoo->front_offset = voodoo->params.front_offset; - thread_wait_mutex(voodoo->swap_mutex); - if (voodoo->swap_count > 0) - voodoo->swap_count--; - thread_release_mutex(voodoo->swap_mutex); - } - else if (TRIPLE_BUFFER) - { - if (voodoo->swap_pending) - voodoo_wait_for_swap_complete(voodoo); - - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; - } - else - { - voodoo->swap_interval = (val >> 1) & 0xff; - voodoo->swap_offset = voodoo->params.front_offset; - voodoo->swap_pending = 1; - + if (!(val & 1)) { + banshee_set_overlay_addr(voodoo->p, voodoo->leftOverlayBuf); + thread_wait_mutex(voodoo->swap_mutex); + if (voodoo->swap_count > 0) + voodoo->swap_count--; + thread_release_mutex(voodoo->swap_mutex); + voodoo->frame_count++; + } else if (TRIPLE_BUFFER) { + if (voodoo->swap_pending) voodoo_wait_for_swap_complete(voodoo); + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->leftOverlayBuf; + voodoo->swap_pending = 1; + } else { + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->leftOverlayBuf; + voodoo->swap_pending = 1; + + voodoo_wait_for_swap_complete(voodoo); } - voodoo->cmd_read++; - break; - - case SST_vertexAx: case SST_remap_vertexAx: - voodoo->params.vertexAx = val & 0xffff; - break; - case SST_vertexAy: case SST_remap_vertexAy: - voodoo->params.vertexAy = val & 0xffff; - break; - case SST_vertexBx: case SST_remap_vertexBx: - voodoo->params.vertexBx = val & 0xffff; - break; - case SST_vertexBy: case SST_remap_vertexBy: - voodoo->params.vertexBy = val & 0xffff; - break; - case SST_vertexCx: case SST_remap_vertexCx: - voodoo->params.vertexCx = val & 0xffff; - break; - case SST_vertexCy: case SST_remap_vertexCy: - voodoo->params.vertexCy = val & 0xffff; - break; - - case SST_startR: case SST_remap_startR: - voodoo->params.startR = val & 0xffffff; - break; - case SST_startG: case SST_remap_startG: - voodoo->params.startG = val & 0xffffff; - break; - case SST_startB: case SST_remap_startB: - voodoo->params.startB = val & 0xffffff; - break; - case SST_startZ: case SST_remap_startZ: - voodoo->params.startZ = val; - break; - case SST_startA: case SST_remap_startA: - voodoo->params.startA = val & 0xffffff; - break; - case SST_startS: case SST_remap_startS: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = ((int64_t)(int32_t)val) << 14; - break; - case SST_startT: case SST_remap_startT: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = ((int64_t)(int32_t)val) << 14; - break; - case SST_startW: case SST_remap_startW: - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(int32_t)val << 2; - break; - - case SST_dRdX: case SST_remap_dRdX: - voodoo->params.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdX: case SST_remap_dGdX: - voodoo->params.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdX: case SST_remap_dBdX: - voodoo->params.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdX: case SST_remap_dZdX: - voodoo->params.dZdX = val; - break; - case SST_dAdX: case SST_remap_dAdX: - voodoo->params.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdX: case SST_remap_dSdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdX: case SST_remap_dTdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdX: case SST_remap_dWdX: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(int32_t)val << 2; - break; - - case SST_dRdY: case SST_remap_dRdY: - voodoo->params.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dGdY: case SST_remap_dGdY: - voodoo->params.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dBdY: case SST_remap_dBdY: - voodoo->params.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dZdY: case SST_remap_dZdY: - voodoo->params.dZdY = val; - break; - case SST_dAdY: case SST_remap_dAdY: - voodoo->params.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); - break; - case SST_dSdY: case SST_remap_dSdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dTdY: case SST_remap_dTdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = ((int64_t)(int32_t)val) << 14; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = ((int64_t)(int32_t)val) << 14; - break; - case SST_dWdY: case SST_remap_dWdY: - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(int32_t)val << 2; - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(int32_t)val << 2; - break; - - case SST_triangleCMD: case SST_remap_triangleCMD: - voodoo->params.sign = val & (1 << 31); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - voodoo_queue_triangle(voodoo, &voodoo->params); voodoo->cmd_read++; break; + } - case SST_fvertexAx: case SST_remap_fvertexAx: - voodoo->fvertexAx.i = val; - voodoo->params.vertexAx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAx.f * 16.0f) & 0xffff; - break; - case SST_fvertexAy: case SST_remap_fvertexAy: - voodoo->fvertexAy.i = val; - voodoo->params.vertexAy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexAy.f * 16.0f) & 0xffff; - break; - case SST_fvertexBx: case SST_remap_fvertexBx: - voodoo->fvertexBx.i = val; - voodoo->params.vertexBx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBx.f * 16.0f) & 0xffff; - break; - case SST_fvertexBy: case SST_remap_fvertexBy: - voodoo->fvertexBy.i = val; - voodoo->params.vertexBy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexBy.f * 16.0f) & 0xffff; - break; - case SST_fvertexCx: case SST_remap_fvertexCx: - voodoo->fvertexCx.i = val; - voodoo->params.vertexCx = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCx.f * 16.0f) & 0xffff; - break; - case SST_fvertexCy: case SST_remap_fvertexCy: - voodoo->fvertexCy.i = val; - voodoo->params.vertexCy = (int32_t)(int16_t)(int32_t)(voodoo->fvertexCy.f * 16.0f) & 0xffff; - break; + if (TRIPLE_BUFFER) { + voodoo->disp_buffer = (voodoo->disp_buffer + 1) % 3; + voodoo->draw_buffer = (voodoo->draw_buffer + 1) % 3; + } else { + voodoo->disp_buffer = !voodoo->disp_buffer; + voodoo->draw_buffer = !voodoo->draw_buffer; + } + voodoo_recalc(voodoo); - case SST_fstartR: case SST_remap_fstartR: - tempif.i = val; - voodoo->params.startR = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartG: case SST_remap_fstartG: - tempif.i = val; - voodoo->params.startG = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartB: case SST_remap_fstartB: - tempif.i = val; - voodoo->params.startB = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartZ: case SST_remap_fstartZ: - tempif.i = val; - voodoo->params.startZ = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartA: case SST_remap_fstartA: - tempif.i = val; - voodoo->params.startA = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fstartS: case SST_remap_fstartS: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startS = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startS = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartT: case SST_remap_fstartT: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startT = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startT = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fstartW: case SST_remap_fstartW: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].startW = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.startW = (int64_t)(tempif.f * 4294967296.0f); - break; + voodoo->params.swapbufferCMD = val; - case SST_fdRdX: case SST_remap_fdRdX: - tempif.i = val; - voodoo->params.dRdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdX: case SST_remap_fdGdX: - tempif.i = val; - voodoo->params.dGdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdX: case SST_remap_fdBdX: - tempif.i = val; - voodoo->params.dBdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdX: case SST_remap_fdZdX: - tempif.i = val; - voodoo->params.dZdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdX: case SST_remap_fdAdX: - tempif.i = val; - voodoo->params.dAdX = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdX: case SST_remap_fdSdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdX: case SST_remap_fdTdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdX = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdX: case SST_remap_fdWdX: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdX = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdX = (int64_t)(tempif.f * 4294967296.0f); - break; + // voodoo_reg_log("Swap buffer %08x %d %p %i\n", val, voodoo->swap_count, &voodoo->swap_count, (voodoo == voodoo->set->voodoos[1]) ? 1 : 0); + // voodoo->front_offset = params->front_offset; + voodoo_wait_for_render_thread_idle(voodoo); + if (!(val & 1)) { + memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line)); + voodoo->front_offset = voodoo->params.front_offset; + thread_wait_mutex(voodoo->swap_mutex); + if (voodoo->swap_count > 0) + voodoo->swap_count--; + thread_release_mutex(voodoo->swap_mutex); + } else if (TRIPLE_BUFFER) { + if (voodoo->swap_pending) + voodoo_wait_for_swap_complete(voodoo); - case SST_fdRdY: case SST_remap_fdRdY: - tempif.i = val; - voodoo->params.dRdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdGdY: case SST_remap_fdGdY: - tempif.i = val; - voodoo->params.dGdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdBdY: case SST_remap_fdBdY: - tempif.i = val; - voodoo->params.dBdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdZdY: case SST_remap_fdZdY: - tempif.i = val; - voodoo->params.dZdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdAdY: case SST_remap_fdAdY: - tempif.i = val; - voodoo->params.dAdY = (int32_t)(tempif.f * 4096.0f); - break; - case SST_fdSdY: case SST_remap_fdSdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dSdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dSdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdTdY: case SST_remap_fdTdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dTdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dTdY = (int64_t)(tempif.f * 4294967296.0f); - break; - case SST_fdWdY: case SST_remap_fdWdY: - tempif.i = val; - if (chip & CHIP_TREX0) - voodoo->params.tmu[0].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_TREX1) - voodoo->params.tmu[1].dWdY = (int64_t)(tempif.f * 4294967296.0f); - if (chip & CHIP_FBI) - voodoo->params.dWdY = (int64_t)(tempif.f * 4294967296.0f); - break; + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->params.front_offset; + voodoo->swap_pending = 1; + } else { + voodoo->swap_interval = (val >> 1) & 0xff; + voodoo->swap_offset = voodoo->params.front_offset; + voodoo->swap_pending = 1; - case SST_ftriangleCMD: - voodoo->params.sign = val & (1 << 31); + voodoo_wait_for_swap_complete(voodoo); + } + voodoo->cmd_read++; + break; - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + case SST_vertexAx: + case SST_remap_vertexAx: + voodoo->params.vertexAx = val & 0xffff; + break; + case SST_vertexAy: + case SST_remap_vertexAy: + voodoo->params.vertexAy = val & 0xffff; + break; + case SST_vertexBx: + case SST_remap_vertexBx: + voodoo->params.vertexBx = val & 0xffff; + break; + case SST_vertexBy: + case SST_remap_vertexBy: + voodoo->params.vertexBy = val & 0xffff; + break; + case SST_vertexCx: + case SST_remap_vertexCx: + voodoo->params.vertexCx = val & 0xffff; + break; + case SST_vertexCy: + case SST_remap_vertexCy: + voodoo->params.vertexCy = val & 0xffff; + break; - voodoo_queue_triangle(voodoo, &voodoo->params); + case SST_startR: + case SST_remap_startR: + voodoo->params.startR = val & 0xffffff; + break; + case SST_startG: + case SST_remap_startG: + voodoo->params.startG = val & 0xffffff; + break; + case SST_startB: + case SST_remap_startB: + voodoo->params.startB = val & 0xffffff; + break; + case SST_startZ: + case SST_remap_startZ: + voodoo->params.startZ = val; + break; + case SST_startA: + case SST_remap_startA: + voodoo->params.startA = val & 0xffffff; + break; + case SST_startS: + case SST_remap_startS: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startS = ((int64_t) (int32_t) val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startS = ((int64_t) (int32_t) val) << 14; + break; + case SST_startT: + case SST_remap_startT: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startT = ((int64_t) (int32_t) val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startT = ((int64_t) (int32_t) val) << 14; + break; + case SST_startW: + case SST_remap_startW: + if (chip & CHIP_FBI) + voodoo->params.startW = (int64_t) (int32_t) val << 2; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startW = (int64_t) (int32_t) val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startW = (int64_t) (int32_t) val << 2; + break; - voodoo->cmd_read++; - break; + case SST_dRdX: + case SST_remap_dRdX: + voodoo->params.dRdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dGdX: + case SST_remap_dGdX: + voodoo->params.dGdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dBdX: + case SST_remap_dBdX: + voodoo->params.dBdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dZdX: + case SST_remap_dZdX: + voodoo->params.dZdX = val; + break; + case SST_dAdX: + case SST_remap_dAdX: + voodoo->params.dAdX = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dSdX: + case SST_remap_dSdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdX = ((int64_t) (int32_t) val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdX = ((int64_t) (int32_t) val) << 14; + break; + case SST_dTdX: + case SST_remap_dTdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdX = ((int64_t) (int32_t) val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdX = ((int64_t) (int32_t) val) << 14; + break; + case SST_dWdX: + case SST_remap_dWdX: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdX = (int64_t) (int32_t) val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdX = (int64_t) (int32_t) val << 2; + if (chip & CHIP_FBI) + voodoo->params.dWdX = (int64_t) (int32_t) val << 2; + break; - case SST_fbzColorPath: - voodoo->params.fbzColorPath = val; - voodoo->rgb_sel = val & 3; - break; + case SST_dRdY: + case SST_remap_dRdY: + voodoo->params.dRdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dGdY: + case SST_remap_dGdY: + voodoo->params.dGdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dBdY: + case SST_remap_dBdY: + voodoo->params.dBdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dZdY: + case SST_remap_dZdY: + voodoo->params.dZdY = val; + break; + case SST_dAdY: + case SST_remap_dAdY: + voodoo->params.dAdY = (val & 0xffffff) | ((val & 0x800000) ? 0xff000000 : 0); + break; + case SST_dSdY: + case SST_remap_dSdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdY = ((int64_t) (int32_t) val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdY = ((int64_t) (int32_t) val) << 14; + break; + case SST_dTdY: + case SST_remap_dTdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdY = ((int64_t) (int32_t) val) << 14; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdY = ((int64_t) (int32_t) val) << 14; + break; + case SST_dWdY: + case SST_remap_dWdY: + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdY = (int64_t) (int32_t) val << 2; + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdY = (int64_t) (int32_t) val << 2; + if (chip & CHIP_FBI) + voodoo->params.dWdY = (int64_t) (int32_t) val << 2; + break; - case SST_fogMode: - voodoo->params.fogMode = val; - break; - case SST_alphaMode: - voodoo->params.alphaMode = val; - break; - case SST_fbzMode: - voodoo->params.fbzMode = val; - voodoo_recalc(voodoo); - break; - case SST_lfbMode: - voodoo->lfbMode = val; - voodoo_recalc(voodoo); - break; + case SST_triangleCMD: + case SST_remap_triangleCMD: + voodoo->params.sign = val & (1 << 31); - case SST_clipLeftRight: - if (voodoo->type >= VOODOO_2) - { - voodoo->params.clipRight = val & 0xfff; - voodoo->params.clipLeft = (val >> 16) & 0xfff; + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + + voodoo_queue_triangle(voodoo, &voodoo->params); + + voodoo->cmd_read++; + break; + + case SST_fvertexAx: + case SST_remap_fvertexAx: + voodoo->fvertexAx.i = val; + voodoo->params.vertexAx = (int32_t) (int16_t) (int32_t) (voodoo->fvertexAx.f * 16.0f) & 0xffff; + break; + case SST_fvertexAy: + case SST_remap_fvertexAy: + voodoo->fvertexAy.i = val; + voodoo->params.vertexAy = (int32_t) (int16_t) (int32_t) (voodoo->fvertexAy.f * 16.0f) & 0xffff; + break; + case SST_fvertexBx: + case SST_remap_fvertexBx: + voodoo->fvertexBx.i = val; + voodoo->params.vertexBx = (int32_t) (int16_t) (int32_t) (voodoo->fvertexBx.f * 16.0f) & 0xffff; + break; + case SST_fvertexBy: + case SST_remap_fvertexBy: + voodoo->fvertexBy.i = val; + voodoo->params.vertexBy = (int32_t) (int16_t) (int32_t) (voodoo->fvertexBy.f * 16.0f) & 0xffff; + break; + case SST_fvertexCx: + case SST_remap_fvertexCx: + voodoo->fvertexCx.i = val; + voodoo->params.vertexCx = (int32_t) (int16_t) (int32_t) (voodoo->fvertexCx.f * 16.0f) & 0xffff; + break; + case SST_fvertexCy: + case SST_remap_fvertexCy: + voodoo->fvertexCy.i = val; + voodoo->params.vertexCy = (int32_t) (int16_t) (int32_t) (voodoo->fvertexCy.f * 16.0f) & 0xffff; + break; + + case SST_fstartR: + case SST_remap_fstartR: + tempif.i = val; + voodoo->params.startR = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fstartG: + case SST_remap_fstartG: + tempif.i = val; + voodoo->params.startG = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fstartB: + case SST_remap_fstartB: + tempif.i = val; + voodoo->params.startB = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fstartZ: + case SST_remap_fstartZ: + tempif.i = val; + voodoo->params.startZ = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fstartA: + case SST_remap_fstartA: + tempif.i = val; + voodoo->params.startA = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fstartS: + case SST_remap_fstartS: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startS = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startS = (int64_t) (tempif.f * 4294967296.0f); + break; + case SST_fstartT: + case SST_remap_fstartT: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startT = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startT = (int64_t) (tempif.f * 4294967296.0f); + break; + case SST_fstartW: + case SST_remap_fstartW: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].startW = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].startW = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.startW = (int64_t) (tempif.f * 4294967296.0f); + break; + + case SST_fdRdX: + case SST_remap_fdRdX: + tempif.i = val; + voodoo->params.dRdX = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdGdX: + case SST_remap_fdGdX: + tempif.i = val; + voodoo->params.dGdX = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdBdX: + case SST_remap_fdBdX: + tempif.i = val; + voodoo->params.dBdX = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdZdX: + case SST_remap_fdZdX: + tempif.i = val; + voodoo->params.dZdX = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdAdX: + case SST_remap_fdAdX: + tempif.i = val; + voodoo->params.dAdX = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdSdX: + case SST_remap_fdSdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdX = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdX = (int64_t) (tempif.f * 4294967296.0f); + break; + case SST_fdTdX: + case SST_remap_fdTdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdX = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdX = (int64_t) (tempif.f * 4294967296.0f); + break; + case SST_fdWdX: + case SST_remap_fdWdX: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdX = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdX = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.dWdX = (int64_t) (tempif.f * 4294967296.0f); + break; + + case SST_fdRdY: + case SST_remap_fdRdY: + tempif.i = val; + voodoo->params.dRdY = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdGdY: + case SST_remap_fdGdY: + tempif.i = val; + voodoo->params.dGdY = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdBdY: + case SST_remap_fdBdY: + tempif.i = val; + voodoo->params.dBdY = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdZdY: + case SST_remap_fdZdY: + tempif.i = val; + voodoo->params.dZdY = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdAdY: + case SST_remap_fdAdY: + tempif.i = val; + voodoo->params.dAdY = (int32_t) (tempif.f * 4096.0f); + break; + case SST_fdSdY: + case SST_remap_fdSdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dSdY = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dSdY = (int64_t) (tempif.f * 4294967296.0f); + break; + case SST_fdTdY: + case SST_remap_fdTdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dTdY = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dTdY = (int64_t) (tempif.f * 4294967296.0f); + break; + case SST_fdWdY: + case SST_remap_fdWdY: + tempif.i = val; + if (chip & CHIP_TREX0) + voodoo->params.tmu[0].dWdY = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_TREX1) + voodoo->params.tmu[1].dWdY = (int64_t) (tempif.f * 4294967296.0f); + if (chip & CHIP_FBI) + voodoo->params.dWdY = (int64_t) (tempif.f * 4294967296.0f); + break; + + case SST_ftriangleCMD: + voodoo->params.sign = val & (1 << 31); + + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; + + voodoo_queue_triangle(voodoo, &voodoo->params); + + voodoo->cmd_read++; + break; + + case SST_fbzColorPath: + voodoo->params.fbzColorPath = val; + voodoo->rgb_sel = val & 3; + break; + + case SST_fogMode: + voodoo->params.fogMode = val; + break; + case SST_alphaMode: + voodoo->params.alphaMode = val; + break; + case SST_fbzMode: + voodoo->params.fbzMode = val; + voodoo_recalc(voodoo); + break; + case SST_lfbMode: + voodoo->lfbMode = val; + voodoo_recalc(voodoo); + break; + + case SST_clipLeftRight: + if (voodoo->type >= VOODOO_2) { + voodoo->params.clipRight = val & 0xfff; + voodoo->params.clipLeft = (val >> 16) & 0xfff; + } else { + voodoo->params.clipRight = val & 0x3ff; + voodoo->params.clipLeft = (val >> 16) & 0x3ff; + } + break; + case SST_clipLowYHighY: + if (voodoo->type >= VOODOO_2) { + voodoo->params.clipHighY = val & 0xfff; + voodoo->params.clipLowY = (val >> 16) & 0xfff; + } else { + voodoo->params.clipHighY = val & 0x3ff; + voodoo->params.clipLowY = (val >> 16) & 0x3ff; + } + break; + + case SST_nopCMD: + voodoo->cmd_read++; + voodoo->fbiPixelsIn = 0; + voodoo->fbiChromaFail = 0; + voodoo->fbiZFuncFail = 0; + voodoo->fbiAFuncFail = 0; + voodoo->fbiPixelsOut = 0; + break; + case SST_fastfillCMD: + voodoo_wait_for_render_thread_idle(voodoo); + voodoo_fastfill(voodoo, &voodoo->params); + voodoo->cmd_read++; + break; + + case SST_fogColor: + voodoo->params.fogColor.r = (val >> 16) & 0xff; + voodoo->params.fogColor.g = (val >> 8) & 0xff; + voodoo->params.fogColor.b = val & 0xff; + break; + + case SST_zaColor: + voodoo->params.zaColor = val; + break; + case SST_chromaKey: + voodoo->params.chromaKey_r = (val >> 16) & 0xff; + voodoo->params.chromaKey_g = (val >> 8) & 0xff; + voodoo->params.chromaKey_b = val & 0xff; + voodoo->params.chromaKey = val & 0xffffff; + break; + case SST_stipple: + voodoo->params.stipple = val; + break; + case SST_color0: + voodoo->params.color0 = val; + break; + case SST_color1: + voodoo->params.color1 = val; + break; + + case SST_fogTable00: + case SST_fogTable01: + case SST_fogTable02: + case SST_fogTable03: + case SST_fogTable04: + case SST_fogTable05: + case SST_fogTable06: + case SST_fogTable07: + case SST_fogTable08: + case SST_fogTable09: + case SST_fogTable0a: + case SST_fogTable0b: + case SST_fogTable0c: + case SST_fogTable0d: + case SST_fogTable0e: + case SST_fogTable0f: + case SST_fogTable10: + case SST_fogTable11: + case SST_fogTable12: + case SST_fogTable13: + case SST_fogTable14: + case SST_fogTable15: + case SST_fogTable16: + case SST_fogTable17: + case SST_fogTable18: + case SST_fogTable19: + case SST_fogTable1a: + case SST_fogTable1b: + case SST_fogTable1c: + case SST_fogTable1d: + case SST_fogTable1e: + case SST_fogTable1f: + addr = (addr - SST_fogTable00) >> 1; + voodoo->params.fogTable[addr].dfog = val & 0xff; + voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; + voodoo->params.fogTable[addr + 1].dfog = (val >> 16) & 0xff; + voodoo->params.fogTable[addr + 1].fog = (val >> 24) & 0xff; + break; + + case SST_clipLeftRight1: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.clipRight1 = val & 0xfff; + voodoo->params.clipLeft1 = (val >> 16) & 0xfff; + } + break; + case SST_clipTopBottom1: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.clipHighY1 = val & 0xfff; + voodoo->params.clipLowY1 = (val >> 16) & 0xfff; + } + break; + + case SST_colBufferAddr: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.draw_offset = val & 0xfffff0; + voodoo->fb_write_offset = voodoo->params.draw_offset; + // voodoo_reg_log("colorBufferAddr=%06x\n", voodoo->params.draw_offset); + } + break; + case SST_colBufferStride: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->col_tiled = val & (1 << 15); + voodoo->params.col_tiled = voodoo->col_tiled; + if (voodoo->col_tiled) { + voodoo->row_width = (val & 0x7f) * 128 * 32; + // voodoo_reg_log("colBufferStride tiled = %i bytes, tiled %08x\n", voodoo->row_width, val); + } else { + voodoo->row_width = val & 0x3fff; + // voodoo_reg_log("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); } + voodoo->params.row_width = voodoo->row_width; + } + break; + case SST_auxBufferAddr: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->params.aux_offset = val & 0xfffff0; + // pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); + } + break; + case SST_auxBufferStride: + if (voodoo->type >= VOODOO_BANSHEE) { + voodoo->aux_tiled = val & (1 << 15); + voodoo->params.aux_tiled = voodoo->aux_tiled; + if (voodoo->aux_tiled) { + voodoo->aux_row_width = (val & 0x7f) * 128 * 32; + // voodoo_reg_log("auxBufferStride tiled = %i bytes, tiled\n", voodoo->aux_row_width); + } else { + voodoo->aux_row_width = val & 0x3fff; + // voodoo_reg_log("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); + } + voodoo->params.aux_row_width = voodoo->aux_row_width; + } + break; + + case SST_clutData: + voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; + voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; + if (val & 0x20000000) { + voodoo->clutData[(val >> 24) & 0x3f].b = 255; + voodoo->clutData[(val >> 24) & 0x3f].g = 255; + voodoo->clutData[(val >> 24) & 0x3f].r = 255; + } + voodoo->clutData_dirty = 1; + break; + + case SST_sSetupMode: + voodoo->sSetupMode = val; + break; + case SST_sVx: + tempif.i = val; + voodoo->verts[3].sVx = tempif.f; + // voodoo_reg_log("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); + break; + case SST_sVy: + tempif.i = val; + voodoo->verts[3].sVy = tempif.f; + // voodoo_reg_log("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); + break; + case SST_sARGB: + voodoo->verts[3].sBlue = (float) (val & 0xff); + voodoo->verts[3].sGreen = (float) ((val >> 8) & 0xff); + voodoo->verts[3].sRed = (float) ((val >> 16) & 0xff); + voodoo->verts[3].sAlpha = (float) ((val >> 24) & 0xff); + break; + case SST_sRed: + tempif.i = val; + voodoo->verts[3].sRed = tempif.f; + break; + case SST_sGreen: + tempif.i = val; + voodoo->verts[3].sGreen = tempif.f; + break; + case SST_sBlue: + tempif.i = val; + voodoo->verts[3].sBlue = tempif.f; + break; + case SST_sAlpha: + tempif.i = val; + voodoo->verts[3].sAlpha = tempif.f; + break; + case SST_sVz: + tempif.i = val; + voodoo->verts[3].sVz = tempif.f; + break; + case SST_sWb: + tempif.i = val; + voodoo->verts[3].sWb = tempif.f; + break; + case SST_sW0: + tempif.i = val; + voodoo->verts[3].sW0 = tempif.f; + break; + case SST_sS0: + tempif.i = val; + voodoo->verts[3].sS0 = tempif.f; + break; + case SST_sT0: + tempif.i = val; + voodoo->verts[3].sT0 = tempif.f; + break; + case SST_sW1: + tempif.i = val; + voodoo->verts[3].sW1 = tempif.f; + break; + case SST_sS1: + tempif.i = val; + voodoo->verts[3].sS1 = tempif.f; + break; + case SST_sT1: + tempif.i = val; + voodoo->verts[3].sT1 = tempif.f; + break; + + case SST_sBeginTriCMD: + // voodoo_reg_log("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); + voodoo->verts[0] = voodoo->verts[3]; + voodoo->verts[1] = voodoo->verts[3]; + voodoo->verts[2] = voodoo->verts[3]; + voodoo->vertex_next_age = 0; + voodoo->vertex_ages[0] = voodoo->vertex_next_age++; + + voodoo->num_verticies = 1; + voodoo->cull_pingpong = 0; + break; + case SST_sDrawTriCMD: + // voodoo_reg_log("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); + /*I'm not sure this is the vertex selection algorithm actually used in the 3dfx + chips, but this works with a number of games that switch between strip and fan + mode in the middle of a run (eg Black & White, Viper Racing)*/ + if (voodoo->vertex_next_age < 3) { + /*Fewer than three vertices already written, store in next slot*/ + int vertex_nr = voodoo->vertex_next_age; + + voodoo->verts[vertex_nr] = voodoo->verts[3]; + voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; + } else { + int vertex_nr = 0; + + if (!(voodoo->sSetupMode & SETUPMODE_STRIP_MODE)) { + /*Strip - find oldest vertex*/ + if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) + vertex_nr = 1; + else + vertex_nr = 2; + } else { + /*Fan - find second oldest vertex (ie pivot around oldest)*/ + if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[0]) && (voodoo->vertex_ages[0] < voodoo->vertex_ages[1])) + vertex_nr = 0; + else if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) + vertex_nr = 1; + else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[1]) && (voodoo->vertex_ages[1] < voodoo->vertex_ages[0])) + vertex_nr = 1; + else + vertex_nr = 2; + } + voodoo->verts[vertex_nr] = voodoo->verts[3]; + voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; + } + + voodoo->num_verticies++; + if (voodoo->num_verticies == 3) { + // voodoo_reg_log("triangle_setup\n"); + voodoo_triangle_setup(voodoo); + voodoo->cull_pingpong = !voodoo->cull_pingpong; + + voodoo->num_verticies = 2; + } + break; + + case SST_bltSrcBaseAddr: + voodoo->bltSrcBaseAddr = val & 0x3fffff; + break; + case SST_bltDstBaseAddr: + // voodoo_reg_log("Write bltDstBaseAddr %08x\n", val); + voodoo->bltDstBaseAddr = val & 0x3fffff; + break; + case SST_bltXYStrides: + voodoo->bltSrcXYStride = val & 0xfff; + voodoo->bltDstXYStride = (val >> 16) & 0xfff; + // voodoo_reg_log("Write bltXYStrides %08x\n", val); + break; + case SST_bltSrcChromaRange: + voodoo->bltSrcChromaRange = val; + voodoo->bltSrcChromaMinB = val & 0x1f; + voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; + voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; + voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; + voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; + voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; + break; + case SST_bltDstChromaRange: + voodoo->bltDstChromaRange = val; + voodoo->bltDstChromaMinB = val & 0x1f; + voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; + voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; + voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; + voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; + voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; + break; + case SST_bltClipX: + voodoo->bltClipRight = val & 0xfff; + voodoo->bltClipLeft = (val >> 16) & 0xfff; + break; + case SST_bltClipY: + voodoo->bltClipHighY = val & 0xfff; + voodoo->bltClipLowY = (val >> 16) & 0xfff; + break; + + case SST_bltSrcXY: + voodoo->bltSrcX = val & 0x7ff; + voodoo->bltSrcY = (val >> 16) & 0x7ff; + break; + case SST_bltDstXY: + // voodoo_reg_log("Write bltDstXY %08x\n", val); + voodoo->bltDstX = val & 0x7ff; + voodoo->bltDstY = (val >> 16) & 0x7ff; + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltSize: + // voodoo_reg_log("Write bltSize %08x\n", val); + voodoo->bltSizeX = val & 0xfff; + if (voodoo->bltSizeX & 0x800) + voodoo->bltSizeX |= 0xfffff000; + voodoo->bltSizeY = (val >> 16) & 0xfff; + if (voodoo->bltSizeY & 0x800) + voodoo->bltSizeY |= 0xfffff000; + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltRop: + voodoo->bltRop[0] = val & 0xf; + voodoo->bltRop[1] = (val >> 4) & 0xf; + voodoo->bltRop[2] = (val >> 8) & 0xf; + voodoo->bltRop[3] = (val >> 12) & 0xf; + break; + case SST_bltColor: + // voodoo_reg_log("Write bltColor %08x\n", val); + voodoo->bltColorFg = val & 0xffff; + voodoo->bltColorBg = (val >> 16) & 0xffff; + break; + + case SST_bltCommand: + voodoo->bltCommand = val; + // voodoo_reg_log("Write bltCommand %08x\n", val); + if (val & (1 << 31)) + voodoo_v2_blit_start(voodoo); + break; + case SST_bltData: + voodoo_v2_blit_data(voodoo, val); + break; + + case SST_textureMode: + if (chip & CHIP_TREX0) { + voodoo->params.textureMode[0] = val; + voodoo->params.tformat[0] = (val >> 8) & 0xf; + } + if (chip & CHIP_TREX1) { + voodoo->params.textureMode[1] = val; + voodoo->params.tformat[1] = (val >> 8) & 0xf; + } + break; + case SST_tLOD: + if (chip & CHIP_TREX0) { + voodoo->params.tLOD[0] = val; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + voodoo->params.tLOD[1] = val; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_tDetail: + if (chip & CHIP_TREX0) { + voodoo->params.detail_max[0] = val & 0xff; + voodoo->params.detail_bias[0] = (val >> 8) & 0x3f; + voodoo->params.detail_scale[0] = (val >> 14) & 7; + } + if (chip & CHIP_TREX1) { + voodoo->params.detail_max[1] = val & 0xff; + voodoo->params.detail_bias[1] = (val >> 8) & 0x3f; + voodoo->params.detail_scale[1] = (val >> 14) & 7; + } + break; + case SST_texBaseAddr: + if (chip & CHIP_TREX0) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr[0] = val & 0xfffff0; else - { - voodoo->params.clipRight = val & 0x3ff; - voodoo->params.clipLeft = (val >> 16) & 0x3ff; - } - break; - case SST_clipLowYHighY: - if (voodoo->type >= VOODOO_2) - { - voodoo->params.clipHighY = val & 0xfff; - voodoo->params.clipLowY = (val >> 16) & 0xfff; - } + voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; + // voodoo_reg_log("texBaseAddr = %08x %08x\n", voodoo->params.texBaseAddr[0], val); + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr[1] = val & 0xfffff0; else - { - voodoo->params.clipHighY = val & 0x3ff; - voodoo->params.clipLowY = (val >> 16) & 0x3ff; - } - break; - - case SST_nopCMD: - voodoo->cmd_read++; - voodoo->fbiPixelsIn = 0; - voodoo->fbiChromaFail = 0; - voodoo->fbiZFuncFail = 0; - voodoo->fbiAFuncFail = 0; - voodoo->fbiPixelsOut = 0; - break; - case SST_fastfillCMD: - voodoo_wait_for_render_thread_idle(voodoo); - voodoo_fastfill(voodoo, &voodoo->params); - voodoo->cmd_read++; - break; - - case SST_fogColor: - voodoo->params.fogColor.r = (val >> 16) & 0xff; - voodoo->params.fogColor.g = (val >> 8) & 0xff; - voodoo->params.fogColor.b = val & 0xff; - break; - - case SST_zaColor: - voodoo->params.zaColor = val; - break; - case SST_chromaKey: - voodoo->params.chromaKey_r = (val >> 16) & 0xff; - voodoo->params.chromaKey_g = (val >> 8) & 0xff; - voodoo->params.chromaKey_b = val & 0xff; - voodoo->params.chromaKey = val & 0xffffff; - break; - case SST_stipple: - voodoo->params.stipple = val; - break; - case SST_color0: - voodoo->params.color0 = val; - break; - case SST_color1: - voodoo->params.color1 = val; - break; - - case SST_fogTable00: case SST_fogTable01: case SST_fogTable02: case SST_fogTable03: - case SST_fogTable04: case SST_fogTable05: case SST_fogTable06: case SST_fogTable07: - case SST_fogTable08: case SST_fogTable09: case SST_fogTable0a: case SST_fogTable0b: - case SST_fogTable0c: case SST_fogTable0d: case SST_fogTable0e: case SST_fogTable0f: - case SST_fogTable10: case SST_fogTable11: case SST_fogTable12: case SST_fogTable13: - case SST_fogTable14: case SST_fogTable15: case SST_fogTable16: case SST_fogTable17: - case SST_fogTable18: case SST_fogTable19: case SST_fogTable1a: case SST_fogTable1b: - case SST_fogTable1c: case SST_fogTable1d: case SST_fogTable1e: case SST_fogTable1f: - addr = (addr - SST_fogTable00) >> 1; - voodoo->params.fogTable[addr].dfog = val & 0xff; - voodoo->params.fogTable[addr].fog = (val >> 8) & 0xff; - voodoo->params.fogTable[addr+1].dfog = (val >> 16) & 0xff; - voodoo->params.fogTable[addr+1].fog = (val >> 24) & 0xff; - break; - - case SST_clipLeftRight1: + voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr1: + if (chip & CHIP_TREX0) { if (voodoo->type >= VOODOO_BANSHEE) - { - voodoo->params.clipRight1 = val & 0xfff; - voodoo->params.clipLeft1 = (val >> 16) & 0xfff; - } - break; - case SST_clipTopBottom1: - if (voodoo->type >= VOODOO_BANSHEE) - { - voodoo->params.clipHighY1 = val & 0xfff; - voodoo->params.clipLowY1 = (val >> 16) & 0xfff; - } - break; - - case SST_colBufferAddr: - if (voodoo->type >= VOODOO_BANSHEE) - { - voodoo->params.draw_offset = val & 0xfffff0; - voodoo->fb_write_offset = voodoo->params.draw_offset; -// voodoo_reg_log("colorBufferAddr=%06x\n", voodoo->params.draw_offset); - } - break; - case SST_colBufferStride: - if (voodoo->type >= VOODOO_BANSHEE) - { - voodoo->col_tiled = val & (1 << 15); - voodoo->params.col_tiled = voodoo->col_tiled; - if (voodoo->col_tiled) - { - voodoo->row_width = (val & 0x7f) * 128*32; -// voodoo_reg_log("colBufferStride tiled = %i bytes, tiled %08x\n", voodoo->row_width, val); - } - else - { - voodoo->row_width = val & 0x3fff; -// voodoo_reg_log("colBufferStride linear = %i bytes, linear\n", voodoo->row_width); - } - voodoo->params.row_width = voodoo->row_width; - } - break; - case SST_auxBufferAddr: - if (voodoo->type >= VOODOO_BANSHEE) - { - voodoo->params.aux_offset = val & 0xfffff0; -// pclog("auxBufferAddr=%06x\n", voodoo->params.aux_offset); - } - break; - case SST_auxBufferStride: - if (voodoo->type >= VOODOO_BANSHEE) - { - voodoo->aux_tiled = val & (1 << 15); - voodoo->params.aux_tiled = voodoo->aux_tiled; - if (voodoo->aux_tiled) - { - voodoo->aux_row_width = (val & 0x7f) * 128*32; -// voodoo_reg_log("auxBufferStride tiled = %i bytes, tiled\n", voodoo->aux_row_width); - } - else - { - voodoo->aux_row_width = val & 0x3fff; -// voodoo_reg_log("auxBufferStride linear = %i bytes, linear\n", voodoo->aux_row_width); - } - voodoo->params.aux_row_width = voodoo->aux_row_width; - } - break; - - case SST_clutData: - voodoo->clutData[(val >> 24) & 0x3f].b = val & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].g = (val >> 8) & 0xff; - voodoo->clutData[(val >> 24) & 0x3f].r = (val >> 16) & 0xff; - if (val & 0x20000000) - { - voodoo->clutData[(val >> 24) & 0x3f].b = 255; - voodoo->clutData[(val >> 24) & 0x3f].g = 255; - voodoo->clutData[(val >> 24) & 0x3f].r = 255; - } - voodoo->clutData_dirty = 1; - break; - - case SST_sSetupMode: - voodoo->sSetupMode = val; - break; - case SST_sVx: - tempif.i = val; - voodoo->verts[3].sVx = tempif.f; -// voodoo_reg_log("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); - break; - case SST_sVy: - tempif.i = val; - voodoo->verts[3].sVy = tempif.f; -// voodoo_reg_log("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); - break; - case SST_sARGB: - voodoo->verts[3].sBlue = (float)(val & 0xff); - voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff); - voodoo->verts[3].sRed = (float)((val >> 16) & 0xff); - voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff); - break; - case SST_sRed: - tempif.i = val; - voodoo->verts[3].sRed = tempif.f; - break; - case SST_sGreen: - tempif.i = val; - voodoo->verts[3].sGreen = tempif.f; - break; - case SST_sBlue: - tempif.i = val; - voodoo->verts[3].sBlue = tempif.f; - break; - case SST_sAlpha: - tempif.i = val; - voodoo->verts[3].sAlpha = tempif.f; - break; - case SST_sVz: - tempif.i = val; - voodoo->verts[3].sVz = tempif.f; - break; - case SST_sWb: - tempif.i = val; - voodoo->verts[3].sWb = tempif.f; - break; - case SST_sW0: - tempif.i = val; - voodoo->verts[3].sW0 = tempif.f; - break; - case SST_sS0: - tempif.i = val; - voodoo->verts[3].sS0 = tempif.f; - break; - case SST_sT0: - tempif.i = val; - voodoo->verts[3].sT0 = tempif.f; - break; - case SST_sW1: - tempif.i = val; - voodoo->verts[3].sW1 = tempif.f; - break; - case SST_sS1: - tempif.i = val; - voodoo->verts[3].sS1 = tempif.f; - break; - case SST_sT1: - tempif.i = val; - voodoo->verts[3].sT1 = tempif.f; - break; - - case SST_sBeginTriCMD: -// voodoo_reg_log("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); - voodoo->verts[0] = voodoo->verts[3]; - voodoo->verts[1] = voodoo->verts[3]; - voodoo->verts[2] = voodoo->verts[3]; - voodoo->vertex_next_age = 0; - voodoo->vertex_ages[0] = voodoo->vertex_next_age++; - - voodoo->num_verticies = 1; - voodoo->cull_pingpong = 0; - break; - case SST_sDrawTriCMD: -// voodoo_reg_log("sDrawTriCMD %i %i\n", voodoo->num_verticies, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); - /*I'm not sure this is the vertex selection algorithm actually used in the 3dfx - chips, but this works with a number of games that switch between strip and fan - mode in the middle of a run (eg Black & White, Viper Racing)*/ - if (voodoo->vertex_next_age < 3) - { - /*Fewer than three vertices already written, store in next slot*/ - int vertex_nr = voodoo->vertex_next_age; - - voodoo->verts[vertex_nr] = voodoo->verts[3]; - voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; - } + voodoo->params.texBaseAddr1[0] = val & 0xfffff0; else - { - int vertex_nr = 0; + voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr1[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr2: + if (chip & CHIP_TREX0) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr2[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr2[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; + case SST_texBaseAddr38: + if (chip & CHIP_TREX0) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr38[0] = val & 0xfffff0; + else + voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 0); + } + if (chip & CHIP_TREX1) { + if (voodoo->type >= VOODOO_BANSHEE) + voodoo->params.texBaseAddr38[1] = val & 0xfffff0; + else + voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; + voodoo_recalc_tex(voodoo, 1); + } + break; - if (!(voodoo->sSetupMode & SETUPMODE_STRIP_MODE)) - { - /*Strip - find oldest vertex*/ - if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && - (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) - vertex_nr = 0; - else if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && - (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) - vertex_nr = 1; - else - vertex_nr = 2; - } - else - { - /*Fan - find second oldest vertex (ie pivot around oldest)*/ - if ((voodoo->vertex_ages[1] < voodoo->vertex_ages[0]) && - (voodoo->vertex_ages[0] < voodoo->vertex_ages[2])) - vertex_nr = 0; - else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[0]) && - (voodoo->vertex_ages[0] < voodoo->vertex_ages[1])) - vertex_nr = 0; - else if ((voodoo->vertex_ages[0] < voodoo->vertex_ages[1]) && - (voodoo->vertex_ages[1] < voodoo->vertex_ages[2])) - vertex_nr = 1; - else if ((voodoo->vertex_ages[2] < voodoo->vertex_ages[1]) && - (voodoo->vertex_ages[1] < voodoo->vertex_ages[0])) - vertex_nr = 1; - else - vertex_nr = 2; - } - voodoo->verts[vertex_nr] = voodoo->verts[3]; - voodoo->vertex_ages[vertex_nr] = voodoo->vertex_next_age++; - } + case SST_trexInit1: + if (chip & CHIP_TREX0) + voodoo->trexInit1[0] = val; + if (chip & CHIP_TREX1) + voodoo->trexInit1[1] = val; + break; - voodoo->num_verticies++; - if (voodoo->num_verticies == 3) - { -// voodoo_reg_log("triangle_setup\n"); - voodoo_triangle_setup(voodoo); - voodoo->cull_pingpong = !voodoo->cull_pingpong; + case SST_nccTable0_Y0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable0_Y3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].y[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].y[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; - voodoo->num_verticies = 2; + case SST_nccTable0_I0: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[0] = val; + voodoo->ncc_dirty[1] = 1; } break; + } + case SST_nccTable0_I2: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q0: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].q[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].q[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + case SST_nccTable0_Q2: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + } + if (val & (1 << 31)) { + int p = (val >> 23) & 0xfe; + if (chip & CHIP_TREX0) { + voodoo->palette[0][p].u = val | 0xff000000; + voodoo->palette_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->palette[1][p].u = val | 0xff000000; + voodoo->palette_dirty[1] = 1; + } + } + break; - case SST_bltSrcBaseAddr: - voodoo->bltSrcBaseAddr = val & 0x3fffff; + case SST_nccTable0_I1: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[1] = val; + voodoo->ncc_dirty[1] = 1; + } break; - case SST_bltDstBaseAddr: -// voodoo_reg_log("Write bltDstBaseAddr %08x\n", val); - voodoo->bltDstBaseAddr = val & 0x3fffff; + } + case SST_nccTable0_I3: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].i[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].i[3] = val; + voodoo->ncc_dirty[1] = 1; + } break; - case SST_bltXYStrides: - voodoo->bltSrcXYStride = val & 0xfff; - voodoo->bltDstXYStride = (val >> 16) & 0xfff; -// voodoo_reg_log("Write bltXYStrides %08x\n", val); + } + case SST_nccTable0_Q1: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].q[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].q[1] = val; + voodoo->ncc_dirty[1] = 1; + } break; - case SST_bltSrcChromaRange: - voodoo->bltSrcChromaRange = val; - voodoo->bltSrcChromaMinB = val & 0x1f; - voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; - voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; - voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltDstChromaRange: - voodoo->bltDstChromaRange = val; - voodoo->bltDstChromaMinB = val & 0x1f; - voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; - voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; - voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; - voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; - break; - case SST_bltClipX: - voodoo->bltClipRight = val & 0xfff; - voodoo->bltClipLeft = (val >> 16) & 0xfff; - break; - case SST_bltClipY: - voodoo->bltClipHighY = val & 0xfff; - voodoo->bltClipLowY = (val >> 16) & 0xfff; + } + case SST_nccTable0_Q3: + if (!(val & (1 << 31))) { + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][0].q[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][0].q[3] = val; + voodoo->ncc_dirty[1] = 1; + } break; + } + if (val & (1 << 31)) { + int p = ((val >> 23) & 0xfe) | 0x01; + if (chip & CHIP_TREX0) { + voodoo->palette[0][p].u = val | 0xff000000; + voodoo->palette_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->palette[1][p].u = val | 0xff000000; + voodoo->palette_dirty[1] = 1; + } + } + break; - case SST_bltSrcXY: - voodoo->bltSrcX = val & 0x7ff; - voodoo->bltSrcY = (val >> 16) & 0x7ff; - break; - case SST_bltDstXY: -// voodoo_reg_log("Write bltDstXY %08x\n", val); - voodoo->bltDstX = val & 0x7ff; - voodoo->bltDstY = (val >> 16) & 0x7ff; - if (val & (1 << 31)) - voodoo_v2_blit_start(voodoo); - break; - case SST_bltSize: -// voodoo_reg_log("Write bltSize %08x\n", val); - voodoo->bltSizeX = val & 0xfff; - if (voodoo->bltSizeX & 0x800) - voodoo->bltSizeX |= 0xfffff000; - voodoo->bltSizeY = (val >> 16) & 0xfff; - if (voodoo->bltSizeY & 0x800) - voodoo->bltSizeY |= 0xfffff000; - if (val & (1 << 31)) - voodoo_v2_blit_start(voodoo); - break; - case SST_bltRop: - voodoo->bltRop[0] = val & 0xf; - voodoo->bltRop[1] = (val >> 4) & 0xf; - voodoo->bltRop[2] = (val >> 8) & 0xf; - voodoo->bltRop[3] = (val >> 12) & 0xf; - break; - case SST_bltColor: -// voodoo_reg_log("Write bltColor %08x\n", val); - voodoo->bltColorFg = val & 0xffff; - voodoo->bltColorBg = (val >> 16) & 0xffff; - break; + case SST_nccTable1_Y0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Y3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].y[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].y[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_I3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].i[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].i[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q0: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[0] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[0] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q1: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[1] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[1] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q2: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[2] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[2] = val; + voodoo->ncc_dirty[1] = 1; + } + break; + case SST_nccTable1_Q3: + if (chip & CHIP_TREX0) { + voodoo->nccTable[0][1].q[3] = val; + voodoo->ncc_dirty[0] = 1; + } + if (chip & CHIP_TREX1) { + voodoo->nccTable[1][1].q[3] = val; + voodoo->ncc_dirty[1] = 1; + } + break; - case SST_bltCommand: - voodoo->bltCommand = val; -// voodoo_reg_log("Write bltCommand %08x\n", val); - if (val & (1 << 31)) - voodoo_v2_blit_start(voodoo); - break; - case SST_bltData: - voodoo_v2_blit_data(voodoo, val); - break; + case SST_userIntrCMD: + fatal("userIntrCMD write %08x from FIFO\n", val); + break; - case SST_textureMode: - if (chip & CHIP_TREX0) - { - voodoo->params.textureMode[0] = val; - voodoo->params.tformat[0] = (val >> 8) & 0xf; - } - if (chip & CHIP_TREX1) - { - voodoo->params.textureMode[1] = val; - voodoo->params.tformat[1] = (val >> 8) & 0xf; - } - break; - case SST_tLOD: - if (chip & CHIP_TREX0) - { - voodoo->params.tLOD[0] = val; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - voodoo->params.tLOD[1] = val; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_tDetail: - if (chip & CHIP_TREX0) - { - voodoo->params.detail_max[0] = val & 0xff; - voodoo->params.detail_bias[0] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[0] = (val >> 14) & 7; - } - if (chip & CHIP_TREX1) - { - voodoo->params.detail_max[1] = val & 0xff; - voodoo->params.detail_bias[1] = (val >> 8) & 0x3f; - voodoo->params.detail_scale[1] = (val >> 14) & 7; - } - break; - case SST_texBaseAddr: - if (chip & CHIP_TREX0) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr[0] = (val & 0x7ffff) << 3; -// voodoo_reg_log("texBaseAddr = %08x %08x\n", voodoo->params.texBaseAddr[0], val); - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr1: - if (chip & CHIP_TREX0) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr1[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr1[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr1[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr1[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr2: - if (chip & CHIP_TREX0) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr2[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr2[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr2[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr2[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - case SST_texBaseAddr38: - if (chip & CHIP_TREX0) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr38[0] = val & 0xfffff0; - else - voodoo->params.texBaseAddr38[0] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 0); - } - if (chip & CHIP_TREX1) - { - if (voodoo->type >= VOODOO_BANSHEE) - voodoo->params.texBaseAddr38[1] = val & 0xfffff0; - else - voodoo->params.texBaseAddr38[1] = (val & 0x7ffff) << 3; - voodoo_recalc_tex(voodoo, 1); - } - break; - - case SST_trexInit1: - if (chip & CHIP_TREX0) - voodoo->trexInit1[0] = val; - if (chip & CHIP_TREX1) - voodoo->trexInit1[1] = val; - break; - - case SST_nccTable0_Y0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable0_Y3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - - case SST_nccTable0_I0: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I2: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q0: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q2: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) - { - int p = (val >> 23) & 0xfe; - if (chip & CHIP_TREX0) - { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; - - case SST_nccTable0_I1: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_I3: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q1: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - case SST_nccTable0_Q3: - if (!(val & (1 << 31))) - { - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][0].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][0].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - } - if (val & (1 << 31)) - { - int p = ((val >> 23) & 0xfe) | 0x01; - if (chip & CHIP_TREX0) - { - voodoo->palette[0][p].u = val | 0xff000000; - voodoo->palette_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->palette[1][p].u = val | 0xff000000; - voodoo->palette_dirty[1] = 1; - } - } - break; - - case SST_nccTable1_Y0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Y3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].y[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].y[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_I3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].i[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].i[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q0: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[0] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[0] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q1: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[1] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[1] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q2: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[2] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[2] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - case SST_nccTable1_Q3: - if (chip & CHIP_TREX0) - { - voodoo->nccTable[0][1].q[3] = val; - voodoo->ncc_dirty[0] = 1; - } - if (chip & CHIP_TREX1) - { - voodoo->nccTable[1][1].q[3] = val; - voodoo->ncc_dirty[1] = 1; - } - break; - - case SST_userIntrCMD: - fatal("userIntrCMD write %08x from FIFO\n", val); - break; - - - case SST_leftOverlayBuf: - voodoo->leftOverlayBuf = val; - break; - } + case SST_leftOverlayBuf: + voodoo->leftOverlayBuf = val; + break; + } } diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index 362f45abe..608f99a6a 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -38,59 +38,57 @@ #include <86box/vid_voodoo_render.h> #include <86box/vid_voodoo_texture.h> +typedef struct voodoo_state_t { + int xstart, xend, xdir; + uint32_t base_r, base_g, base_b, base_a, base_z; + struct + { + int64_t base_s, base_t, base_w; + int lod; + } tmu[2]; + int64_t base_w; + int lod; + int lod_min[2], lod_max[2]; + int dx1, dx2; + int y, yend, ydir; + int32_t dxAB, dxAC, dxBC; + int tex_b[2], tex_g[2], tex_r[2], tex_a[2]; + int tex_s, tex_t; + int clamp_s[2], clamp_t[2]; -typedef struct voodoo_state_t -{ - int xstart, xend, xdir; - uint32_t base_r, base_g, base_b, base_a, base_z; - struct - { - int64_t base_s, base_t, base_w; - int lod; - } tmu[2]; - int64_t base_w; - int lod; - int lod_min[2], lod_max[2]; - int dx1, dx2; - int y, yend, ydir; - int32_t dxAB, dxAC, dxBC; - int tex_b[2], tex_g[2], tex_r[2], tex_a[2]; - int tex_s, tex_t; - int clamp_s[2], clamp_t[2]; + int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; - int32_t vertexAx, vertexAy, vertexBx, vertexBy, vertexCx, vertexCy; + uint32_t *tex[2][LOD_MAX + 1]; + int tformat; - uint32_t *tex[2][LOD_MAX+1]; - int tformat; + int *tex_w_mask[2]; + int *tex_h_mask[2]; + int *tex_shift[2]; + int *tex_lod[2]; - int *tex_w_mask[2]; - int *tex_h_mask[2]; - int *tex_shift[2]; - int *tex_lod[2]; + uint16_t *fb_mem, *aux_mem; - uint16_t *fb_mem, *aux_mem; + int32_t ib, ig, ir, ia; + int32_t z; - int32_t ib, ig, ir, ia; - int32_t z; + int32_t new_depth; - int32_t new_depth; + int64_t tmu0_s, tmu0_t; + int64_t tmu0_w; + int64_t tmu1_s, tmu1_t; + int64_t tmu1_w; + int64_t w; - int64_t tmu0_s, tmu0_t; - int64_t tmu0_w; - int64_t tmu1_s, tmu1_t; - int64_t tmu1_w; - int64_t w; + int pixel_count, texel_count; + int x, x2, x_tiled; - int pixel_count, texel_count; - int x, x2, x_tiled; + uint32_t w_depth; - uint32_t w_depth; + float log_temp; + uint32_t ebp_store; + uint32_t texBaseAddr; - float log_temp; - uint32_t ebp_store; - uint32_t texBaseAddr; - - int lod_frac[2]; + int lod_frac[2]; } voodoo_state_t; #ifdef ENABLE_VOODOO_RENDER_LOG @@ -102,1589 +100,1453 @@ voodoo_render_log(const char *fmt, ...) va_list ap; if (voodoo_render_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoo_render_log(fmt, ...) +# define voodoo_render_log(fmt, ...) #endif - -static uint8_t logtable[256] = -{ - 0x00,0x01,0x02,0x04,0x05,0x07,0x08,0x09,0x0b,0x0c,0x0e,0x0f,0x10,0x12,0x13,0x15, - 0x16,0x17,0x19,0x1a,0x1b,0x1d,0x1e,0x1f,0x21,0x22,0x23,0x25,0x26,0x27,0x28,0x2a, - 0x2b,0x2c,0x2e,0x2f,0x30,0x31,0x33,0x34,0x35,0x36,0x38,0x39,0x3a,0x3b,0x3d,0x3e, - 0x3f,0x40,0x41,0x43,0x44,0x45,0x46,0x47,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x50,0x51, - 0x52,0x53,0x54,0x55,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x60,0x61,0x62,0x63, - 0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74, - 0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x83,0x84,0x85, - 0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94, - 0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa2,0xa3, - 0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xad,0xae,0xaf,0xb0,0xb1,0xb2, - 0xb3,0xb4,0xb5,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbc,0xbd,0xbe,0xbf,0xc0, - 0xc1,0xc2,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xcd, - 0xce,0xcf,0xd0,0xd1,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd6,0xd7,0xd8,0xd9,0xda,0xda, - 0xdb,0xdc,0xdd,0xde,0xde,0xdf,0xe0,0xe1,0xe1,0xe2,0xe3,0xe4,0xe5,0xe5,0xe6,0xe7, - 0xe8,0xe8,0xe9,0xea,0xeb,0xeb,0xec,0xed,0xee,0xef,0xef,0xf0,0xf1,0xf2,0xf2,0xf3, - 0xf4,0xf5,0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff +static uint8_t logtable[256] = { + 0x00, 0x01, 0x02, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x12, 0x13, 0x15, + 0x16, 0x17, 0x19, 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x23, 0x25, 0x26, 0x27, 0x28, 0x2a, + 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x33, 0x34, 0x35, 0x36, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3e, + 0x3f, 0x40, 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, + 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x83, 0x84, 0x85, + 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, + 0xb3, 0xb4, 0xb5, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, + 0xc1, 0xc2, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xda, + 0xdb, 0xdc, 0xdd, 0xde, 0xde, 0xdf, 0xe0, 0xe1, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe8, 0xe9, 0xea, 0xeb, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xef, 0xf0, 0xf1, 0xf2, 0xf2, 0xf3, + 0xf4, 0xf5, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xfa, 0xfa, 0xfb, 0xfc, 0xfd, 0xfd, 0xfe, 0xff }; -static __inline int fastlog(uint64_t val) +static __inline int +fastlog(uint64_t val) { - uint64_t oldval = val; - int exp = 63; - int frac; + uint64_t oldval = val; + int exp = 63; + int frac; - if (!val || val & (1ULL << 63)) - return 0x80000000; + if (!val || val & (1ULL << 63)) + return 0x80000000; - if (!(val & 0xffffffff00000000)) - { - exp -= 32; - val <<= 32; - } - if (!(val & 0xffff000000000000)) - { - exp -= 16; - val <<= 16; - } - if (!(val & 0xff00000000000000)) - { - exp -= 8; - val <<= 8; - } - if (!(val & 0xf000000000000000)) - { - exp -= 4; - val <<= 4; - } - if (!(val & 0xc000000000000000)) - { - exp -= 2; - val <<= 2; - } - if (!(val & 0x8000000000000000)) - { - exp -= 1; - val <<= 1; - } + if (!(val & 0xffffffff00000000)) { + exp -= 32; + val <<= 32; + } + if (!(val & 0xffff000000000000)) { + exp -= 16; + val <<= 16; + } + if (!(val & 0xff00000000000000)) { + exp -= 8; + val <<= 8; + } + if (!(val & 0xf000000000000000)) { + exp -= 4; + val <<= 4; + } + if (!(val & 0xc000000000000000)) { + exp -= 2; + val <<= 2; + } + if (!(val & 0x8000000000000000)) { + exp -= 1; + val <<= 1; + } - if (exp >= 8) - frac = (oldval >> (exp - 8)) & 0xff; - else - frac = (oldval << (8 - exp)) & 0xff; + if (exp >= 8) + frac = (oldval >> (exp - 8)) & 0xff; + else + frac = (oldval << (8 - exp)) & 0xff; - return (exp << 8) | logtable[frac]; + return (exp << 8) | logtable[frac]; } -static inline int voodoo_fls(uint16_t val) +static inline int +voodoo_fls(uint16_t val) { - int num = 0; + int num = 0; -//voodoo_render_log("fls(%04x) = ", val); - if (!(val & 0xff00)) - { - num += 8; - val <<= 8; - } - if (!(val & 0xf000)) - { - num += 4; - val <<= 4; - } - if (!(val & 0xc000)) - { - num += 2; - val <<= 2; - } - if (!(val & 0x8000)) - { - num += 1; - val <<= 1; - } -//voodoo_render_log("%i %04x\n", num, val); - return num; + // voodoo_render_log("fls(%04x) = ", val); + if (!(val & 0xff00)) { + num += 8; + val <<= 8; + } + if (!(val & 0xf000)) { + num += 4; + val <<= 4; + } + if (!(val & 0xc000)) { + num += 2; + val <<= 2; + } + if (!(val & 0x8000)) { + num += 1; + val <<= 1; + } + // voodoo_render_log("%i %04x\n", num, val); + return num; } -typedef struct voodoo_texture_state_t -{ - int s, t; - int w_mask, h_mask; - int tex_shift; +typedef struct voodoo_texture_state_t { + int s, t; + int w_mask, h_mask; + int tex_shift; } voodoo_texture_state_t; -static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) +static inline void +tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) { - uint32_t dat; + uint32_t dat; - if (texture_state->s & ~texture_state->w_mask) - { - if (state->clamp_s[tmu]) - { - if (texture_state->s < 0) - texture_state->s = 0; - if (texture_state->s > texture_state->w_mask) - texture_state->s = texture_state->w_mask; - } - else - texture_state->s &= texture_state->w_mask; - } - if (texture_state->t & ~texture_state->h_mask) - { - if (state->clamp_t[tmu]) - { - if (texture_state->t < 0) - texture_state->t = 0; - if (texture_state->t > texture_state->h_mask) - texture_state->t = texture_state->h_mask; - } - else - texture_state->t &= texture_state->h_mask; - } + if (texture_state->s & ~texture_state->w_mask) { + if (state->clamp_s[tmu]) { + if (texture_state->s < 0) + texture_state->s = 0; + if (texture_state->s > texture_state->w_mask) + texture_state->s = texture_state->w_mask; + } else + texture_state->s &= texture_state->w_mask; + } + if (texture_state->t & ~texture_state->h_mask) { + if (state->clamp_t[tmu]) { + if (texture_state->t < 0) + texture_state->t = 0; + if (texture_state->t > texture_state->h_mask) + texture_state->t = texture_state->h_mask; + } else + texture_state->t &= texture_state->h_mask; + } - dat = state->tex[tmu][state->lod][texture_state->s + (texture_state->t << texture_state->tex_shift)]; + dat = state->tex[tmu][state->lod][texture_state->s + (texture_state->t << texture_state->tex_shift)]; - state->tex_b[tmu] = dat & 0xff; - state->tex_g[tmu] = (dat >> 8) & 0xff; - state->tex_r[tmu] = (dat >> 16) & 0xff; - state->tex_a[tmu] = (dat >> 24) & 0xff; + state->tex_b[tmu] = dat & 0xff; + state->tex_g[tmu] = (dat >> 8) & 0xff; + state->tex_r[tmu] = (dat >> 16) & 0xff; + state->tex_a[tmu] = (dat >> 24) & 0xff; } #define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) #define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) -static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) +static inline void +tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) { - rgba_u dat[4]; + rgba_u dat[4]; - if (((s | (s + 1)) & ~texture_state->w_mask) || ((t | (t + 1)) & ~texture_state->h_mask)) - { - int c; - for (c = 0; c < 4; c++) - { - int _s = s + (c & 1); - int _t = t + ((c & 2) >> 1); + if (((s | (s + 1)) & ~texture_state->w_mask) || ((t | (t + 1)) & ~texture_state->h_mask)) { + int c; + for (c = 0; c < 4; c++) { + int _s = s + (c & 1); + int _t = t + ((c & 2) >> 1); - if (_s & ~texture_state->w_mask) - { - if (state->clamp_s[tmu]) - { - if (_s < 0) - _s = 0; - if (_s > texture_state->w_mask) - _s = texture_state->w_mask; - } - else - _s &= texture_state->w_mask; - } - if (_t & ~texture_state->h_mask) - { - if (state->clamp_t[tmu]) - { - if (_t < 0) - _t = 0; - if (_t > texture_state->h_mask) - _t = texture_state->h_mask; - } - else - _t &= texture_state->h_mask; - } - dat[c].u = state->tex[tmu][state->lod][_s + (_t << texture_state->tex_shift)]; - } - } - else - { - dat[0].u = state->tex[tmu][state->lod][s + (t << texture_state->tex_shift)]; - dat[1].u = state->tex[tmu][state->lod][s + 1 + (t << texture_state->tex_shift)]; - dat[2].u = state->tex[tmu][state->lod][s + ((t + 1) << texture_state->tex_shift)]; - dat[3].u = state->tex[tmu][state->lod][s + 1 + ((t + 1) << texture_state->tex_shift)]; + if (_s & ~texture_state->w_mask) { + if (state->clamp_s[tmu]) { + if (_s < 0) + _s = 0; + if (_s > texture_state->w_mask) + _s = texture_state->w_mask; + } else + _s &= texture_state->w_mask; + } + if (_t & ~texture_state->h_mask) { + if (state->clamp_t[tmu]) { + if (_t < 0) + _t = 0; + if (_t > texture_state->h_mask) + _t = texture_state->h_mask; + } else + _t &= texture_state->h_mask; + } + dat[c].u = state->tex[tmu][state->lod][_s + (_t << texture_state->tex_shift)]; } + } else { + dat[0].u = state->tex[tmu][state->lod][s + (t << texture_state->tex_shift)]; + dat[1].u = state->tex[tmu][state->lod][s + 1 + (t << texture_state->tex_shift)]; + dat[2].u = state->tex[tmu][state->lod][s + ((t + 1) << texture_state->tex_shift)]; + dat[3].u = state->tex[tmu][state->lod][s + 1 + ((t + 1) << texture_state->tex_shift)]; + } - state->tex_r[tmu] = (dat[0].rgba.r * d[0] + dat[1].rgba.r * d[1] + dat[2].rgba.r * d[2] + dat[3].rgba.r * d[3]) >> 8; - state->tex_g[tmu] = (dat[0].rgba.g * d[0] + dat[1].rgba.g * d[1] + dat[2].rgba.g * d[2] + dat[3].rgba.g * d[3]) >> 8; - state->tex_b[tmu] = (dat[0].rgba.b * d[0] + dat[1].rgba.b * d[1] + dat[2].rgba.b * d[2] + dat[3].rgba.b * d[3]) >> 8; - state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; + state->tex_r[tmu] = (dat[0].rgba.r * d[0] + dat[1].rgba.r * d[1] + dat[2].rgba.r * d[2] + dat[3].rgba.r * d[3]) >> 8; + state->tex_g[tmu] = (dat[0].rgba.g * d[0] + dat[1].rgba.g * d[1] + dat[2].rgba.g * d[2] + dat[3].rgba.g * d[3]) >> 8; + state->tex_b[tmu] = (dat[0].rgba.b * d[0] + dat[1].rgba.b * d[1] + dat[2].rgba.b * d[2] + dat[3].rgba.b * d[3]) >> 8; + state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; } -static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) +static inline void +voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { - voodoo_texture_state_t texture_state; - int d[4]; - int s, t; - int tex_lod = state->tex_lod[tmu][state->lod]; + voodoo_texture_state_t texture_state; + int d[4]; + int s, t; + int tex_lod = state->tex_lod[tmu][state->lod]; - texture_state.w_mask = state->tex_w_mask[tmu][state->lod]; - texture_state.h_mask = state->tex_h_mask[tmu][state->lod]; - texture_state.tex_shift = 8 - tex_lod; + texture_state.w_mask = state->tex_w_mask[tmu][state->lod]; + texture_state.h_mask = state->tex_h_mask[tmu][state->lod]; + texture_state.tex_shift = 8 - tex_lod; - if (params->tLOD[tmu] & LOD_TMIRROR_S) - { - if (state->tex_s & 0x1000) - state->tex_s = ~state->tex_s; - } - if (params->tLOD[tmu] & LOD_TMIRROR_T) - { - if (state->tex_t & 0x1000) - state->tex_t = ~state->tex_t; - } + if (params->tLOD[tmu] & LOD_TMIRROR_S) { + if (state->tex_s & 0x1000) + state->tex_s = ~state->tex_s; + } + if (params->tLOD[tmu] & LOD_TMIRROR_T) { + if (state->tex_t & 0x1000) + state->tex_t = ~state->tex_t; + } - if (voodoo->bilinear_enabled && params->textureMode[tmu] & 6) - { - int _ds, dt; + if (voodoo->bilinear_enabled && params->textureMode[tmu] & 6) { + int _ds, dt; - state->tex_s -= 1 << (3+tex_lod); - state->tex_t -= 1 << (3+tex_lod); + state->tex_s -= 1 << (3 + tex_lod); + state->tex_t -= 1 << (3 + tex_lod); - s = state->tex_s >> tex_lod; - t = state->tex_t >> tex_lod; + s = state->tex_s >> tex_lod; + t = state->tex_t >> tex_lod; - _ds = s & 0xf; - dt = t & 0xf; + _ds = s & 0xf; + dt = t & 0xf; - s >>= 4; - t >>= 4; -//if (x == 80) -//if (voodoo_output) -// voodoo_render_log("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); - d[0] = (16 - _ds) * (16 - dt); - d[1] = _ds * (16 - dt); - d[2] = (16 - _ds) * dt; - d[3] = _ds * dt; + s >>= 4; + t >>= 4; + // if (x == 80) + // if (voodoo_output) + // voodoo_render_log("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); + d[0] = (16 - _ds) * (16 - dt); + d[1] = _ds * (16 - dt); + d[2] = (16 - _ds) * dt; + d[3] = _ds * dt; -// texture_state.s = s; -// texture_state.t = t; - tex_read_4(state, &texture_state, s, t, d, tmu, x); + // texture_state.s = s; + // texture_state.t = t; + tex_read_4(state, &texture_state, s, t, d, tmu, x); - -/* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; - state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; - state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; - state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ -/* state->tex_r = tex_samples[0].r; - state->tex_g = tex_samples[0].g; - state->tex_b = tex_samples[0].b; - state->tex_a = tex_samples[0].a;*/ - } - else - { + /* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; + state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; + state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; + state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ + /* state->tex_r = tex_samples[0].r; + state->tex_g = tex_samples[0].g; + state->tex_b = tex_samples[0].b; + state->tex_a = tex_samples[0].a;*/ + } else { // rgba_t tex_samples; // voodoo_texture_state_t texture_state; -// int s = state->tex_s >> (18+state->lod); -// int t = state->tex_t >> (18+state->lod); + // int s = state->tex_s >> (18+state->lod); + // int t = state->tex_t >> (18+state->lod); // int s, t; -// state->tex_s -= 1 << (17+state->lod); -// state->tex_t -= 1 << (17+state->lod); + // state->tex_s -= 1 << (17+state->lod); + // state->tex_t -= 1 << (17+state->lod); - s = state->tex_s >> (4+tex_lod); - t = state->tex_t >> (4+tex_lod); + s = state->tex_s >> (4 + tex_lod); + t = state->tex_t >> (4 + tex_lod); - texture_state.s = s; - texture_state.t = t; - tex_read(state, &texture_state, tmu); + texture_state.s = s; + texture_state.t = t; + tex_read(state, &texture_state, tmu); -/* state->tex_r = tex_samples[0].rgba.r; - state->tex_g = tex_samples[0].rgba.g; - state->tex_b = tex_samples[0].rgba.b; - state->tex_a = tex_samples[0].rgba.a;*/ - } + /* state->tex_r = tex_samples[0].rgba.r; + state->tex_g = tex_samples[0].rgba.g; + state->tex_b = tex_samples[0].rgba.b; + state->tex_a = tex_samples[0].rgba.a;*/ + } } -static inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) +static inline void +voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { - if (params->textureMode[tmu] & 1) - { - int64_t _w = 0; + if (params->textureMode[tmu] & 1) { + int64_t _w = 0; - if (tmu) - { - if (state->tmu1_w) - _w = (int64_t)((1ULL << 48) / state->tmu1_w); - state->tex_s = (int32_t)(((((state->tmu1_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu1_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } - else - { - if (state->tmu0_w) - _w = (int64_t)((1ULL << 48) / state->tmu0_w); - state->tex_s = (int32_t)(((((state->tmu0_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - state->tex_t = (int32_t)(((((state->tmu0_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); - } - - state->lod = state->tmu[tmu].lod + (fastlog(_w) - (19 << 8)); - } - else - { - if (tmu) - { - state->tex_s = (int32_t)(state->tmu1_s >> (14+14)); - state->tex_t = (int32_t)(state->tmu1_t >> (14+14)); - } - else - { - state->tex_s = (int32_t)(state->tmu0_s >> (14+14)); - state->tex_t = (int32_t)(state->tmu0_t >> (14+14)); - } - state->lod = state->tmu[tmu].lod; + if (tmu) { + if (state->tmu1_w) + _w = (int64_t) ((1ULL << 48) / state->tmu1_w); + state->tex_s = (int32_t) (((((state->tmu1_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + state->tex_t = (int32_t) (((((state->tmu1_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + } else { + if (state->tmu0_w) + _w = (int64_t) ((1ULL << 48) / state->tmu0_w); + state->tex_s = (int32_t) (((((state->tmu0_s + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); + state->tex_t = (int32_t) (((((state->tmu0_t + (1 << 13)) >> 14) * _w) + (1 << 29)) >> 30); } - if (state->lod < state->lod_min[tmu]) - state->lod = state->lod_min[tmu]; - else if (state->lod > state->lod_max[tmu]) - state->lod = state->lod_max[tmu]; - state->lod_frac[tmu] = state->lod & 0xff; - state->lod >>= 8; + state->lod = state->tmu[tmu].lod + (fastlog(_w) - (19 << 8)); + } else { + if (tmu) { + state->tex_s = (int32_t) (state->tmu1_s >> (14 + 14)); + state->tex_t = (int32_t) (state->tmu1_t >> (14 + 14)); + } else { + state->tex_s = (int32_t) (state->tmu0_s >> (14 + 14)); + state->tex_t = (int32_t) (state->tmu0_t >> (14 + 14)); + } + state->lod = state->tmu[tmu].lod; + } - voodoo_get_texture(voodoo, params, state, tmu, x); + if (state->lod < state->lod_min[tmu]) + state->lod = state->lod_min[tmu]; + else if (state->lod > state->lod_max[tmu]) + state->lod = state->lod_max[tmu]; + state->lod_frac[tmu] = state->lod & 0xff; + state->lod >>= 8; + + voodoo_get_texture(voodoo, params, state, tmu, x); } - /*Perform texture fetch and blending for both TMUs*/ -static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) +static inline void +voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) { - int r,g,b,a; - int c_reverse, a_reverse; -// int c_reverse1, a_reverse1; - int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; + int r, g, b, a; + int c_reverse, a_reverse; + // int c_reverse1, a_reverse1; + int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; - voodoo_tmu_fetch(voodoo, params, state, 1, x); + voodoo_tmu_fetch(voodoo, params, state, 1, x); - if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) - { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } - else - { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } -/* c_reverse1 = c_reverse; - a_reverse1 = a_reverse;*/ - if (tc_sub_clocal_1) - { - switch (tc_mselect_1) - { - case TC_MSELECT_ZERO: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_CLOCAL: - factor_r = state->tex_r[1]; - factor_g = state->tex_g[1]; - factor_b = state->tex_b[1]; - break; - case TC_MSELECT_AOTHER: - factor_r = factor_g = factor_b = 0; - break; - case TC_MSELECT_ALOCAL: - factor_r = factor_g = factor_b = state->tex_a[1]; - break; - case TC_MSELECT_DETAIL: - factor_r = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_r > params->detail_max[1]) - factor_r = params->detail_max[1]; - factor_g = factor_b = factor_r; - break; - case TC_MSELECT_LOD_FRAC: - factor_r = factor_g = factor_b = state->lod_frac[1]; - break; - } - if (!c_reverse) - { - r = (-state->tex_r[1] * (factor_r + 1)) >> 8; - g = (-state->tex_g[1] * (factor_g + 1)) >> 8; - b = (-state->tex_b[1] * (factor_b + 1)) >> 8; - } - else - { - r = (-state->tex_r[1] * ((factor_r^0xff) + 1)) >> 8; - g = (-state->tex_g[1] * ((factor_g^0xff) + 1)) >> 8; - b = (-state->tex_b[1] * ((factor_b^0xff) + 1)) >> 8; - } - if (tc_add_clocal_1) - { - r += state->tex_r[1]; - g += state->tex_g[1]; - b += state->tex_b[1]; - } - else if (tc_add_alocal_1) - { - r += state->tex_a[1]; - g += state->tex_a[1]; - b += state->tex_a[1]; - } - state->tex_r[1] = CLAMP(r); - state->tex_g[1] = CLAMP(g); - state->tex_b[1] = CLAMP(b); - } - if (tca_sub_clocal_1) - { - switch (tca_mselect_1) - { - case TCA_MSELECT_ZERO: - factor_a = 0; - break; - case TCA_MSELECT_CLOCAL: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_AOTHER: - factor_a = 0; - break; - case TCA_MSELECT_ALOCAL: - factor_a = state->tex_a[1]; - break; - case TCA_MSELECT_DETAIL: - factor_a = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; - if (factor_a > params->detail_max[1]) - factor_a = params->detail_max[1]; - break; - case TCA_MSELECT_LOD_FRAC: - factor_a = state->lod_frac[1]; - break; - } - if (!a_reverse) - a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; - else - a = (-state->tex_a[1] * (factor_a + 1)) >> 8; - if (tca_add_clocal_1 || tca_add_alocal_1) - a += state->tex_a[1]; - state->tex_a[1] = CLAMP(a); - } - - - voodoo_tmu_fetch(voodoo, params, state, 0, x); - - if ((params->textureMode[0] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) - { - c_reverse = tc_reverse_blend; - a_reverse = tca_reverse_blend; - } - else - { - c_reverse = !tc_reverse_blend; - a_reverse = !tca_reverse_blend; - } - - if (!tc_zero_other) - { - r = state->tex_r[1]; - g = state->tex_g[1]; - b = state->tex_b[1]; - } - else - r = g = b = 0; - if (tc_sub_clocal) - { - r -= state->tex_r[0]; - g -= state->tex_g[0]; - b -= state->tex_b[0]; - } - switch (tc_mselect) - { - case TC_MSELECT_ZERO: + if ((params->textureMode[1] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) { + c_reverse = tc_reverse_blend; + a_reverse = tca_reverse_blend; + } else { + c_reverse = !tc_reverse_blend; + a_reverse = !tca_reverse_blend; + } + /* c_reverse1 = c_reverse; + a_reverse1 = a_reverse;*/ + if (tc_sub_clocal_1) { + switch (tc_mselect_1) { + case TC_MSELECT_ZERO: factor_r = factor_g = factor_b = 0; break; - case TC_MSELECT_CLOCAL: - factor_r = state->tex_r[0]; - factor_g = state->tex_g[0]; - factor_b = state->tex_b[0]; + case TC_MSELECT_CLOCAL: + factor_r = state->tex_r[1]; + factor_g = state->tex_g[1]; + factor_b = state->tex_b[1]; break; - case TC_MSELECT_AOTHER: + case TC_MSELECT_AOTHER: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_ALOCAL: factor_r = factor_g = factor_b = state->tex_a[1]; break; - case TC_MSELECT_ALOCAL: - factor_r = factor_g = factor_b = state->tex_a[0]; - break; - case TC_MSELECT_DETAIL: - factor_r = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_r > params->detail_max[0]) - factor_r = params->detail_max[0]; + case TC_MSELECT_DETAIL: + factor_r = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; + if (factor_r > params->detail_max[1]) + factor_r = params->detail_max[1]; factor_g = factor_b = factor_r; break; - case TC_MSELECT_LOD_FRAC: - factor_r = factor_g = factor_b = state->lod_frac[0]; + case TC_MSELECT_LOD_FRAC: + factor_r = factor_g = factor_b = state->lod_frac[1]; break; } - if (!c_reverse) - { - r = (r * (factor_r + 1)) >> 8; - g = (g * (factor_g + 1)) >> 8; - b = (b * (factor_b + 1)) >> 8; + if (!c_reverse) { + r = (-state->tex_r[1] * (factor_r + 1)) >> 8; + g = (-state->tex_g[1] * (factor_g + 1)) >> 8; + b = (-state->tex_b[1] * (factor_b + 1)) >> 8; + } else { + r = (-state->tex_r[1] * ((factor_r ^ 0xff) + 1)) >> 8; + g = (-state->tex_g[1] * ((factor_g ^ 0xff) + 1)) >> 8; + b = (-state->tex_b[1] * ((factor_b ^ 0xff) + 1)) >> 8; } - else - { - r = (r * ((factor_r^0xff) + 1)) >> 8; - g = (g * ((factor_g^0xff) + 1)) >> 8; - b = (b * ((factor_b^0xff) + 1)) >> 8; + if (tc_add_clocal_1) { + r += state->tex_r[1]; + g += state->tex_g[1]; + b += state->tex_b[1]; + } else if (tc_add_alocal_1) { + r += state->tex_a[1]; + g += state->tex_a[1]; + b += state->tex_a[1]; } - if (tc_add_clocal) - { - r += state->tex_r[0]; - g += state->tex_g[0]; - b += state->tex_b[0]; - } - else if (tc_add_alocal) - { - r += state->tex_a[0]; - g += state->tex_a[0]; - b += state->tex_a[0]; - } - - if (!tca_zero_other) - a = state->tex_a[1]; - else - a = 0; - if (tca_sub_clocal) - a -= state->tex_a[0]; - switch (tca_mselect) - { - case TCA_MSELECT_ZERO: + state->tex_r[1] = CLAMP(r); + state->tex_g[1] = CLAMP(g); + state->tex_b[1] = CLAMP(b); + } + if (tca_sub_clocal_1) { + switch (tca_mselect_1) { + case TCA_MSELECT_ZERO: factor_a = 0; break; - case TCA_MSELECT_CLOCAL: - factor_a = state->tex_a[0]; - break; - case TCA_MSELECT_AOTHER: + case TCA_MSELECT_CLOCAL: factor_a = state->tex_a[1]; break; - case TCA_MSELECT_ALOCAL: - factor_a = state->tex_a[0]; + case TCA_MSELECT_AOTHER: + factor_a = 0; break; - case TCA_MSELECT_DETAIL: - factor_a = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; - if (factor_a > params->detail_max[0]) - factor_a = params->detail_max[0]; + case TCA_MSELECT_ALOCAL: + factor_a = state->tex_a[1]; break; - case TCA_MSELECT_LOD_FRAC: - factor_a = state->lod_frac[0]; + case TCA_MSELECT_DETAIL: + factor_a = (params->detail_bias[1] - state->lod) << params->detail_scale[1]; + if (factor_a > params->detail_max[1]) + factor_a = params->detail_max[1]; + break; + case TCA_MSELECT_LOD_FRAC: + factor_a = state->lod_frac[1]; break; } - if (a_reverse) - a = (a * ((factor_a ^ 0xff) + 1)) >> 8; + if (!a_reverse) + a = (-state->tex_a[1] * ((factor_a ^ 0xff) + 1)) >> 8; else - a = (a * (factor_a + 1)) >> 8; - if (tca_add_clocal || tca_add_alocal) - a += state->tex_a[0]; + a = (-state->tex_a[1] * (factor_a + 1)) >> 8; + if (tca_add_clocal_1 || tca_add_alocal_1) + a += state->tex_a[1]; + state->tex_a[1] = CLAMP(a); + } + voodoo_tmu_fetch(voodoo, params, state, 0, x); - state->tex_r[0] = CLAMP(r); - state->tex_g[0] = CLAMP(g); - state->tex_b[0] = CLAMP(b); - state->tex_a[0] = CLAMP(a); + if ((params->textureMode[0] & TEXTUREMODE_TRILINEAR) && (state->lod & 1)) { + c_reverse = tc_reverse_blend; + a_reverse = tca_reverse_blend; + } else { + c_reverse = !tc_reverse_blend; + a_reverse = !tca_reverse_blend; + } - if (tc_invert_output) - { - state->tex_r[0] ^= 0xff; - state->tex_g[0] ^= 0xff; - state->tex_b[0] ^= 0xff; - } - if (tca_invert_output) - state->tex_a[0] ^= 0xff; + if (!tc_zero_other) { + r = state->tex_r[1]; + g = state->tex_g[1]; + b = state->tex_b[1]; + } else + r = g = b = 0; + if (tc_sub_clocal) { + r -= state->tex_r[0]; + g -= state->tex_g[0]; + b -= state->tex_b[0]; + } + switch (tc_mselect) { + case TC_MSELECT_ZERO: + factor_r = factor_g = factor_b = 0; + break; + case TC_MSELECT_CLOCAL: + factor_r = state->tex_r[0]; + factor_g = state->tex_g[0]; + factor_b = state->tex_b[0]; + break; + case TC_MSELECT_AOTHER: + factor_r = factor_g = factor_b = state->tex_a[1]; + break; + case TC_MSELECT_ALOCAL: + factor_r = factor_g = factor_b = state->tex_a[0]; + break; + case TC_MSELECT_DETAIL: + factor_r = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; + if (factor_r > params->detail_max[0]) + factor_r = params->detail_max[0]; + factor_g = factor_b = factor_r; + break; + case TC_MSELECT_LOD_FRAC: + factor_r = factor_g = factor_b = state->lod_frac[0]; + break; + } + if (!c_reverse) { + r = (r * (factor_r + 1)) >> 8; + g = (g * (factor_g + 1)) >> 8; + b = (b * (factor_b + 1)) >> 8; + } else { + r = (r * ((factor_r ^ 0xff) + 1)) >> 8; + g = (g * ((factor_g ^ 0xff) + 1)) >> 8; + b = (b * ((factor_b ^ 0xff) + 1)) >> 8; + } + if (tc_add_clocal) { + r += state->tex_r[0]; + g += state->tex_g[0]; + b += state->tex_b[0]; + } else if (tc_add_alocal) { + r += state->tex_a[0]; + g += state->tex_a[0]; + b += state->tex_a[0]; + } + + if (!tca_zero_other) + a = state->tex_a[1]; + else + a = 0; + if (tca_sub_clocal) + a -= state->tex_a[0]; + switch (tca_mselect) { + case TCA_MSELECT_ZERO: + factor_a = 0; + break; + case TCA_MSELECT_CLOCAL: + factor_a = state->tex_a[0]; + break; + case TCA_MSELECT_AOTHER: + factor_a = state->tex_a[1]; + break; + case TCA_MSELECT_ALOCAL: + factor_a = state->tex_a[0]; + break; + case TCA_MSELECT_DETAIL: + factor_a = (params->detail_bias[0] - state->lod) << params->detail_scale[0]; + if (factor_a > params->detail_max[0]) + factor_a = params->detail_max[0]; + break; + case TCA_MSELECT_LOD_FRAC: + factor_a = state->lod_frac[0]; + break; + } + if (a_reverse) + a = (a * ((factor_a ^ 0xff) + 1)) >> 8; + else + a = (a * (factor_a + 1)) >> 8; + if (tca_add_clocal || tca_add_alocal) + a += state->tex_a[0]; + + state->tex_r[0] = CLAMP(r); + state->tex_g[0] = CLAMP(g); + state->tex_b[0] = CLAMP(b); + state->tex_a[0] = CLAMP(a); + + if (tc_invert_output) { + state->tex_r[0] ^= 0xff; + state->tex_g[0] ^= 0xff; + state->tex_b[0] ^= 0xff; + } + if (tca_invert_output) + state->tex_a[0] ^= 0xff; } #if (defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86) && !(defined __amd64__ || defined _M_X64) -#include <86box/vid_voodoo_codegen_x86.h> +# include <86box/vid_voodoo_codegen_x86.h> #elif (defined __amd64__ || defined _M_X64) -#include <86box/vid_voodoo_codegen_x86-64.h> +# include <86box/vid_voodoo_codegen_x86-64.h> #else int voodoo_recomp = 0; #endif -static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) +static void +voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int ystart, int yend, int odd_even) { -/* int rgb_sel = params->fbzColorPath & 3; - int a_sel = (params->fbzColorPath >> 2) & 3; - int cc_localselect = params->fbzColorPath & (1 << 4); - int cca_localselect = (params->fbzColorPath >> 5) & 3; - int cc_localselect_override = params->fbzColorPath & (1 << 7); - int cc_zero_other = params->fbzColorPath & (1 << 8); - int cc_sub_clocal = params->fbzColorPath & (1 << 9); - int cc_mselect = (params->fbzColorPath >> 10) & 7; - int cc_reverse_blend = params->fbzColorPath & (1 << 13); - int cc_add = (params->fbzColorPath >> 14) & 3; - int cc_add_alocal = params->fbzColorPath & (1 << 15); - int cc_invert_output = params->fbzColorPath & (1 << 16); - int cca_zero_other = params->fbzColorPath & (1 << 17); - int cca_sub_clocal = params->fbzColorPath & (1 << 18); - int cca_mselect = (params->fbzColorPath >> 19) & 7; - int cca_reverse_blend = params->fbzColorPath & (1 << 22); - int cca_add = (params->fbzColorPath >> 23) & 3; - int cca_invert_output = params->fbzColorPath & (1 << 25); - int src_afunc = (params->alphaMode >> 8) & 0xf; - int dest_afunc = (params->alphaMode >> 12) & 0xf; - int alpha_func = (params->alphaMode >> 1) & 7; - int a_ref = params->alphaMode >> 24; - int depth_op = (params->fbzMode >> 5) & 7; - int dither = params->fbzMode & FBZ_DITHER;*/ - int texels; - int c; + /* int rgb_sel = params->fbzColorPath & 3; + int a_sel = (params->fbzColorPath >> 2) & 3; + int cc_localselect = params->fbzColorPath & (1 << 4); + int cca_localselect = (params->fbzColorPath >> 5) & 3; + int cc_localselect_override = params->fbzColorPath & (1 << 7); + int cc_zero_other = params->fbzColorPath & (1 << 8); + int cc_sub_clocal = params->fbzColorPath & (1 << 9); + int cc_mselect = (params->fbzColorPath >> 10) & 7; + int cc_reverse_blend = params->fbzColorPath & (1 << 13); + int cc_add = (params->fbzColorPath >> 14) & 3; + int cc_add_alocal = params->fbzColorPath & (1 << 15); + int cc_invert_output = params->fbzColorPath & (1 << 16); + int cca_zero_other = params->fbzColorPath & (1 << 17); + int cca_sub_clocal = params->fbzColorPath & (1 << 18); + int cca_mselect = (params->fbzColorPath >> 19) & 7; + int cca_reverse_blend = params->fbzColorPath & (1 << 22); + int cca_add = (params->fbzColorPath >> 23) & 3; + int cca_invert_output = params->fbzColorPath & (1 << 25); + int src_afunc = (params->alphaMode >> 8) & 0xf; + int dest_afunc = (params->alphaMode >> 12) & 0xf; + int alpha_func = (params->alphaMode >> 1) & 7; + int a_ref = params->alphaMode >> 24; + int depth_op = (params->fbzMode >> 5) & 7; + int dither = params->fbzMode & FBZ_DITHER;*/ + int texels; + int c; #ifndef NO_CODEGEN - uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y); + uint8_t (*voodoo_draw)(voodoo_state_t * state, voodoo_params_t * params, int x, int real_y); #endif - int y_diff = SLI_ENABLED ? 2 : 1; - int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? voodoo->y_origin_swap : (voodoo->v_disp-1); + int y_diff = SLI_ENABLED ? 2 : 1; + int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? voodoo->y_origin_swap : (voodoo->v_disp - 1); - if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || - (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) - texels = 1; + if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH || (params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL) + texels = 1; + else + texels = 2; + + state->clamp_s[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPS; + state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; + state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; + state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; + // int last_x; + // voodoo_render_log("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, yend, ydir); + + for (c = 0; c <= LOD_MAX; c++) { + state->tex[0][c] = &voodoo->texture_cache[0][params->tex_entry[0]].data[texture_offset[c]]; + state->tex[1][c] = &voodoo->texture_cache[1][params->tex_entry[1]].data[texture_offset[c]]; + } + + state->tformat = params->tformat[0]; + + state->tex_w_mask[0] = params->tex_w_mask[0]; + state->tex_h_mask[0] = params->tex_h_mask[0]; + state->tex_shift[0] = params->tex_shift[0]; + state->tex_lod[0] = params->tex_lod[0]; + state->tex_w_mask[1] = params->tex_w_mask[1]; + state->tex_h_mask[1] = params->tex_h_mask[1]; + state->tex_shift[1] = params->tex_shift[1]; + state->tex_lod[1] = params->tex_lod[1]; + + if ((params->fbzMode & 1) && (ystart < params->clipLowY)) { + int dy = params->clipLowY - ystart; + + state->base_r += params->dRdY * dy; + state->base_g += params->dGdY * dy; + state->base_b += params->dBdY * dy; + state->base_a += params->dAdY * dy; + state->base_z += params->dZdY * dy; + state->tmu[0].base_s += params->tmu[0].dSdY * dy; + state->tmu[0].base_t += params->tmu[0].dTdY * dy; + state->tmu[0].base_w += params->tmu[0].dWdY * dy; + state->tmu[1].base_s += params->tmu[1].dSdY * dy; + state->tmu[1].base_t += params->tmu[1].dTdY * dy; + state->tmu[1].base_w += params->tmu[1].dWdY * dy; + state->base_w += params->dWdY * dy; + state->xstart += state->dx1 * dy; + state->xend += state->dx2 * dy; + + ystart = params->clipLowY; + } + + if ((params->fbzMode & 1) && (yend >= params->clipHighY)) + yend = params->clipHighY; + + state->y = ystart; + // yend--; + + if (SLI_ENABLED) { + int test_y; + + if (params->fbzMode & (1 << 17)) + test_y = y_origin - state->y; else - texels = 2; + test_y = state->y; - state->clamp_s[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPS; - state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; - state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; - state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; -// int last_x; -// voodoo_render_log("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, yend, ydir); + if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) { + state->y++; - for (c = 0; c <= LOD_MAX; c++) - { - state->tex[0][c] = &voodoo->texture_cache[0][params->tex_entry[0]].data[texture_offset[c]]; - state->tex[1][c] = &voodoo->texture_cache[1][params->tex_entry[1]].data[texture_offset[c]]; - } - - state->tformat = params->tformat[0]; - - state->tex_w_mask[0] = params->tex_w_mask[0]; - state->tex_h_mask[0] = params->tex_h_mask[0]; - state->tex_shift[0] = params->tex_shift[0]; - state->tex_lod[0] = params->tex_lod[0]; - state->tex_w_mask[1] = params->tex_w_mask[1]; - state->tex_h_mask[1] = params->tex_h_mask[1]; - state->tex_shift[1] = params->tex_shift[1]; - state->tex_lod[1] = params->tex_lod[1]; - - if ((params->fbzMode & 1) && (ystart < params->clipLowY)) - { - int dy = params->clipLowY - ystart; - - state->base_r += params->dRdY*dy; - state->base_g += params->dGdY*dy; - state->base_b += params->dBdY*dy; - state->base_a += params->dAdY*dy; - state->base_z += params->dZdY*dy; - state->tmu[0].base_s += params->tmu[0].dSdY*dy; - state->tmu[0].base_t += params->tmu[0].dTdY*dy; - state->tmu[0].base_w += params->tmu[0].dWdY*dy; - state->tmu[1].base_s += params->tmu[1].dSdY*dy; - state->tmu[1].base_t += params->tmu[1].dTdY*dy; - state->tmu[1].base_w += params->tmu[1].dWdY*dy; - state->base_w += params->dWdY*dy; - state->xstart += state->dx1*dy; - state->xend += state->dx2*dy; - - ystart = params->clipLowY; - } - - if ((params->fbzMode & 1) && (yend >= params->clipHighY)) - yend = params->clipHighY; - - state->y = ystart; -// yend--; - - if (SLI_ENABLED) - { - int test_y; - - if (params->fbzMode & (1 << 17)) - test_y = y_origin - state->y; - else - test_y = state->y; - - if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (test_y & 1)) || - ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(test_y & 1))) - { - state->y++; - - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; } + } #ifndef NO_CODEGEN - if (voodoo->use_recompiler) - voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); + if (voodoo->use_recompiler) + voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); + else + voodoo_draw = NULL; +#endif + + voodoo_render_log("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); + // voodoo_render_log("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); + + for (; state->y < yend; state->y += y_diff) { + int x, x2; + int real_y = (state->y << 4) + 8; + int start_x; + int dx; + uint16_t *fb_mem, *aux_mem; + + state->ir = state->base_r; + state->ig = state->base_g; + state->ib = state->base_b; + state->ia = state->base_a; + state->z = state->base_z; + state->tmu0_s = state->tmu[0].base_s; + state->tmu0_t = state->tmu[0].base_t; + state->tmu0_w = state->tmu[0].base_w; + state->tmu1_s = state->tmu[1].base_s; + state->tmu1_t = state->tmu[1].base_t; + state->tmu1_w = state->tmu[1].base_w; + state->w = state->base_w; + + x = (state->vertexAx << 12) + ((state->dxAC * (real_y - state->vertexAy)) >> 4); + + if (real_y < state->vertexBy) + x2 = (state->vertexAx << 12) + ((state->dxAB * (real_y - state->vertexAy)) >> 4); else - voodoo_draw = NULL; -#endif + x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); - voodoo_render_log("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); -// voodoo_render_log("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); + if (params->fbzMode & (1 << 17)) + real_y = y_origin - (real_y >> 4); + else + real_y >>= 4; - for (; state->y < yend; state->y += y_diff) - { - int x, x2; - int real_y = (state->y << 4) + 8; - int start_x; - int dx; - uint16_t *fb_mem, *aux_mem; + if (SLI_ENABLED) { + if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) + goto next_line; + } else { + if ((real_y & voodoo->odd_even_mask) != odd_even) + goto next_line; + } - state->ir = state->base_r; - state->ig = state->base_g; - state->ib = state->base_b; - state->ia = state->base_a; - state->z = state->base_z; - state->tmu0_s = state->tmu[0].base_s; - state->tmu0_t = state->tmu[0].base_t; - state->tmu0_w = state->tmu[0].base_w; - state->tmu1_s = state->tmu[1].base_s; - state->tmu1_t = state->tmu[1].base_t; - state->tmu1_w = state->tmu[1].base_w; - state->w = state->base_w; + start_x = x; - x = (state->vertexAx << 12) + ((state->dxAC * (real_y - state->vertexAy)) >> 4); + if (state->xdir > 0) + x2 -= (1 << 16); + else + x -= (1 << 16); + dx = ((x + 0x7000) >> 16) - (((state->vertexAx << 12) + 0x7000) >> 16); + x = (x + 0x7000) >> 16; + x2 = (x2 + 0x7000) >> 16; - if (real_y < state->vertexBy) - x2 = (state->vertexAx << 12) + ((state->dxAB * (real_y - state->vertexAy)) >> 4); - else - x2 = (state->vertexBx << 12) + ((state->dxBC * (real_y - state->vertexBy)) >> 4); + voodoo_render_log("%03i:%03i : Ax=%08x start_x=%08x dSdX=%016llx dx=%08x s=%08x -> ", x, state->y, state->vertexAx << 8, start_x, params->tmu[0].dTdX, dx, state->tmu0_t); - if (params->fbzMode & (1 << 17)) - real_y = y_origin - (real_y >> 4); - else - real_y >>= 4; + state->ir += (params->dRdX * dx); + state->ig += (params->dGdX * dx); + state->ib += (params->dBdX * dx); + state->ia += (params->dAdX * dx); + state->z += (params->dZdX * dx); + state->tmu0_s += (params->tmu[0].dSdX * dx); + state->tmu0_t += (params->tmu[0].dTdX * dx); + state->tmu0_w += (params->tmu[0].dWdX * dx); + state->tmu1_s += (params->tmu[1].dSdX * dx); + state->tmu1_t += (params->tmu[1].dTdX * dx); + state->tmu1_w += (params->tmu[1].dWdX * dx); + state->w += (params->dWdX * dx); - if (SLI_ENABLED) - { - if (((real_y >> 1) & voodoo->odd_even_mask) != odd_even) - goto next_line; + voodoo_render_log("%08llx %lli %lli\n", state->tmu0_t, state->tmu0_t >> (18 + state->lod), (state->tmu0_t + (1 << (17 + state->lod))) >> (18 + state->lod)); + + if (params->fbzMode & 1) { + if (state->xdir > 0) { + if (x < params->clipLeft) { + int dx = params->clipLeft - x; + + state->ir += params->dRdX * dx; + state->ig += params->dGdX * dx; + state->ib += params->dBdX * dx; + state->ia += params->dAdX * dx; + state->z += params->dZdX * dx; + state->tmu0_s += params->tmu[0].dSdX * dx; + state->tmu0_t += params->tmu[0].dTdX * dx; + state->tmu0_w += params->tmu[0].dWdX * dx; + state->tmu1_s += params->tmu[1].dSdX * dx; + state->tmu1_t += params->tmu[1].dTdX * dx; + state->tmu1_w += params->tmu[1].dWdX * dx; + state->w += params->dWdX * dx; + + x = params->clipLeft; } - else - { - if ((real_y & voodoo->odd_even_mask) != odd_even) - goto next_line; + if (x2 >= params->clipRight) + x2 = params->clipRight - 1; + } else { + if (x >= params->clipRight) { + int dx = (params->clipRight - 1) - x; + + state->ir += params->dRdX * dx; + state->ig += params->dGdX * dx; + state->ib += params->dBdX * dx; + state->ia += params->dAdX * dx; + state->z += params->dZdX * dx; + state->tmu0_s += params->tmu[0].dSdX * dx; + state->tmu0_t += params->tmu[0].dTdX * dx; + state->tmu0_w += params->tmu[0].dWdX * dx; + state->tmu1_s += params->tmu[1].dSdX * dx; + state->tmu1_t += params->tmu[1].dTdX * dx; + state->tmu1_w += params->tmu[1].dWdX * dx; + state->w += params->dWdX * dx; + + x = params->clipRight - 1; } + if (x2 < params->clipLeft) + x2 = params->clipLeft; + } + } - start_x = x; + if (x2 < x && state->xdir > 0) + goto next_line; + if (x2 > x && state->xdir < 0) + goto next_line; - if (state->xdir > 0) - x2 -= (1 << 16); - else - x -= (1 << 16); - dx = ((x + 0x7000) >> 16) - (((state->vertexAx << 12) + 0x7000) >> 16); - x = (x + 0x7000) >> 16; - x2 = (x2 + 0x7000) >> 16; + if (SLI_ENABLED) { + state->fb_mem = fb_mem = (uint16_t *) &voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * params->row_width)]; + state->aux_mem = aux_mem = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * params->row_width)) & voodoo->fb_mask]; + } else { + if (params->col_tiled) + state->fb_mem = fb_mem = (uint16_t *) &voodoo->fb_mem[params->draw_offset + (real_y >> 5) * params->row_width + (real_y & 31) * 128]; + else + state->fb_mem = fb_mem = (uint16_t *) &voodoo->fb_mem[params->draw_offset + (real_y * params->row_width)]; + if (params->aux_tiled) + state->aux_mem = aux_mem = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * params->aux_row_width + (real_y & 31) * 128) & voodoo->fb_mask]; + else + state->aux_mem = aux_mem = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + (real_y * params->row_width)) & voodoo->fb_mask]; + } - voodoo_render_log("%03i:%03i : Ax=%08x start_x=%08x dSdX=%016llx dx=%08x s=%08x -> ", x, state->y, state->vertexAx << 8, start_x, params->tmu[0].dTdX, dx, state->tmu0_t); + voodoo_render_log("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x\n", state->y, x, x2, state->xstart, state->xend, dx); - state->ir += (params->dRdX * dx); - state->ig += (params->dGdX * dx); - state->ib += (params->dBdX * dx); - state->ia += (params->dAdX * dx); - state->z += (params->dZdX * dx); - state->tmu0_s += (params->tmu[0].dSdX * dx); - state->tmu0_t += (params->tmu[0].dTdX * dx); - state->tmu0_w += (params->tmu[0].dWdX * dx); - state->tmu1_s += (params->tmu[1].dSdX * dx); - state->tmu1_t += (params->tmu[1].dTdX * dx); - state->tmu1_w += (params->tmu[1].dWdX * dx); - state->w += (params->dWdX * dx); - - voodoo_render_log("%08llx %lli %lli\n", state->tmu0_t, state->tmu0_t >> (18+state->lod), (state->tmu0_t + (1 << (17+state->lod))) >> (18+state->lod)); - - if (params->fbzMode & 1) - { - if (state->xdir > 0) - { - if (x < params->clipLeft) - { - int dx = params->clipLeft - x; - - state->ir += params->dRdX*dx; - state->ig += params->dGdX*dx; - state->ib += params->dBdX*dx; - state->ia += params->dAdX*dx; - state->z += params->dZdX*dx; - state->tmu0_s += params->tmu[0].dSdX*dx; - state->tmu0_t += params->tmu[0].dTdX*dx; - state->tmu0_w += params->tmu[0].dWdX*dx; - state->tmu1_s += params->tmu[1].dSdX*dx; - state->tmu1_t += params->tmu[1].dTdX*dx; - state->tmu1_w += params->tmu[1].dWdX*dx; - state->w += params->dWdX*dx; - - x = params->clipLeft; - } - if (x2 >= params->clipRight) - x2 = params->clipRight-1; - } - else - { - if (x >= params->clipRight) - { - int dx = (params->clipRight-1) - x; - - state->ir += params->dRdX*dx; - state->ig += params->dGdX*dx; - state->ib += params->dBdX*dx; - state->ia += params->dAdX*dx; - state->z += params->dZdX*dx; - state->tmu0_s += params->tmu[0].dSdX*dx; - state->tmu0_t += params->tmu[0].dTdX*dx; - state->tmu0_w += params->tmu[0].dWdX*dx; - state->tmu1_s += params->tmu[1].dSdX*dx; - state->tmu1_t += params->tmu[1].dTdX*dx; - state->tmu1_w += params->tmu[1].dWdX*dx; - state->w += params->dWdX*dx; - - x = params->clipRight-1; - } - if (x2 < params->clipLeft) - x2 = params->clipLeft; - } - } - - if (x2 < x && state->xdir > 0) - goto next_line; - if (x2 > x && state->xdir < 0) - goto next_line; - - if (SLI_ENABLED) - { - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + ((real_y >> 1) * params->row_width)]; - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + ((real_y >> 1) * params->row_width)) & voodoo->fb_mask]; - } - else - { - if (params->col_tiled) - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y >> 5) * params->row_width + (real_y & 31) * 128]; - else - state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * params->row_width)]; - if (params->aux_tiled) - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y >> 5) * params->aux_row_width + (real_y & 31) * 128) & voodoo->fb_mask]; - else - state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * params->row_width)) & voodoo->fb_mask]; - } - - voodoo_render_log("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x\n", state->y, x, x2, state->xstart, state->xend, dx); - - state->pixel_count = 0; - state->texel_count = 0; - state->x = x; - state->x2 = x2; + state->pixel_count = 0; + state->texel_count = 0; + state->x = x; + state->x2 = x2; #ifndef NO_CODEGEN - if (voodoo->use_recompiler) - { - voodoo_draw(state, params, x, real_y); - } - else + if (voodoo->use_recompiler) { + voodoo_draw(state, params, x, real_y); + } else #endif - do + do { + int x_tiled = (x & 63) | ((x >> 6) * 128 * 32 / 2); + start_x = x; + state->x = x; + voodoo->pixel_count[odd_even]++; + voodoo->texel_count[odd_even] += texels; + voodoo->fbiPixelsIn++; + + voodoo_render_log(" X=%03i T=%08x\n", x, state->tmu0_t); + // if (voodoo->fbzMode & FBZ_RGB_WMASK) { - int x_tiled = (x & 63) | ((x >> 6) * 128*32/2); - start_x = x; - state->x = x; - voodoo->pixel_count[odd_even]++; - voodoo->texel_count[odd_even] += texels; - voodoo->fbiPixelsIn++; + int update = 1; + uint8_t cother_r = 0, cother_g = 0, cother_b = 0, aother; + uint8_t clocal_r, clocal_g, clocal_b, alocal; + int src_r = 0, src_g = 0, src_b = 0, src_a = 0; + int msel_r, msel_g, msel_b, msel_a; + uint8_t dest_r, dest_g, dest_b, dest_a; + uint16_t dat; + int sel; + int32_t new_depth, w_depth; - voodoo_render_log(" X=%03i T=%08x\n", x, state->tmu0_t); -// if (voodoo->fbzMode & FBZ_RGB_WMASK) - { - int update = 1; - uint8_t cother_r = 0, cother_g = 0, cother_b = 0, aother; - uint8_t clocal_r, clocal_g, clocal_b, alocal; - int src_r = 0, src_g = 0, src_b = 0, src_a = 0; - int msel_r, msel_g, msel_b, msel_a; - uint8_t dest_r, dest_g, dest_b, dest_a; - uint16_t dat; - int sel; - int32_t new_depth, w_depth; + if (state->w & 0xffff00000000) + w_depth = 0; + else if (!(state->w & 0xffff0000)) + w_depth = 0xf001; + else { + int exp = voodoo_fls((uint16_t) ((uint32_t) state->w >> 16)); + int mant = ((~(uint32_t) state->w >> (19 - exp))) & 0xfff; + w_depth = (exp << 12) + mant + 1; + if (w_depth > 0xffff) + w_depth = 0xffff; + } - if (state->w & 0xffff00000000) - w_depth = 0; - else if (!(state->w & 0xffff0000)) - w_depth = 0xf001; - else - { - int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); - int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; - w_depth = (exp << 12) + mant + 1; - if (w_depth > 0xffff) - w_depth = 0xffff; - } + // w_depth = CLAMP16(w_depth); -// w_depth = CLAMP16(w_depth); + if (params->fbzMode & FBZ_W_BUFFER) + new_depth = w_depth; + else + new_depth = CLAMP16(state->z >> 12); - if (params->fbzMode & FBZ_W_BUFFER) - new_depth = w_depth; - else - new_depth = CLAMP16(state->z >> 12); + if (params->fbzMode & FBZ_DEPTH_BIAS) + new_depth = CLAMP16(new_depth + (int16_t) params->zaColor); - if (params->fbzMode & FBZ_DEPTH_BIAS) - new_depth = CLAMP16(new_depth + (int16_t)params->zaColor); + if (params->fbzMode & FBZ_DEPTH_ENABLE) { + uint16_t old_depth = voodoo->params.aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; - if (params->fbzMode & FBZ_DEPTH_ENABLE) - { - uint16_t old_depth = voodoo->params.aux_tiled ? aux_mem[x_tiled] : aux_mem[x]; + DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); + } - DEPTH_TEST((params->fbzMode & FBZ_DEPTH_SOURCE) ? (params->zaColor & 0xffff) : new_depth); - } + dat = voodoo->params.col_tiled ? fb_mem[x_tiled] : fb_mem[x]; + dest_r = (dat >> 8) & 0xf8; + dest_g = (dat >> 3) & 0xfc; + dest_b = (dat << 3) & 0xf8; + dest_r |= (dest_r >> 5); + dest_g |= (dest_g >> 6); + dest_b |= (dest_b >> 5); + dest_a = 0xff; - dat = voodoo->params.col_tiled ? fb_mem[x_tiled] : fb_mem[x]; - dest_r = (dat >> 8) & 0xf8; - dest_g = (dat >> 3) & 0xfc; - dest_b = (dat << 3) & 0xf8; - dest_r |= (dest_r >> 5); - dest_g |= (dest_g >> 6); - dest_b |= (dest_b >> 5); - dest_a = 0xff; + if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) { + if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) { + /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ + voodoo_tmu_fetch(voodoo, params, state, 0, x); + } else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) { + /*TMU0 in pass-through mode, only sample TMU1*/ + voodoo_tmu_fetch(voodoo, params, state, 1, x); - if (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) - { - if ((params->textureMode[0] & TEXTUREMODE_LOCAL_MASK) == TEXTUREMODE_LOCAL || !voodoo->dual_tmus) - { - /*TMU0 only sampling local colour or only one TMU, only sample TMU0*/ - voodoo_tmu_fetch(voodoo, params, state, 0, x); - } - else if ((params->textureMode[0] & TEXTUREMODE_MASK) == TEXTUREMODE_PASSTHROUGH) - { - /*TMU0 in pass-through mode, only sample TMU1*/ - voodoo_tmu_fetch(voodoo, params, state, 1, x); - - state->tex_r[0] = state->tex_r[1]; - state->tex_g[0] = state->tex_g[1]; - state->tex_b[0] = state->tex_b[1]; - state->tex_a[0] = state->tex_a[1]; - } - else - { - voodoo_tmu_fetch_and_blend(voodoo, params, state, x); - } - - if ((params->fbzMode & FBZ_CHROMAKEY) && - state->tex_r[0] == params->chromaKey_r && - state->tex_g[0] == params->chromaKey_g && - state->tex_b[0] == params->chromaKey_b) - { - voodoo->fbiChromaFail++; - goto skip_pixel; - } - } - - if (voodoo->trexInit1[0] & (1 << 18)) - { - state->tex_r[0] = state->tex_g[0] = 0; - state->tex_b[0] = voodoo->tmuConfig; - } - - if (cc_localselect_override) - sel = (state->tex_a[0] & 0x80) ? 1 : 0; - else - sel = cc_localselect; - - if (sel) - { - clocal_r = (params->color0 >> 16) & 0xff; - clocal_g = (params->color0 >> 8) & 0xff; - clocal_b = params->color0 & 0xff; - } - else - { - clocal_r = CLAMP(state->ir >> 12); - clocal_g = CLAMP(state->ig >> 12); - clocal_b = CLAMP(state->ib >> 12); - } - - switch (_rgb_sel) - { - case CC_LOCALSELECT_ITER_RGB: /*Iterated RGB*/ - cother_r = CLAMP(state->ir >> 12); - cother_g = CLAMP(state->ig >> 12); - cother_b = CLAMP(state->ib >> 12); - break; - - case CC_LOCALSELECT_TEX: /*TREX Color Output*/ - cother_r = state->tex_r[0]; - cother_g = state->tex_g[0]; - cother_b = state->tex_b[0]; - break; - - case CC_LOCALSELECT_COLOR1: /*Color1 RGB*/ - cother_r = (params->color1 >> 16) & 0xff; - cother_g = (params->color1 >> 8) & 0xff; - cother_b = params->color1 & 0xff; - break; - - case CC_LOCALSELECT_LFB: /*Linear Frame Buffer*/ - cother_r = src_r; - cother_g = src_g; - cother_b = src_b; - break; - } - - switch (cca_localselect) - { - case CCA_LOCALSELECT_ITER_A: - alocal = CLAMP(state->ia >> 12); - break; - - case CCA_LOCALSELECT_COLOR0: - alocal = (params->color0 >> 24) & 0xff; - break; - - case CCA_LOCALSELECT_ITER_Z: - alocal = CLAMP(state->z >> 20); - break; - - default: - fatal("Bad cca_localselect %i\n", cca_localselect); - alocal = 0xff; - break; - } - - switch (a_sel) - { - case A_SEL_ITER_A: - aother = CLAMP(state->ia >> 12); - break; - case A_SEL_TEX: - aother = state->tex_a[0]; - break; - case A_SEL_COLOR1: - aother = (params->color1 >> 24) & 0xff; - break; - default: - fatal("Bad a_sel %i\n", a_sel); - aother = 0; - break; - } - - if (cc_zero_other) - { - src_r = 0; - src_g = 0; - src_b = 0; - } - else - { - src_r = cother_r; - src_g = cother_g; - src_b = cother_b; - } - - if (cca_zero_other) - src_a = 0; - else - src_a = aother; - - if (cc_sub_clocal) - { - src_r -= clocal_r; - src_g -= clocal_g; - src_b -= clocal_b; - } - - if (cca_sub_clocal) - src_a -= alocal; - - switch (cc_mselect) - { - case CC_MSELECT_ZERO: - msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - case CC_MSELECT_CLOCAL: - msel_r = clocal_r; - msel_g = clocal_g; - msel_b = clocal_b; - break; - case CC_MSELECT_AOTHER: - msel_r = aother; - msel_g = aother; - msel_b = aother; - break; - case CC_MSELECT_ALOCAL: - msel_r = alocal; - msel_g = alocal; - msel_b = alocal; - break; - case CC_MSELECT_TEX: - msel_r = state->tex_a[0]; - msel_g = state->tex_a[0]; - msel_b = state->tex_a[0]; - break; - case CC_MSELECT_TEXRGB: - msel_r = state->tex_r[0]; - msel_g = state->tex_g[0]; - msel_b = state->tex_b[0]; - break; - - default: - fatal("Bad cc_mselect %i\n", cc_mselect); - msel_r = 0; - msel_g = 0; - msel_b = 0; - break; - } - - switch (cca_mselect) - { - case CCA_MSELECT_ZERO: - msel_a = 0; - break; - case CCA_MSELECT_ALOCAL: - msel_a = alocal; - break; - case CCA_MSELECT_AOTHER: - msel_a = aother; - break; - case CCA_MSELECT_ALOCAL2: - msel_a = alocal; - break; - case CCA_MSELECT_TEX: - msel_a = state->tex_a[0]; - break; - - default: - fatal("Bad cca_mselect %i\n", cca_mselect); - msel_a = 0; - break; - } - - if (!cc_reverse_blend) - { - msel_r ^= 0xff; - msel_g ^= 0xff; - msel_b ^= 0xff; - } - msel_r++; - msel_g++; - msel_b++; - - if (!cca_reverse_blend) - msel_a ^= 0xff; - msel_a++; - - src_r = (src_r * msel_r) >> 8; - src_g = (src_g * msel_g) >> 8; - src_b = (src_b * msel_b) >> 8; - src_a = (src_a * msel_a) >> 8; - - switch (cc_add) - { - case CC_ADD_CLOCAL: - src_r += clocal_r; - src_g += clocal_g; - src_b += clocal_b; - break; - case CC_ADD_ALOCAL: - src_r += alocal; - src_g += alocal; - src_b += alocal; - break; - case 0: - break; - default: - fatal("Bad cc_add %i\n", cc_add); - } - - if (cca_add) - src_a += alocal; - - src_r = CLAMP(src_r); - src_g = CLAMP(src_g); - src_b = CLAMP(src_b); - src_a = CLAMP(src_a); - - if (cc_invert_output) - { - src_r ^= 0xff; - src_g ^= 0xff; - src_b ^= 0xff; - } - if (cca_invert_output) - src_a ^= 0xff; - - if (params->fogMode & FOG_ENABLE) - APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); - - if (params->alphaMode & 1) - ALPHA_TEST(src_a); - - if (params->alphaMode & (1 << 4)) { - if (dithersub && !dither2x2 && voodoo->dithersub_enabled) - { - dest_r = dithersub_rb[dest_r][real_y & 3][x & 3]; - dest_g = dithersub_g [dest_g][real_y & 3][x & 3]; - dest_b = dithersub_rb[dest_b][real_y & 3][x & 3]; - } - if (dithersub && dither2x2 && voodoo->dithersub_enabled) - { - dest_r = dithersub_rb2x2[dest_r][real_y & 1][x & 1]; - dest_g = dithersub_g2x2 [dest_g][real_y & 1][x & 1]; - dest_b = dithersub_rb2x2[dest_b][real_y & 1][x & 1]; - } - ALPHA_BLEND(src_r, src_g, src_b, src_a); - } - - if (update) - { - if (dither) - { - if (dither2x2) - { - src_r = dither_rb2x2[src_r][real_y & 1][x & 1]; - src_g = dither_g2x2[src_g][real_y & 1][x & 1]; - src_b = dither_rb2x2[src_b][real_y & 1][x & 1]; - } - else - { - src_r = dither_rb[src_r][real_y & 3][x & 3]; - src_g = dither_g[src_g][real_y & 3][x & 3]; - src_b = dither_rb[src_b][real_y & 3][x & 3]; - } - } - else - { - src_r >>= 3; - src_g >>= 2; - src_b >>= 3; - } - - if (params->fbzMode & FBZ_RGB_WMASK) - { - if (voodoo->params.col_tiled) - fb_mem[x_tiled] = src_b | (src_g << 5) | (src_r << 11); - else - fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); - } - if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) - { - if (voodoo->params.aux_tiled) - aux_mem[x_tiled] = new_depth; - else - aux_mem[x] = new_depth; - } - } + state->tex_r[0] = state->tex_r[1]; + state->tex_g[0] = state->tex_g[1]; + state->tex_b[0] = state->tex_b[1]; + state->tex_a[0] = state->tex_a[1]; + } else { + voodoo_tmu_fetch_and_blend(voodoo, params, state, x); } - voodoo->fbiPixelsOut++; + + if ((params->fbzMode & FBZ_CHROMAKEY) && state->tex_r[0] == params->chromaKey_r && state->tex_g[0] == params->chromaKey_g && state->tex_b[0] == params->chromaKey_b) { + voodoo->fbiChromaFail++; + goto skip_pixel; + } + } + + if (voodoo->trexInit1[0] & (1 << 18)) { + state->tex_r[0] = state->tex_g[0] = 0; + state->tex_b[0] = voodoo->tmuConfig; + } + + if (cc_localselect_override) + sel = (state->tex_a[0] & 0x80) ? 1 : 0; + else + sel = cc_localselect; + + if (sel) { + clocal_r = (params->color0 >> 16) & 0xff; + clocal_g = (params->color0 >> 8) & 0xff; + clocal_b = params->color0 & 0xff; + } else { + clocal_r = CLAMP(state->ir >> 12); + clocal_g = CLAMP(state->ig >> 12); + clocal_b = CLAMP(state->ib >> 12); + } + + switch (_rgb_sel) { + case CC_LOCALSELECT_ITER_RGB: /*Iterated RGB*/ + cother_r = CLAMP(state->ir >> 12); + cother_g = CLAMP(state->ig >> 12); + cother_b = CLAMP(state->ib >> 12); + break; + + case CC_LOCALSELECT_TEX: /*TREX Color Output*/ + cother_r = state->tex_r[0]; + cother_g = state->tex_g[0]; + cother_b = state->tex_b[0]; + break; + + case CC_LOCALSELECT_COLOR1: /*Color1 RGB*/ + cother_r = (params->color1 >> 16) & 0xff; + cother_g = (params->color1 >> 8) & 0xff; + cother_b = params->color1 & 0xff; + break; + + case CC_LOCALSELECT_LFB: /*Linear Frame Buffer*/ + cother_r = src_r; + cother_g = src_g; + cother_b = src_b; + break; + } + + switch (cca_localselect) { + case CCA_LOCALSELECT_ITER_A: + alocal = CLAMP(state->ia >> 12); + break; + + case CCA_LOCALSELECT_COLOR0: + alocal = (params->color0 >> 24) & 0xff; + break; + + case CCA_LOCALSELECT_ITER_Z: + alocal = CLAMP(state->z >> 20); + break; + + default: + fatal("Bad cca_localselect %i\n", cca_localselect); + alocal = 0xff; + break; + } + + switch (a_sel) { + case A_SEL_ITER_A: + aother = CLAMP(state->ia >> 12); + break; + case A_SEL_TEX: + aother = state->tex_a[0]; + break; + case A_SEL_COLOR1: + aother = (params->color1 >> 24) & 0xff; + break; + default: + fatal("Bad a_sel %i\n", a_sel); + aother = 0; + break; + } + + if (cc_zero_other) { + src_r = 0; + src_g = 0; + src_b = 0; + } else { + src_r = cother_r; + src_g = cother_g; + src_b = cother_b; + } + + if (cca_zero_other) + src_a = 0; + else + src_a = aother; + + if (cc_sub_clocal) { + src_r -= clocal_r; + src_g -= clocal_g; + src_b -= clocal_b; + } + + if (cca_sub_clocal) + src_a -= alocal; + + switch (cc_mselect) { + case CC_MSELECT_ZERO: + msel_r = 0; + msel_g = 0; + msel_b = 0; + break; + case CC_MSELECT_CLOCAL: + msel_r = clocal_r; + msel_g = clocal_g; + msel_b = clocal_b; + break; + case CC_MSELECT_AOTHER: + msel_r = aother; + msel_g = aother; + msel_b = aother; + break; + case CC_MSELECT_ALOCAL: + msel_r = alocal; + msel_g = alocal; + msel_b = alocal; + break; + case CC_MSELECT_TEX: + msel_r = state->tex_a[0]; + msel_g = state->tex_a[0]; + msel_b = state->tex_a[0]; + break; + case CC_MSELECT_TEXRGB: + msel_r = state->tex_r[0]; + msel_g = state->tex_g[0]; + msel_b = state->tex_b[0]; + break; + + default: + fatal("Bad cc_mselect %i\n", cc_mselect); + msel_r = 0; + msel_g = 0; + msel_b = 0; + break; + } + + switch (cca_mselect) { + case CCA_MSELECT_ZERO: + msel_a = 0; + break; + case CCA_MSELECT_ALOCAL: + msel_a = alocal; + break; + case CCA_MSELECT_AOTHER: + msel_a = aother; + break; + case CCA_MSELECT_ALOCAL2: + msel_a = alocal; + break; + case CCA_MSELECT_TEX: + msel_a = state->tex_a[0]; + break; + + default: + fatal("Bad cca_mselect %i\n", cca_mselect); + msel_a = 0; + break; + } + + if (!cc_reverse_blend) { + msel_r ^= 0xff; + msel_g ^= 0xff; + msel_b ^= 0xff; + } + msel_r++; + msel_g++; + msel_b++; + + if (!cca_reverse_blend) + msel_a ^= 0xff; + msel_a++; + + src_r = (src_r * msel_r) >> 8; + src_g = (src_g * msel_g) >> 8; + src_b = (src_b * msel_b) >> 8; + src_a = (src_a * msel_a) >> 8; + + switch (cc_add) { + case CC_ADD_CLOCAL: + src_r += clocal_r; + src_g += clocal_g; + src_b += clocal_b; + break; + case CC_ADD_ALOCAL: + src_r += alocal; + src_g += alocal; + src_b += alocal; + break; + case 0: + break; + default: + fatal("Bad cc_add %i\n", cc_add); + } + + if (cca_add) + src_a += alocal; + + src_r = CLAMP(src_r); + src_g = CLAMP(src_g); + src_b = CLAMP(src_b); + src_a = CLAMP(src_a); + + if (cc_invert_output) { + src_r ^= 0xff; + src_g ^= 0xff; + src_b ^= 0xff; + } + if (cca_invert_output) + src_a ^= 0xff; + + if (params->fogMode & FOG_ENABLE) + APPLY_FOG(src_r, src_g, src_b, state->z, state->ia, state->w); + + if (params->alphaMode & 1) + ALPHA_TEST(src_a); + + if (params->alphaMode & (1 << 4)) { + if (dithersub && !dither2x2 && voodoo->dithersub_enabled) { + dest_r = dithersub_rb[dest_r][real_y & 3][x & 3]; + dest_g = dithersub_g[dest_g][real_y & 3][x & 3]; + dest_b = dithersub_rb[dest_b][real_y & 3][x & 3]; + } + if (dithersub && dither2x2 && voodoo->dithersub_enabled) { + dest_r = dithersub_rb2x2[dest_r][real_y & 1][x & 1]; + dest_g = dithersub_g2x2[dest_g][real_y & 1][x & 1]; + dest_b = dithersub_rb2x2[dest_b][real_y & 1][x & 1]; + } + ALPHA_BLEND(src_r, src_g, src_b, src_a); + } + + if (update) { + if (dither) { + if (dither2x2) { + src_r = dither_rb2x2[src_r][real_y & 1][x & 1]; + src_g = dither_g2x2[src_g][real_y & 1][x & 1]; + src_b = dither_rb2x2[src_b][real_y & 1][x & 1]; + } else { + src_r = dither_rb[src_r][real_y & 3][x & 3]; + src_g = dither_g[src_g][real_y & 3][x & 3]; + src_b = dither_rb[src_b][real_y & 3][x & 3]; + } + } else { + src_r >>= 3; + src_g >>= 2; + src_b >>= 3; + } + + if (params->fbzMode & FBZ_RGB_WMASK) { + if (voodoo->params.col_tiled) + fb_mem[x_tiled] = src_b | (src_g << 5) | (src_r << 11); + else + fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); + } + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { + if (voodoo->params.aux_tiled) + aux_mem[x_tiled] = new_depth; + else + aux_mem[x] = new_depth; + } + } + } + voodoo->fbiPixelsOut++; skip_pixel: - if (state->xdir > 0) - { - state->ir += params->dRdX; - state->ig += params->dGdX; - state->ib += params->dBdX; - state->ia += params->dAdX; - state->z += params->dZdX; - state->tmu0_s += params->tmu[0].dSdX; - state->tmu0_t += params->tmu[0].dTdX; - state->tmu0_w += params->tmu[0].dWdX; - state->tmu1_s += params->tmu[1].dSdX; - state->tmu1_t += params->tmu[1].dTdX; - state->tmu1_w += params->tmu[1].dWdX; - state->w += params->dWdX; - } - else - { - state->ir -= params->dRdX; - state->ig -= params->dGdX; - state->ib -= params->dBdX; - state->ia -= params->dAdX; - state->z -= params->dZdX; - state->tmu0_s -= params->tmu[0].dSdX; - state->tmu0_t -= params->tmu[0].dTdX; - state->tmu0_w -= params->tmu[0].dWdX; - state->tmu1_s -= params->tmu[1].dSdX; - state->tmu1_t -= params->tmu[1].dTdX; - state->tmu1_w -= params->tmu[1].dWdX; - state->w -= params->dWdX; - } + if (state->xdir > 0) { + state->ir += params->dRdX; + state->ig += params->dGdX; + state->ib += params->dBdX; + state->ia += params->dAdX; + state->z += params->dZdX; + state->tmu0_s += params->tmu[0].dSdX; + state->tmu0_t += params->tmu[0].dTdX; + state->tmu0_w += params->tmu[0].dWdX; + state->tmu1_s += params->tmu[1].dSdX; + state->tmu1_t += params->tmu[1].dTdX; + state->tmu1_w += params->tmu[1].dWdX; + state->w += params->dWdX; + } else { + state->ir -= params->dRdX; + state->ig -= params->dGdX; + state->ib -= params->dBdX; + state->ia -= params->dAdX; + state->z -= params->dZdX; + state->tmu0_s -= params->tmu[0].dSdX; + state->tmu0_t -= params->tmu[0].dTdX; + state->tmu0_w -= params->tmu[0].dWdX; + state->tmu1_s -= params->tmu[1].dSdX; + state->tmu1_t -= params->tmu[1].dTdX; + state->tmu1_w -= params->tmu[1].dWdX; + state->w -= params->dWdX; + } - x += state->xdir; - } while (start_x != x2); + x += state->xdir; + } while (start_x != x2); - voodoo->pixel_count[odd_even] += state->pixel_count; - voodoo->texel_count[odd_even] += state->texel_count; - voodoo->fbiPixelsIn += state->pixel_count; + voodoo->pixel_count[odd_even] += state->pixel_count; + voodoo->texel_count[odd_even] += state->texel_count; + voodoo->fbiPixelsIn += state->pixel_count; - if (voodoo->params.draw_offset == voodoo->params.front_offset && (real_y >> 1) < 2048) - voodoo->dirty_line[real_y >> 1] = 1; + if (voodoo->params.draw_offset == voodoo->params.front_offset && (real_y >> 1) < 2048) + voodoo->dirty_line[real_y >> 1] = 1; next_line: - if (SLI_ENABLED) - { - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; - } - state->base_r += params->dRdY; - state->base_g += params->dGdY; - state->base_b += params->dBdY; - state->base_a += params->dAdY; - state->base_z += params->dZdY; - state->tmu[0].base_s += params->tmu[0].dSdY; - state->tmu[0].base_t += params->tmu[0].dTdY; - state->tmu[0].base_w += params->tmu[0].dWdY; - state->tmu[1].base_s += params->tmu[1].dSdY; - state->tmu[1].base_t += params->tmu[1].dTdY; - state->tmu[1].base_w += params->tmu[1].dWdY; - state->base_w += params->dWdY; - state->xstart += state->dx1; - state->xend += state->dx2; + if (SLI_ENABLED) { + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; } + state->base_r += params->dRdY; + state->base_g += params->dGdY; + state->base_b += params->dBdY; + state->base_a += params->dAdY; + state->base_z += params->dZdY; + state->tmu[0].base_s += params->tmu[0].dSdY; + state->tmu[0].base_t += params->tmu[0].dTdY; + state->tmu[0].base_w += params->tmu[0].dWdY; + state->tmu[1].base_s += params->tmu[1].dSdY; + state->tmu[1].base_t += params->tmu[1].dTdY; + state->tmu[1].base_w += params->tmu[1].dWdY; + state->base_w += params->dWdY; + state->xstart += state->dx1; + state->xend += state->dx2; + } - voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; - voodoo->texture_cache[1][params->tex_entry[1]].refcount_r[odd_even]++; + voodoo->texture_cache[0][params->tex_entry[0]].refcount_r[odd_even]++; + voodoo->texture_cache[1][params->tex_entry[1]].refcount_r[odd_even]++; } -void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) +void +voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_even) { - voodoo_state_t state; - int vertexAy_adjusted; - int vertexCy_adjusted; - int dx, dy; + voodoo_state_t state; + int vertexAy_adjusted; + int vertexCy_adjusted; + int dx, dy; - uint64_t tempdx, tempdy; - uint64_t tempLOD; - int LOD; - int lodbias; + uint64_t tempdx, tempdy; + uint64_t tempLOD; + int LOD; + int lodbias; - voodoo->tri_count++; + voodoo->tri_count++; - dx = 8 - (params->vertexAx & 0xf); - if ((params->vertexAx & 0xf) > 8) - dx += 16; - dy = 8 - (params->vertexAy & 0xf); - if ((params->vertexAy & 0xf) > 8) - dy += 16; + dx = 8 - (params->vertexAx & 0xf); + if ((params->vertexAx & 0xf) > 8) + dx += 16; + dy = 8 - (params->vertexAy & 0xf); + if ((params->vertexAy & 0xf) > 8) + dy += 16; -/* voodoo_render_log("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, - (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, - (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, - (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ + /* voodoo_render_log("voodoo_triangle %i %i %i : vA %f, %f vB %f, %f vC %f, %f f %i,%i %08x %08x %08x,%08x tex=%i,%i fogMode=%08x\n", odd_even, voodoo->params_read_idx[odd_even], voodoo->params_read_idx[odd_even] & PARAM_MASK, (float)params->vertexAx / 16.0, (float)params->vertexAy / 16.0, + (float)params->vertexBx / 16.0, (float)params->vertexBy / 16.0, + (float)params->vertexCx / 16.0, (float)params->vertexCy / 16.0, + (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[0] : 0, + (params->fbzColorPath & FBZCP_TEXTURE_ENABLED) ? params->tformat[1] : 0, params->fbzColorPath, params->alphaMode, params->textureMode[0],params->textureMode[1], params->tex_entry[0],params->tex_entry[1], params->fogMode);*/ - state.base_r = params->startR; - state.base_g = params->startG; - state.base_b = params->startB; - state.base_a = params->startA; - state.base_z = params->startZ; - state.tmu[0].base_s = params->tmu[0].startS; - state.tmu[0].base_t = params->tmu[0].startT; - state.tmu[0].base_w = params->tmu[0].startW; - state.tmu[1].base_s = params->tmu[1].startS; - state.tmu[1].base_t = params->tmu[1].startT; - state.tmu[1].base_w = params->tmu[1].startW; - state.base_w = params->startW; + state.base_r = params->startR; + state.base_g = params->startG; + state.base_b = params->startB; + state.base_a = params->startA; + state.base_z = params->startZ; + state.tmu[0].base_s = params->tmu[0].startS; + state.tmu[0].base_t = params->tmu[0].startT; + state.tmu[0].base_w = params->tmu[0].startW; + state.tmu[1].base_s = params->tmu[1].startS; + state.tmu[1].base_t = params->tmu[1].startT; + state.tmu[1].base_w = params->tmu[1].startW; + state.base_w = params->startW; - if (params->fbzColorPath & FBZ_PARAM_ADJUST) - { - state.base_r += (dx*params->dRdX + dy*params->dRdY) >> 4; - state.base_g += (dx*params->dGdX + dy*params->dGdY) >> 4; - state.base_b += (dx*params->dBdX + dy*params->dBdY) >> 4; - state.base_a += (dx*params->dAdX + dy*params->dAdY) >> 4; - state.base_z += (dx*params->dZdX + dy*params->dZdY) >> 4; - state.tmu[0].base_s += (dx*params->tmu[0].dSdX + dy*params->tmu[0].dSdY) >> 4; - state.tmu[0].base_t += (dx*params->tmu[0].dTdX + dy*params->tmu[0].dTdY) >> 4; - state.tmu[0].base_w += (dx*params->tmu[0].dWdX + dy*params->tmu[0].dWdY) >> 4; - state.tmu[1].base_s += (dx*params->tmu[1].dSdX + dy*params->tmu[1].dSdY) >> 4; - state.tmu[1].base_t += (dx*params->tmu[1].dTdX + dy*params->tmu[1].dTdY) >> 4; - state.tmu[1].base_w += (dx*params->tmu[1].dWdX + dy*params->tmu[1].dWdY) >> 4; - state.base_w += (dx*params->dWdX + dy*params->dWdY) >> 4; - } + if (params->fbzColorPath & FBZ_PARAM_ADJUST) { + state.base_r += (dx * params->dRdX + dy * params->dRdY) >> 4; + state.base_g += (dx * params->dGdX + dy * params->dGdY) >> 4; + state.base_b += (dx * params->dBdX + dy * params->dBdY) >> 4; + state.base_a += (dx * params->dAdX + dy * params->dAdY) >> 4; + state.base_z += (dx * params->dZdX + dy * params->dZdY) >> 4; + state.tmu[0].base_s += (dx * params->tmu[0].dSdX + dy * params->tmu[0].dSdY) >> 4; + state.tmu[0].base_t += (dx * params->tmu[0].dTdX + dy * params->tmu[0].dTdY) >> 4; + state.tmu[0].base_w += (dx * params->tmu[0].dWdX + dy * params->tmu[0].dWdY) >> 4; + state.tmu[1].base_s += (dx * params->tmu[1].dSdX + dy * params->tmu[1].dSdY) >> 4; + state.tmu[1].base_t += (dx * params->tmu[1].dTdX + dy * params->tmu[1].dTdY) >> 4; + state.tmu[1].base_w += (dx * params->tmu[1].dWdX + dy * params->tmu[1].dWdY) >> 4; + state.base_w += (dx * params->dWdX + dy * params->dWdY) >> 4; + } - tris++; + tris++; - state.vertexAy = params->vertexAy & ~0xffff0000; - if (state.vertexAy & 0x8000) - state.vertexAy |= 0xffff0000; - state.vertexBy = params->vertexBy & ~0xffff0000; - if (state.vertexBy & 0x8000) - state.vertexBy |= 0xffff0000; - state.vertexCy = params->vertexCy & ~0xffff0000; - if (state.vertexCy & 0x8000) - state.vertexCy |= 0xffff0000; + state.vertexAy = params->vertexAy & ~0xffff0000; + if (state.vertexAy & 0x8000) + state.vertexAy |= 0xffff0000; + state.vertexBy = params->vertexBy & ~0xffff0000; + if (state.vertexBy & 0x8000) + state.vertexBy |= 0xffff0000; + state.vertexCy = params->vertexCy & ~0xffff0000; + if (state.vertexCy & 0x8000) + state.vertexCy |= 0xffff0000; - state.vertexAx = params->vertexAx & ~0xffff0000; - if (state.vertexAx & 0x8000) - state.vertexAx |= 0xffff0000; - state.vertexBx = params->vertexBx & ~0xffff0000; - if (state.vertexBx & 0x8000) - state.vertexBx |= 0xffff0000; - state.vertexCx = params->vertexCx & ~0xffff0000; - if (state.vertexCx & 0x8000) - state.vertexCx |= 0xffff0000; + state.vertexAx = params->vertexAx & ~0xffff0000; + if (state.vertexAx & 0x8000) + state.vertexAx |= 0xffff0000; + state.vertexBx = params->vertexBx & ~0xffff0000; + if (state.vertexBx & 0x8000) + state.vertexBx |= 0xffff0000; + state.vertexCx = params->vertexCx & ~0xffff0000; + if (state.vertexCx & 0x8000) + state.vertexCx |= 0xffff0000; - vertexAy_adjusted = (state.vertexAy+7) >> 4; - vertexCy_adjusted = (state.vertexCy+7) >> 4; + vertexAy_adjusted = (state.vertexAy + 7) >> 4; + vertexCy_adjusted = (state.vertexCy + 7) >> 4; - if (state.vertexBy - state.vertexAy) - state.dxAB = (int)((((int64_t)state.vertexBx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexBy - state.vertexAy); - else - state.dxAB = 0; - if (state.vertexCy - state.vertexAy) - state.dxAC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexAx << 12)) << 4) / (int)(state.vertexCy - state.vertexAy); - else - state.dxAC = 0; - if (state.vertexCy - state.vertexBy) - state.dxBC = (int)((((int64_t)state.vertexCx << 12) - ((int64_t)state.vertexBx << 12)) << 4) / (int)(state.vertexCy - state.vertexBy); - else - state.dxBC = 0; + if (state.vertexBy - state.vertexAy) + state.dxAB = (int) ((((int64_t) state.vertexBx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexBy - state.vertexAy); + else + state.dxAB = 0; + if (state.vertexCy - state.vertexAy) + state.dxAC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexAx << 12)) << 4) / (int) (state.vertexCy - state.vertexAy); + else + state.dxAC = 0; + if (state.vertexCy - state.vertexBy) + state.dxBC = (int) ((((int64_t) state.vertexCx << 12) - ((int64_t) state.vertexBx << 12)) << 4) / (int) (state.vertexCy - state.vertexBy); + else + state.dxBC = 0; - state.lod_min[0] = (params->tLOD[0] & 0x3f) << 6; - state.lod_max[0] = ((params->tLOD[0] >> 6) & 0x3f) << 6; - if (state.lod_max[0] > 0x800) - state.lod_max[0] = 0x800; - state.lod_min[1] = (params->tLOD[1] & 0x3f) << 6; - state.lod_max[1] = ((params->tLOD[1] >> 6) & 0x3f) << 6; - if (state.lod_max[1] > 0x800) - state.lod_max[1] = 0x800; + state.lod_min[0] = (params->tLOD[0] & 0x3f) << 6; + state.lod_max[0] = ((params->tLOD[0] >> 6) & 0x3f) << 6; + if (state.lod_max[0] > 0x800) + state.lod_max[0] = 0x800; + state.lod_min[1] = (params->tLOD[1] & 0x3f) << 6; + state.lod_max[1] = ((params->tLOD[1] >> 6) & 0x3f) << 6; + if (state.lod_max[1] > 0x800) + state.lod_max[1] = 0x800; - state.xstart = state.xend = state.vertexAx << 8; - state.xdir = params->sign ? -1 : 1; + state.xstart = state.xend = state.vertexAx << 8; + state.xdir = params->sign ? -1 : 1; - state.y = (state.vertexAy + 8) >> 4; - state.ydir = 1; + state.y = (state.vertexAy + 8) >> 4; + state.ydir = 1; + tempdx = (params->tmu[0].dSdX >> 14) * (params->tmu[0].dSdX >> 14) + (params->tmu[0].dTdX >> 14) * (params->tmu[0].dTdX >> 14); + tempdy = (params->tmu[0].dSdY >> 14) * (params->tmu[0].dSdY >> 14) + (params->tmu[0].dTdY >> 14) * (params->tmu[0].dTdY >> 14); - tempdx = (params->tmu[0].dSdX >> 14) * (params->tmu[0].dSdX >> 14) + (params->tmu[0].dTdX >> 14) * (params->tmu[0].dTdX >> 14); - tempdy = (params->tmu[0].dSdY >> 14) * (params->tmu[0].dSdY >> 14) + (params->tmu[0].dTdY >> 14) * (params->tmu[0].dTdY >> 14); + if (tempdx > tempdy) + tempLOD = tempdx; + else + tempLOD = tempdy; - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; + LOD = (int) (log2((double) tempLOD / (double) (1ULL << 36)) * 256); + LOD >>= 2; - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; + lodbias = (params->tLOD[0] >> 12) & 0x3f; + if (lodbias & 0x20) + lodbias |= ~0x3f; + state.tmu[0].lod = LOD + (lodbias << 6); - lodbias = (params->tLOD[0] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[0].lod = LOD + (lodbias << 6); + tempdx = (params->tmu[1].dSdX >> 14) * (params->tmu[1].dSdX >> 14) + (params->tmu[1].dTdX >> 14) * (params->tmu[1].dTdX >> 14); + tempdy = (params->tmu[1].dSdY >> 14) * (params->tmu[1].dSdY >> 14) + (params->tmu[1].dTdY >> 14) * (params->tmu[1].dTdY >> 14); + if (tempdx > tempdy) + tempLOD = tempdx; + else + tempLOD = tempdy; - tempdx = (params->tmu[1].dSdX >> 14) * (params->tmu[1].dSdX >> 14) + (params->tmu[1].dTdX >> 14) * (params->tmu[1].dTdX >> 14); - tempdy = (params->tmu[1].dSdY >> 14) * (params->tmu[1].dSdY >> 14) + (params->tmu[1].dTdY >> 14) * (params->tmu[1].dTdY >> 14); + LOD = (int) (log2((double) tempLOD / (double) (1ULL << 36)) * 256); + LOD >>= 2; - if (tempdx > tempdy) - tempLOD = tempdx; - else - tempLOD = tempdy; + lodbias = (params->tLOD[1] >> 12) & 0x3f; + if (lodbias & 0x20) + lodbias |= ~0x3f; + state.tmu[1].lod = LOD + (lodbias << 6); - LOD = (int)(log2((double)tempLOD / (double)(1ULL << 36)) * 256); - LOD >>= 2; - - lodbias = (params->tLOD[1] >> 12) & 0x3f; - if (lodbias & 0x20) - lodbias |= ~0x3f; - state.tmu[1].lod = LOD + (lodbias << 6); - - - voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); + voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); } - -static void render_thread(void *param, int odd_even) +static void +render_thread(void *param, int odd_even) { - voodoo_t *voodoo = (voodoo_t *)param; + voodoo_t *voodoo = (voodoo_t *) param; - while (voodoo->render_thread_run[odd_even]) - { + while (voodoo->render_thread_run[odd_even]) { + thread_set_event(voodoo->render_not_full_event[odd_even]); + thread_wait_event(voodoo->wake_render_thread[odd_even], -1); + thread_reset_event(voodoo->wake_render_thread[odd_even]); + voodoo->render_voodoo_busy[odd_even] = 1; + + while (!PARAM_EMPTY(odd_even)) { + uint64_t start_time = plat_timer_read(); + uint64_t end_time; + voodoo_params_t *params = &voodoo->params_buffer[voodoo->params_read_idx[odd_even] & PARAM_MASK]; + + voodoo_triangle(voodoo, params, odd_even); + + voodoo->params_read_idx[odd_even]++; + + if (PARAM_ENTRIES(odd_even) > (PARAM_SIZE - 10)) thread_set_event(voodoo->render_not_full_event[odd_even]); - thread_wait_event(voodoo->wake_render_thread[odd_even], -1); - thread_reset_event(voodoo->wake_render_thread[odd_even]); - voodoo->render_voodoo_busy[odd_even] = 1; - while (!PARAM_EMPTY(odd_even)) - { - uint64_t start_time = plat_timer_read(); - uint64_t end_time; - voodoo_params_t *params = &voodoo->params_buffer[voodoo->params_read_idx[odd_even] & PARAM_MASK]; - - voodoo_triangle(voodoo, params, odd_even); - - voodoo->params_read_idx[odd_even]++; - - if (PARAM_ENTRIES(odd_even) > (PARAM_SIZE - 10)) - thread_set_event(voodoo->render_not_full_event[odd_even]); - - end_time = plat_timer_read(); - voodoo->render_time[odd_even] += end_time - start_time; - } - - voodoo->render_voodoo_busy[odd_even] = 0; - } -} - -void voodoo_render_thread_1(void *param) -{ - render_thread(param, 0); -} -void voodoo_render_thread_2(void *param) -{ - render_thread(param, 1); -} -void voodoo_render_thread_3(void *param) -{ - render_thread(param, 2); -} -void voodoo_render_thread_4(void *param) -{ - render_thread(param, 3); -} - -void voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) -{ - voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; - - while (PARAM_FULL(0) || (voodoo->render_threads >= 2 && PARAM_FULL(1)) || - (voodoo->render_threads == 4 && (PARAM_FULL(2) || PARAM_FULL(3)))) - { - thread_reset_event(voodoo->render_not_full_event[0]); - if (voodoo->render_threads >= 2) - thread_reset_event(voodoo->render_not_full_event[1]); - if (voodoo->render_threads == 4) - { - thread_reset_event(voodoo->render_not_full_event[2]); - thread_reset_event(voodoo->render_not_full_event[3]); - } - if (PARAM_FULL(0)) - thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ - if (voodoo->render_threads >= 2 && PARAM_FULL(1)) - thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ - if (voodoo->render_threads == 4 && PARAM_FULL(2)) - thread_wait_event(voodoo->render_not_full_event[2], -1); /*Wait for room in ringbuffer*/ - if (voodoo->render_threads == 4 && PARAM_FULL(3)) - thread_wait_event(voodoo->render_not_full_event[3], -1); /*Wait for room in ringbuffer*/ + end_time = plat_timer_read(); + voodoo->render_time[odd_even] += end_time - start_time; } - voodoo_use_texture(voodoo, params, 0); - if (voodoo->dual_tmus) - voodoo_use_texture(voodoo, params, 1); - - memcpy(params_new, params, sizeof(voodoo_params_t)); - - voodoo->params_write_idx++; - - if (PARAM_ENTRIES(0) < 4 || (voodoo->render_threads >= 2 && PARAM_ENTRIES(1) < 4) || - (voodoo->render_threads == 4 && (PARAM_ENTRIES(2) < 4 || PARAM_ENTRIES(3) < 4))) - voodoo_wake_render_thread(voodoo); + voodoo->render_voodoo_busy[odd_even] = 0; + } +} + +void +voodoo_render_thread_1(void *param) +{ + render_thread(param, 0); +} +void +voodoo_render_thread_2(void *param) +{ + render_thread(param, 1); +} +void +voodoo_render_thread_3(void *param) +{ + render_thread(param, 2); +} +void +voodoo_render_thread_4(void *param) +{ + render_thread(param, 3); +} + +void +voodoo_queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) +{ + voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; + + while (PARAM_FULL(0) || (voodoo->render_threads >= 2 && PARAM_FULL(1)) || (voodoo->render_threads == 4 && (PARAM_FULL(2) || PARAM_FULL(3)))) { + thread_reset_event(voodoo->render_not_full_event[0]); + if (voodoo->render_threads >= 2) + thread_reset_event(voodoo->render_not_full_event[1]); + if (voodoo->render_threads == 4) { + thread_reset_event(voodoo->render_not_full_event[2]); + thread_reset_event(voodoo->render_not_full_event[3]); + } + if (PARAM_FULL(0)) + thread_wait_event(voodoo->render_not_full_event[0], -1); /*Wait for room in ringbuffer*/ + if (voodoo->render_threads >= 2 && PARAM_FULL(1)) + thread_wait_event(voodoo->render_not_full_event[1], -1); /*Wait for room in ringbuffer*/ + if (voodoo->render_threads == 4 && PARAM_FULL(2)) + thread_wait_event(voodoo->render_not_full_event[2], -1); /*Wait for room in ringbuffer*/ + if (voodoo->render_threads == 4 && PARAM_FULL(3)) + thread_wait_event(voodoo->render_not_full_event[3], -1); /*Wait for room in ringbuffer*/ + } + + voodoo_use_texture(voodoo, params, 0); + if (voodoo->dual_tmus) + voodoo_use_texture(voodoo, params, 1); + + memcpy(params_new, params, sizeof(voodoo_params_t)); + + voodoo->params_write_idx++; + + if (PARAM_ENTRIES(0) < 4 || (voodoo->render_threads >= 2 && PARAM_ENTRIES(1) < 4) || (voodoo->render_threads == 4 && (PARAM_ENTRIES(2) < 4 || PARAM_ENTRIES(3) < 4))) + voodoo_wake_render_thread(voodoo); } diff --git a/src/video/vid_voodoo_setup.c b/src/video/vid_voodoo_setup.c index 92a984c87..0da5449bf 100644 --- a/src/video/vid_voodoo_setup.c +++ b/src/video/vid_voodoo_setup.c @@ -46,216 +46,190 @@ voodoo_setup_log(const char *fmt, ...) va_list ap; if (voodoo_setup_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoo_setup_log(fmt, ...) +# define voodoo_setup_log(fmt, ...) #endif - -void voodoo_triangle_setup(voodoo_t *voodoo) +void +voodoo_triangle_setup(voodoo_t *voodoo) { - float dxAB, dxBC, dyAB, dyBC; - float area; - int va = 0, vb = 1, vc = 2; - vert_t verts[3]; + float dxAB, dxBC, dyAB, dyBC; + float area; + int va = 0, vb = 1, vc = 2; + vert_t verts[3]; - verts[0] = voodoo->verts[0]; - verts[1] = voodoo->verts[1]; - verts[2] = voodoo->verts[2]; + verts[0] = voodoo->verts[0]; + verts[1] = voodoo->verts[1]; + verts[2] = voodoo->verts[2]; - if (verts[0].sVy < verts[1].sVy) - { - if (verts[1].sVy < verts[2].sVy) - { - /* V1>V0, V2>V1, V2>V1>V0*/ - va = 0; /*OK*/ - vb = 1; - vc = 2; - } - else - { - /* V1>V0, V1>V2*/ - if (verts[0].sVy < verts[2].sVy) - { - /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ - va = 0; - vb = 2; - vc = 1; - } - else - { - /* V1>V0, V1>V2, V0>V2, V1>V0>V2*/ - va = 2; - vb = 0; - vc = 1; - } - } + if (verts[0].sVy < verts[1].sVy) { + if (verts[1].sVy < verts[2].sVy) { + /* V1>V0, V2>V1, V2>V1>V0*/ + va = 0; /*OK*/ + vb = 1; + vc = 2; + } else { + /* V1>V0, V1>V2*/ + if (verts[0].sVy < verts[2].sVy) { + /* V1>V0, V1>V2, V2>V0, V1>V2>V0*/ + va = 0; + vb = 2; + vc = 1; + } else { + /* V1>V0, V1>V2, V0>V2, V1>V0>V2*/ + va = 2; + vb = 0; + vc = 1; + } } - else - { - if (verts[1].sVy < verts[2].sVy) - { - /* V0>V1, V2>V1*/ - if (verts[0].sVy < verts[2].sVy) - { - /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ - va = 1; - vb = 0; - vc = 2; - } - else - { - /* V0>V1, V2>V1, V0>V2, V0>V2>V1*/ - va = 1; - vb = 2; - vc = 0; - } - } - else - { - /*V0>V1>V2*/ - va = 2; - vb = 1; - vc = 0; - } + } else { + if (verts[1].sVy < verts[2].sVy) { + /* V0>V1, V2>V1*/ + if (verts[0].sVy < verts[2].sVy) { + /* V0>V1, V2>V1, V2>V0, V2>V0>V1*/ + va = 1; + vb = 0; + vc = 2; + } else { + /* V0>V1, V2>V1, V0>V2, V0>V2>V1*/ + va = 1; + vb = 2; + vc = 0; + } + } else { + /*V0>V1>V2*/ + va = 2; + vb = 1; + vc = 0; } + } - dxAB = verts[0].sVx - verts[1].sVx; - dxBC = verts[1].sVx - verts[2].sVx; - dyAB = verts[0].sVy - verts[1].sVy; - dyBC = verts[1].sVy - verts[2].sVy; + dxAB = verts[0].sVx - verts[1].sVx; + dxBC = verts[1].sVx - verts[2].sVx; + dyAB = verts[0].sVy - verts[1].sVy; + dyBC = verts[1].sVy - verts[2].sVy; - area = dxAB * dyBC - dxBC * dyAB; + area = dxAB * dyBC - dxBC * dyAB; - if (area == 0.0) - return; + if (area == 0.0) + return; - if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) - { - int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; - int sign = (area < 0.0); + if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) { + int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN; + int sign = (area < 0.0); - if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG)) - == SETUPMODE_CULLING_ENABLE && voodoo->cull_pingpong) - cull_sign = !cull_sign; + if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG)) + == SETUPMODE_CULLING_ENABLE + && voodoo->cull_pingpong) + cull_sign = !cull_sign; - if (cull_sign && sign) - return; - if (!cull_sign && !sign) - return; - } + if (cull_sign && sign) + return; + if (!cull_sign && !sign) + return; + } + dxAB = verts[va].sVx - verts[vb].sVx; + dxBC = verts[vb].sVx - verts[vc].sVx; + dyAB = verts[va].sVy - verts[vb].sVy; + dyBC = verts[vb].sVy - verts[vc].sVy; - dxAB = verts[va].sVx - verts[vb].sVx; - dxBC = verts[vb].sVx - verts[vc].sVx; - dyAB = verts[va].sVy - verts[vb].sVy; - dyBC = verts[vb].sVy - verts[vc].sVy; + area = dxAB * dyBC - dxBC * dyAB; - area = dxAB * dyBC - dxBC * dyAB; + dxAB /= area; + dxBC /= area; + dyAB /= area; + dyBC /= area; - dxAB /= area; - dxBC /= area; - dyAB /= area; - dyBC /= area; + voodoo->params.vertexAx = (int32_t) (int16_t) ((int32_t) (verts[va].sVx * 16.0f) & 0xffff); + voodoo->params.vertexAy = (int32_t) (int16_t) ((int32_t) (verts[va].sVy * 16.0f) & 0xffff); + voodoo->params.vertexBx = (int32_t) (int16_t) ((int32_t) (verts[vb].sVx * 16.0f) & 0xffff); + voodoo->params.vertexBy = (int32_t) (int16_t) ((int32_t) (verts[vb].sVy * 16.0f) & 0xffff); + voodoo->params.vertexCx = (int32_t) (int16_t) ((int32_t) (verts[vc].sVx * 16.0f) & 0xffff); + voodoo->params.vertexCy = (int32_t) (int16_t) ((int32_t) (verts[vc].sVy * 16.0f) & 0xffff); + if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) { + voodoo_setup_log("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); + return; + } + if (voodoo->sSetupMode & SETUPMODE_RGB) { + voodoo->params.startR = (int32_t) (verts[va].sRed * 4096.0f); + voodoo->params.dRdX = (int32_t) (((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f); + voodoo->params.dRdY = (int32_t) (((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f); + voodoo->params.startG = (int32_t) (verts[va].sGreen * 4096.0f); + voodoo->params.dGdX = (int32_t) (((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f); + voodoo->params.dGdY = (int32_t) (((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f); + voodoo->params.startB = (int32_t) (verts[va].sBlue * 4096.0f); + voodoo->params.dBdX = (int32_t) (((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f); + voodoo->params.dBdY = (int32_t) (((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_ALPHA) { + voodoo->params.startA = (int32_t) (verts[va].sAlpha * 4096.0f); + voodoo->params.dAdX = (int32_t) (((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f); + voodoo->params.dAdY = (int32_t) (((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_Z) { + voodoo->params.startZ = (int32_t) (verts[va].sVz * 4096.0f); + voodoo->params.dZdX = (int32_t) (((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f); + voodoo->params.dZdY = (int32_t) (((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f); + } + if (voodoo->sSetupMode & SETUPMODE_Wb) { + voodoo->params.startW = (int64_t) (verts[va].sWb * 4294967296.0f); + voodoo->params.dWdX = (int64_t) (((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); + voodoo->params.dWdY = (int64_t) (((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; + voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; + voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; + } + if (voodoo->sSetupMode & SETUPMODE_W0) { + voodoo->params.tmu[0].startW = (int64_t) (verts[va].sW0 * 4294967296.0f); + voodoo->params.tmu[0].dWdX = (int64_t) (((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dWdY = (int64_t) (((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; + voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; + voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; + } + if (voodoo->sSetupMode & SETUPMODE_S0_T0) { + voodoo->params.tmu[0].startS = (int64_t) (verts[va].sS0 * 4294967296.0f); + voodoo->params.tmu[0].dSdX = (int64_t) (((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dSdY = (int64_t) (((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[0].startT = (int64_t) (verts[va].sT0 * 4294967296.0f); + voodoo->params.tmu[0].dTdX = (int64_t) (((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f); + voodoo->params.tmu[0].dTdY = (int64_t) (((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; + voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; + voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; + voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT; + voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX; + voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY; + } + if (voodoo->sSetupMode & SETUPMODE_W1) { + voodoo->params.tmu[1].startW = (int64_t) (verts[va].sW1 * 4294967296.0f); + voodoo->params.tmu[1].dWdX = (int64_t) (((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dWdY = (int64_t) (((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f); + } + if (voodoo->sSetupMode & SETUPMODE_S1_T1) { + voodoo->params.tmu[1].startS = (int64_t) (verts[va].sS1 * 4294967296.0f); + voodoo->params.tmu[1].dSdX = (int64_t) (((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dSdY = (int64_t) (((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startT = (int64_t) (verts[va].sT1 * 4294967296.0f); + voodoo->params.tmu[1].dTdX = (int64_t) (((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dTdY = (int64_t) (((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f); + } - voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff); - voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff); - voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff); - voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff); - voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff); - voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff); + voodoo->params.sign = (area < 0.0); - if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) { - voodoo_setup_log("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy); - return; - } + if (voodoo->ncc_dirty[0]) + voodoo_update_ncc(voodoo, 0); + if (voodoo->ncc_dirty[1]) + voodoo_update_ncc(voodoo, 1); + voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - if (voodoo->sSetupMode & SETUPMODE_RGB) - { - voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f); - voodoo->params.dRdX = (int32_t)(((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f); - voodoo->params.dRdY = (int32_t)(((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f); - voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f); - voodoo->params.dGdX = (int32_t)(((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f); - voodoo->params.dGdY = (int32_t)(((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f); - voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f); - voodoo->params.dBdX = (int32_t)(((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f); - voodoo->params.dBdY = (int32_t)(((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_ALPHA) - { - voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f); - voodoo->params.dAdX = (int32_t)(((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f); - voodoo->params.dAdY = (int32_t)(((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Z) - { - voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f); - voodoo->params.dZdX = (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f); - voodoo->params.dZdY = (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f); - } - if (voodoo->sSetupMode & SETUPMODE_Wb) - { - voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f); - voodoo->params.dWdX = (int64_t)(((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f); - voodoo->params.dWdY = (int64_t)(((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW; - voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX; - voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_W0) - { - voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f); - voodoo->params.tmu[0].dWdX = (int64_t)(((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dWdY = (int64_t)(((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW; - voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX; - voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY; - } - if (voodoo->sSetupMode & SETUPMODE_S0_T0) - { - voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f); - voodoo->params.tmu[0].dSdX = (int64_t)(((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dSdY = (int64_t)(((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f); - voodoo->params.tmu[0].dTdX = (int64_t)(((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[0].dTdY = (int64_t)(((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS; - voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX; - voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY; - voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT; - voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX; - voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY; - } - if (voodoo->sSetupMode & SETUPMODE_W1) - { - voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f); - voodoo->params.tmu[1].dWdX = (int64_t)(((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dWdY = (int64_t)(((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f); - } - if (voodoo->sSetupMode & SETUPMODE_S1_T1) - { - voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f); - voodoo->params.tmu[1].dSdX = (int64_t)(((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dSdY = (int64_t)(((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f); - voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f); - voodoo->params.tmu[1].dTdX = (int64_t)(((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dTdY = (int64_t)(((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f); - } - - voodoo->params.sign = (area < 0.0); - - if (voodoo->ncc_dirty[0]) - voodoo_update_ncc(voodoo, 0); - if (voodoo->ncc_dirty[1]) - voodoo_update_ncc(voodoo, 1); - voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0; - - voodoo_queue_triangle(voodoo, &voodoo->params); + voodoo_queue_triangle(voodoo, &voodoo->params); } diff --git a/src/video/vid_voodoo_texture.c b/src/video/vid_voodoo_texture.c index 784ea17fe..e0530c6d4 100644 --- a/src/video/vid_voodoo_texture.c +++ b/src/video/vid_voodoo_texture.c @@ -38,7 +38,6 @@ #include <86box/vid_voodoo_render.h> #include <86box/vid_voodoo_texture.h> - #ifdef ENABLE_VOODOO_TEXTURE_LOG int voodoo_texture_do_log = ENABLE_VOODOO_TEXTURE_LOG; @@ -48,581 +47,501 @@ voodoo_texture_log(const char *fmt, ...) va_list ap; if (voodoo_texture_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define voodoo_texture_log(fmt, ...) +# define voodoo_texture_log(fmt, ...) #endif - -void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) +void +voodoo_recalc_tex(voodoo_t *voodoo, int tmu) { - int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; - int width = 256, height = 256; - int shift = 8; - int lod; - uint32_t base = voodoo->params.texBaseAddr[tmu]; - uint32_t offset = 0; - int tex_lod = 0; - uint32_t offsets[LOD_MAX+3]; - int widths[LOD_MAX+3], heights[LOD_MAX+3], shifts[LOD_MAX+3]; + int aspect = (voodoo->params.tLOD[tmu] >> 21) & 3; + int width = 256, height = 256; + int shift = 8; + int lod; + uint32_t base = voodoo->params.texBaseAddr[tmu]; + uint32_t offset = 0; + int tex_lod = 0; + uint32_t offsets[LOD_MAX + 3]; + int widths[LOD_MAX + 3], heights[LOD_MAX + 3], shifts[LOD_MAX + 3]; - if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) - height >>= aspect; + if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER) + height >>= aspect; + else { + width >>= aspect; + shift -= aspect; + } + + for (lod = 0; lod <= LOD_MAX + 2; lod++) { + offsets[lod] = offset; + widths[lod] = width >> lod; + heights[lod] = height >> lod; + shifts[lod] = shift - lod; + + if (!widths[lod]) + widths[lod] = 1; + if (!heights[lod]) + heights[lod] = 1; + if (shifts[lod] < 0) + shifts[lod] = 0; + + if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { + if (voodoo->params.tformat[tmu] & 8) + offset += (width >> lod) * (height >> lod) * 2; + else + offset += (width >> lod) * (height >> lod); + } + } + + if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) + tex_lod++; /*Skip LOD 0*/ + + // voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); + for (lod = 0; lod <= LOD_MAX + 1; lod++) { + if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) { + switch (tex_lod) { + case 0: + base = voodoo->params.texBaseAddr[tmu]; + break; + case 1: + base = voodoo->params.texBaseAddr1[tmu]; + break; + case 2: + base = voodoo->params.texBaseAddr2[tmu]; + break; + default: + base = voodoo->params.texBaseAddr38[tmu]; + break; + } + } + + voodoo->params.tex_base[tmu][lod] = base + offsets[tex_lod]; + if (voodoo->params.tformat[tmu] & 8) + voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod] * 2); else - { - width >>= aspect; - shift -= aspect; - } + voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod]); + voodoo->params.tex_w_mask[tmu][lod] = widths[tex_lod] - 1; + voodoo->params.tex_w_nmask[tmu][lod] = ~(widths[tex_lod] - 1); + voodoo->params.tex_h_mask[tmu][lod] = heights[tex_lod] - 1; + voodoo->params.tex_shift[tmu][lod] = shifts[tex_lod]; + voodoo->params.tex_lod[tmu][lod] = tex_lod; - for (lod = 0; lod <= LOD_MAX + 2; lod++) - { - offsets[lod] = offset; - widths[lod] = width >> lod; - heights[lod] = height >> lod; - shifts[lod] = shift - lod; - - if (!widths[lod]) - widths[lod] = 1; - if (!heights[lod]) - heights[lod] = 1; - if (shifts[lod] < 0) - shifts[lod] = 0; - - if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || - ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || - (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) - { - if (voodoo->params.tformat[tmu] & 8) - offset += (width >> lod) * (height >> lod) * 2; - else - offset += (width >> lod) * (height >> lod); - } - } - - - if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD)) - tex_lod++; /*Skip LOD 0*/ - -// voodoo_texture_log("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]); - for (lod = 0; lod <= LOD_MAX+1; lod++) - { - if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR) - { - switch (tex_lod) - { - case 0: - base = voodoo->params.texBaseAddr[tmu]; - break; - case 1: - base = voodoo->params.texBaseAddr1[tmu]; - break; - case 2: - base = voodoo->params.texBaseAddr2[tmu]; - break; - default: - base = voodoo->params.texBaseAddr38[tmu]; - break; - } - } - - voodoo->params.tex_base[tmu][lod] = base + offsets[tex_lod]; - if (voodoo->params.tformat[tmu] & 8) - voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod] * 2); + if (!(voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) { + if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) { + if (voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) + tex_lod += 2; else - voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod]); - voodoo->params.tex_w_mask[tmu][lod] = widths[tex_lod] - 1; - voodoo->params.tex_w_nmask[tmu][lod] = ~(widths[tex_lod] - 1); - voodoo->params.tex_h_mask[tmu][lod] = heights[tex_lod] - 1; - voodoo->params.tex_shift[tmu][lod] = shifts[tex_lod]; - voodoo->params.tex_lod[tmu][lod] = tex_lod; - - if (!(voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) || - ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || - (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD))) - { - if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0) - { - if (voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) - tex_lod += 2; - else - tex_lod++; - } - } + tex_lod++; + } } + } - voodoo->params.tex_width[tmu] = width; + voodoo->params.tex_width[tmu] = width; } -#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24)) +#define makergba(r, g, b, a) ((b) | ((g) << 8) | ((r) << 16) | ((a) << 24)) -void voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) +void +voodoo_use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) { - int c, d; - int lod; - int lod_min, lod_max; - uint32_t addr = 0, addr_end; - uint32_t palette_checksum; + int c, d; + int lod; + int lod_min, lod_max; + uint32_t addr = 0, addr_end; + uint32_t palette_checksum; - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; + lod_min = (params->tLOD[tmu] >> 2) & 15; + lod_max = (params->tLOD[tmu] >> 8) & 15; - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) - { - if (voodoo->palette_dirty[tmu]) - { - palette_checksum = 0; + if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) { + if (voodoo->palette_dirty[tmu]) { + palette_checksum = 0; - for (c = 0; c < 256; c++) - palette_checksum ^= voodoo->palette[tmu][c].u; + for (c = 0; c < 256; c++) + palette_checksum ^= voodoo->palette[tmu][c].u; - voodoo->palette_checksum[tmu] = palette_checksum; - voodoo->palette_dirty[tmu] = 0; - } - else - palette_checksum = voodoo->palette_checksum[tmu]; + voodoo->palette_checksum[tmu] = palette_checksum; + voodoo->palette_dirty[tmu] = 0; + } else + palette_checksum = voodoo->palette_checksum[tmu]; + } else + palette_checksum = 0; + + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + addr = params->texBaseAddr1[tmu]; + else + addr = params->texBaseAddr[tmu]; + + /*Try to find texture in cache*/ + for (c = 0; c < TEX_CACHE_MAX; c++) { + if (voodoo->texture_cache[tmu][c].base == addr && voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) { + params->tex_entry[tmu] = c; + voodoo->texture_cache[tmu][c].refcount++; + return; } - else - palette_checksum = 0; + } - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - addr = params->texBaseAddr1[tmu]; - else - addr = params->texBaseAddr[tmu]; - - /*Try to find texture in cache*/ - for (c = 0; c < TEX_CACHE_MAX; c++) - { - if (voodoo->texture_cache[tmu][c].base == addr && - voodoo->texture_cache[tmu][c].tLOD == (params->tLOD[tmu] & 0xf00fff) && - voodoo->texture_cache[tmu][c].palette_checksum == palette_checksum) - { - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; - return; - } + /*Texture not found, search for unused texture*/ + do { + for (c = 0; c < TEX_CACHE_MAX; c++) { + voodoo->texture_last_removed++; + voodoo->texture_last_removed &= (TEX_CACHE_MAX - 1); + if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] && (voodoo->render_threads == 1 || voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1])) + break; } - - /*Texture not found, search for unused texture*/ - do - { - for (c = 0; c < TEX_CACHE_MAX; c++) - { - voodoo->texture_last_removed++; - voodoo->texture_last_removed &= (TEX_CACHE_MAX-1); - if (voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[0] && - (voodoo->render_threads == 1 || voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount == voodoo->texture_cache[tmu][voodoo->texture_last_removed].refcount_r[1])) - break; - } - if (c == TEX_CACHE_MAX) - voodoo_wait_for_render_thread_idle(voodoo); - } while (c == TEX_CACHE_MAX); if (c == TEX_CACHE_MAX) - fatal("Texture cache full!\n"); + voodoo_wait_for_render_thread_idle(voodoo); + } while (c == TEX_CACHE_MAX); + if (c == TEX_CACHE_MAX) + fatal("Texture cache full!\n"); - c = voodoo->texture_last_removed; + c = voodoo->texture_last_removed; + if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) + voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; + else + voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; + voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; - if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD) && (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)) - voodoo->texture_cache[tmu][c].base = params->texBaseAddr1[tmu]; - else - voodoo->texture_cache[tmu][c].base = params->texBaseAddr[tmu]; - voodoo->texture_cache[tmu][c].tLOD = params->tLOD[tmu] & 0xf00fff; + lod_min = (params->tLOD[tmu] >> 2) & 15; + lod_max = (params->tLOD[tmu] >> 8) & 15; + // voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); + lod_min = MIN(lod_min, 8); + lod_max = MIN(lod_max, 8); + for (lod = lod_min; lod <= lod_max; lod++) { + uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; + uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; + int x, y; + int shift = 8 - params->tex_lod[tmu][lod]; + rgba_u *pal; - lod_min = (params->tLOD[tmu] >> 2) & 15; - lod_max = (params->tLOD[tmu] >> 8) & 15; -// voodoo_texture_log(" add new texture to %i tformat=%i %08x LOD=%i-%i tmu=%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max, tmu); - lod_min = MIN(lod_min, 8); - lod_max = MIN(lod_max, 8); - for (lod = lod_min; lod <= lod_max; lod++) - { - uint32_t *base = &voodoo->texture_cache[tmu][c].data[texture_offset[lod]]; - uint32_t tex_addr = params->tex_base[tmu][lod] & voodoo->texture_mask; - int x, y; - int shift = 8 - params->tex_lod[tmu][lod]; - rgba_u *pal; + // voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); - //voodoo_texture_log(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); + switch (params->tformat[tmu]) { + case TEX_RGB332: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - - switch (params->tformat[tmu]) - { - case TEX_RGB332: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_Y4I2Q2: - pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_A8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(dat, dat, dat, dat); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(dat, dat, dat, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_AI8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba((dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f)); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_PAL8: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_APAL8: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint8_t dat = voodoo->tex_mem[tmu][(tex_addr+x) & voodoo->texture_mask]; - - int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | (pal[dat].rgba.r & 3); - int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | ((pal[dat].rgba.g & 0xf) >> 2); - int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4); - int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6); - - base[x] = makergba(r, g, b, a); - } - tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); - base += (1 << shift); - } - break; - - case TEX_ARGB8332: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_A8Y4I2Q2: - pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_R5G6B5: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_ARGB1555: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_ARGB4444: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_A8I8: - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - case TEX_APAL88: - pal = voodoo->palette[tmu]; - for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod]+1; y++) - { - for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod]+1; x++) - { - uint16_t dat = *(uint16_t *)&voodoo->tex_mem[tmu][(tex_addr + x*2) & voodoo->texture_mask]; - - base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); - } - tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod]+1)); - base += (1 << shift); - } - break; - - default: - fatal("Unknown texture format %i\n", params->tformat[tmu]); + base[x] = makergba(rgb332[dat].r, rgb332[dat].g, rgb332[dat].b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); } - } + break; - voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; + case TEX_Y4I2Q2: + pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; - if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) - voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; - else - voodoo->texture_cache[tmu][c].palette_checksum = 0; - - if (lod_min == 0) - { - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; - voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; - } - else - voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; - - if (lod_min <= 1 && lod_max >= 1) - { - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; - voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; - } - else - voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; - - if (lod_min <= 2 && lod_max >= 2) - { - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; - voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; - } - else - voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; - - if (lod_max >= 3) - { - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; - voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; - } - else - voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; - - - for (d = 0; d < 4; d++) - { - addr = voodoo->texture_cache[tmu][c].addr_start[d]; - addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - - if (addr_end != 0) - { - for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); } - } + break; - params->tex_entry[tmu] = c; - voodoo->texture_cache[tmu][c].refcount++; + case TEX_A8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + + base[x] = makergba(dat, dat, dat, dat); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_I8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + + base[x] = makergba(dat, dat, dat, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_AI8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + + base[x] = makergba((dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0x0f) | ((dat << 4) & 0xf0), (dat & 0xf0) | ((dat >> 4) & 0x0f)); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_PAL8: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + + base[x] = makergba(pal[dat].rgba.r, pal[dat].rgba.g, pal[dat].rgba.b, 0xff); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_APAL8: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint8_t dat = voodoo->tex_mem[tmu][(tex_addr + x) & voodoo->texture_mask]; + + int r = ((pal[dat].rgba.r & 3) << 6) | ((pal[dat].rgba.g & 0xf0) >> 2) | (pal[dat].rgba.r & 3); + int g = ((pal[dat].rgba.g & 0xf) << 4) | ((pal[dat].rgba.b & 0xc0) >> 4) | ((pal[dat].rgba.g & 0xf) >> 2); + int b = ((pal[dat].rgba.b & 0x3f) << 2) | ((pal[dat].rgba.b & 0x30) >> 4); + int a = (pal[dat].rgba.r & 0xfc) | ((pal[dat].rgba.r & 0xc0) >> 6); + + base[x] = makergba(r, g, b, a); + } + tex_addr += (1 << voodoo->params.tex_shift[tmu][lod]); + base += (1 << shift); + } + break; + + case TEX_ARGB8332: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = *(uint16_t *) &voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + + base[x] = makergba(rgb332[dat & 0xff].r, rgb332[dat & 0xff].g, rgb332[dat & 0xff].b, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; + + case TEX_A8Y4I2Q2: + pal = voodoo->ncc_lookup[tmu][(voodoo->params.textureMode[tmu] & TEXTUREMODE_NCC_SEL) ? 1 : 0]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = *(uint16_t *) &voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + + base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; + + case TEX_R5G6B5: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = *(uint16_t *) &voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + + base[x] = makergba(rgb565[dat].r, rgb565[dat].g, rgb565[dat].b, 0xff); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; + + case TEX_ARGB1555: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = *(uint16_t *) &voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + + base[x] = makergba(argb1555[dat].r, argb1555[dat].g, argb1555[dat].b, argb1555[dat].a); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; + + case TEX_ARGB4444: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = *(uint16_t *) &voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + + base[x] = makergba(argb4444[dat].r, argb4444[dat].g, argb4444[dat].b, argb4444[dat].a); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; + + case TEX_A8I8: + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = *(uint16_t *) &voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + + base[x] = makergba(dat & 0xff, dat & 0xff, dat & 0xff, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; + + case TEX_APAL88: + pal = voodoo->palette[tmu]; + for (y = 0; y < voodoo->params.tex_h_mask[tmu][lod] + 1; y++) { + for (x = 0; x < voodoo->params.tex_w_mask[tmu][lod] + 1; x++) { + uint16_t dat = *(uint16_t *) &voodoo->tex_mem[tmu][(tex_addr + x * 2) & voodoo->texture_mask]; + + base[x] = makergba(pal[dat & 0xff].rgba.r, pal[dat & 0xff].rgba.g, pal[dat & 0xff].rgba.b, dat >> 8); + } + tex_addr += (1 << (voodoo->params.tex_shift[tmu][lod] + 1)); + base += (1 << shift); + } + break; + + default: + fatal("Unknown texture format %i\n", params->tformat[tmu]); + } + } + + voodoo->texture_cache[tmu][c].is16 = voodoo->params.tformat[tmu] & 8; + + if (params->tformat[tmu] == TEX_PAL8 || params->tformat[tmu] == TEX_APAL8 || params->tformat[tmu] == TEX_APAL88) + voodoo->texture_cache[tmu][c].palette_checksum = palette_checksum; + else + voodoo->texture_cache[tmu][c].palette_checksum = 0; + + if (lod_min == 0) { + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->params.tex_base[tmu][0]; + voodoo->texture_cache[tmu][c].addr_end[0] = voodoo->params.tex_end[tmu][0]; + } else + voodoo->texture_cache[tmu][c].addr_start[0] = voodoo->texture_cache[tmu][c].addr_end[0] = 0; + + if (lod_min <= 1 && lod_max >= 1) { + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->params.tex_base[tmu][1]; + voodoo->texture_cache[tmu][c].addr_end[1] = voodoo->params.tex_end[tmu][1]; + } else + voodoo->texture_cache[tmu][c].addr_start[1] = voodoo->texture_cache[tmu][c].addr_end[1] = 0; + + if (lod_min <= 2 && lod_max >= 2) { + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->params.tex_base[tmu][2]; + voodoo->texture_cache[tmu][c].addr_end[2] = voodoo->params.tex_end[tmu][2]; + } else + voodoo->texture_cache[tmu][c].addr_start[2] = voodoo->texture_cache[tmu][c].addr_end[2] = 0; + + if (lod_max >= 3) { + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->params.tex_base[tmu][(lod_min > 3) ? lod_min : 3]; + voodoo->texture_cache[tmu][c].addr_end[3] = voodoo->params.tex_end[tmu][(lod_max < 8) ? lod_max : 8]; + } else + voodoo->texture_cache[tmu][c].addr_start[3] = voodoo->texture_cache[tmu][c].addr_end[3] = 0; + + for (d = 0; d < 4; d++) { + addr = voodoo->texture_cache[tmu][c].addr_start[d]; + addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + + if (addr_end != 0) { + for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + } + } + + params->tex_entry[tmu] = c; + voodoo->texture_cache[tmu][c].refcount++; } -void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) +void +flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) { - int wait_for_idle = 0; - int c; + int wait_for_idle = 0; + int c; - memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); -// voodoo_texture_log("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); - for (c = 0; c < TEX_CACHE_MAX; c++) - { - if (voodoo->texture_cache[tmu][c].base != -1) - { - int d; + memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); + // voodoo_texture_log("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); + for (c = 0; c < TEX_CACHE_MAX; c++) { + if (voodoo->texture_cache[tmu][c].base != -1) { + int d; - for (d = 0; d < 4; d++) - { - int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; - int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; + for (d = 0; d < 4; d++) { + int addr_start = voodoo->texture_cache[tmu][c].addr_start[d]; + int addr_end = voodoo->texture_cache[tmu][c].addr_end[d]; - if (addr_end != 0) - { - int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; - int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; + if (addr_end != 0) { + int addr_start_masked = addr_start & voodoo->texture_mask & ~0x3ff; + int addr_end_masked = ((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff; - if (addr_end_masked < addr_start_masked) - addr_end_masked = voodoo->texture_mask+1; - if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) - { -// voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); + if (addr_end_masked < addr_start_masked) + addr_end_masked = voodoo->texture_mask + 1; + if (dirty_addr >= addr_start_masked && dirty_addr < addr_end_masked) { + // voodoo_texture_log(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); - if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || - (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) - wait_for_idle = 1; + if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) + wait_for_idle = 1; - voodoo->texture_cache[tmu][c].base = -1; - } - else - { - for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) - voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; - } - } - } + voodoo->texture_cache[tmu][c].base = -1; + } else { + for (; addr_start <= addr_end; addr_start += (1 << TEX_DIRTY_SHIFT)) + voodoo->texture_present[tmu][(addr_start & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; + } } + } } - if (wait_for_idle) - voodoo_wait_for_render_thread_idle(voodoo); + } + if (wait_for_idle) + voodoo_wait_for_render_thread_idle(voodoo); } -void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) +void +voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) { - int lod, s, t; - voodoo_t *voodoo = (voodoo_t *)p; - int tmu; + int lod, s, t; + voodoo_t *voodoo = (voodoo_t *) p; + int tmu; - if (addr & 0x400000) - return; /*TREX != 0*/ + if (addr & 0x400000) + return; /*TREX != 0*/ - tmu = (addr & 0x200000) ? 1 : 0; + tmu = (addr & 0x200000) ? 1 : 0; - if (tmu && !voodoo->dual_tmus) - return; + if (tmu && !voodoo->dual_tmus) + return; - if (voodoo->type < VOODOO_BANSHEE) - { - if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type >= VOODOO_BANSHEE) - { - lod = (addr >> 16) & 0xf; - t = (addr >> 8) & 0xff; - } - else - { - lod = (addr >> 17) & 0xf; - t = (addr >> 9) & 0xff; - } - if (voodoo->params.tformat[tmu] & 8) - s = (addr >> 1) & 0xfe; - else - { - if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type >= VOODOO_BANSHEE) - s = addr & 0xfc; - else - s = (addr >> 1) & 0xfc; - } - if (lod > LOD_MAX) - return; - -// if (addr >= 0x200000) -// return; - - if (voodoo->params.tformat[tmu] & 8) - addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2; - else - addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); + if (voodoo->type < VOODOO_BANSHEE) { + if (!(voodoo->params.tformat[tmu] & 8) && voodoo->type >= VOODOO_BANSHEE) { + lod = (addr >> 16) & 0xf; + t = (addr >> 8) & 0xff; + } else { + lod = (addr >> 17) & 0xf; + t = (addr >> 9) & 0xff; } + if (voodoo->params.tformat[tmu] & 8) + s = (addr >> 1) & 0xfe; + else { + if ((voodoo->params.textureMode[tmu] & (1 << 31)) || voodoo->type >= VOODOO_BANSHEE) + s = addr & 0xfc; + else + s = (addr >> 1) & 0xfc; + } + if (lod > LOD_MAX) + return; + + // if (addr >= 0x200000) + // return; + + if (voodoo->params.tformat[tmu] & 8) + addr = voodoo->params.tex_base[tmu][lod] + s * 2 + (t << voodoo->params.tex_shift[tmu][lod]) * 2; else - addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][0]; + addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); + } else + addr = (addr & 0x1ffffc) + voodoo->params.tex_base[tmu][0]; - if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) - { -// voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); - } - if (voodoo->type == VOODOO_3 && voodoo->texture_present[tmu^1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) - { -// voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); - flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu^1); - } - *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; + if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); + } + if (voodoo->type == VOODOO_3 && voodoo->texture_present[tmu ^ 1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { + // voodoo_texture_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); + flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu ^ 1); + } + *(uint32_t *) (&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; } diff --git a/src/video/vid_wy700.c b/src/video/vid_wy700.c index ef641627b..2478a5089 100644 --- a/src/video/vid_wy700.c +++ b/src/video/vid_wy700.c @@ -29,14 +29,11 @@ #include <86box/device.h> #include <86box/video.h> - #define WY700_XSIZE 1280 #define WY700_YSIZE 800 - void updatewindowsize(int x, int y); - /* The Wyse 700 is an unusual video card. Though it has an MC6845 CRTC, this * is not exposed directly to the host PC. Instead, the CRTC is controlled by * an MC68705P3 microcontroller. @@ -81,145 +78,136 @@ void updatewindowsize(int x, int y); * - Cursor detach (commands 4 and 5) */ - /* The microcontroller sets up the real CRTC with one of five fixed mode * definitions. As written, this is a fairly simplistic emulation that * doesn't attempt to closely follow the actual working of the CRTC; but I've * included the definitions here for information. */ -static uint8_t mode_1280x800[] = -{ - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x29, /* Horizontal sync position */ - 0x06, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x03, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ +static uint8_t mode_1280x800[] = { + 0x31, /* Horizontal total */ + 0x28, /* Horizontal displayed */ + 0x29, /* Horizontal sync position */ + 0x06, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x03, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ }; -static uint8_t mode_1280x400[] = -{ - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x29, /* Horizontal sync position */ - 0x06, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ +static uint8_t mode_1280x400[] = { + 0x31, /* Horizontal total */ + 0x28, /* Horizontal displayed */ + 0x29, /* Horizontal sync position */ + 0x06, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ }; -static uint8_t mode_640x400[] = -{ - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x14, /* Horizontal sync position */ - 0x03, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ +static uint8_t mode_640x400[] = { + 0x18, /* Horizontal total */ + 0x14, /* Horizontal displayed */ + 0x14, /* Horizontal sync position */ + 0x03, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ }; -static uint8_t mode_640x200[] = -{ - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x14, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x37, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x32, /* Vertical displayed */ - 0x34, /* Vsync position */ - 0x03, /* Interlace and skew */ - 0x07, /* Maximum raster address */ +static uint8_t mode_640x200[] = { + 0x18, /* Horizontal total */ + 0x14, /* Horizontal displayed */ + 0x14, /* Horizontal sync position */ + 0xff, /* Horizontal sync width */ + 0x37, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x32, /* Vertical displayed */ + 0x34, /* Vsync position */ + 0x03, /* Interlace and skew */ + 0x07, /* Maximum raster address */ }; -static uint8_t mode_80x24[] = -{ - 0x31, /* Horizontal total */ - 0x28, /* Horizontal displayed */ - 0x2A, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ +static uint8_t mode_80x24[] = { + 0x31, /* Horizontal total */ + 0x28, /* Horizontal displayed */ + 0x2A, /* Horizontal sync position */ + 0xff, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ }; -static uint8_t mode_40x24[] = -{ - 0x18, /* Horizontal total */ - 0x14, /* Horizontal displayed */ - 0x15, /* Horizontal sync position */ - 0xff, /* Horizontal sync width */ - 0x1b, /* Vertical total */ - 0x00, /* Vertical total adjust */ - 0x19, /* Vertical displayed */ - 0x1a, /* Vsync position */ - 0x01, /* Interlace and skew */ - 0x0f, /* Maximum raster address */ +static uint8_t mode_40x24[] = { + 0x18, /* Horizontal total */ + 0x14, /* Horizontal displayed */ + 0x15, /* Horizontal sync position */ + 0xff, /* Horizontal sync width */ + 0x1b, /* Vertical total */ + 0x00, /* Vertical total adjust */ + 0x19, /* Vertical displayed */ + 0x1a, /* Vsync position */ + 0x01, /* Interlace and skew */ + 0x0f, /* Maximum raster address */ }; - /* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */ extern uint8_t fontdatw[512][32]; -typedef struct wy700_t -{ - mem_mapping_t mapping; +typedef struct wy700_t { + mem_mapping_t mapping; - /* The microcontroller works by watching four ports: - * 0x3D8 / 0x3B8 (mode control register) - * 0x3DD (top scanline address) - * 0x3DF (Wy700 control register) - * CRTC reg 14 (cursor location high) - * - * It will do nothing until one of these registers is touched. When - * one is, it then reconfigures the internal 6845 based on what it - * sees. - */ - uint8_t last_03D8; /* Copies of values written to the listed */ - uint8_t last_03DD; /* I/O ports */ - uint8_t last_03DF; - uint8_t last_crtc_0E; + /* The microcontroller works by watching four ports: + * 0x3D8 / 0x3B8 (mode control register) + * 0x3DD (top scanline address) + * 0x3DF (Wy700 control register) + * CRTC reg 14 (cursor location high) + * + * It will do nothing until one of these registers is touched. When + * one is, it then reconfigures the internal 6845 based on what it + * sees. + */ + uint8_t last_03D8; /* Copies of values written to the listed */ + uint8_t last_03DD; /* I/O ports */ + uint8_t last_03DF; + uint8_t last_crtc_0E; - uint8_t cga_crtc[32]; /* The 'CRTC' as the host PC sees it */ - uint8_t real_crtc[32]; /* The internal CRTC as the microcontroller */ - /* sees it */ - int cga_crtcreg; /* Current CRTC register */ - uint16_t wy700_base; /* Framebuffer base address (native modes) */ - uint8_t wy700_control; /* Native control / command register */ - uint8_t wy700_mode; /* Current mode (see list at top of file) */ - uint8_t cga_ctrl; /* Emulated MDA/CGA control register */ - uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ + uint8_t cga_crtc[32]; /* The 'CRTC' as the host PC sees it */ + uint8_t real_crtc[32]; /* The internal CRTC as the microcontroller */ + /* sees it */ + int cga_crtcreg; /* Current CRTC register */ + uint16_t wy700_base; /* Framebuffer base address (native modes) */ + uint8_t wy700_control; /* Native control / command register */ + uint8_t wy700_mode; /* Current mode (see list at top of file) */ + uint8_t cga_ctrl; /* Emulated MDA/CGA control register */ + uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ - uint8_t mda_stat; /* MDA status (IN 0x3BA) */ - uint8_t cga_stat; /* CGA status (IN 0x3DA) */ + uint8_t mda_stat; /* MDA status (IN 0x3BA) */ + uint8_t cga_stat; /* CGA status (IN 0x3DA) */ - int font; /* Current font, 0 or 1 */ - int enabled; /* Display enabled, 0 or 1 */ - int detach; /* Detach cursor, 0 or 1 */ + int font; /* Current font, 0 or 1 */ + int enabled; /* Display enabled, 0 or 1 */ + int detach; /* Detach cursor, 0 or 1 */ - uint64_t dispontime, dispofftime; - pc_timer_t timer; + uint64_t dispontime, dispofftime; + pc_timer_t timer; - int linepos, displine; - int vc; - int dispon, blink; - int vsynctime; + int linepos, displine; + int vc; + int dispon, blink; + int vsynctime; - uint8_t *vram; + uint8_t *vram; } wy700_t; /* Mapping of attributes to colours, in CGA emulation... */ @@ -227,796 +215,771 @@ static int cgacols[256][2][2]; /* ... and MDA emulation. */ static int mdacols[256][2][2]; -void wy700_recalctimings(wy700_t *wy700); -void wy700_write(uint32_t addr, uint8_t val, void *p); +void wy700_recalctimings(wy700_t *wy700); +void wy700_write(uint32_t addr, uint8_t val, void *p); uint8_t wy700_read(uint32_t addr, void *p); -void wy700_checkchanges(wy700_t *wy700); +void wy700_checkchanges(wy700_t *wy700); -static video_timings_t timing_wy700 = {VIDEO_ISA, 8, 16, 32, 8, 16, 32}; +static video_timings_t timing_wy700 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; - -void wy700_out(uint16_t addr, uint8_t val, void *p) +void +wy700_out(uint16_t addr, uint8_t val, void *p) { - wy700_t *wy700 = (wy700_t *)p; - switch (addr) - { - /* These three registers are only mapped in the 3Dx range, - * not the 3Bx range. */ - case 0x3DD: /* Base address (low) */ - wy700->wy700_base &= 0xFF00; - wy700->wy700_base |= val; - wy700_checkchanges(wy700); - break; + wy700_t *wy700 = (wy700_t *) p; + switch (addr) { + /* These three registers are only mapped in the 3Dx range, + * not the 3Bx range. */ + case 0x3DD: /* Base address (low) */ + wy700->wy700_base &= 0xFF00; + wy700->wy700_base |= val; + wy700_checkchanges(wy700); + break; - case 0x3DE: /* Base address (high) */ - wy700->wy700_base &= 0xFF; - wy700->wy700_base |= ((uint16_t)val) << 8; - wy700_checkchanges(wy700); - break; + case 0x3DE: /* Base address (high) */ + wy700->wy700_base &= 0xFF; + wy700->wy700_base |= ((uint16_t) val) << 8; + wy700_checkchanges(wy700); + break; - case 0x3DF: /* Command / control register */ - wy700->wy700_control = val; - wy700_checkchanges(wy700); - break; + case 0x3DF: /* Command / control register */ + wy700->wy700_control = val; + wy700_checkchanges(wy700); + break; - /* Emulated CRTC, register select */ - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - wy700->cga_crtcreg = val & 31; - break; + /* Emulated CRTC, register select */ + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + wy700->cga_crtcreg = val & 31; + break; - /* Emulated CRTC, value */ - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - wy700->cga_crtc[wy700->cga_crtcreg] = val; + /* Emulated CRTC, value */ + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + wy700->cga_crtc[wy700->cga_crtcreg] = val; - wy700_checkchanges(wy700); - wy700_recalctimings(wy700); - return; + wy700_checkchanges(wy700); + wy700_recalctimings(wy700); + return; - /* Emulated MDA / CGA control register */ - case 0x3b8: case 0x3D8: - wy700->cga_ctrl = val; - wy700_checkchanges(wy700); - return; - /* Emulated CGA colour register */ - case 0x3D9: - wy700->cga_colour = val; - return; - } + /* Emulated MDA / CGA control register */ + case 0x3b8: + case 0x3D8: + wy700->cga_ctrl = val; + wy700_checkchanges(wy700); + return; + /* Emulated CGA colour register */ + case 0x3D9: + wy700->cga_colour = val; + return; + } } -uint8_t wy700_in(uint16_t addr, void *p) +uint8_t +wy700_in(uint16_t addr, void *p) { - wy700_t *wy700 = (wy700_t *)p; - switch (addr) - { - case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: - case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: - return wy700->cga_crtcreg; - case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: - case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: - return wy700->cga_crtc[wy700->cga_crtcreg]; - case 0x3b8: case 0x3d8: - return wy700->cga_ctrl; - case 0x3d9: - return wy700->cga_colour; - case 0x3ba: - return wy700->mda_stat; - case 0x3da: - return wy700->cga_stat; - } - return 0xff; + wy700_t *wy700 = (wy700_t *) p; + switch (addr) { + case 0x3b0: + case 0x3b2: + case 0x3b4: + case 0x3b6: + case 0x3d0: + case 0x3d2: + case 0x3d4: + case 0x3d6: + return wy700->cga_crtcreg; + case 0x3b1: + case 0x3b3: + case 0x3b5: + case 0x3b7: + case 0x3d1: + case 0x3d3: + case 0x3d5: + case 0x3d7: + return wy700->cga_crtc[wy700->cga_crtcreg]; + case 0x3b8: + case 0x3d8: + return wy700->cga_ctrl; + case 0x3d9: + return wy700->cga_colour; + case 0x3ba: + return wy700->mda_stat; + case 0x3da: + return wy700->cga_stat; + } + return 0xff; } - /* Check if any of the four key registers has changed. If so, check for a * mode change or cursor size change */ -void wy700_checkchanges(wy700_t *wy700) +void +wy700_checkchanges(wy700_t *wy700) { - uint8_t curstart, curend; + uint8_t curstart, curend; - if (wy700->last_03D8 == wy700->cga_ctrl && - wy700->last_03DD == (wy700->wy700_base & 0xFF) && - wy700->last_03DF == wy700->wy700_control && - wy700->last_crtc_0E == wy700->cga_crtc[0x0E]) - { - return; /* Nothing changed */ - } - /* Check for control register changes */ - if (wy700->last_03DF != wy700->wy700_control) - { - wy700->last_03DF = wy700->wy700_control; + if (wy700->last_03D8 == wy700->cga_ctrl && wy700->last_03DD == (wy700->wy700_base & 0xFF) && wy700->last_03DF == wy700->wy700_control && wy700->last_crtc_0E == wy700->cga_crtc[0x0E]) { + return; /* Nothing changed */ + } + /* Check for control register changes */ + if (wy700->last_03DF != wy700->wy700_control) { + wy700->last_03DF = wy700->wy700_control; - /* Values 1-7 are commands. */ - switch (wy700->wy700_control) - { - case 1: /* Reset */ - wy700->font = 0; - wy700->enabled = 1; - wy700->detach = 0; - break; + /* Values 1-7 are commands. */ + switch (wy700->wy700_control) { + case 1: /* Reset */ + wy700->font = 0; + wy700->enabled = 1; + wy700->detach = 0; + break; - case 2: /* Font 1 */ - wy700->font = 0; - break; + case 2: /* Font 1 */ + wy700->font = 0; + break; - case 3: /* Font 2 */ - wy700->font = 1; - break; + case 3: /* Font 2 */ + wy700->font = 1; + break; -/* Even with the microprogram from an original card, I can't really work out - * what commands 4 and 5 (which I've called 'cursor detach' / 'cursor attach') - * do. Command 4 sets a flag in microcontroller RAM, and command 5 clears - * it. When the flag is set, the real cursor doesn't track the cursor in the - * emulated CRTC, and its blink rate increases. Possibly it's a self-test - * function of some kind. - * - * The card documentation doesn't cover these commands. - */ + /* Even with the microprogram from an original card, I can't really work out + * what commands 4 and 5 (which I've called 'cursor detach' / 'cursor attach') + * do. Command 4 sets a flag in microcontroller RAM, and command 5 clears + * it. When the flag is set, the real cursor doesn't track the cursor in the + * emulated CRTC, and its blink rate increases. Possibly it's a self-test + * function of some kind. + * + * The card documentation doesn't cover these commands. + */ - case 4: /* Detach cursor */ - wy700->detach = 1; - break; + case 4: /* Detach cursor */ + wy700->detach = 1; + break; - case 5: /* Attach cursor */ - wy700->detach = 0; - break; + case 5: /* Attach cursor */ + wy700->detach = 0; + break; - case 6: /* Disable display */ - wy700->enabled = 0; - break; + case 6: /* Disable display */ + wy700->enabled = 0; + break; - case 7: /* Enable display */ - wy700->enabled = 1; - break; - } - /* A control write with the top bit set selects graphics mode */ - if (wy700->wy700_control & 0x80) - { - /* Select hi-res graphics mode; map framebuffer at A0000 */ - mem_mapping_set_addr(&wy700->mapping, 0xa0000, 0x20000); - wy700->wy700_mode = wy700->wy700_control; + case 7: /* Enable display */ + wy700->enabled = 1; + break; + } + /* A control write with the top bit set selects graphics mode */ + if (wy700->wy700_control & 0x80) { + /* Select hi-res graphics mode; map framebuffer at A0000 */ + mem_mapping_set_addr(&wy700->mapping, 0xa0000, 0x20000); + wy700->wy700_mode = wy700->wy700_control; - /* Select appropriate preset timings */ - if (wy700->wy700_mode & 0x40) - { - memcpy(wy700->real_crtc, mode_1280x800, - sizeof(mode_1280x800)); - } - else if (wy700->wy700_mode & 0x20) - { - memcpy(wy700->real_crtc, mode_1280x400, - sizeof(mode_1280x400)); - } - else - { - memcpy(wy700->real_crtc, mode_640x400, - sizeof(mode_640x400)); - } - } - } - /* An attempt to program the CGA / MDA selects low-res mode */ - else if (wy700->last_03D8 != wy700->cga_ctrl) - { - wy700->last_03D8 = wy700->cga_ctrl; - /* Set lo-res text or graphics mode. - * (Strictly speaking, when not in hi-res mode the card - * should be mapped at B0000-B3FFF and B8000-BBFFF, leaving - * a 16k hole between the two ranges) */ - mem_mapping_set_addr(&wy700->mapping, 0xb0000, 0x0C000); - if (wy700->cga_ctrl & 2) /* Graphics mode */ - { - wy700->wy700_mode = (wy700->cga_ctrl & 0x10) ? 6 : 4; - memcpy(wy700->real_crtc, mode_640x200, - sizeof(mode_640x200)); - } - else if (wy700->cga_ctrl & 1) /* Text mode 80x24 */ - { - wy700->wy700_mode = 2; - memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); - } - else /* Text mode 40x24 */ - { - wy700->wy700_mode = 0; - memcpy(wy700->real_crtc, mode_40x24, sizeof(mode_40x24)); - } - } - /* Convert the cursor sizes from the ones used by the CGA or MDA - * to native */ + /* Select appropriate preset timings */ + if (wy700->wy700_mode & 0x40) { + memcpy(wy700->real_crtc, mode_1280x800, + sizeof(mode_1280x800)); + } else if (wy700->wy700_mode & 0x20) { + memcpy(wy700->real_crtc, mode_1280x400, + sizeof(mode_1280x400)); + } else { + memcpy(wy700->real_crtc, mode_640x400, + sizeof(mode_640x400)); + } + } + } + /* An attempt to program the CGA / MDA selects low-res mode */ + else if (wy700->last_03D8 != wy700->cga_ctrl) { + wy700->last_03D8 = wy700->cga_ctrl; + /* Set lo-res text or graphics mode. + * (Strictly speaking, when not in hi-res mode the card + * should be mapped at B0000-B3FFF and B8000-BBFFF, leaving + * a 16k hole between the two ranges) */ + mem_mapping_set_addr(&wy700->mapping, 0xb0000, 0x0C000); + if (wy700->cga_ctrl & 2) /* Graphics mode */ + { + wy700->wy700_mode = (wy700->cga_ctrl & 0x10) ? 6 : 4; + memcpy(wy700->real_crtc, mode_640x200, + sizeof(mode_640x200)); + } else if (wy700->cga_ctrl & 1) /* Text mode 80x24 */ + { + wy700->wy700_mode = 2; + memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); + } else /* Text mode 40x24 */ + { + wy700->wy700_mode = 0; + memcpy(wy700->real_crtc, mode_40x24, sizeof(mode_40x24)); + } + } + /* Convert the cursor sizes from the ones used by the CGA or MDA + * to native */ - if (wy700->cga_crtc[9] == 13) /* MDA scaling */ - { - curstart = wy700->cga_crtc[10] & 0x1F; - wy700->real_crtc[10] = ((curstart + 5) >> 3) + curstart; - if (wy700->real_crtc[10] > 31) wy700->real_crtc[10] = 31; - /* And bring 'cursor disabled' flag across */ - if ((wy700->cga_crtc[10] & 0x60) == 0x20) - { - wy700->real_crtc[10] |= 0x20; - } - curend = wy700->cga_crtc[11] & 0x1F; - wy700->real_crtc[11] = ((curend + 5) >> 3) + curend; - if (wy700->real_crtc[11] > 31) wy700->real_crtc[11] = 31; - } - else /* CGA scaling */ - { - curstart = wy700->cga_crtc[10] & 0x1F; - wy700->real_crtc[10] = curstart << 1; - if (wy700->real_crtc[10] > 31) wy700->real_crtc[10] = 31; - /* And bring 'cursor disabled' flag across */ - if ((wy700->cga_crtc[10] & 0x60) == 0x20) - { - wy700->real_crtc[10] |= 0x20; - } - curend = wy700->cga_crtc[11] & 0x1F; - wy700->real_crtc[11] = curend << 1; - if (wy700->real_crtc[11] > 31) wy700->real_crtc[11] = 31; - } + if (wy700->cga_crtc[9] == 13) /* MDA scaling */ + { + curstart = wy700->cga_crtc[10] & 0x1F; + wy700->real_crtc[10] = ((curstart + 5) >> 3) + curstart; + if (wy700->real_crtc[10] > 31) + wy700->real_crtc[10] = 31; + /* And bring 'cursor disabled' flag across */ + if ((wy700->cga_crtc[10] & 0x60) == 0x20) { + wy700->real_crtc[10] |= 0x20; + } + curend = wy700->cga_crtc[11] & 0x1F; + wy700->real_crtc[11] = ((curend + 5) >> 3) + curend; + if (wy700->real_crtc[11] > 31) + wy700->real_crtc[11] = 31; + } else /* CGA scaling */ + { + curstart = wy700->cga_crtc[10] & 0x1F; + wy700->real_crtc[10] = curstart << 1; + if (wy700->real_crtc[10] > 31) + wy700->real_crtc[10] = 31; + /* And bring 'cursor disabled' flag across */ + if ((wy700->cga_crtc[10] & 0x60) == 0x20) { + wy700->real_crtc[10] |= 0x20; + } + curend = wy700->cga_crtc[11] & 0x1F; + wy700->real_crtc[11] = curend << 1; + if (wy700->real_crtc[11] > 31) + wy700->real_crtc[11] = 31; + } } - -void wy700_write(uint32_t addr, uint8_t val, void *p) +void +wy700_write(uint32_t addr, uint8_t val, void *p) { - wy700_t *wy700 = (wy700_t *)p; + wy700_t *wy700 = (wy700_t *) p; - if (wy700->wy700_mode & 0x80) /* High-res mode. */ - { - addr &= 0xFFFF; -/* In 800-line modes, bit 1 of the control register sets the high bit of the - * write address. */ - if ((wy700->wy700_mode & 0x42) == 0x42) - { - addr |= 0x10000; - } - wy700->vram[addr] = val; - } - else - { - wy700->vram[addr & 0x3fff] = val; - } + if (wy700->wy700_mode & 0x80) /* High-res mode. */ + { + addr &= 0xFFFF; + /* In 800-line modes, bit 1 of the control register sets the high bit of the + * write address. */ + if ((wy700->wy700_mode & 0x42) == 0x42) { + addr |= 0x10000; + } + wy700->vram[addr] = val; + } else { + wy700->vram[addr & 0x3fff] = val; + } } - - -uint8_t wy700_read(uint32_t addr, void *p) +uint8_t +wy700_read(uint32_t addr, void *p) { - wy700_t *wy700 = (wy700_t *)p; - if (wy700->wy700_mode & 0x80) /* High-res mode. */ - { - addr &= 0xFFFF; -/* In 800-line modes, bit 0 of the control register sets the high bit of the - * read address. */ - if ((wy700->wy700_mode & 0x41) == 0x41) - { - addr |= 0x10000; - } - return wy700->vram[addr]; - } - else - { - return wy700->vram[addr & 0x3fff]; - } + wy700_t *wy700 = (wy700_t *) p; + if (wy700->wy700_mode & 0x80) /* High-res mode. */ + { + addr &= 0xFFFF; + /* In 800-line modes, bit 0 of the control register sets the high bit of the + * read address. */ + if ((wy700->wy700_mode & 0x41) == 0x41) { + addr |= 0x10000; + } + return wy700->vram[addr]; + } else { + return wy700->vram[addr & 0x3fff]; + } } - - -void wy700_recalctimings(wy700_t *wy700) +void +wy700_recalctimings(wy700_t *wy700) { - double disptime; - double _dispontime, _dispofftime; + double disptime; + double _dispontime, _dispofftime; - disptime = wy700->real_crtc[0] + 1; - _dispontime = wy700->real_crtc[1]; - _dispofftime = disptime - _dispontime; - _dispontime *= MDACONST; - _dispofftime *= MDACONST; - wy700->dispontime = (uint64_t)(_dispontime); - wy700->dispofftime = (uint64_t)(_dispofftime); + disptime = wy700->real_crtc[0] + 1; + _dispontime = wy700->real_crtc[1]; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + wy700->dispontime = (uint64_t) (_dispontime); + wy700->dispofftime = (uint64_t) (_dispofftime); } - /* Draw a single line of the screen in either text mode */ -void wy700_textline(wy700_t *wy700) +void +wy700_textline(wy700_t *wy700) { - int x; - int w = (wy700->wy700_mode == 0) ? 40 : 80; - int cw = (wy700->wy700_mode == 0) ? 32 : 16; - uint8_t chr, attr; - uint8_t bitmap[2]; - uint8_t *fontbase = &fontdatw[0][0]; - int blink, c; - int drawcursor, cursorline; - int mda = 0; - uint16_t addr; - uint8_t sc; - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; + int x; + int w = (wy700->wy700_mode == 0) ? 40 : 80; + int cw = (wy700->wy700_mode == 0) ? 32 : 16; + uint8_t chr, attr; + uint8_t bitmap[2]; + uint8_t *fontbase = &fontdatw[0][0]; + int blink, c; + int drawcursor, cursorline; + int mda = 0; + uint16_t addr; + uint8_t sc; + uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; + uint16_t ca = (wy700->cga_crtc[15] | (wy700->cga_crtc[14] << 8)) & 0x3fff; + /* The fake CRTC character height register selects whether MDA or CGA + * attributes are used */ + if (wy700->cga_crtc[9] == 0 || wy700->cga_crtc[9] == 13) { + mda = 1; + } -/* The fake CRTC character height register selects whether MDA or CGA - * attributes are used */ - if (wy700->cga_crtc[9] == 0 || wy700->cga_crtc[9] == 13) - { - mda = 1; - } + if (wy700->font) { + fontbase += 256 * 32; + } + addr = ((ma & ~1) + (wy700->displine >> 5) * w) * 2; + sc = (wy700->displine >> 1) & 15; - if (wy700->font) - { - fontbase += 256*32; - } - addr = ((ma & ~1) + (wy700->displine >> 5) * w) * 2; - sc = (wy700->displine >> 1) & 15; + ma += ((wy700->displine >> 5) * w); - ma += ((wy700->displine >> 5) * w); + if ((wy700->real_crtc[10] & 0x60) == 0x20) { + cursorline = 0; + } else { + cursorline = ((wy700->real_crtc[10] & 0x1F) <= sc) && ((wy700->real_crtc[11] & 0x1F) >= sc); + } - if ((wy700->real_crtc[10] & 0x60) == 0x20) - { - cursorline = 0; - } - else - { - cursorline = ((wy700->real_crtc[10] & 0x1F) <= sc) && - ((wy700->real_crtc[11] & 0x1F) >= sc); - } + for (x = 0; x < w; x++) { + chr = wy700->vram[(addr + 2 * x) & 0x3FFF]; + attr = wy700->vram[(addr + 2 * x + 1) & 0x3FFF]; + drawcursor = ((ma == ca) && cursorline && wy700->enabled && (wy700->cga_ctrl & 8) && (wy700->blink & 16)); + blink = ((wy700->blink & 16) && (wy700->cga_ctrl & 0x20) && (attr & 0x80) && !drawcursor); - for (x = 0; x < w; x++) - { - chr = wy700->vram[(addr + 2 * x) & 0x3FFF]; - attr = wy700->vram[(addr + 2 * x + 1) & 0x3FFF]; - drawcursor = ((ma == ca) && cursorline && wy700->enabled && - (wy700->cga_ctrl & 8) && (wy700->blink & 16)); - blink = ((wy700->blink & 16) && - (wy700->cga_ctrl & 0x20) && - (attr & 0x80) && !drawcursor); + if (wy700->cga_ctrl & 0x20) + attr &= 0x7F; + /* MDA underline */ + if (sc == 14 && mda && ((attr & 7) == 1)) { + for (c = 0; c < cw; c++) + buffer32->line[wy700->displine][(x * cw) + c] = mdacols[attr][blink][1]; + } else /* Draw 16 pixels of character */ + { + bitmap[0] = fontbase[chr * 32 + 2 * sc]; + bitmap[1] = fontbase[chr * 32 + 2 * sc + 1]; + for (c = 0; c < 16; c++) { + int col; + if (c < 8) + col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; + else + col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; + if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) + col = mdacols[0][0][0]; + if (w == 40) { + buffer32->line[wy700->displine][(x * cw) + 2 * c] = col; + buffer32->line[wy700->displine][(x * cw) + 2 * c + 1] = col; + } else + buffer32->line[wy700->displine][(x * cw) + c] = col; + } - if (wy700->cga_ctrl & 0x20) attr &= 0x7F; - /* MDA underline */ - if (sc == 14 && mda && ((attr & 7) == 1)) - { - for (c = 0; c < cw; c++) - buffer32->line[wy700->displine][(x * cw) + c] = - mdacols[attr][blink][1]; - } - else /* Draw 16 pixels of character */ - { - bitmap[0] = fontbase[chr * 32 + 2 * sc]; - bitmap[1] = fontbase[chr * 32 + 2 * sc + 1]; - for (c = 0; c < 16; c++) - { - int col; - if (c < 8) - col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; - else col = (mda ? mdacols : cgacols)[attr][blink][(bitmap[1] & (1 << ((c & 7) ^ 7))) ? 1 : 0]; - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - col = mdacols[0][0][0]; - if (w == 40) - { - buffer32->line[wy700->displine][(x * cw) + 2*c] = col; - buffer32->line[wy700->displine][(x * cw) + 2*c + 1] = col; - } - else buffer32->line[wy700->displine][(x * cw) + c] = col; - } - - if (drawcursor) - { - for (c = 0; c < cw; c++) - buffer32->line[wy700->displine][(x * cw) + c] ^= (mda ? mdacols : cgacols)[attr][0][1]; - } - ++ma; - } - } + if (drawcursor) { + for (c = 0; c < cw; c++) + buffer32->line[wy700->displine][(x * cw) + c] ^= (mda ? mdacols : cgacols)[attr][0][1]; + } + ++ma; + } + } } - /* Draw a line in either of the CGA graphics modes (320x200 or 640x200) */ -void wy700_cgaline(wy700_t *wy700) +void +wy700_cgaline(wy700_t *wy700) { - int x, c; - uint32_t dat; - uint8_t ink = 0; - uint16_t addr; + int x, c; + uint32_t dat; + uint8_t ink = 0; + uint16_t addr; - uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; - addr = ((wy700->displine >> 2) & 1) * 0x2000 + - (wy700->displine >> 3) * 80 + - ((ma & ~1) << 1); + uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; + addr = ((wy700->displine >> 2) & 1) * 0x2000 + (wy700->displine >> 3) * 80 + ((ma & ~1) << 1); - /* The fixed mode setting here programs the real CRTC with a screen - * width to 20, so draw in 20 fixed chunks of 4 bytes each */ - for (x = 0; x < 20; x++) - { - dat = ((wy700->vram[addr & 0x3FFF] << 24) | - (wy700->vram[(addr+1) & 0x3FFF] << 16) | - (wy700->vram[(addr+2) & 0x3FFF] << 8) | - (wy700->vram[(addr+3) & 0x3FFF])); - addr += 4; + /* The fixed mode setting here programs the real CRTC with a screen + * width to 20, so draw in 20 fixed chunks of 4 bytes each */ + for (x = 0; x < 20; x++) { + dat = ((wy700->vram[addr & 0x3FFF] << 24) | (wy700->vram[(addr + 1) & 0x3FFF] << 16) | (wy700->vram[(addr + 2) & 0x3FFF] << 8) | (wy700->vram[(addr + 3) & 0x3FFF])); + addr += 4; - if (wy700->wy700_mode == 6) - { - for (c = 0; c < 32; c++) - { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = 16; - buffer32->line[wy700->displine][x*64 + 2*c] = - buffer32->line[wy700->displine][x*64 + 2*c+1] = - ink; - dat = dat << 1; - } - } - else - { - for (c = 0; c < 16; c++) - { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } - if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) - ink = 16; - buffer32->line[wy700->displine][x*64 + 4*c] = - buffer32->line[wy700->displine][x*64 + 4*c+1] = - buffer32->line[wy700->displine][x*64 + 4*c+2] = - buffer32->line[wy700->displine][x*64 + 4*c+3] = - ink; - dat = dat << 2; - } - } - } + if (wy700->wy700_mode == 6) { + for (c = 0; c < 32; c++) { + ink = (dat & 0x80000000) ? 16 + 15 : 16 + 0; + if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) + ink = 16; + buffer32->line[wy700->displine][x * 64 + 2 * c] = buffer32->line[wy700->displine][x * 64 + 2 * c + 1] = ink; + dat = dat << 1; + } + } else { + for (c = 0; c < 16; c++) { + switch ((dat >> 30) & 3) { + case 0: + ink = 16 + 0; + break; + case 1: + ink = 16 + 8; + break; + case 2: + ink = 16 + 7; + break; + case 3: + ink = 16 + 15; + break; + } + if (!(wy700->enabled) || !(wy700->cga_ctrl & 8)) + ink = 16; + buffer32->line[wy700->displine][x * 64 + 4 * c] = buffer32->line[wy700->displine][x * 64 + 4 * c + 1] = buffer32->line[wy700->displine][x * 64 + 4 * c + 2] = buffer32->line[wy700->displine][x * 64 + 4 * c + 3] = ink; + dat = dat << 2; + } + } + } } /* Draw a line in the medium-resolution graphics modes (640x400 or 320x400) */ -void wy700_medresline(wy700_t *wy700) +void +wy700_medresline(wy700_t *wy700) { - int x, c; - uint32_t dat; - uint8_t ink = 0; - uint32_t addr; + int x, c; + uint32_t dat; + uint8_t ink = 0; + uint32_t addr; - addr = (wy700->displine >> 1) * 80 + 4 * wy700->wy700_base; + addr = (wy700->displine >> 1) * 80 + 4 * wy700->wy700_base; - for (x = 0; x < 20; x++) - { - dat = ((wy700->vram[addr & 0x1FFFF] << 24) | - (wy700->vram[(addr+1) & 0x1FFFF] << 16) | - (wy700->vram[(addr+2) & 0x1FFFF] << 8) | - (wy700->vram[(addr+3) & 0x1FFFF])); - addr += 4; + for (x = 0; x < 20; x++) { + dat = ((wy700->vram[addr & 0x1FFFF] << 24) | (wy700->vram[(addr + 1) & 0x1FFFF] << 16) | (wy700->vram[(addr + 2) & 0x1FFFF] << 8) | (wy700->vram[(addr + 3) & 0x1FFFF])); + addr += 4; - if (wy700->wy700_mode & 0x10) - { - for (c = 0; c < 16; c++) - { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer32->line[wy700->displine][x*64 + 4*c] = - buffer32->line[wy700->displine][x*64 + 4*c+1] = - buffer32->line[wy700->displine][x*64 + 4*c+2] = - buffer32->line[wy700->displine][x*64 + 4*c+3] = - ink; - dat = dat << 2; - } - } - else - { - for (c = 0; c < 32; c++) - { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer32->line[wy700->displine][x*64 + 2*c] = - buffer32->line[wy700->displine][x*64 + 2*c+1] = - ink; - dat = dat << 1; - } - } - } + if (wy700->wy700_mode & 0x10) { + for (c = 0; c < 16; c++) { + switch ((dat >> 30) & 3) { + case 0: + ink = 16 + 0; + break; + case 1: + ink = 16 + 8; + break; + case 2: + ink = 16 + 7; + break; + case 3: + ink = 16 + 15; + break; + } + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = 16; + buffer32->line[wy700->displine][x * 64 + 4 * c] = buffer32->line[wy700->displine][x * 64 + 4 * c + 1] = buffer32->line[wy700->displine][x * 64 + 4 * c + 2] = buffer32->line[wy700->displine][x * 64 + 4 * c + 3] = ink; + dat = dat << 2; + } + } else { + for (c = 0; c < 32; c++) { + ink = (dat & 0x80000000) ? 16 + 15 : 16 + 0; + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = 16; + buffer32->line[wy700->displine][x * 64 + 2 * c] = buffer32->line[wy700->displine][x * 64 + 2 * c + 1] = ink; + dat = dat << 1; + } + } + } } - - - /* Draw a line in one of the high-resolution modes */ -void wy700_hiresline(wy700_t *wy700) +void +wy700_hiresline(wy700_t *wy700) { - int x, c; - uint32_t dat; - uint8_t ink = 0; - uint32_t addr; + int x, c; + uint32_t dat; + uint8_t ink = 0; + uint32_t addr; - addr = (wy700->displine >> 1) * 160 + 4 * wy700->wy700_base; + addr = (wy700->displine >> 1) * 160 + 4 * wy700->wy700_base; - if (wy700->wy700_mode & 0x40) /* 800-line interleaved modes */ - { - if (wy700->displine & 1) addr += 0x10000; - } - for (x = 0; x < 40; x++) - { - dat = ((wy700->vram[addr & 0x1FFFF] << 24) | - (wy700->vram[(addr+1) & 0x1FFFF] << 16) | - (wy700->vram[(addr+2) & 0x1FFFF] << 8) | - (wy700->vram[(addr+3) & 0x1FFFF])); - addr += 4; + if (wy700->wy700_mode & 0x40) /* 800-line interleaved modes */ + { + if (wy700->displine & 1) + addr += 0x10000; + } + for (x = 0; x < 40; x++) { + dat = ((wy700->vram[addr & 0x1FFFF] << 24) | (wy700->vram[(addr + 1) & 0x1FFFF] << 16) | (wy700->vram[(addr + 2) & 0x1FFFF] << 8) | (wy700->vram[(addr + 3) & 0x1FFFF])); + addr += 4; - if (wy700->wy700_mode & 0x10) - { - for (c = 0; c < 16; c++) - { - switch ((dat >> 30) & 3) - { - case 0: ink = 16 + 0; break; - case 1: ink = 16 + 8; break; - case 2: ink = 16 + 7; break; - case 3: ink = 16 + 15; break; - } - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer32->line[wy700->displine][x*32 + 2*c] = - buffer32->line[wy700->displine][x*32 + 2*c+1] = - ink; - dat = dat << 2; - } - } - else - { - for (c = 0; c < 32; c++) - { - ink = (dat & 0x80000000) ? 16 + 15: 16 + 0; - /* Display disabled? */ - if (!(wy700->wy700_mode & 8)) ink = 16; - buffer32->line[wy700->displine][x*32 + c] = ink; - dat = dat << 1; - } - } - } + if (wy700->wy700_mode & 0x10) { + for (c = 0; c < 16; c++) { + switch ((dat >> 30) & 3) { + case 0: + ink = 16 + 0; + break; + case 1: + ink = 16 + 8; + break; + case 2: + ink = 16 + 7; + break; + case 3: + ink = 16 + 15; + break; + } + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = 16; + buffer32->line[wy700->displine][x * 32 + 2 * c] = buffer32->line[wy700->displine][x * 32 + 2 * c + 1] = ink; + dat = dat << 2; + } + } else { + for (c = 0; c < 32; c++) { + ink = (dat & 0x80000000) ? 16 + 15 : 16 + 0; + /* Display disabled? */ + if (!(wy700->wy700_mode & 8)) + ink = 16; + buffer32->line[wy700->displine][x * 32 + c] = ink; + dat = dat << 1; + } + } + } } - - - -void wy700_poll(void *p) +void +wy700_poll(void *p) { - wy700_t *wy700 = (wy700_t *)p; - int mode; + wy700_t *wy700 = (wy700_t *) p; + int mode; - if (!wy700->linepos) - { - timer_advance_u64(&wy700->timer, wy700->dispofftime); - wy700->cga_stat |= 1; - wy700->mda_stat |= 1; - wy700->linepos = 1; - if (wy700->dispon) - { - if (wy700->displine == 0) - { - video_wait_for_buffer(); - } + if (!wy700->linepos) { + timer_advance_u64(&wy700->timer, wy700->dispofftime); + wy700->cga_stat |= 1; + wy700->mda_stat |= 1; + wy700->linepos = 1; + if (wy700->dispon) { + if (wy700->displine == 0) { + video_wait_for_buffer(); + } - if (wy700->wy700_mode & 0x80) - mode = wy700->wy700_mode & 0xF0; - else mode = wy700->wy700_mode & 0x0F; + if (wy700->wy700_mode & 0x80) + mode = wy700->wy700_mode & 0xF0; + else + mode = wy700->wy700_mode & 0x0F; - switch (mode) - { - default: - case 0x00: - case 0x02: - wy700_textline(wy700); - break; - case 0x04: - case 0x06: - wy700_cgaline(wy700); - break; - case 0x80: - case 0x90: - wy700_medresline(wy700); - break; - case 0xA0: - case 0xB0: - case 0xC0: - case 0xD0: - case 0xE0: - case 0xF0: - wy700_hiresline(wy700); - break; - } - } - wy700->displine++; - /* Hardcode a fixed refresh rate and VSYNC timing */ - if (wy700->displine == 800) /* Start of VSYNC */ - { - wy700->cga_stat |= 8; - wy700->dispon = 0; - } - if (wy700->displine == 832) /* End of VSYNC */ - { - wy700->displine = 0; - wy700->cga_stat &= ~8; - wy700->dispon = 1; - } + switch (mode) { + default: + case 0x00: + case 0x02: + wy700_textline(wy700); + break; + case 0x04: + case 0x06: + wy700_cgaline(wy700); + break; + case 0x80: + case 0x90: + wy700_medresline(wy700); + break; + case 0xA0: + case 0xB0: + case 0xC0: + case 0xD0: + case 0xE0: + case 0xF0: + wy700_hiresline(wy700); + break; + } } + wy700->displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (wy700->displine == 800) /* Start of VSYNC */ + { + wy700->cga_stat |= 8; + wy700->dispon = 0; + } + if (wy700->displine == 832) /* End of VSYNC */ + { + wy700->displine = 0; + wy700->cga_stat &= ~8; + wy700->dispon = 1; + } + } else { + if (wy700->dispon) { + wy700->cga_stat &= ~1; + wy700->mda_stat &= ~1; + } + timer_advance_u64(&wy700->timer, wy700->dispontime); + wy700->linepos = 0; + + if (wy700->displine == 800) { + /* Hardcode 1280x800 window size */ + if ((WY700_XSIZE != xsize) || (WY700_YSIZE != ysize) || video_force_resize_get()) { + xsize = WY700_XSIZE; + ysize = WY700_YSIZE; + if (xsize < 64) + xsize = 656; + if (ysize < 32) + ysize = 200; + set_screen_size(xsize, ysize); + + if (video_force_resize_get()) + video_force_resize_set(0); + } + video_blit_memtoscreen_8(0, 0, xsize, ysize); + + frames++; + /* Fixed 1280x800 resolution */ + video_res_x = WY700_XSIZE; + video_res_y = WY700_YSIZE; + if (wy700->wy700_mode & 0x80) + mode = wy700->wy700_mode & 0xF0; + else + mode = wy700->wy700_mode & 0x0F; + switch (mode) { + case 0x00: + case 0x02: + video_bpp = 0; + break; + case 0x04: + case 0x90: + case 0xB0: + case 0xD0: + case 0xF0: + video_bpp = 2; + break; + default: + video_bpp = 1; + break; + } + wy700->blink++; + } + } +} + +void * +wy700_init(const device_t *info) +{ + int c; + wy700_t *wy700 = malloc(sizeof(wy700_t)); + memset(wy700, 0, sizeof(wy700_t)); + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_wy700); + + /* 128k video RAM */ + wy700->vram = malloc(0x20000); + + loadfont("roms/video/wyse700/wy700.rom", 3); + + timer_add(&wy700->timer, wy700_poll, wy700, 1); + + /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in + * high-resolution modes) */ + mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, wy700); + /* Respond to both MDA and CGA I/O ports */ + io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); + io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); + + /* Set up the emulated attributes. + * CGA is done in four groups: 00-0F, 10-7F, 80-8F, 90-FF */ + for (c = 0; c < 0x10; c++) { + cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16; + if (c & 8) + cgacols[c][0][1] = 15 + 16; else - { - if (wy700->dispon) - { - wy700->cga_stat &= ~1; - wy700->mda_stat &= ~1; - } - timer_advance_u64(&wy700->timer, wy700->dispontime); - wy700->linepos = 0; + cgacols[c][0][1] = 7 + 16; + } + for (c = 0x10; c < 0x80; c++) { + cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16 + 7; + if (c & 8) + cgacols[c][0][1] = 15 + 16; + else + cgacols[c][0][1] = 0 + 16; - if (wy700->displine == 800) - { -/* Hardcode 1280x800 window size */ - if ((WY700_XSIZE != xsize) || (WY700_YSIZE != ysize) || video_force_resize_get()) - { - xsize = WY700_XSIZE; - ysize = WY700_YSIZE; - if (xsize < 64) xsize = 656; - if (ysize < 32) ysize = 200; - set_screen_size(xsize, ysize); + if ((c & 0x0F) == 8) + cgacols[c][0][1] = 8 + 16; + } + /* With special cases for 00, 11, 22, ... 77 */ + cgacols[0x00][0][1] = cgacols[0x00][1][1] = 16; + for (c = 0x11; c <= 0x77; c += 0x11) { + cgacols[c][0][1] = cgacols[c][1][1] = 16 + 7; + } + for (c = 0x80; c < 0x90; c++) { + cgacols[c][0][0] = 16 + 8; + if (c & 8) + cgacols[c][0][1] = 15 + 16; + else + cgacols[c][0][1] = 7 + 16; + cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; + } + for (c = 0x90; c < 0x100; c++) { + cgacols[c][0][0] = 16 + 15; + if (c & 8) + cgacols[c][0][1] = 8 + 16; + else + cgacols[c][0][1] = 7 + 16; + if ((c & 0x0F) == 0) + cgacols[c][0][1] = 16; + cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c - 0x80][0][0]; + } + /* Also special cases for 99, AA, ..., FF */ + for (c = 0x99; c <= 0xFF; c += 0x11) { + cgacols[c][0][1] = 16 + 15; + } + /* Special cases for 08, 80 and 88 */ + cgacols[0x08][0][1] = 16 + 8; + cgacols[0x80][0][1] = 16; + cgacols[0x88][0][1] = 16 + 8; - if (video_force_resize_get()) - video_force_resize_set(0); - } - video_blit_memtoscreen_8(0, 0, xsize, ysize); + /* MDA attributes */ + for (c = 0; c < 256; c++) { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; + if (c & 8) + mdacols[c][0][1] = 15 + 16; + else + mdacols[c][0][1] = 7 + 16; + } + mdacols[0x70][0][1] = 16; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; + mdacols[0xF0][0][1] = 16; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; + mdacols[0x78][0][1] = 16 + 7; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; + mdacols[0xF8][0][1] = 16 + 7; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - frames++; - /* Fixed 1280x800 resolution */ - video_res_x = WY700_XSIZE; - video_res_y = WY700_YSIZE; - if (wy700->wy700_mode & 0x80) - mode = wy700->wy700_mode & 0xF0; - else mode = wy700->wy700_mode & 0x0F; - switch(mode) - { - case 0x00: - case 0x02: video_bpp = 0; break; - case 0x04: - case 0x90: - case 0xB0: - case 0xD0: - case 0xF0: video_bpp = 2; break; - default: video_bpp = 1; break; - } - wy700->blink++; - } - } + /* Start off in 80x25 text mode */ + wy700->cga_stat = 0xF4; + wy700->wy700_mode = 2; + wy700->enabled = 1; + memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); + return wy700; } - -void *wy700_init(const device_t *info) +void +wy700_close(void *p) { - int c; - wy700_t *wy700 = malloc(sizeof(wy700_t)); - memset(wy700, 0, sizeof(wy700_t)); - video_inform(VIDEO_FLAG_TYPE_CGA, &timing_wy700); + wy700_t *wy700 = (wy700_t *) p; - /* 128k video RAM */ - wy700->vram = malloc(0x20000); - - loadfont("roms/video/wyse700/wy700.rom", 3); - - timer_add(&wy700->timer, wy700_poll, wy700, 1); - - /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in - * high-resolution modes) */ - mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, wy700); - /* Respond to both MDA and CGA I/O ports */ - io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); - io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); - - /* Set up the emulated attributes. - * CGA is done in four groups: 00-0F, 10-7F, 80-8F, 90-FF */ - for (c = 0; c < 0x10; c++) - { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 7 + 16; - } - for (c = 0x10; c < 0x80; c++) - { - cgacols[c][0][0] = cgacols[c][1][0] = cgacols[c][1][1] = 16 + 7; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 0 + 16; - - if ((c & 0x0F) == 8) cgacols[c][0][1] = 8 + 16; - } - /* With special cases for 00, 11, 22, ... 77 */ - cgacols[0x00][0][1] = cgacols[0x00][1][1] = 16; - for (c = 0x11; c <= 0x77; c += 0x11) - { - cgacols[c][0][1] = cgacols[c][1][1] = 16 + 7; - } - for (c = 0x80; c < 0x90; c++) - { - cgacols[c][0][0] = 16 + 8; - if (c & 8) cgacols[c][0][1] = 15 + 16; - else cgacols[c][0][1] = 7 + 16; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c-0x80][0][0]; - } - for (c = 0x90; c < 0x100; c++) - { - cgacols[c][0][0] = 16 + 15; - if (c & 8) cgacols[c][0][1] = 8 + 16; - else cgacols[c][0][1] = 7 + 16; - if ((c & 0x0F) == 0) cgacols[c][0][1] = 16; - cgacols[c][1][0] = cgacols[c][1][1] = cgacols[c-0x80][0][0]; - } - /* Also special cases for 99, AA, ..., FF */ - for (c = 0x99; c <= 0xFF; c += 0x11) - { - cgacols[c][0][1] = 16 + 15; - } - /* Special cases for 08, 80 and 88 */ - cgacols[0x08][0][1] = 16 + 8; - cgacols[0x80][0][1] = 16; - cgacols[0x88][0][1] = 16 + 8; - - /* MDA attributes */ - for (c = 0; c < 256; c++) - { - mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; - if (c & 8) mdacols[c][0][1] = 15 + 16; - else mdacols[c][0][1] = 7 + 16; - } - mdacols[0x70][0][1] = 16; - mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; - mdacols[0xF0][0][1] = 16; - mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; - mdacols[0x78][0][1] = 16 + 7; - mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; - mdacols[0xF8][0][1] = 16 + 7; - mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; - mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; - mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; - mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; - mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; - -/* Start off in 80x25 text mode */ - wy700->cga_stat = 0xF4; - wy700->wy700_mode = 2; - wy700->enabled = 1; - memcpy(wy700->real_crtc, mode_80x24, sizeof(mode_80x24)); - return wy700; + free(wy700->vram); + free(wy700); } -void wy700_close(void *p) +void +wy700_speed_changed(void *p) { - wy700_t *wy700 = (wy700_t *)p; + wy700_t *wy700 = (wy700_t *) p; - free(wy700->vram); - free(wy700); -} - -void wy700_speed_changed(void *p) -{ - wy700_t *wy700 = (wy700_t *)p; - - wy700_recalctimings(wy700); + wy700_recalctimings(wy700); } const device_t wy700_device = { - .name = "Wyse 700", + .name = "Wyse 700", .internal_name = "wy700", - .flags = DEVICE_ISA, - .local = 0, - .init = wy700_init, - .close = wy700_close, - .reset = NULL, + .flags = DEVICE_ISA, + .local = 0, + .init = wy700_init, + .close = wy700_close, + .reset = NULL, { .available = NULL }, .speed_changed = wy700_speed_changed, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index f6734627b..f8787fa53 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -35,10 +35,10 @@ #include <86box/vid_xga_device.h> #include "cpu.h" -#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" +#define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" #define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin" -static void xga_ext_outb(uint16_t addr, uint8_t val, void *p); +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 @@ -46,7 +46,7 @@ xga_updatemapping(svga_t *svga) { xga_t *xga = &svga->xga; - //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c); + // pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c); if ((xga->op_mode & 7) >= 4) { if (xga->aperture_cntl == 1) { mem_mapping_disable(&svga->mapping); @@ -72,7 +72,7 @@ linear: mem_mapping_disable(&xga->linear_mapping); } xga->on = 0; - vga_on = 1; + vga_on = 1; if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test) xga->linear_endian_reverse = 1; } else { @@ -99,7 +99,7 @@ linear: } mem_mapping_disable(&xga->linear_mapping); xga->on = 0; - vga_on = 1; + vga_on = 1; } } @@ -109,10 +109,10 @@ xga_recalctimings(svga_t *svga) xga_t *xga = &svga->xga; if (xga->on) { - xga->v_total = xga->vtotal + 1; - xga->dispend = xga->vdispend + 1; - xga->v_syncstart = xga->vsyncstart + 1; - xga->split = xga->linecmp + 1; + xga->v_total = xga->vtotal + 1; + xga->dispend = xga->vdispend + 1; + xga->v_syncstart = xga->vsyncstart + 1; + xga->split = xga->linecmp + 1; xga->v_blankstart = xga->vblankstart + 1; xga->h_disp = (xga->hdisp + 1) << 3; @@ -120,7 +120,7 @@ xga_recalctimings(svga_t *svga) xga->rowoffset = (xga->hdisp + 1); xga->interlace = !!(xga->disp_cntl_1 & 0x08); - xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; + xga->rowcount = (xga->disp_cntl_2 & 0xc0) >> 6; if (xga->interlace) { xga->v_total >>= 1; @@ -135,16 +135,16 @@ xga_recalctimings(svga_t *svga) switch (xga->clk_sel_1 & 0x0c) { case 0: if (xga->clk_sel_2 & 0x80) { - svga->clock = (cpuclock * (double)(1ull << 32)) / 41539000.0; + svga->clock = (cpuclock * (double) (1ull << 32)) / 41539000.0; } else { - svga->clock = (cpuclock * (double)(1ull << 32)) / 25175000.0; + svga->clock = (cpuclock * (double) (1ull << 32)) / 25175000.0; } break; case 4: - svga->clock = (cpuclock * (double)(1ull << 32)) / 28322000.0; + svga->clock = (cpuclock * (double) (1ull << 32)) / 28322000.0; break; case 0x0c: - svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; break; } } else { @@ -215,11 +215,11 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x30: - xga->hwc_pos_x = (xga->hwc_pos_x & 0x0700) | val; + xga->hwc_pos_x = (xga->hwc_pos_x & 0x0700) | val; xga->hwcursor.x = xga->hwc_pos_x; break; case 0x31: - xga->hwc_pos_x = (xga->hwc_pos_x & 0xff) | ((val & 0x07) << 8); + xga->hwc_pos_x = (xga->hwc_pos_x & 0xff) | ((val & 0x07) << 8); xga->hwcursor.x = xga->hwc_pos_x; break; @@ -229,11 +229,11 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x33: - xga->hwc_pos_y = (xga->hwc_pos_y & 0x0700) | val; + xga->hwc_pos_y = (xga->hwc_pos_y & 0x0700) | val; xga->hwcursor.y = xga->hwc_pos_y; break; case 0x34: - xga->hwc_pos_y = (xga->hwc_pos_y & 0xff) | ((val & 0x07) << 8); + xga->hwc_pos_y = (xga->hwc_pos_y & 0xff) | ((val & 0x07) << 8); xga->hwcursor.y = xga->hwc_pos_y; break; @@ -243,7 +243,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) break; case 0x36: - xga->hwc_control = val; + xga->hwc_control = val; xga->hwcursor.ena = xga->hwc_control & 1; break; @@ -306,12 +306,12 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x60: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0x3f00) | val; - svga->dac_pos = 0; - svga->dac_addr = val & 0xff; + svga->dac_pos = 0; + svga->dac_addr = val & 0xff; break; case 0x61: xga->sprite_pal_addr_idx = (xga->sprite_pal_addr_idx & 0xff) | ((val & 0x3f) << 8); - xga->sprite_pos = xga->sprite_pal_addr_idx & 0x1ff; + xga->sprite_pos = xga->sprite_pal_addr_idx & 0x1ff; if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) { if ((xga->op_mode & 7) >= 5) xga->cursor_data_on = 1; @@ -333,17 +333,17 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) 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); + // 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: xga->sprite_pal_addr_idx_prefetch = (xga->sprite_pal_addr_idx_prefetch & 0x3f00) | val; - svga->dac_pos = 0; - svga->dac_addr = val & 0xff; + svga->dac_pos = 0; + svga->dac_addr = val & 0xff; break; case 0x63: xga->sprite_pal_addr_idx_prefetch = (xga->sprite_pal_addr_idx_prefetch & 0xff) | ((val & 0x3f) << 8); - xga->sprite_pos_prefetch = xga->sprite_pal_addr_idx_prefetch & 0x1ff; + xga->sprite_pos_prefetch = xga->sprite_pal_addr_idx_prefetch & 0x1ff; break; case 0x64: @@ -362,14 +362,14 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) svga->dac_pos++; break; case 2: - xga->pal_b = val; - index = svga->dac_addr & 0xff; + xga->pal_b = val; + index = svga->dac_addr & 0xff; svga->vgapal[index].r = svga->dac_r; svga->vgapal[index].g = svga->dac_g; svga->vgapal[index].b = xga->pal_b; - svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); - svga->dac_pos = 0; - svga->dac_addr = (svga->dac_addr + 1) & 0xff; + svga->pallook[index] = makecol32(svga->vgapal[index].r, svga->vgapal[index].g, svga->vgapal[index].b); + svga->dac_pos = 0; + svga->dac_addr = (svga->dac_addr + 1) & 0xff; break; } break; @@ -390,7 +390,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) case 0x6a: xga->sprite_data[xga->sprite_pos] = val; - xga->sprite_pos = (xga->sprite_pos + 1) & 0x3ff; + xga->sprite_pos = (xga->sprite_pos + 1) & 0x3ff; break; case 0x70: @@ -403,10 +403,10 @@ 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 *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + 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); + // pclog("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); switch (addr & 0x0f) { case 0: xga->op_mode = val; @@ -421,17 +421,17 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p) xga->aperture_cntl = 0; break; case 6: - vga_on = 0; + vga_on = 0; xga->on = 1; break; case 8: xga->ap_idx = val; - //pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f); + // pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f); if ((xga->op_mode & 7) < 4) { xga->write_bank = xga->read_bank = 0; } else { xga->write_bank = (xga->ap_idx & 0x3f) << 16; - xga->read_bank = xga->write_bank; + xga->read_bank = xga->write_bank; } break; case 9: @@ -454,8 +454,8 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *p) static uint8_t xga_ext_inb(uint16_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; uint8_t ret, index; switch (addr & 0x0f) { @@ -629,9 +629,9 @@ xga_ext_inb(uint16_t addr, void *p) ret = svga->vgapal[index].g; break; case 2: - svga->dac_pos = 0; + svga->dac_pos = 0; svga->dac_addr = (svga->dac_addr + 1) & 0xff; - ret = svga->vgapal[index].b; + ret = svga->vgapal[index].b; break; } break; @@ -651,8 +651,8 @@ xga_ext_inb(uint16_t addr, void *p) break; case 0x6a: - //pclog("Sprite POS Read = %d, addr idx = %04x\n", xga->sprite_pos, xga->sprite_pal_addr_idx_prefetch); - ret = xga->sprite_data[xga->sprite_pos_prefetch]; + // pclog("Sprite POS Read = %d, addr idx = %04x\n", xga->sprite_pos, xga->sprite_pal_addr_idx_prefetch); + ret = xga->sprite_data[xga->sprite_pos_prefetch]; xga->sprite_pos_prefetch = (xga->sprite_pos_prefetch + 1) & 0x3ff; break; @@ -667,70 +667,114 @@ xga_ext_inb(uint16_t addr, void *p) break; } - //pclog("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret); + // pclog("[%04X:%08X]: EXT INB = %02x, ret = %02x\n", CS, cpu_state.pc, addr, ret); return ret; } - #define READ(addr, dat) \ dat = xga->vram[(addr) & (xga->vram_mask)]; -#define WRITE(addr, dat) \ - xga->vram[((addr)) & (xga->vram_mask)] = dat; \ +#define WRITE(addr, dat) \ + xga->vram[((addr)) & (xga->vram_mask)] = dat; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; #define READW(addr, dat) \ - dat = *(uint16_t *)&xga->vram[(addr) & (xga->vram_mask)]; + dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)]; -#define READW_REVERSE(addr, dat) \ +#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 WRITEW(addr, dat) \ - *(uint16_t *)&xga->vram[((addr)) & (xga->vram_mask)] = dat; \ +#define WRITEW(addr, dat) \ + *(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = 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; \ +#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] = changeframecount; -#define ROP(mix, d, s) { \ - switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \ - case 0x00: d = 0; break; \ - case 0x01: d = s & d; break; \ - case 0x02: d = s & ~d; break; \ - case 0x03: d = s; break; \ - case 0x04: d = ~s & d; break; \ - case 0x05: d = d; break; \ - case 0x06: d = s ^ d; break; \ - case 0x07: d = s | d; break; \ - case 0x08: d = ~s & ~d; break; \ - case 0x09: d = s ^ ~d; break; \ - case 0x0a: d = ~d; break; \ - case 0x0b: d = s | ~d; break; \ - case 0x0c: d = ~s; break; \ - case 0x0d: d = ~s | d; break; \ - case 0x0e: d = ~s | ~d; break; \ - case 0x0f: d = ~0; break; \ - case 0x10: d = MAX(s, d); break; \ - case 0x11: d = MIN(s, d); break; \ - case 0x12: d = MIN(0xff, s + d); break; \ - case 0x13: d = MAX(0, d - s); break; \ - case 0x14: d = MAX(0, s - d); break; \ - case 0x15: d = (s + d) >> 1; break; \ - } \ - } +#define ROP(mix, d, s) \ + { \ + switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \ + case 0x00: \ + d = 0; \ + break; \ + case 0x01: \ + d = s & d; \ + break; \ + case 0x02: \ + d = s & ~d; \ + break; \ + case 0x03: \ + d = s; \ + break; \ + case 0x04: \ + d = ~s & d; \ + break; \ + case 0x05: \ + d = d; \ + break; \ + case 0x06: \ + d = s ^ d; \ + break; \ + case 0x07: \ + d = s | d; \ + break; \ + case 0x08: \ + d = ~s & ~d; \ + break; \ + case 0x09: \ + d = s ^ ~d; \ + break; \ + case 0x0a: \ + d = ~d; \ + break; \ + case 0x0b: \ + d = s | ~d; \ + break; \ + case 0x0c: \ + d = ~s; \ + break; \ + case 0x0d: \ + d = ~s | d; \ + break; \ + case 0x0e: \ + d = ~s | ~d; \ + break; \ + case 0x0f: \ + d = ~0; \ + break; \ + case 0x10: \ + d = MAX(s, d); \ + break; \ + case 0x11: \ + d = MIN(s, d); \ + break; \ + case 0x12: \ + d = MIN(0xff, s + d); \ + break; \ + case 0x13: \ + d = MAX(0, d - s); \ + break; \ + case 0x14: \ + d = MAX(0, s - d); \ + break; \ + case 0x15: \ + d = (s + d) >> 1; \ + break; \ + } \ + } static uint32_t xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) { - xga_t *xga = &svga->xga; + xga_t *xga = &svga->xga; uint32_t addr = base; - int bits; + int bits; uint32_t byte; - uint8_t px; - int skip = 0; + uint8_t px; + int skip = 0; if (xga->base_addr_1mb) { if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) @@ -759,16 +803,15 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b 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_t *xga = &svga->xga; + xga_t *xga = &svga->xga; uint32_t addr = base; - int bits; + int bits; uint32_t byte; - uint8_t px; - int skip = 0; + uint8_t px; + int skip = 0; if (xga->base_addr_1mb) { if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) @@ -831,10 +874,10 @@ 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) { - xga_t *xga = &svga->xga; + xga_t *xga = &svga->xga; uint32_t addr = base; - uint8_t byte, mask; - int skip = 0; + uint8_t byte, mask; + int skip = 0; if (xga->base_addr_1mb) { if (addr < xga->base_addr_1mb || (addr > (xga->base_addr_1mb + 0xfffff))) @@ -848,11 +891,11 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui case 0: /*1-bit*/ addr += (y * (width) >> 3); addr += (x >> 3); - if (!skip) { + if (!skip) { READ(addr, byte); - } else { + } 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)); @@ -905,15 +948,15 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui static void xga_short_stroke(svga_t *svga, uint8_t ssv) { - xga_t *xga = &svga->xga; + xga_t *xga = &svga->xga; uint32_t src_dat, dest_dat, old_dest_dat; - uint32_t color_cmp = xga->accel.color_cmp; + uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; - uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; - uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; - int y = ssv & 0x0f; - int x = 0; - int dx, dy, dirx = 0, diry = 0; + uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; + uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; + int y = ssv & 0x0f; + int x = 0; + int dx, dy, dirx = 0, diry = 0; dx = xga->accel.dst_map_x & 0x1fff; if (xga->accel.dst_map_x & 0x1800) @@ -961,18 +1004,11 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) if (xga->accel.pat_src == 8) { 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; + 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); - 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))) { + 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); @@ -989,16 +1025,10 @@ 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; + 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)) || - ((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))) { + 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); @@ -1031,37 +1061,40 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) xga->accel.dst_map_y = dy; } -#define SWAP(a,b) tmpswap = a; a = b; b = tmpswap; +#define SWAP(a, b) \ + tmpswap = a; \ + a = b; \ + b = tmpswap; static void xga_line_draw_write(svga_t *svga) { - xga_t *xga = &svga->xga; + xga_t *xga = &svga->xga; uint32_t src_dat, dest_dat, old_dest_dat; - uint32_t color_cmp = xga->accel.color_cmp; + uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; - uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; - uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; - int dminor, destxtmp, dmajor, err, tmpswap; - int steep = 1; - int xdir, ydir; - int y = xga->accel.blt_width; - int x = 0; - int dx, dy; + uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; + uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; + int dminor, destxtmp, dmajor, err, tmpswap; + int steep = 1; + int xdir, ydir; + int y = xga->accel.blt_width; + int x = 0; + int dx, dy; - dminor = ((int16_t)xga->accel.bres_k1); - if (xga->accel.bres_k1 & 0x2000) + dminor = ((int16_t) xga->accel.bres_k1); + if (xga->accel.bres_k1 & 0x2000) dminor |= ~0x1fff; - dminor >>= 1; + dminor >>= 1; - destxtmp = ((int16_t)xga->accel.bres_k2); - if (xga->accel.bres_k2 & 0x2000) + destxtmp = ((int16_t) xga->accel.bres_k2); + if (xga->accel.bres_k2 & 0x2000) destxtmp |= ~0x1fff; dmajor = -(destxtmp - (dminor << 1)) >> 1; - err = ((int16_t)xga->accel.bres_err_term); - if (xga->accel.bres_err_term & 0x2000) + err = ((int16_t) xga->accel.bres_err_term); + if (xga->accel.bres_err_term & 0x2000) destxtmp |= ~0x1fff; if (xga->accel.octant & 0x02) { @@ -1085,27 +1118,20 @@ xga_line_draw_write(svga_t *svga) dy |= ~0x17ff; if (xga->accel.octant & 0x01) { - steep = 0; - SWAP(dx, dy); - SWAP(xdir, ydir); + steep = 0; + SWAP(dx, dy); + SWAP(xdir, ydir); } if (xga->accel.pat_src == 8) { while (y >= 0) { 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; + 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); - 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))) { + 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); @@ -1118,18 +1144,11 @@ 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; + 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); - 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))) { + 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); @@ -1144,16 +1163,10 @@ 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; + 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)) || - ((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))) { + 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); @@ -1165,16 +1178,10 @@ 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; + 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)) || - ((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))) { + 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); @@ -1214,7 +1221,6 @@ xga_line_draw_write(svga_t *svga) } } - static int16_t xga_dst_wrap(int16_t addr) { @@ -1225,20 +1231,20 @@ xga_dst_wrap(int16_t addr) static void xga_bitblt(svga_t *svga) { - xga_t *xga = &svga->xga; + xga_t *xga = &svga->xga; uint32_t src_dat, dest_dat, old_dest_dat; - uint32_t color_cmp = xga->accel.color_cmp; + uint32_t color_cmp = xga->accel.color_cmp; uint32_t plane_mask = xga->accel.plane_mask; - uint32_t patbase = xga->accel.px_map_base[xga->accel.pat_src]; - uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; - uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; - uint32_t patwidth = xga->accel.px_map_width[xga->accel.pat_src]; - uint32_t dstwidth = xga->accel.px_map_width[xga->accel.dst_map]; - 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]; - int mix = 0; - int xdir, ydir; + uint32_t patbase = xga->accel.px_map_base[xga->accel.pat_src]; + uint32_t dstbase = xga->accel.px_map_base[xga->accel.dst_map]; + uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map]; + uint32_t patwidth = xga->accel.px_map_width[xga->accel.pat_src]; + uint32_t dstwidth = xga->accel.px_map_width[xga->accel.dst_map]; + 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]; + int mix = 0; + int xdir, ydir; if (xga->accel.octant & 0x02) { ydir = -1; @@ -1277,22 +1283,15 @@ 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]); + // 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; + 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); - 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))) { + 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); @@ -1300,16 +1299,10 @@ 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; + 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)) || - ((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))) { + 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); @@ -1368,14 +1361,13 @@ xga_bitblt(svga_t *svga) } } - //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]); + // 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) { mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, xga->accel.pat_src, patbase, patwidth + 1); 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 ((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 @@ -1383,13 +1375,7 @@ xga_bitblt(svga_t *svga) 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)) || - ((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))) { + 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); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); @@ -1404,13 +1390,7 @@ xga_bitblt(svga_t *svga) 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)) || - ((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))) { + 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); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); @@ -1418,7 +1398,6 @@ xga_bitblt(svga_t *svga) } } - xga->accel.sx += xdir; if (xga->accel.pattern) xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth); @@ -1487,7 +1466,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) case 0x18: if (len == 4) { - xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xffff; + xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xffff; xga->accel.px_map_height[xga->accel.px_map_idx] = (val >> 16) & 0xffff; } else if (len == 2) { xga->accel.px_map_width[xga->accel.px_map_idx] = val & 0xffff; @@ -1564,13 +1543,13 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) case 0x2c: if (len == 4) { - xga->accel.short_stroke = val; + xga->accel.short_stroke = val; xga->accel.short_stroke_vector1 = xga->accel.short_stroke & 0xff; xga->accel.short_stroke_vector2 = (xga->accel.short_stroke >> 8) & 0xff; xga->accel.short_stroke_vector3 = (xga->accel.short_stroke >> 16) & 0xff; xga->accel.short_stroke_vector4 = (xga->accel.short_stroke >> 24) & 0xff; - //pclog("1Vector = %02x, 2Vector = %02x, 3Vector = %02x, 4Vector = %02x\n", xga->accel.short_stroke_vector1, xga->accel.short_stroke_vector2, xga->accel.short_stroke_vector3, xga->accel.short_stroke_vector4); + // pclog("1Vector = %02x, 2Vector = %02x, 3Vector = %02x, 4Vector = %02x\n", xga->accel.short_stroke_vector1, xga->accel.short_stroke_vector2, xga->accel.short_stroke_vector3, xga->accel.short_stroke_vector4); xga_short_stroke(svga, xga->accel.short_stroke_vector1); xga_short_stroke(svga, xga->accel.short_stroke_vector2); xga_short_stroke(svga, xga->accel.short_stroke_vector3); @@ -1600,7 +1579,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) xga->accel.frgd_mix = val & 0xff; if (len == 4) { xga->accel.bkgd_mix = (val >> 8) & 0xff; - xga->accel.cc_cond = (val >> 16) & 0x07; + xga->accel.cc_cond = (val >> 16) & 0x07; } else if (len == 2) { xga->accel.bkgd_mix = (val >> 8) & 0xff; } @@ -1708,7 +1687,7 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) case 0x60: if (len == 4) { - xga->accel.blt_width = val & 0xffff; + xga->accel.blt_width = val & 0xffff; xga->accel.blt_height = (val >> 16) & 0xffff; } else if (len == 2) { xga->accel.blt_width = val; @@ -1835,30 +1814,30 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (len == 4) { xga->accel.command = val; exec_command: - xga->accel.octant = xga->accel.command & 0x07; + 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); + 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); - //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, 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], - // xga->accel.px_map_height[xga->accel.src_map], - // xga->accel.pat_map_x, xga->accel.pat_map_y, - // xga->accel.dst_map_x, xga->accel.dst_map_y, - // 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, xga->accel.plane_mask); - // //pclog("\n"); - //} + // 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, 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], + // xga->accel.px_map_height[xga->accel.src_map], + // xga->accel.pat_map_x, xga->accel.pat_map_y, + // xga->accel.dst_map_x, xga->accel.dst_map_y, + // 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, xga->accel.plane_mask); + // //pclog("\n"); + // } 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*/ break; @@ -1869,7 +1848,7 @@ exec_command: xga_bitblt(svga); break; case 9: /*Inverting BitBLT*/ - //pclog("Inverting BitBLT\n"); + // pclog("Inverting BitBLT\n"); break; } } else if (len == 2) { @@ -1901,31 +1880,31 @@ exec_command: static void xga_memio_writeb(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; xga_mem_write(addr, val, xga, svga, 1); - //pclog("Write MEMIOB = %04x, val = %02x\n", addr & 0x7f, val); + // pclog("Write MEMIOB = %04x, val = %02x\n", addr & 0x7f, val); } static void xga_memio_writew(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; xga_mem_write(addr, val, xga, svga, 2); - //pclog("Write MEMIOW = %04x, val = %04x\n", addr & 0x7f, val); + // pclog("Write MEMIOW = %04x, val = %04x\n", addr & 0x7f, val); } static void xga_memio_writel(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; xga_mem_write(addr, val, xga, svga, 4); - //pclog("Write MEMIOL = %04x, val = %08x\n", addr & 0x7f, val); + // pclog("Write MEMIOL = %04x, val = %08x\n", addr & 0x7f, val); } static uint8_t @@ -2002,35 +1981,35 @@ xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga) static uint8_t xga_memio_readb(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; uint8_t temp; temp = xga_mem_read(addr, xga, svga); - //pclog("[%04X:%08X]: Read MEMIOB = %04x, temp = %02x\n", CS, cpu_state.pc, addr, temp); + // pclog("[%04X:%08X]: Read MEMIOB = %04x, temp = %02x\n", CS, cpu_state.pc, addr, temp); return temp; } static uint16_t xga_memio_readw(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; uint16_t temp; temp = xga_mem_read(addr, xga, svga); temp |= (xga_mem_read(addr + 1, xga, svga) << 8); - //pclog("[%04X:%08X]: Read MEMIOW = %04x, temp = %04x\n", CS, cpu_state.pc, addr, temp); + // pclog("[%04X:%08X]: Read MEMIOW = %04x, temp = %04x\n", CS, cpu_state.pc, addr, temp); return temp; } static uint32_t xga_memio_readl(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; uint32_t temp; temp = xga_mem_read(addr, xga, svga); @@ -2038,59 +2017,59 @@ xga_memio_readl(uint32_t addr, void *p) temp |= (xga_mem_read(addr + 2, xga, svga) << 16); temp |= (xga_mem_read(addr + 3, xga, svga) << 24); - //pclog("Read MEMIOL = %04x, temp = %08x\n", addr, temp); + // pclog("Read MEMIOL = %04x, temp = %08x\n", addr, temp); return temp; } static void xga_hwcursor_draw(svga_t *svga, int displine) { - xga_t *xga = &svga->xga; - uint8_t dat = 0; - int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; - int x, x_pos, y_pos; - int comb = 0; + xga_t *xga = &svga->xga; + uint8_t dat = 0; + int offset = xga->hwcursor_latch.x - xga->hwcursor_latch.xoff; + int x, x_pos, y_pos; + int comb = 0; uint32_t *p; - int idx = (xga->cursor_data_on) ? 32 : 0; + int idx = (xga->cursor_data_on) ? 32 : 0; if (xga->interlace && xga->hwcursor_oddeven) - xga->hwcursor_latch.addr += 16; + xga->hwcursor_latch.addr += 16; y_pos = displine; x_pos = offset + svga->x_add; - p = buffer32->line[y_pos]; + p = buffer32->line[y_pos]; for (x = 0; x < xga->hwcursor_latch.cur_xsize; x++) { - if (x >= idx) { - if (!(x & 0x03)) - dat = xga->sprite_data[xga->hwcursor_latch.addr & 0x3ff]; + if (x >= idx) { + if (!(x & 0x03)) + dat = xga->sprite_data[xga->hwcursor_latch.addr & 0x3ff]; - comb = (dat >> ((x & 0x03) << 1)) & 0x03; + comb = (dat >> ((x & 0x03) << 1)) & 0x03; - x_pos = offset + svga->x_add + x; + x_pos = offset + svga->x_add + x; - switch (comb) { - case 0x00: - /* Cursor Color 1 */ - p[x_pos] = xga->hwc_color0; - break; - case 0x01: - /* Cursor Color 2 */ - p[x_pos] = xga->hwc_color1; - break; - case 0x03: - /* Complement */ - p[x_pos] ^= 0xffffff; - break; + switch (comb) { + case 0x00: + /* Cursor Color 1 */ + p[x_pos] = xga->hwc_color0; + break; + case 0x01: + /* Cursor Color 2 */ + p[x_pos] = xga->hwc_color1; + break; + case 0x03: + /* Complement */ + p[x_pos] ^= 0xffffff; + break; + } } - } - if ((x & 0x03) == 0x03) - xga->hwcursor_latch.addr++; + if ((x & 0x03) == 0x03) + xga->hwcursor_latch.addr++; } if (xga->interlace && !xga->hwcursor_oddeven) - xga->hwcursor_latch.addr += 16; + xga->hwcursor_latch.addr += 16; } static void @@ -2099,13 +2078,13 @@ xga_render_overscan_left(xga_t *xga, svga_t *svga) int i; if ((xga->displine + svga->y_add) < 0) - return; + return; if (svga->scrblank || (xga->h_disp == 0)) - return; + return; for (i = 0; i < svga->x_add; i++) - buffer32->line[xga->displine + svga->y_add][i] = svga->overscan_color; + buffer32->line[xga->displine + svga->y_add][i] = svga->overscan_color; } static void @@ -2114,62 +2093,62 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga) int i, right; if ((xga->displine + svga->y_add) < 0) - return; + return; if (svga->scrblank || (xga->h_disp == 0)) - return; + return; right = (overscan_x >> 1); for (i = 0; i < right; i++) - buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp + i] = svga->overscan_color; + buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp + i] = svga->overscan_color; } static void xga_render_8bpp(xga_t *xga, svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; + uint32_t dat; if ((xga->displine + svga->y_add) < 0) - return; + return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; + p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; - if (xga->firstline_draw == 2000) - xga->firstline_draw = xga->displine; - xga->lastline_draw = xga->displine; + if (xga->firstline_draw == 2000) + xga->firstline_draw = xga->displine; + xga->lastline_draw = xga->displine; - for (x = 0; x <= xga->h_disp; x += 8) { - dat = *(uint32_t *)(&xga->vram[xga->ma & xga->vram_mask]); - p[0] = svga->pallook[dat & 0xff]; - p[1] = svga->pallook[(dat >> 8) & 0xff]; - p[2] = svga->pallook[(dat >> 16) & 0xff]; - p[3] = svga->pallook[(dat >> 24) & 0xff]; + for (x = 0; x <= xga->h_disp; x += 8) { + dat = *(uint32_t *) (&xga->vram[xga->ma & xga->vram_mask]); + p[0] = svga->pallook[dat & 0xff]; + p[1] = svga->pallook[(dat >> 8) & 0xff]; + p[2] = svga->pallook[(dat >> 16) & 0xff]; + p[3] = svga->pallook[(dat >> 24) & 0xff]; - dat = *(uint32_t *)(&xga->vram[(xga->ma + 4) & xga->vram_mask]); - p[4] = svga->pallook[dat & 0xff]; - p[5] = svga->pallook[(dat >> 8) & 0xff]; - p[6] = svga->pallook[(dat >> 16) & 0xff]; - p[7] = svga->pallook[(dat >> 24) & 0xff]; + dat = *(uint32_t *) (&xga->vram[(xga->ma + 4) & xga->vram_mask]); + p[4] = svga->pallook[dat & 0xff]; + p[5] = svga->pallook[(dat >> 8) & 0xff]; + p[6] = svga->pallook[(dat >> 16) & 0xff]; + p[7] = svga->pallook[(dat >> 24) & 0xff]; - xga->ma += 8; - p += 8; - } - xga->ma &= xga->vram_mask; + xga->ma += 8; + p += 8; + } + xga->ma &= xga->vram_mask; } } static void xga_render_16bpp(xga_t *xga, svga_t *svga) { - int x; + int x; uint32_t *p; - uint32_t dat; + uint32_t dat; if ((xga->displine + svga->y_add) < 0) - return; + return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; @@ -2179,19 +2158,19 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) xga->lastline_draw = xga->displine; for (x = 0; x <= (xga->h_disp); x += 8) { - dat = *(uint32_t *)(&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); - p[x] = video_16to32[dat & 0xffff]; + dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1)) & xga->vram_mask]); + p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&xga->vram[(xga->ma + (x << 1) + 4) & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1) + 4) & xga->vram_mask]); p[x + 2] = video_16to32[dat & 0xffff]; p[x + 3] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&xga->vram[(xga->ma + (x << 1) + 8) & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1) + 8) & xga->vram_mask]); p[x + 4] = video_16to32[dat & 0xffff]; p[x + 5] = video_16to32[dat >> 16]; - dat = *(uint32_t *)(&xga->vram[(xga->ma + (x << 1) + 12) & xga->vram_mask]); + dat = *(uint32_t *) (&xga->vram[(xga->ma + (x << 1) + 12) & xga->vram_mask]); p[x + 6] = video_16to32[dat & 0xffff]; p[x + 7] = video_16to32[dat >> 16]; } @@ -2203,8 +2182,8 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) static void xga_write(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (!xga->on) { svga_write(addr, val, svga); @@ -2220,20 +2199,20 @@ xga_write(uint32_t addr, uint8_t val, void *p) cycles -= video_timing_write_b; xga->changedvram[(addr & xga->vram_mask) >> 12] = 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 *p) { - //pclog("[%04X:%08X]: WriteB\n", CS, cpu_state.pc); + // pclog("[%04X:%08X]: WriteB\n", CS, cpu_state.pc); xga_write(addr, val, p); } static void xga_writew(uint32_t addr, uint16_t val, void *p) { - //pclog("[%04X:%08X]: WriteW\n", CS, cpu_state.pc); + // pclog("[%04X:%08X]: WriteW\n", CS, cpu_state.pc); xga_write(addr, val, p); xga_write(addr + 1, val >> 8, p); } @@ -2241,7 +2220,7 @@ xga_writew(uint32_t addr, uint16_t val, void *p) static void xga_writel(uint32_t addr, uint32_t val, void *p) { - //pclog("[%04X:%08X]: WriteL\n", CS, cpu_state.pc); + // pclog("[%04X:%08X]: WriteL\n", CS, cpu_state.pc); xga_write(addr, val, p); xga_write(addr + 1, val >> 8, p); xga_write(addr + 2, val >> 16, p); @@ -2251,8 +2230,8 @@ xga_writel(uint32_t addr, uint32_t val, void *p) static void xga_write_linear(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (!xga->on) { svga_write_linear(addr, val, svga); @@ -2267,14 +2246,14 @@ xga_write_linear(uint32_t addr, uint8_t val, void *p) cycles -= video_timing_write_b; xga->changedvram[(addr & xga->vram_mask) >> 12] = changeframecount; - xga->vram[addr & xga->vram_mask] = val; + xga->vram[addr & xga->vram_mask] = val; } static void xga_writew_linear(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (!xga->on) { svga_writew_linear(addr, val, svga); @@ -2309,8 +2288,8 @@ xga_writew_linear(uint32_t addr, uint16_t val, void *p) static void xga_writel_linear(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (!xga->on) { svga_writel_linear(addr, val, svga); @@ -2326,8 +2305,8 @@ xga_writel_linear(uint32_t addr, uint32_t val, void *p) static uint8_t xga_read(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (!xga->on) return svga_read(addr, svga); @@ -2380,8 +2359,8 @@ xga_readl(uint32_t addr, void *p) static uint8_t xga_read_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (!xga->on) return svga_read_linear(addr, svga); @@ -2399,8 +2378,8 @@ xga_read_linear(uint32_t addr, void *p) static uint16_t xga_readw_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; uint16_t ret; if (!xga->on) @@ -2427,14 +2406,13 @@ xga_readw_linear(uint32_t addr, void *p) static uint32_t xga_readl_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (!xga->on) return svga_readl_linear(addr, svga); - return xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8) | - (xga_read_linear(addr + 2, p) << 16) | (xga_read_linear(addr + 3, p) << 24); + return xga_read_linear(addr, p) | (xga_read_linear(addr + 1, p) << 8) | (xga_read_linear(addr + 2, p) << 16) | (xga_read_linear(addr + 3, p) << 24); } static void @@ -2451,16 +2429,16 @@ xga_do_render(svga_t *svga) break; } - svga->x_add = (overscan_x >> 1); - xga_render_overscan_left(xga, svga); - xga_render_overscan_right(xga, svga); - svga->x_add = (overscan_x >> 1); + svga->x_add = (overscan_x >> 1); + xga_render_overscan_left(xga, svga); + xga_render_overscan_right(xga, svga); + svga->x_add = (overscan_x >> 1); if (xga->hwcursor_on) { - xga_hwcursor_draw(svga, xga->displine + svga->y_add); - xga->hwcursor_on--; - if (xga->hwcursor_on && xga->interlace) - xga->hwcursor_on--; + xga_hwcursor_draw(svga, xga->displine + svga->y_add); + xga->hwcursor_on--; + if (xga->hwcursor_on && xga->interlace) + xga->hwcursor_on--; } } @@ -2468,160 +2446,158 @@ void xga_poll(xga_t *xga, svga_t *svga) { uint32_t x; - int wx, wy; + int wx, wy; if (!xga->linepos) { - if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 32 : 0); - xga->hwcursor_oddeven = 0; - } - - if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && - xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 33 : 1); - xga->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, svga->dispofftime); - xga->linepos = 1; - - if (xga->dispon) { - xga->h_disp_on = 1; - - xga->ma &= xga->vram_mask; - - if (xga->firstline == 2000) { - xga->firstline = xga->displine; - video_wait_for_buffer(); + if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 32 : 0); + xga->hwcursor_oddeven = 0; } - if (xga->hwcursor_on) { - xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = - xga->interlace ? 3 : 2; + if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - (xga->cursor_data_on ? 33 : 1); + xga->hwcursor_oddeven = 1; } - xga_do_render(svga); + timer_advance_u64(&svga->timer, svga->dispofftime); + xga->linepos = 1; - if (xga->lastline < xga->displine) - xga->lastline = xga->displine; - } + if (xga->dispon) { + xga->h_disp_on = 1; - xga->displine++; - if (xga->interlace) - xga->displine++; - if (xga->displine > 1500) - xga->displine = 0; - } else { - timer_advance_u64(&svga->timer, svga->dispontime); - xga->h_disp_on = 0; + xga->ma &= xga->vram_mask; - xga->linepos = 0; - if (xga->dispon) { - if (xga->sc == xga->rowcount) { - xga->sc = 0; - - if ((xga->disp_cntl_2 & 7) == 4) { - xga->maback += (xga->rowoffset << 4); - if (xga->interlace) - xga->maback += (xga->rowoffset << 4); - } else { - xga->maback += (xga->rowoffset << 3); - if (xga->interlace) - xga->maback += (xga->rowoffset << 3); + if (xga->firstline == 2000) { + xga->firstline = xga->displine; + video_wait_for_buffer(); } - xga->maback &= xga->vram_mask; - xga->ma = xga->maback; - } else { - xga->sc++; - xga->sc &= 0x1f; - xga->ma = xga->maback; + + if (xga->hwcursor_on) { + xga->changedvram[xga->ma >> 12] = xga->changedvram[(xga->ma >> 12) + 1] = xga->interlace ? 3 : 2; + } + + xga_do_render(svga); + + if (xga->lastline < xga->displine) + xga->lastline = xga->displine; } - } - xga->vc++; - xga->vc &= 2047; + xga->displine++; + if (xga->interlace) + xga->displine++; + if (xga->displine > 1500) + xga->displine = 0; + } else { + timer_advance_u64(&svga->timer, svga->dispontime); + xga->h_disp_on = 0; - if (xga->vc == xga->split) { - if (xga->interlace && xga->oddeven) - xga->ma = xga->maback = (xga->rowoffset << 1); - else - xga->ma = xga->maback = 0; - xga->ma = (xga->ma << 2); - xga->maback = (xga->maback << 2); + xga->linepos = 0; + if (xga->dispon) { + if (xga->sc == xga->rowcount) { + xga->sc = 0; - xga->sc = 0; - } - if (xga->vc == xga->dispend) { - xga->dispon = 0; - - for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { - if (xga->changedvram[x]) - xga->changedvram[x]--; + if ((xga->disp_cntl_2 & 7) == 4) { + xga->maback += (xga->rowoffset << 4); + if (xga->interlace) + xga->maback += (xga->rowoffset << 4); + } else { + xga->maback += (xga->rowoffset << 3); + if (xga->interlace) + xga->maback += (xga->rowoffset << 3); + } + xga->maback &= xga->vram_mask; + xga->ma = xga->maback; + } else { + xga->sc++; + xga->sc &= 0x1f; + xga->ma = xga->maback; + } } - if (svga->fullchange) - svga->fullchange--; - } - if (xga->vc == xga->v_syncstart) { - xga->dispon = 0; - x = xga->h_disp; - if (xga->interlace && !xga->oddeven) - xga->lastline++; - if (xga->interlace && xga->oddeven) - xga->firstline--; + xga->vc++; + xga->vc &= 2047; - wx = x; + if (xga->vc == xga->split) { + if (xga->interlace && xga->oddeven) + xga->ma = xga->maback = (xga->rowoffset << 1); + else + xga->ma = xga->maback = 0; + xga->ma = (xga->ma << 2); + xga->maback = (xga->maback << 2); - wy = xga->lastline - xga->firstline; - svga_doblit(wx, wy, svga); + xga->sc = 0; + } + if (xga->vc == xga->dispend) { + xga->dispon = 0; - xga->firstline = 2000; - xga->lastline = 0; + for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { + if (xga->changedvram[x]) + xga->changedvram[x]--; + } + if (svga->fullchange) + svga->fullchange--; + } + if (xga->vc == xga->v_syncstart) { + xga->dispon = 0; + x = xga->h_disp; - xga->firstline_draw = 2000; - xga->lastline_draw = 0; + if (xga->interlace && !xga->oddeven) + xga->lastline++; + if (xga->interlace && xga->oddeven) + xga->firstline--; - xga->oddeven ^= 1; + wx = x; - changeframecount = xga->interlace ? 3 : 2; + wy = xga->lastline - xga->firstline; + svga_doblit(wx, wy, svga); - if (xga->interlace && xga->oddeven) - xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1); - else - xga->ma = xga->maback = xga->ma_latch; + xga->firstline = 2000; + xga->lastline = 0; - xga->ma = (xga->ma << 2); - xga->maback = (xga->maback << 2); - } - if (xga->vc == xga->v_total) { - xga->vc = 0; - xga->sc = 0; - xga->dispon = 1; - xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; + xga->firstline_draw = 2000; + xga->lastline_draw = 0; - svga->x_add = (overscan_x >> 1); + xga->oddeven ^= 1; - xga->hwcursor_on = 0; - xga->hwcursor_latch = xga->hwcursor; - } + changeframecount = xga->interlace ? 3 : 2; + + if (xga->interlace && xga->oddeven) + xga->ma = xga->maback = xga->ma_latch + (xga->rowoffset << 1); + else + xga->ma = xga->maback = xga->ma_latch; + + xga->ma = (xga->ma << 2); + xga->maback = (xga->maback << 2); + } + if (xga->vc == xga->v_total) { + xga->vc = 0; + xga->sc = 0; + xga->dispon = 1; + xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; + + svga->x_add = (overscan_x >> 1); + + xga->hwcursor_on = 0; + xga->hwcursor_latch = xga->hwcursor; + } } } static uint8_t xga_mca_read(int port, void *priv) { - svga_t *svga = (svga_t *)priv; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = &svga->xga; - //pclog("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]); + // pclog("[%04X:%08X]: POS Read Port = %x, val = %02x\n", CS, cpu_state.pc, port & 7, xga->pos_regs[port & 7]); return (xga->pos_regs[port & 7]); } static void xga_mca_write(int port, uint8_t val, void *priv) { - svga_t *svga = (svga_t *)priv; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = &svga->xga; /* MCA does not write registers below 0x0100. */ if (port < 0x0102) @@ -2631,19 +2607,19 @@ xga_mca_write(int port, uint8_t val, void *priv) mem_mapping_disable(&xga->bios_rom.mapping); mem_mapping_disable(&xga->memio_mapping); xga->on = 0; - vga_on = 1; + vga_on = 1; /* Save the MCA register value. */ xga->pos_regs[port & 7] = val; if (!(xga->pos_regs[4] & 1)) /*MCA 4MB addressing on systems with more than 16MB of memory*/ xga->pos_regs[4] |= 1; - //pclog("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, xga->instance, xga->rom_addr); + // pclog("[%04X:%08X]: POS Write Port = %x, val = %02x, linear base = %08x, instance = %d, rom addr = %05x\n", CS, cpu_state.pc, port & 7, val, xga->linear_base, xga->instance, xga->rom_addr); if (xga->pos_regs[2] & 1) { - xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; + xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; xga->base_addr_1mb = (xga->pos_regs[5] & 0x0f) << 20; - xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); + xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); mem_mapping_set_addr(&xga->bios_rom.mapping, xga->rom_addr, 0x2000); @@ -2654,8 +2630,8 @@ xga_mca_write(int port, uint8_t val, void *priv) static uint8_t xga_mca_feedb(void *priv) { - svga_t *svga = (svga_t *)priv; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) priv; + xga_t *xga = &svga->xga; return xga->pos_regs[2] & 1; } @@ -2663,7 +2639,7 @@ xga_mca_feedb(void *priv) static void xga_mca_reset(void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; xga_mca_write(0x102, 0, svga); } @@ -2671,47 +2647,48 @@ xga_mca_reset(void *p) static uint8_t xga_pos_in(uint16_t addr, void *priv) { - svga_t *svga = (svga_t *)priv; + svga_t *svga = (svga_t *) priv; return (xga_mca_read(addr, svga)); } static void -*xga_init(const device_t *info) + * + xga_init(const device_t *info) { - svga_t *svga = svga_get_pri(); - xga_t *xga = &svga->xga; - FILE *f; + svga_t *svga = svga_get_pri(); + xga_t *xga = &svga->xga; + FILE *f; uint32_t temp; uint32_t initial_bios_addr = device_get_config_hex20("init_bios_addr"); - uint8_t *rom = NULL; + uint8_t *rom = NULL; xga->type = device_get_config_int("type"); - xga->bus = info->flags; + xga->bus = info->flags; - xga->vram_size = (1024 << 10); - xga->vram_mask = xga->vram_size - 1; - xga->vram = calloc(xga->vram_size, 1); - xga->changedvram = calloc(xga->vram_size >> 12, 1); - xga->on = 0; - xga->hwcursor.cur_xsize = 64; - xga->hwcursor.cur_ysize = 64; - xga->bios_rom.sz = 0x2000; + xga->vram_size = (1024 << 10); + xga->vram_mask = xga->vram_size - 1; + xga->vram = calloc(xga->vram_size, 1); + xga->changedvram = calloc(xga->vram_size >> 12, 1); + xga->on = 0; + xga->hwcursor.cur_xsize = 64; + xga->hwcursor.cur_ysize = 64; + xga->bios_rom.sz = 0x2000; xga->linear_endian_reverse = 0; - xga->a5_test = 0; + xga->a5_test = 0; f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); - (void)fseek(f, 0L, SEEK_END); + (void) fseek(f, 0L, SEEK_END); temp = ftell(f); - (void)fseek(f, 0L, SEEK_SET); + (void) fseek(f, 0L, SEEK_SET); rom = malloc(xga->bios_rom.sz); memset(rom, 0xff, xga->bios_rom.sz); (void) !fread(rom, xga->bios_rom.sz, 1, f); temp -= xga->bios_rom.sz; - (void)fclose(f); + (void) fclose(f); - xga->bios_rom.rom = rom; + xga->bios_rom.rom = rom; xga->bios_rom.mask = xga->bios_rom.sz - 1; if (f != NULL) { free(rom); @@ -2720,29 +2697,29 @@ static void xga->base_addr_1mb = 0; if (info->flags & DEVICE_MCA) { xga->linear_base = 0; - xga->instance = 0; - xga->rom_addr = 0; + xga->instance = 0; + xga->rom_addr = 0; mem_mapping_add(&xga->bios_rom.mapping, - initial_bios_addr, xga->bios_rom.sz, - rom_read, rom_readw, rom_readl, - NULL, NULL, NULL, - xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, &xga->bios_rom); + initial_bios_addr, xga->bios_rom.sz, + rom_read, rom_readw, rom_readl, + NULL, NULL, NULL, + xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, &xga->bios_rom); } else { xga->pos_regs[2] = 1 | 0x0c | 0xf0; - xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; + xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; xga->pos_regs[4] = 1 | 2; xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + 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, NULL, MEM_MAPPING_EXTERNAL, svga); - mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear, + 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, - NULL, MEM_MAPPING_EXTERNAL, svga); + NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, - xga_memio_writeb, xga_memio_writew, xga_memio_writel, + xga_memio_writeb, xga_memio_writew, xga_memio_writel, xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); mem_mapping_disable(&xga->video_mapping); @@ -2766,8 +2743,8 @@ static void static void xga_close(void *p) { - svga_t *svga = (svga_t *)p; - xga_t *xga = &svga->xga; + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; if (svga) { free(xga->vram); @@ -2784,7 +2761,7 @@ xga_available(void) static void xga_speed_changed(void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; svga_recalctimings(svga); } @@ -2792,13 +2769,13 @@ xga_speed_changed(void *p) static void xga_force_redraw(void *p) { - svga_t *svga = (svga_t *)p; + svga_t *svga = (svga_t *) p; svga->fullchange = changeframecount; } static const device_config_t xga_configuration[] = { - // clang-format off + // clang-format off { .name = "init_bios_addr", .description = "Initial MCA BIOS Address (before POS configuration)", @@ -2839,35 +2816,35 @@ static const device_config_t xga_configuration[] = { } }, { .name = "", .description = "", .type = CONFIG_END } - // clang-format on +// clang-format on }; const device_t xga_device = { - .name = "XGA (MCA)", + .name = "XGA (MCA)", .internal_name = "xga_mca", - .flags = DEVICE_MCA, - .local = 0, - .init = xga_init, - .close = xga_close, - .reset = NULL, + .flags = DEVICE_MCA, + .local = 0, + .init = xga_init, + .close = xga_close, + .reset = NULL, { .available = xga_available }, .speed_changed = xga_speed_changed, - .force_redraw = xga_force_redraw, - .config = xga_configuration + .force_redraw = xga_force_redraw, + .config = xga_configuration }; const device_t xga_isa_device = { - .name = "XGA (ISA)", + .name = "XGA (ISA)", .internal_name = "xga_isa", - .flags = DEVICE_ISA | DEVICE_AT, - .local = 0, - .init = xga_init, - .close = xga_close, - .reset = NULL, + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = xga_init, + .close = xga_close, + .reset = NULL, { .available = xga_available }, .speed_changed = xga_speed_changed, - .force_redraw = xga_force_redraw, - .config = xga_configuration + .force_redraw = xga_force_redraw, + .config = xga_configuration }; void diff --git a/src/video/video.c b/src/video/video.c index 945247934..37a0fe9fc 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -76,35 +76,34 @@ #include -volatile int screenshots = 0; -uint8_t edatlookup[4][4]; -uint8_t fontdat[2048][8]; /* IBM CGA font */ -uint8_t fontdatm[2048][16]; /* IBM MDA font */ -uint8_t fontdatw[512][32]; /* Wyse700 font */ -uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ -uint8_t fontdat12x18[256][36]; /* IM1024 font */ -dbcs_font_t *fontdatksc5601 = NULL; /* Korean KSC-5601 font */ -dbcs_font_t *fontdatksc5601_user = NULL; /* Korean KSC-5601 user defined font */ -int herc_blend = 0; -int frames = 0; -int fullchange = 0; -int video_grayscale = 0; -int video_graytype = 0; -int monitor_index_global = 0; -uint32_t *video_6to8 = NULL, - *video_8togs = NULL, - *video_8to32 = NULL, - *video_15to32 = NULL, - *video_16to32 = NULL; -monitor_t monitors[MONITORS_NUM]; -monitor_settings_t monitor_settings[MONITORS_NUM]; -atomic_bool doresize_monitors[MONITORS_NUM]; - +volatile int screenshots = 0; +uint8_t edatlookup[4][4]; +uint8_t fontdat[2048][8]; /* IBM CGA font */ +uint8_t fontdatm[2048][16]; /* IBM MDA font */ +uint8_t fontdatw[512][32]; /* Wyse700 font */ +uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ +uint8_t fontdat12x18[256][36]; /* IM1024 font */ +dbcs_font_t *fontdatksc5601 = NULL; /* Korean KSC-5601 font */ +dbcs_font_t *fontdatksc5601_user = NULL; /* Korean KSC-5601 user defined font */ +int herc_blend = 0; +int frames = 0; +int fullchange = 0; +int video_grayscale = 0; +int video_graytype = 0; +int monitor_index_global = 0; +uint32_t *video_6to8 = NULL, + *video_8togs = NULL, + *video_8to32 = NULL, + *video_15to32 = NULL, + *video_16to32 = NULL; +monitor_t monitors[MONITORS_NUM]; +monitor_settings_t monitor_settings[MONITORS_NUM]; +atomic_bool doresize_monitors[MONITORS_NUM]; #ifdef _WIN32 -void * __cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; +void *__cdecl (*video_copy)(void *_Dst, const void *_Src, size_t _Size) = memcpy; #else -void * (*video_copy)(void *__restrict, const void *__restrict, size_t); +void *(*video_copy)(void *__restrict, const void *__restrict, size_t); #endif @@ -235,147 +234,136 @@ const uint32_t shade[5][256] = } }; - typedef struct blit_data_struct { - int x, y, w, h; - int busy; - int buffer_in_use; - int thread_run; - int monitor_index; + int x, y, w, h; + int busy; + int buffer_in_use; + int thread_run; + int monitor_index; - thread_t *blit_thread; - event_t *wake_blit_thread; - event_t *blit_complete; - event_t *buffer_not_in_use; + thread_t *blit_thread; + event_t *wake_blit_thread; + event_t *blit_complete; + event_t *buffer_not_in_use; } blit_data_t; - -static uint32_t cga_2_table[16]; - +static uint32_t cga_2_table[16]; static void (*blit_func)(int x, int y, int w, int h, int monitor_index); - #ifdef ENABLE_VIDEO_LOG int sdl_do_log = ENABLE_VIDEO_LOG; - static void video_log(const char *fmt, ...) { va_list ap; if (video_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define video_log(fmt, ...) +# define video_log(fmt, ...) #endif - void -video_setblit(void(*blit)(int,int,int,int,int)) +video_setblit(void (*blit)(int, int, int, int, int)) { blit_func = blit; } - void video_blit_complete_monitor(int monitor_index) { - blit_data_t* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; blit_data_ptr->buffer_in_use = 0; thread_set_event(blit_data_ptr->buffer_not_in_use); } - void video_wait_for_blit_monitor(int monitor_index) { - blit_data_t* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; while (blit_data_ptr->busy) - thread_wait_event(blit_data_ptr->blit_complete, -1); + thread_wait_event(blit_data_ptr->blit_complete, -1); thread_reset_event(blit_data_ptr->blit_complete); } - void video_wait_for_buffer_monitor(int monitor_index) { - blit_data_t* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; while (blit_data_ptr->buffer_in_use) - thread_wait_event(blit_data_ptr->buffer_not_in_use, -1); + thread_wait_event(blit_data_ptr->buffer_not_in_use, -1); thread_reset_event(blit_data_ptr->buffer_not_in_use); } - -static png_structp png_ptr[MONITORS_NUM]; -static png_infop info_ptr[MONITORS_NUM]; - +static png_structp png_ptr[MONITORS_NUM]; +static png_infop info_ptr[MONITORS_NUM]; static void video_take_screenshot_monitor(const char *fn, uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index) { - int i, x, y; - png_bytep *b_rgb = NULL; - FILE *fp = NULL; - uint32_t temp = 0x00000000; - blit_data_t* blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; + int i, x, y; + png_bytep *b_rgb = NULL; + FILE *fp = NULL; + uint32_t temp = 0x00000000; + blit_data_t *blit_data_ptr = monitors[monitor_index].mon_blit_data_ptr; /* create file */ fp = plat_fopen((char *) fn, (char *) "wb"); if (!fp) { - video_log("[video_take_screenshot] File %s could not be opened for writing", fn); - return; + video_log("[video_take_screenshot] File %s could not be opened for writing", fn); + return; } /* initialize stuff */ png_ptr[monitor_index] = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr[monitor_index]) { - video_log("[video_take_screenshot] png_create_write_struct failed"); - fclose(fp); - return; + video_log("[video_take_screenshot] png_create_write_struct failed"); + fclose(fp); + return; } info_ptr[monitor_index] = png_create_info_struct(png_ptr[monitor_index]); if (!info_ptr[monitor_index]) { - video_log("[video_take_screenshot] png_create_info_struct failed"); - fclose(fp); - return; + video_log("[video_take_screenshot] png_create_info_struct failed"); + fclose(fp); + return; } png_init_io(png_ptr[monitor_index], fp); png_set_IHDR(png_ptr[monitor_index], info_ptr[monitor_index], blit_data_ptr->w, blit_data_ptr->h, - 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); b_rgb = (png_bytep *) malloc(sizeof(png_bytep) * blit_data_ptr->h); if (b_rgb == NULL) { - video_log("[video_take_screenshot] Unable to Allocate RGB Bitmap Memory"); - fclose(fp); - return; + video_log("[video_take_screenshot] Unable to Allocate RGB Bitmap Memory"); + fclose(fp); + return; } for (y = 0; y < blit_data_ptr->h; ++y) { - b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr[monitor_index], info_ptr[monitor_index])); + b_rgb[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr[monitor_index], info_ptr[monitor_index])); for (x = 0; x < blit_data_ptr->w; ++x) { - if (buf == NULL) - memset(&(b_rgb[y][x * 3]), 0x00, 3); - else { - temp = buf[((start_y + y) * row_len) + start_x + x]; - b_rgb[y][x * 3] = (temp >> 16) & 0xff; - b_rgb[y][(x * 3) + 1] = (temp >> 8) & 0xff; - b_rgb[y][(x * 3) + 2] = temp & 0xff; - } - } + if (buf == NULL) + memset(&(b_rgb[y][x * 3]), 0x00, 3); + else { + temp = buf[((start_y + y) * row_len) + start_x + x]; + b_rgb[y][x * 3] = (temp >> 16) & 0xff; + b_rgb[y][(x * 3) + 1] = (temp >> 8) & 0xff; + b_rgb[y][(x * 3) + 2] = temp & 0xff; + } + } } png_write_info(png_ptr[monitor_index], info_ptr[monitor_index]); @@ -386,14 +374,16 @@ video_take_screenshot_monitor(const char *fn, uint32_t *buf, int start_x, int st /* cleanup heap allocation */ for (i = 0; i < blit_data_ptr->h; i++) - if (b_rgb[i]) free(b_rgb[i]); + if (b_rgb[i]) + free(b_rgb[i]); - if (b_rgb) free(b_rgb); + if (b_rgb) + free(b_rgb); - if (fp) fclose(fp); + if (fp) + fclose(fp); } - void video_screenshot_monitor(uint32_t *buf, int start_x, int start_y, int row_len, int monitor_index) { @@ -404,8 +394,8 @@ video_screenshot_monitor(uint32_t *buf, int start_x, int start_y, int row_len, i path_append_filename(path, usr_path, SCREENSHOT_PATH); - if (! plat_dir_check(path)) - plat_dir_create(path); + if (!plat_dir_check(path)) + plat_dir_create(path); path_slash(path); strcat(path, "Monitor_"); @@ -428,476 +418,461 @@ video_screenshot(uint32_t *buf, int start_x, int start_y, int row_len) video_screenshot_monitor(buf, start_x, start_y, row_len, 0); } - #ifdef _WIN32 -void * __cdecl -video_transform_copy(void *_Dst, const void *_Src, size_t _Size) +void *__cdecl video_transform_copy(void *_Dst, const void *_Src, size_t _Size) #else void * video_transform_copy(void *__restrict _Dst, const void *__restrict _Src, size_t _Size) #endif { - int i; + int i; uint32_t *dest_ex = (uint32_t *) _Dst; - uint32_t *src_ex = (uint32_t *) _Src; + uint32_t *src_ex = (uint32_t *) _Src; _Size /= sizeof(uint32_t); if ((dest_ex != NULL) && (src_ex != NULL)) { - for (i = 0; i < _Size; i++) { - *dest_ex = video_color_transform(*src_ex); - dest_ex++; - src_ex++; - } + for (i = 0; i < _Size; i++) { + *dest_ex = video_color_transform(*src_ex); + dest_ex++; + src_ex++; + } } return _Dst; } - -static -void blit_thread(void *param) +static void +blit_thread(void *param) { - blit_data_t* data = param; + blit_data_t *data = param; while (data->thread_run) { - thread_wait_event(data->wake_blit_thread, -1); - thread_reset_event(data->wake_blit_thread); - MTR_BEGIN("video", "blit_thread"); + thread_wait_event(data->wake_blit_thread, -1); + thread_reset_event(data->wake_blit_thread); + MTR_BEGIN("video", "blit_thread"); - if (blit_func) - blit_func(data->x, data->y, data->w, data->h, data->monitor_index); + if (blit_func) + blit_func(data->x, data->y, data->w, data->h, data->monitor_index); - data->busy = 0; + data->busy = 0; - MTR_END("video", "blit_thread"); - thread_set_event(data->blit_complete); + MTR_END("video", "blit_thread"); + thread_set_event(data->blit_complete); } } - void video_blit_memtoscreen_monitor(int x, int y, int w, int h, int monitor_index) { MTR_BEGIN("video", "video_blit_memtoscreen"); if ((w <= 0) || (h <= 0)) - return; + return; video_wait_for_blit_monitor(monitor_index); - monitors[monitor_index].mon_blit_data_ptr->busy = 1; + monitors[monitor_index].mon_blit_data_ptr->busy = 1; monitors[monitor_index].mon_blit_data_ptr->buffer_in_use = 1; - monitors[monitor_index].mon_blit_data_ptr->x = x; - monitors[monitor_index].mon_blit_data_ptr->y = y; - monitors[monitor_index].mon_blit_data_ptr->w = w; - monitors[monitor_index].mon_blit_data_ptr->h = h; + monitors[monitor_index].mon_blit_data_ptr->x = x; + monitors[monitor_index].mon_blit_data_ptr->y = y; + monitors[monitor_index].mon_blit_data_ptr->w = w; + monitors[monitor_index].mon_blit_data_ptr->h = h; thread_set_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread); MTR_END("video", "video_blit_memtoscreen"); } - -uint8_t pixels8(uint32_t *pixels) +uint8_t +pixels8(uint32_t *pixels) { - int i; + int i; uint8_t temp = 0; for (i = 0; i < 8; i++) - temp |= (!!*(pixels + i) << (i ^ 7)); + temp |= (!!*(pixels + i) << (i ^ 7)); return temp; } - -uint32_t pixel_to_color(uint8_t *pixels32, uint8_t pos) +uint32_t +pixel_to_color(uint8_t *pixels32, uint8_t pos) { uint32_t temp; temp = *(pixels32 + pos) & 0x03; switch (temp) { - case 0: - default: - return 0x00; - case 1: - return 0x07; - case 2: - return 0x0f; + case 0: + default: + return 0x00; + case 1: + return 0x07; + case 2: + return 0x0f; } } - void video_blend_monitor(int x, int y, int monitor_index) { - int xx; - uint32_t pixels32_1, pixels32_2; - unsigned int val1, val2; + int xx; + uint32_t pixels32_1, pixels32_2; + unsigned int val1, val2; static unsigned int carry = 0; if (!herc_blend) - return; + return; if (!x) - carry = 0; + carry = 0; - val1 = pixels8(&(monitors[monitor_index].target_buffer->line[y][x])); - val2 = (val1 >> 1) + carry; - carry = (val1 & 1) << 7; + val1 = pixels8(&(monitors[monitor_index].target_buffer->line[y][x])); + val2 = (val1 >> 1) + carry; + carry = (val1 & 1) << 7; pixels32_1 = cga_2_table[val1 >> 4] + cga_2_table[val2 >> 4]; pixels32_2 = cga_2_table[val1 & 0xf] + cga_2_table[val2 & 0xf]; for (xx = 0; xx < 4; xx++) { - monitors[monitor_index].target_buffer->line[y][x + xx] = pixel_to_color((uint8_t *) &pixels32_1, xx); - monitors[monitor_index].target_buffer->line[y][x + (xx | 4)] = pixel_to_color((uint8_t *) &pixels32_2, xx); + monitors[monitor_index].target_buffer->line[y][x + xx] = pixel_to_color((uint8_t *) &pixels32_1, xx); + monitors[monitor_index].target_buffer->line[y][x + (xx | 4)] = pixel_to_color((uint8_t *) &pixels32_2, xx); } } - - void video_blit_memtoscreen_8_monitor(int x, int y, int w, int h, int monitor_index) { int yy, xx; if ((w > 0) && (h > 0)) { - for (yy = 0; yy < h; yy++) { - if ((y + yy) >= 0 && (y + yy) < monitors[monitor_index].target_buffer->h) { - for (xx = 0; xx < w; xx++) { - if (monitors[monitor_index].target_buffer->line[y + yy][x + xx] <= 0xff) - monitors[monitor_index].target_buffer->line[y + yy][x + xx] = monitors[monitor_index].mon_pal_lookup[monitors[monitor_index].target_buffer->line[y + yy][x + xx]]; - else - monitors[monitor_index].target_buffer->line[y + yy][x + xx] = 0x00000000; + for (yy = 0; yy < h; yy++) { + if ((y + yy) >= 0 && (y + yy) < monitors[monitor_index].target_buffer->h) { + for (xx = 0; xx < w; xx++) { + if (monitors[monitor_index].target_buffer->line[y + yy][x + xx] <= 0xff) + monitors[monitor_index].target_buffer->line[y + yy][x + xx] = monitors[monitor_index].mon_pal_lookup[monitors[monitor_index].target_buffer->line[y + yy][x + xx]]; + else + monitors[monitor_index].target_buffer->line[y + yy][x + xx] = 0x00000000; + } } } } - } video_blit_memtoscreen_monitor(x, y, w, h, monitor_index); } - void cgapal_rebuild_monitor(int monitor_index) { - int c; - uint32_t* palette_lookup = monitors[monitor_index].mon_pal_lookup; - int cga_palette_monitor = 0; + int c; + uint32_t *palette_lookup = monitors[monitor_index].mon_pal_lookup; + int cga_palette_monitor = 0; /* We cannot do this (yet) if we have not been enabled yet. */ - if (video_6to8 == NULL) return; + if (video_6to8 == NULL) + return; - if (monitors[monitor_index].target_buffer == NULL || - monitors[monitor_index].mon_cga_palette == NULL) return; + if (monitors[monitor_index].target_buffer == NULL || monitors[monitor_index].mon_cga_palette == NULL) + return; cga_palette_monitor = *monitors[monitor_index].mon_cga_palette; - for (c=0; c<256; c++) { - palette_lookup[c] = makecol(video_6to8[cgapal[c].r], - video_6to8[cgapal[c].g], - video_6to8[cgapal[c].b]); + for (c = 0; c < 256; c++) { + palette_lookup[c] = makecol(video_6to8[cgapal[c].r], + video_6to8[cgapal[c].g], + video_6to8[cgapal[c].b]); } if ((cga_palette_monitor > 1) && (cga_palette_monitor < 7)) { - if (vid_cga_contrast != 0) { - for (c = 0; c < 16; c++) { - palette_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); - palette_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); - palette_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); - palette_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); - } - } else { - for (c = 0; c < 16; c++) { - palette_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); - palette_lookup[c+16] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); - palette_lookup[c+32] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); - palette_lookup[c+48] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], - video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); - } - } + if (vid_cga_contrast != 0) { + for (c = 0; c < 16; c++) { + palette_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); + palette_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); + palette_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); + palette_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 2][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 2][c].b]); + } + } else { + for (c = 0; c < 16; c++) { + palette_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); + palette_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); + palette_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); + palette_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette_monitor - 1][c].r], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].g], + video_6to8[cgapal_mono[cga_palette_monitor - 1][c].b]); + } + } } if (cga_palette_monitor == 7) - palette_lookup[0x16] = makecol(video_6to8[42],video_6to8[42],video_6to8[0]); + palette_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); } - void video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index) { - monitor_t* monitor = &monitors[monitor_index]; - monitor->mon_vid_type = type; + monitor_t *monitor = &monitors[monitor_index]; + monitor->mon_vid_type = type; monitor->mon_vid_timings = ptr; } - int video_get_type_monitor(int monitor_index) { return monitors[monitor_index].mon_vid_type; } - void video_update_timing(void) { - const video_timings_t* monitor_vid_timings = NULL; - int *vid_timing_read_b = NULL; - int *vid_timing_read_l = NULL; - int *vid_timing_read_w = NULL; - int *vid_timing_write_b = NULL; - int *vid_timing_write_l = NULL; - int *vid_timing_write_w = NULL; - int i = 0; + const video_timings_t *monitor_vid_timings = NULL; + int *vid_timing_read_b = NULL; + int *vid_timing_read_l = NULL; + int *vid_timing_read_w = NULL; + int *vid_timing_write_b = NULL; + int *vid_timing_write_l = NULL; + int *vid_timing_write_w = NULL; + int i = 0; for (i = 0; i < MONITORS_NUM; i++) { monitor_vid_timings = monitors[i].mon_vid_timings; if (!monitor_vid_timings) - continue; - vid_timing_read_b = &monitors[i].mon_video_timing_read_b; - vid_timing_read_l = &monitors[i].mon_video_timing_read_l; - vid_timing_read_w = &monitors[i].mon_video_timing_read_w; + continue; + vid_timing_read_b = &monitors[i].mon_video_timing_read_b; + vid_timing_read_l = &monitors[i].mon_video_timing_read_l; + vid_timing_read_w = &monitors[i].mon_video_timing_read_w; vid_timing_write_b = &monitors[i].mon_video_timing_write_b; vid_timing_write_l = &monitors[i].mon_video_timing_write_l; vid_timing_write_w = &monitors[i].mon_video_timing_write_w; if (monitor_vid_timings->type == VIDEO_ISA) { - *vid_timing_read_b = ISA_CYCLES(monitor_vid_timings->read_b); - *vid_timing_read_w = ISA_CYCLES(monitor_vid_timings->read_w); - *vid_timing_read_l = ISA_CYCLES(monitor_vid_timings->read_l); - *vid_timing_write_b = ISA_CYCLES(monitor_vid_timings->write_b); - *vid_timing_write_w = ISA_CYCLES(monitor_vid_timings->write_w); - *vid_timing_write_l = ISA_CYCLES(monitor_vid_timings->write_l); + *vid_timing_read_b = ISA_CYCLES(monitor_vid_timings->read_b); + *vid_timing_read_w = ISA_CYCLES(monitor_vid_timings->read_w); + *vid_timing_read_l = ISA_CYCLES(monitor_vid_timings->read_l); + *vid_timing_write_b = ISA_CYCLES(monitor_vid_timings->write_b); + *vid_timing_write_w = ISA_CYCLES(monitor_vid_timings->write_w); + *vid_timing_write_l = ISA_CYCLES(monitor_vid_timings->write_l); } else if (monitor_vid_timings->type == VIDEO_PCI) { - *vid_timing_read_b = (int)(pci_timing * monitor_vid_timings->read_b); - *vid_timing_read_w = (int)(pci_timing * monitor_vid_timings->read_w); - *vid_timing_read_l = (int)(pci_timing * monitor_vid_timings->read_l); - *vid_timing_write_b = (int)(pci_timing * monitor_vid_timings->write_b); - *vid_timing_write_w = (int)(pci_timing * monitor_vid_timings->write_w); - *vid_timing_write_l = (int)(pci_timing * monitor_vid_timings->write_l); + *vid_timing_read_b = (int) (pci_timing * monitor_vid_timings->read_b); + *vid_timing_read_w = (int) (pci_timing * monitor_vid_timings->read_w); + *vid_timing_read_l = (int) (pci_timing * monitor_vid_timings->read_l); + *vid_timing_write_b = (int) (pci_timing * monitor_vid_timings->write_b); + *vid_timing_write_w = (int) (pci_timing * monitor_vid_timings->write_w); + *vid_timing_write_l = (int) (pci_timing * monitor_vid_timings->write_l); } else if (monitor_vid_timings->type == VIDEO_AGP) { - *vid_timing_read_b = (int)(agp_timing * monitor_vid_timings->read_b); - *vid_timing_read_w = (int)(agp_timing * monitor_vid_timings->read_w); - *vid_timing_read_l = (int)(agp_timing * monitor_vid_timings->read_l); - *vid_timing_write_b = (int)(agp_timing * monitor_vid_timings->write_b); - *vid_timing_write_w = (int)(agp_timing * monitor_vid_timings->write_w); - *vid_timing_write_l = (int)(agp_timing * monitor_vid_timings->write_l); + *vid_timing_read_b = (int) (agp_timing * monitor_vid_timings->read_b); + *vid_timing_read_w = (int) (agp_timing * monitor_vid_timings->read_w); + *vid_timing_read_l = (int) (agp_timing * monitor_vid_timings->read_l); + *vid_timing_write_b = (int) (agp_timing * monitor_vid_timings->write_b); + *vid_timing_write_w = (int) (agp_timing * monitor_vid_timings->write_w); + *vid_timing_write_l = (int) (agp_timing * monitor_vid_timings->write_l); } else { - *vid_timing_read_b = (int)(bus_timing * monitor_vid_timings->read_b); - *vid_timing_read_w = (int)(bus_timing * monitor_vid_timings->read_w); - *vid_timing_read_l = (int)(bus_timing * monitor_vid_timings->read_l); - *vid_timing_write_b = (int)(bus_timing * monitor_vid_timings->write_b); - *vid_timing_write_w = (int)(bus_timing * monitor_vid_timings->write_w); - *vid_timing_write_l = (int)(bus_timing * monitor_vid_timings->write_l); + *vid_timing_read_b = (int) (bus_timing * monitor_vid_timings->read_b); + *vid_timing_read_w = (int) (bus_timing * monitor_vid_timings->read_w); + *vid_timing_read_l = (int) (bus_timing * monitor_vid_timings->read_l); + *vid_timing_write_b = (int) (bus_timing * monitor_vid_timings->write_b); + *vid_timing_write_w = (int) (bus_timing * monitor_vid_timings->write_w); + *vid_timing_write_l = (int) (bus_timing * monitor_vid_timings->write_l); } if (cpu_16bitbus) { - *vid_timing_read_l = *vid_timing_read_w * 2; - *vid_timing_write_l = *vid_timing_write_w * 2; + *vid_timing_read_l = *vid_timing_read_w * 2; + *vid_timing_write_l = *vid_timing_write_w * 2; } } } - int calc_6to8(int c) { - int ic, i8; + int ic, i8; double d8; ic = c; if (ic == 64) - ic = 63; - else - ic &= 0x3f; + ic = 63; + else + ic &= 0x3f; d8 = (ic / 63.0) * 255.0; i8 = (int) d8; - return(i8 & 0xff); + return (i8 & 0xff); } - int calc_8to32(int c) { - int b, g, r; + int b, g, r; double db, dg, dr; - b = (c & 3); - g = ((c >> 2) & 7); - r = ((c >> 5) & 7); - db = (((double) b) / 3.0) * 255.0; - dg = (((double) g) / 7.0) * 255.0; - dr = (((double) r) / 7.0) * 255.0; - b = (int) db; - g = ((int) dg) << 8; - r = ((int) dr) << 16; + b = (c & 3); + g = ((c >> 2) & 7); + r = ((c >> 5) & 7); + db = (((double) b) / 3.0) * 255.0; + dg = (((double) g) / 7.0) * 255.0; + dr = (((double) r) / 7.0) * 255.0; + b = (int) db; + g = ((int) dg) << 8; + r = ((int) dr) << 16; - return(b | g | r); + return (b | g | r); } - int calc_15to32(int c) { - int b, g, r; + int b, g, r; double db, dg, dr; - b = (c & 31); - g = ((c >> 5) & 31); - r = ((c >> 10) & 31); + b = (c & 31); + g = ((c >> 5) & 31); + r = ((c >> 10) & 31); db = (((double) b) / 31.0) * 255.0; dg = (((double) g) / 31.0) * 255.0; dr = (((double) r) / 31.0) * 255.0; - b = (int) db; - g = ((int) dg) << 8; - r = ((int) dr) << 16; + b = (int) db; + g = ((int) dg) << 8; + r = ((int) dr) << 16; - return(b | g | r); + return (b | g | r); } - int calc_16to32(int c) { - int b, g, r; + int b, g, r; double db, dg, dr; - b = (c & 31); - g = ((c >> 5) & 63); - r = ((c >> 11) & 31); + b = (c & 31); + g = ((c >> 5) & 63); + r = ((c >> 11) & 31); db = (((double) b) / 31.0) * 255.0; dg = (((double) g) / 63.0) * 255.0; dr = (((double) r) / 31.0) * 255.0; - b = (int) db; - g = ((int) dg) << 8; - r = ((int) dr) << 16; + b = (int) db; + g = ((int) dg) << 8; + r = ((int) dr) << 16; - return(b | g | r); + return (b | g | r); } - void hline(bitmap_t *b, int x1, int y, int x2, uint32_t col) { int x; if (y < 0 || y >= b->h) - return; + return; for (x = x1; x < x2; x++) - b->line[y][x] = col; + b->line[y][x] = col; } - void blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int x2, int y2, int xs, int ys) { } - void stretch_blit(bitmap_t *src, bitmap_t *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2) { } - void rectfill(bitmap_t *b, int x1, int y1, int x2, int y2, uint32_t col) { } - void set_palette(PALETTE p) { } - void destroy_bitmap(bitmap_t *b) { if ((b != NULL) && (b->dat != NULL)) - free(b->dat); + free(b->dat); if (b != NULL) - free(b); + free(b); } - bitmap_t * create_bitmap(int x, int y) { bitmap_t *b = malloc(sizeof(bitmap_t) + (y * sizeof(uint32_t *))); - int c; + int c; b->dat = malloc(x * y * 4); for (c = 0; c < y; c++) - b->line[c] = &(b->dat[c * x]); + b->line[c] = &(b->dat[c * x]); b->w = x; b->h = y; - return(b); + return (b); } void video_monitor_init(int index) { memset(&monitors[index], 0, sizeof(monitor_t)); - monitors[index].mon_xsize = 640; - monitors[index].mon_ysize = 480; - monitors[index].mon_res_x = 640; - monitors[index].mon_res_y = 480; - monitors[index].mon_scrnsz_x = 640; - monitors[index].mon_scrnsz_y = 480; - monitors[index].mon_efscrnsz_y = 480; - monitors[index].mon_unscaled_size_x = 480; - monitors[index].mon_unscaled_size_y = 480; - monitors[index].mon_bpp = 8; - monitors[index].mon_changeframecount = 2; - monitors[index].target_buffer = create_bitmap(2048, 2048); - monitors[index].mon_blit_data_ptr = calloc(1, sizeof(blit_data_t)); - monitors[index].mon_blit_data_ptr->wake_blit_thread = thread_create_event(); - monitors[index].mon_blit_data_ptr->blit_complete = thread_create_event(); + monitors[index].mon_xsize = 640; + monitors[index].mon_ysize = 480; + monitors[index].mon_res_x = 640; + monitors[index].mon_res_y = 480; + monitors[index].mon_scrnsz_x = 640; + monitors[index].mon_scrnsz_y = 480; + monitors[index].mon_efscrnsz_y = 480; + monitors[index].mon_unscaled_size_x = 480; + monitors[index].mon_unscaled_size_y = 480; + monitors[index].mon_bpp = 8; + monitors[index].mon_changeframecount = 2; + monitors[index].target_buffer = create_bitmap(2048, 2048); + monitors[index].mon_blit_data_ptr = calloc(1, sizeof(blit_data_t)); + monitors[index].mon_blit_data_ptr->wake_blit_thread = thread_create_event(); + monitors[index].mon_blit_data_ptr->blit_complete = thread_create_event(); monitors[index].mon_blit_data_ptr->buffer_not_in_use = thread_create_event(); - monitors[index].mon_blit_data_ptr->thread_run = 1; - monitors[index].mon_blit_data_ptr->monitor_index = index; - monitors[index].mon_pal_lookup = calloc(sizeof(uint32_t), 256); - monitors[index].mon_cga_palette = calloc(1, sizeof(int)); - monitors[index].mon_force_resize = 1; - monitors[index].mon_vid_type = VIDEO_FLAG_TYPE_NONE; + monitors[index].mon_blit_data_ptr->thread_run = 1; + monitors[index].mon_blit_data_ptr->monitor_index = index; + monitors[index].mon_pal_lookup = calloc(sizeof(uint32_t), 256); + monitors[index].mon_cga_palette = calloc(1, sizeof(int)); + monitors[index].mon_force_resize = 1; + monitors[index].mon_vid_type = VIDEO_FLAG_TYPE_NONE; atomic_init(&doresize_monitors[index], 0); atomic_init(&monitors[index].mon_screenshots, 0); - if (index >= 1) ui_init_monitor(index); + if (index >= 1) + ui_init_monitor(index); monitors[index].mon_blit_data_ptr->blit_thread = thread_create(blit_thread, monitors[index].mon_blit_data_ptr); } void video_monitor_close(int monitor_index) { - if (monitors[monitor_index].target_buffer == NULL) { return; } + if (monitors[monitor_index].target_buffer == NULL) { + return; + } monitors[monitor_index].mon_blit_data_ptr->thread_run = 0; thread_set_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread); thread_wait(monitors[monitor_index].mon_blit_data_ptr->blit_thread); - if (monitor_index >= 1) ui_deinit_monitor(monitor_index); + if (monitor_index >= 1) + ui_deinit_monitor(monitor_index); thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->buffer_not_in_use); thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->blit_complete); thread_destroy_event(monitors[monitor_index].mon_blit_data_ptr->wake_blit_thread); free(monitors[monitor_index].mon_blit_data_ptr); - if (!monitors[monitor_index].mon_pal_lookup_static) free(monitors[monitor_index].mon_pal_lookup); - if (!monitors[monitor_index].mon_cga_palette_static) free(monitors[monitor_index].mon_cga_palette); + if (!monitors[monitor_index].mon_pal_lookup_static) + free(monitors[monitor_index].mon_pal_lookup); + if (!monitors[monitor_index].mon_cga_palette_static) + free(monitors[monitor_index].mon_cga_palette); destroy_bitmap(monitors[monitor_index].target_buffer); monitors[monitor_index].target_buffer = NULL; memset(&monitors[monitor_index], 0, sizeof(monitor_t)); @@ -906,62 +881,64 @@ video_monitor_close(int monitor_index) void video_init(void) { - int c, d; + int c, d; uint8_t total[2] = { 0, 1 }; for (c = 0; c < 16; c++) { - cga_2_table[c] = (total[(c >> 3) & 1] << 0 ) | (total[(c >> 2) & 1] << 8 ) | - (total[(c >> 1) & 1] << 16) | (total[(c >> 0) & 1] << 24); + cga_2_table[c] = (total[(c >> 3) & 1] << 0) | (total[(c >> 2) & 1] << 8) | (total[(c >> 1) & 1] << 16) | (total[(c >> 0) & 1] << 24); } for (c = 0; c < 64; c++) { - cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - if ((c & 0x17) == 6) - cgapal[c + 64].g >>= 1; + cgapal[c + 64].r = (((c & 4) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + cgapal[c + 64].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + cgapal[c + 64].b = (((c & 1) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + if ((c & 0x17) == 6) + cgapal[c + 64].g >>= 1; } for (c = 0; c < 64; c++) { - cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21; - cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; - cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21; + cgapal[c + 128].r = (((c & 4) ? 2 : 0) | ((c & 0x20) ? 1 : 0)) * 21; + cgapal[c + 128].g = (((c & 2) ? 2 : 0) | ((c & 0x10) ? 1 : 0)) * 21; + cgapal[c + 128].b = (((c & 1) ? 2 : 0) | ((c & 0x08) ? 1 : 0)) * 21; } for (c = 0; c < 4; c++) { - for (d = 0; d < 4; d++) { - edatlookup[c][d] = 0; - if (c & 1) edatlookup[c][d] |= 1; - if (d & 1) edatlookup[c][d] |= 2; - if (c & 2) edatlookup[c][d] |= 0x10; - if (d & 2) edatlookup[c][d] |= 0x20; - } + for (d = 0; d < 4; d++) { + edatlookup[c][d] = 0; + if (c & 1) + edatlookup[c][d] |= 1; + if (d & 1) + edatlookup[c][d] |= 2; + if (c & 2) + edatlookup[c][d] |= 0x10; + if (d & 2) + edatlookup[c][d] |= 0x20; + } } video_6to8 = malloc(4 * 256); for (c = 0; c < 256; c++) - video_6to8[c] = calc_6to8(c); + video_6to8[c] = calc_6to8(c); video_8togs = malloc(4 * 256); for (c = 0; c < 256; c++) - video_8togs[c] = c | (c << 16) | (c << 24); + video_8togs[c] = c | (c << 16) | (c << 24); video_8to32 = malloc(4 * 256); for (c = 0; c < 256; c++) - video_8to32[c] = calc_8to32(c); + video_8to32[c] = calc_8to32(c); video_15to32 = malloc(4 * 65536); for (c = 0; c < 65536; c++) - video_15to32[c] = calc_15to32(c & 0x7fff); + video_15to32[c] = calc_15to32(c & 0x7fff); video_16to32 = malloc(4 * 65536); for (c = 0; c < 65536; c++) - video_16to32[c] = calc_16to32(c); + video_16to32[c] = calc_16to32(c); memset(monitors, 0, sizeof(monitors)); video_monitor_init(0); } - void video_close(void) { @@ -974,13 +951,13 @@ video_close(void) free(video_6to8); if (fontdatksc5601) { - free(fontdatksc5601); - fontdatksc5601 = NULL; + free(fontdatksc5601); + fontdatksc5601 = NULL; } if (fontdatksc5601_user) { - free(fontdatksc5601_user); - fontdatksc5601_user = NULL; + free(fontdatksc5601_user); + fontdatksc5601_user = NULL; } } @@ -990,150 +967,138 @@ video_force_resize_get_monitor(int monitor_index) return monitors[monitor_index].mon_force_resize; } - void video_force_resize_set_monitor(uint8_t res, int monitor_index) { monitors[monitor_index].mon_force_resize = res; } - void loadfont_common(FILE *f, int format) { int c, d; - switch (format) { - case 0: /* MDA */ - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdatm[c][d] = fgetc(f) & 0xff; - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdatm[c][d+8] = fgetc(f) & 0xff; - (void)fseek(f, 4096+2048, SEEK_SET); - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdat[c][d] = fgetc(f) & 0xff; - break; + switch (format) { + case 0: /* MDA */ + for (c = 0; c < 256; c++) + for (d = 0; d < 8; d++) + fontdatm[c][d] = fgetc(f) & 0xff; + for (c = 0; c < 256; c++) + for (d = 0; d < 8; d++) + fontdatm[c][d + 8] = fgetc(f) & 0xff; + (void) fseek(f, 4096 + 2048, SEEK_SET); + for (c = 0; c < 256; c++) + for (d = 0; d < 8; d++) + fontdat[c][d] = fgetc(f) & 0xff; + break; - case 1: /* PC200 */ - for (d = 0; d < 4; d++) { - /* There are 4 fonts in the ROM */ - for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ - (void) !fread(&fontdatm[256*d + c][0], 1, 16, f); - for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ - (void) !fread(&fontdat[256*d + c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); - } - } - break; + case 1: /* PC200 */ + for (d = 0; d < 4; d++) { + /* There are 4 fonts in the ROM */ + for (c = 0; c < 256; c++) /* 8x14 MDA in 8x16 cell */ + fread(&fontdatm[256 * d + c][0], 1, 16, f); + for (c = 0; c < 256; c++) { /* 8x8 CGA in 8x16 cell */ + fread(&fontdat[256 * d + c][0], 1, 8, f); + fseek(f, 8, SEEK_CUR); + } + } + break; - default: - case 2: /* CGA */ - for (c=0; c<256; c++) - for (d=0; d<8; d++) - fontdat[c][d] = fgetc(f) & 0xff; - break; + default: + case 2: /* CGA */ + for (c = 0; c < 256; c++) + for (d = 0; d < 8; d++) + fontdat[c][d] = fgetc(f) & 0xff; + break; - case 3: /* Wyse 700 */ - for (c=0; c<512; c++) - for (d=0; d<32; d++) - fontdatw[c][d] = fgetc(f) & 0xff; - break; + case 3: /* Wyse 700 */ + for (c = 0; c < 512; c++) + for (d = 0; d < 32; d++) + fontdatw[c][d] = fgetc(f) & 0xff; + break; - case 4: /* MDSI Genius */ - for (c=0; c<256; c++) - for (d=0; d<16; d++) - fontdat8x12[c][d] = fgetc(f) & 0xff; - break; + case 4: /* MDSI Genius */ + for (c = 0; c < 256; c++) + for (d = 0; d < 16; d++) + fontdat8x12[c][d] = fgetc(f) & 0xff; + break; - case 5: /* Toshiba 3100e */ - for (d = 0; d < 2048; d += 512) /* Four languages... */ - { - for (c = d; c < d+256; c++) - { - (void) !fread(&fontdatm[c][8], 1, 8, f); - } - for (c = d+256; c < d+512; c++) - { - (void) !fread(&fontdatm[c][8], 1, 8, f); - } - for (c = d; c < d+256; c++) - { - (void) !fread(&fontdatm[c][0], 1, 8, f); - } - for (c = d+256; c < d+512; c++) - { - (void) !fread(&fontdatm[c][0], 1, 8, f); - } - fseek(f, 4096, SEEK_CUR); /* Skip blank section */ - for (c = d; c < d+256; c++) - { - (void) !fread(&fontdat[c][0], 1, 8, f); - } - for (c = d+256; c < d+512; c++) - { - (void) !fread(&fontdat[c][0], 1, 8, f); - } - } - break; + case 5: /* Toshiba 3100e */ + for (d = 0; d < 2048; d += 512) { /* Four languages... */ + for (c = d; c < d + 256; c++) { + (void) !fread(&fontdatm[c][8], 1, 8, f); + } + for (c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdatm[c][8], 1, 8, f); + } + for (c = d; c < d + 256; c++) { + (void) !fread(&fontdatm[c][0], 1, 8, f); + } + for (c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdatm[c][0], 1, 8, f); + } + fseek(f, 4096, SEEK_CUR); /* Skip blank section */ + for (c = d; c < d + 256; c++) { + (void) !fread(&fontdat[c][0], 1, 8, f); + } + for (c = d + 256; c < d + 512; c++) { + (void) !fread(&fontdat[c][0], 1, 8, f); + } + } + break; - case 6: /* Korean KSC-5601 */ - if (!fontdatksc5601) - fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t)); + case 6: /* Korean KSC-5601 */ + if (!fontdatksc5601) + fontdatksc5601 = malloc(16384 * sizeof(dbcs_font_t)); - if (!fontdatksc5601_user) - fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t)); + if (!fontdatksc5601_user) + fontdatksc5601_user = malloc(192 * sizeof(dbcs_font_t)); - for (c = 0; c < 16384; c++) - { - for (d = 0; d < 32; d++) - fontdatksc5601[c].chr[d]=fgetc(f) & 0xff; - } - break; + for (c = 0; c < 16384; c++) { + for (d = 0; d < 32; d++) + fontdatksc5601[c].chr[d] = fgetc(f) & 0xff; + } + break; - case 7: /* Sigma Color 400 */ - /* The first 4k of the character ROM holds an 8x8 font */ - for (c = 0; c < 256; c++) { - (void) !fread(&fontdat[c][0], 1, 8, f); - fseek(f, 8, SEEK_CUR); - } - /* The second 4k holds an 8x16 font */ - for (c = 0; c < 256; c++) { - if (fread(&fontdatm[c][0], 1, 16, f) != 16) - fatal("loadfont(): Error reading 8x16 font in Sigma Color 400 mode, c = %i\n", c); - } - break; + case 7: /* Sigma Color 400 */ + /* The first 4k of the character ROM holds an 8x8 font */ + for (c = 0; c < 256; c++) { + (void) !fread(&fontdat[c][0], 1, 8, f); + fseek(f, 8, SEEK_CUR); + } + /* The second 4k holds an 8x16 font */ + for (c = 0; c < 256; c++) { + if (fread(&fontdatm[c][0], 1, 16, f) != 16) + fatal("loadfont(): Error reading 8x16 font in Sigma Color 400 mode, c = %i\n", c); + } + break; - case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */ - for (c = 0; c < 2048; c++) /* Allow up to 2048 chars */ - for (d=0; d<8; d++) - fontdat[c][d] = fgetc(f) & 0xff; - break; + case 8: /* Amstrad PC1512, Toshiba T1000/T1200 */ + for (c = 0; c < 2048; c++) /* Allow up to 2048 chars */ + for (d = 0; d < 8; d++) + fontdat[c][d] = fgetc(f) & 0xff; + break; - case 9: /* Image Manager 1024 native font */ - for (c = 0; c < 256; c++) - (void) !fread(&fontdat12x18[c][0], 1, 36, f); - break; + case 9: /* Image Manager 1024 native font */ + for (c = 0; c < 256; c++) + (void) !fread(&fontdat12x18[c][0], 1, 36, f); + break; + } - } - - (void)fclose(f); + (void) fclose(f); } void loadfont_ex(char *s, int format, int offset) { - FILE *f; + FILE *f; f = rom_fopen(s, "rb"); if (f == NULL) - return; - - fseek(f, offset, SEEK_SET); - loadfont_common(f, format); + return; + fseek(f, offset, SEEK_SET); + loadfont_common(f, format); } void @@ -1147,27 +1112,29 @@ video_color_transform(uint32_t color) { uint8_t *clr8 = (uint8_t *) &color; /* if (!video_grayscale && !invert_display) - return color; */ + return color; */ if (video_grayscale) { - if (video_graytype) { - if (video_graytype == 1) - color = ((54 * (uint32_t)clr8[2]) + (183 * (uint32_t)clr8[1]) + (18 * (uint32_t)clr8[0])) / 255; - else - color = ((uint32_t)clr8[2] + (uint32_t)clr8[1] + (uint32_t)clr8[0]) / 3; - } else - color = ((76 * (uint32_t)clr8[2]) + (150 * (uint32_t)clr8[1]) + (29 * (uint32_t)clr8[0])) / 255; - switch (video_grayscale) { - case 2: case 3: case 4: - color = (uint32_t) shade[video_grayscale][color]; - break; - default: - clr8[3] = 0; - clr8[0] = color; - clr8[1] = clr8[2] = clr8[0]; - break; - } + if (video_graytype) { + if (video_graytype == 1) + color = ((54 * (uint32_t) clr8[2]) + (183 * (uint32_t) clr8[1]) + (18 * (uint32_t) clr8[0])) / 255; + else + color = ((uint32_t) clr8[2] + (uint32_t) clr8[1] + (uint32_t) clr8[0]) / 3; + } else + color = ((76 * (uint32_t) clr8[2]) + (150 * (uint32_t) clr8[1]) + (29 * (uint32_t) clr8[0])) / 255; + switch (video_grayscale) { + case 2: + case 3: + case 4: + color = (uint32_t) shade[video_grayscale][color]; + break; + default: + clr8[3] = 0; + clr8[0] = color; + clr8[1] = clr8[2] = clr8[0]; + break; + } } if (invert_display) - color ^= 0x00ffffff; + color ^= 0x00ffffff; return color; }