diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 6966d1a..accf39f 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.3 2018/03/15 + * Version: @(#)net_pcap.c 1.0.4 2018/03/26 * * Author: Fred N. van Kempen, * @@ -49,7 +49,7 @@ #include #include #include -#ifdef _WIN32 +#if defined(_WIN32) && !defined(WIN32) # define WIN32 #endif #include diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index b550b9c..defb7b1 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -10,7 +10,7 @@ * * Based on the "libpcap" examples. * - * Version: @(#)pcap_if.c 1.0.11 2018/03/25 + * Version: @(#)pcap_if.c 1.0.12 2018/03/26 * * Author: Fred N. van Kempen, * @@ -52,7 +52,7 @@ #include #include #include -#ifdef _WIN32 +#if defined(_WIN32) && !defined(WIN32) # define WIN32 #endif #include diff --git a/src/video/vid_ati18800.c b/src/video/vid_ati18800.c index 54d41b8..497becf 100644 --- a/src/video/vid_ati18800.c +++ b/src/video/vid_ati18800.c @@ -8,7 +8,7 @@ * * ATI 18800 emulation (VGA Edge-16) * - * Version: @(#)vid_ati18800.c 1.0.4 2018/03/17 + * Version: @(#)vid_ati18800.c 1.0.5 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -170,39 +170,6 @@ static uint8_t ati18800_in(uint16_t addr, void *p) case 0x3D5: temp = svga->crtc[svga->crtcreg]; break; - case 0x3DA: - svga->attrff = 0; - svga->attrff = 0; - 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; - } - return svga->cgastat; default: temp = svga_in(addr, svga); break; diff --git a/src/video/vid_ati28800.c b/src/video/vid_ati28800.c index f58e64f..8fbd541 100644 --- a/src/video/vid_ati28800.c +++ b/src/video/vid_ati28800.c @@ -8,7 +8,7 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.9 2018/03/20 + * Version: @(#)vid_ati28800.c 1.0.10 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -275,39 +275,6 @@ static uint8_t ati28800_in(uint16_t addr, void *p) case 0x3D5: temp = svga->crtc[svga->crtcreg]; break; - case 0x3DA: - svga->attrff = 0; - svga->attrff = 0; - 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; - } - return svga->cgastat; default: temp = svga_in(addr, svga); break; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index df956eb..b8cb89c 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -8,7 +8,7 @@ * * ATi Mach64 graphics card emulation. * - * Version: @(#)vid_ati_mach64.c 1.0.7 2018/03/17 + * Version: @(#)vid_ati_mach64.c 1.0.8 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -451,39 +451,6 @@ uint8_t mach64_in(uint16_t addr, void *p) if (svga->crtcreg > 0x18) return 0xff; return svga->crtc[svga->crtcreg]; - case 0x3DA: - svga->attrff = 0; - svga->attrff = 0; - 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; - } - return svga->cgastat; } return svga_in(addr, svga); } diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index ce085d7..e107ca0 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -9,7 +9,7 @@ * Emulation of select Cirrus Logic cards (CL-GD 5428, * CL-GD 5429, 5430, 5434 and 5436 are supported). * - * Version: @(#)vid_cl54xx.c 1.0.12 2018/03/22 + * Version: @(#)vid_cl54xx.c 1.0.13 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -60,7 +60,8 @@ #define BIOS_GD5426_PATH L"roms/video/cirruslogic/diamond speedstar pro vlb v3.04.bin" -#define BIOS_GD5428_PATH L"roms/video/cirruslogic/vlbusjapan.bin" +#define BIOS_GD5428_ISA_PATH L"roms/video/cirruslogic/gd5428.bin" +#define BIOS_GD5428_VLB_PATH L"roms/video/cirruslogic/vlbusjapan.bin" #define BIOS_GD5429_PATH L"roms/video/cirruslogic/gd5429.vbi" #define BIOS_GD5430_VLB_PATH L"roms/video/cirruslogic/diamondvlbus.bin" #define BIOS_GD5430_PCI_PATH L"roms/video/cirruslogic/gd5430pci.bin" @@ -183,15 +184,19 @@ typedef struct gd54xx_t uint16_t scan_cnt; } blt; - int pci, vlb; + int pci, vlb; - uint8_t pci_regs[256]; - uint8_t int_line; - int card; + uint8_t pci_regs[256]; + uint8_t int_line; - uint32_t lfb_base; + int card; - int mmio_vram_overlap; + uint32_t lfb_base; + + int mmio_vram_overlap; + + uint32_t extpallook[256]; + PALETTE extpal; } gd54xx_t; static void @@ -222,16 +227,57 @@ 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; + uint32_t o32; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) 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; + return; case 0x3c4: svga->seqaddr = val; break; case 0x3c5: if (svga->seqaddr > 5) { + o = svga->seqregs[svga->seqaddr & 0x1f]; svga->seqregs[svga->seqaddr & 0x1f] = val; switch (svga->seqaddr & 0x1f) { case 6: @@ -256,6 +302,11 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.y = (val << 3) | (svga->seqaddr >> 5); break; case 0x12: + if (val & 0x80) + 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; svga->hwcursor.xsize = svga->hwcursor.ysize = (val & CIRRUS_CURSOR_LARGE) ? 64 : 32; if (val & CIRRUS_CURSOR_LARGE) @@ -288,6 +339,42 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p) } gd54xx->ramdac.state = 0; break; + case 0x3C9: + 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: + if (svga->seqregs[0x12] & 2) { + gd54xx->extpal[svga->dac_write].r = svga->dac_r; + gd54xx->extpal[svga->dac_write].g = svga->dac_g; + gd54xx->extpal[svga->dac_write].b = val; + gd54xx->extpallook[svga->dac_write & 15] = makecol32(video_6to8[gd54xx->extpal[svga->dac_write].r & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].g & 0x3f], video_6to8[gd54xx->extpal[svga->dac_write].b & 0x3f]); + if ((svga->seqregs[0x12] & 0x80) && ((svga->dac_write & 15) == 2)) { + o32 = svga->overscan_color; + svga->overscan_color = gd54xx->extpallook[2]; + if (o32 != svga->overscan_color) + svga_recalctimings(svga); + } + svga->dac_write = (svga->dac_write + 1) & 15; + } else { + svga->vgapal[svga->dac_write].r = svga->dac_r; + svga->vgapal[svga->dac_write].g = svga->dac_g; + svga->vgapal[svga->dac_write].b = val; + svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r & 0x3f], video_6to8[svga->vgapal[svga->dac_write].g & 0x3f], video_6to8[svga->vgapal[svga->dac_write].b & 0x3f]); + svga->dac_write = (svga->dac_write + 1) & 255; + } + svga->dac_pos = 0; + break; + } + return; case 0x3cf: if (svga->gdcaddr == 0) gd543x_mmio_write(0xb8000, val, gd54xx); @@ -514,6 +601,32 @@ gd54xx_in(uint16_t addr, void *p) } gd54xx->ramdac.state++; break; + case 0x3c9: + svga->dac_status = 3; + switch (svga->dac_pos) { + case 0: + svga->dac_pos++; + if (svga->seqregs[0x12] & 2) + return gd54xx->extpal[svga->dac_read].r & 0x3f; + else + return svga->vgapal[svga->dac_read].r & 0x3f; + case 1: + svga->dac_pos++; + if (svga->seqregs[0x12] & 2) + return gd54xx->extpal[svga->dac_read].g & 0x3f; + else + return svga->vgapal[svga->dac_read].g & 0x3f; + case 2: + svga->dac_pos=0; + if (svga->seqregs[0x12] & 2) { + svga->dac_read = (svga->dac_read + 1) & 15; + return gd54xx->extpal[(svga->dac_read - 1) & 15].b & 0x3f; + } else { + svga->dac_read = (svga->dac_read + 1) & 255; + return svga->vgapal[(svga->dac_read - 1) & 255].b & 0x3f; + } + } + return 0xFF; case 0x3cf: if (svga->gdcaddr > 8) { return svga->gdcreg[svga->gdcaddr & 0x3f]; @@ -761,43 +874,60 @@ gd54xx_recalctimings(svga_t *svga) static void gd54xx_hwcursor_draw(svga_t *svga, int displine) { - int x; - uint8_t dat[2]; - int xx; - int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; - int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; - - if (svga->interlace && svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; - - for (x = 0; x < svga->hwcursor.xsize; x += 8) { - dat[0] = svga->vram[svga->hwcursor_latch.addr]; - if (svga->hwcursor.xsize == 64) - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x08]; - else - dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; - for (xx = 0; xx < 8; xx++) { - if (offset >= svga->hwcursor_latch.x) { - if (dat[1] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = 0; - if (dat[0] & 0x80) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; - } - - offset++; - dat[0] <<= 1; - dat[1] <<= 1; - } - svga->hwcursor_latch.addr++; - } - + 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 y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + int pitch = (svga->hwcursor.xsize == 64) ? 16 : 4; + uint32_t bgcol = gd54xx->extpallook[0x00]; + uint32_t fgcol = gd54xx->extpallook[0x0f]; + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; + + for (x = 0; x < svga->hwcursor.xsize; x += 8) { + dat[0] = svga->vram[svga->hwcursor_latch.addr]; if (svga->hwcursor.xsize == 64) - svga->hwcursor_latch.addr += 8; + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x08]; + else + dat[1] = svga->vram[svga->hwcursor_latch.addr + 0x80]; + 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 + y_add])[offset + 32 + 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 + y_add])[offset + 32 + x_add] ^= 0xffffff; + break; + case 3: + /* The pixel is shown in the cursor foreground color */ + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = fgcol; + break; + } + } + + offset++; + } + svga->hwcursor_latch.addr++; + } - if (svga->interlace && !svga->hwcursor_oddeven) - svga->hwcursor_latch.addr += pitch; + if (svga->hwcursor.xsize == 64) + svga->hwcursor_latch.addr += 8; + + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += pitch; } @@ -2249,7 +2379,10 @@ gd54xx_init(const device_t *info) break; case CIRRUS_ID_CLGD5428: - romfn = BIOS_GD5428_PATH; + if (gd54xx->vlb) + romfn = BIOS_GD5428_VLB_PATH; + else + romfn = BIOS_GD5428_ISA_PATH; break; case CIRRUS_ID_CLGD5429: @@ -2286,19 +2419,29 @@ gd54xx_init(const device_t *info) gd54xx->vram_size = device_get_config_int("memory"); gd54xx->vram_mask = (gd54xx->vram_size << 20) - 1; - rom_init(&gd54xx->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&gd54xx->bios_rom, romfn, + 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&gd54xx->svga, gd54xx, gd54xx->vram_size << 20, gd54xx_recalctimings, gd54xx_in, gd54xx_out, gd54xx_hwcursor_draw, NULL); - mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl, gd54xx_write, gd54xx_writew, gd54xx_writel); + mem_mapping_set_handler(&svga->mapping, + gd54xx_read,gd54xx_readw,gd54xx_readl, + gd54xx_write,gd54xx_writew,gd54xx_writel); mem_mapping_set_p(&svga->mapping, gd54xx); - mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, gd543x_mmio_read, gd543x_mmio_readw, gd543x_mmio_readl, gd543x_mmio_write, gd543x_mmio_writew, gd543x_mmio_writel, NULL, 0, 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, 0, svga); + mem_mapping_add(&gd54xx->mmio_mapping, 0, 0, + gd543x_mmio_read,gd543x_mmio_readw,gd543x_mmio_readl, + gd543x_mmio_write,gd543x_mmio_writew,gd543x_mmio_writel, + NULL, 0, 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, 0, svga); - io_sethandler(0x03c0, 0x0020, gd54xx_in, NULL, NULL, gd54xx_out, NULL, NULL, gd54xx); + io_sethandler(0x03c0, 32, + gd54xx_in,NULL,NULL, gd54xx_out,NULL,NULL, gd54xx); svga->hwcursor.yoff = 32; svga->hwcursor.xoff = 0; @@ -2318,9 +2461,9 @@ gd54xx_init(const device_t *info) gd54xx->pci_regs[0x30] = 0x00; gd54xx->pci_regs[0x32] = 0x0c; gd54xx->pci_regs[0x33] = 0x00; - + svga->crtc[0x27] = id; - + return gd54xx; } @@ -2331,9 +2474,15 @@ gd5426_available(void) } static int -gd5428_available(void) +gd5428_isa_available(void) { - return rom_present(BIOS_GD5428_PATH); + return rom_present(BIOS_GD5428_ISA_PATH); +} + +static int +gd5428_vlb_available(void) +{ + return rom_present(BIOS_GD5428_VLB_PATH); } static int @@ -2500,7 +2649,7 @@ const device_t gd5428_isa_device = gd54xx_init, gd54xx_close, NULL, - gd5428_available, + gd5428_isa_available, gd54xx_speed_changed, gd54xx_force_redraw, gd54xx_add_status_info, @@ -2515,7 +2664,7 @@ const device_t gd5428_vlb_device = gd54xx_init, gd54xx_close, NULL, - gd5428_available, + gd5428_vlb_available, gd54xx_speed_changed, gd54xx_force_redraw, gd54xx_add_status_info, diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index a5efc84..b723d5f 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -10,7 +10,7 @@ * * Known bugs: Accelerator doesn't work in planar modes * - * Version: @(#)vid_et4000w32.c 1.0.4 2018/03/15 + * Version: @(#)vid_et4000w32.c 1.0.5 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -305,6 +305,15 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) case 0x214B: case 0x215B: case 0x216B: case 0x217B: if (et4000->index==0xec) return (et4000->regs[0xec] & 0xf) | 0x60; /*ET4000/W32p rev D*/ + if (et4000->index == 0xee) /*Preliminary implementation*/ + { + if (svga->bpp == 8) + return 3; + else if (svga->bpp == 16) + return 4; + else + break; + } if (et4000->index == 0xef) { if (et4000->pci) return et4000->regs[0xef] | 0xe0; /*PCI*/ diff --git a/src/video/vid_oak_oti.c b/src/video/vid_oak_oti.c index 02e19dc..a85d945 100644 --- a/src/video/vid_oak_oti.c +++ b/src/video/vid_oak_oti.c @@ -8,7 +8,7 @@ * * Oak OTI037C/67/077 emulation. * - * Version: @(#)vid_oak_oti.c 1.0.6 2018/03/15 + * Version: @(#)vid_oak_oti.c 1.0.7 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -87,7 +87,7 @@ oti_out(uint16_t addr, uint8_t val, void *p) if (!(oti->enable_register & 1) && addr != 0x3C3) return; - + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; @@ -95,7 +95,7 @@ oti_out(uint16_t addr, uint8_t val, void *p) case 0x3C3: oti->enable_register = val & 1; return; - + case 0x3D4: svga->crtcreg = val; return; @@ -115,8 +115,8 @@ oti_out(uint16_t addr, uint8_t val, void *p) } break; - case 0x3DE: - oti->index = val; + case 0x3DE: + oti->index = val; return; case 0x3DF: @@ -161,18 +161,18 @@ oti_in(uint16_t addr, void *p) oti_t *oti = (oti_t *)p; svga_t *svga = &oti->svga; uint8_t temp; - + if (!(oti->enable_register & 1) && addr != 0x3C3) - return 0xff; - + return 0xff; + if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; - + switch (addr) { case 0x3C3: temp = oti->enable_register; break; - + case 0x3D4: temp = svga->crtcreg; break; @@ -180,12 +180,46 @@ oti_in(uint16_t addr, void *p) case 0x3D5: temp = svga->crtc[svga->crtcreg & 31]; break; - - case 0x3DE: - temp = oti->index | (oti->chip_id << 5); - break; - case 0x3DF: + case 0x3DA: + svga->attrff = 0; + svga->attrff = 0; + 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; + } + return svga->cgastat; + + case 0x3DE: + temp = oti->index | (oti->chip_id << 5); + break; + + case 0x3DF: if ((oti->index & 0x1f)==0x10) temp = 0x18; else @@ -225,7 +259,7 @@ oti_pos_in(uint16_t addr, void *p) oti_t *oti = (oti_t *)p; return(oti->pos); -} +} static void @@ -253,8 +287,8 @@ oti_init(const device_t *info) switch(oti->chip_id) { case 0: romfn = BIOS_37C_PATH; - break; - + break; + case 2: #if 0 romfn = BIOS_67_PATH; @@ -277,11 +311,11 @@ oti_init(const device_t *info) io_sethandler(0x03c0, 32, oti_in, NULL, NULL, oti_out, NULL, NULL, oti); io_sethandler(0x46e8, 1, oti_pos_in,NULL,NULL, oti_pos_out,NULL,NULL, oti); - + oti->svga.miscout = 1; oti->regs[0] = 0x08; /* fixme: bios wants to read this at index 0? this index is undocumented */ - + return(oti); } @@ -304,7 +338,7 @@ oti_speed_changed(void *p) svga_recalctimings(&oti->svga); } - + static void oti_force_redraw(void *p) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d762c56..0078802 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.7 2018/03/17 + * Version: @(#)vid_svga.c 1.0.8 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -115,10 +115,19 @@ void svga_out(uint16_t addr, uint8_t val, void *p) } } /* Recalculate timings on change of attribute register 0x11 (overscan border color) too. */ - if ((svga->attraddr == 0x10) || (svga->attraddr == 0x11)) - if (o != val) svga_recalctimings(svga); - if (svga->attraddr == 0x12) - { + if (svga->attraddr == 0x10) + { + if (o != val) + svga_recalctimings(svga); + } + else if (svga->attraddr == 0x11) + { + svga->overscan_color = svga->pallook[svga->overscan_color]; + 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; @@ -677,7 +686,7 @@ void svga_poll(void *p) svga->displine = (svga->interlace && svga->oddeven) ? 1 : 0; svga->scrollcache = svga->attrregs[0x13] & 7; svga->linecountff = 0; - + svga->hwcursor_on = 0; svga->hwcursor_latch = svga->hwcursor; @@ -697,9 +706,9 @@ int svga_init(svga_t *svga, void *p, int memsize, 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++) { @@ -710,6 +719,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->readmode = 0; svga->attrregs[0x11] = 0; + svga->overscan_color = 0x000000; overscan_x = 16; overscan_y = 32; @@ -717,7 +727,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->crtc[0] = 63; svga->crtc[6] = 255; svga->dispontime = 1000 * (1 << TIMER_SHIFT); - svga->dispofftime = 1000 * (1 << TIMER_SHIFT); + svga->dispofftime = 1000 * (1 << TIMER_SHIFT); svga->bpp = 8; svga->vram = malloc(memsize); svga->vram_max = memsize; @@ -734,11 +744,11 @@ int svga_init(svga_t *svga, void *p, int memsize, mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga); - + svga_pri = svga; - + svga->ramdac_type = RAMDAC_6BIT; - + return 0; } @@ -746,7 +756,7 @@ void svga_close(svga_t *svga) { free(svga->changedvram); free(svga->vram); - + svga_pri = NULL; } @@ -787,7 +797,7 @@ void svga_write(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_max) return; - + addr &= svga->vram_mask; if (svga_output) pclog("%08X (%i, %i) %02X %i %i %i %02X\n", addr, addr & 1023, addr >> 10, val, writemask2, svga->writemode, svga->chain4, svga->gdcreg[8]); @@ -943,18 +953,18 @@ uint8_t svga_read(uint32_t addr, void *p) uint8_t temp, temp2, temp3, temp4; uint32_t latch_addr; int readplane = svga->readplane; - + cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; - + egareads++; // pclog("Readega %06X ",addr); addr &= svga->banked_mask; addr += svga->read_bank; - + latch_addr = (addr << 2) & svga->decode_mask; - + // pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode); // pclog("%i\n", svga->readmode); if (svga->chain4 || svga->fb_only) @@ -974,7 +984,7 @@ uint8_t svga_read(uint32_t addr, void *p) addr<<=2; addr &= svga->decode_mask; - + if (latch_addr >= svga->vram_max) { svga->la = svga->lb = svga->lc = svga->ld = 0xff; @@ -990,9 +1000,9 @@ uint8_t svga_read(uint32_t addr, void *p) if (addr >= svga->vram_max) return 0xff; - + addr &= svga->vram_mask; - + if (svga->readmode) { temp = svga->la; @@ -1024,7 +1034,7 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) cycles_lost += video_timing_write_b; egawrites++; - + if (svga_output) pclog("Write LFB %08X %02X ", addr, val); if (!(svga->gdcreg[6] & 1)) svga->fullchange = 2; @@ -1051,7 +1061,7 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) addr &= svga->vram_mask; if (svga_output) pclog("%08X\n", addr); svga->changedvram[addr >> 12]=changeframecount; - + switch (svga->writemode) { case 1: @@ -1201,18 +1211,18 @@ uint8_t svga_read_linear(uint32_t addr, void *p) svga_t *svga = (svga_t *)p; uint8_t temp, temp2, temp3, temp4; int readplane = svga->readplane; - + cycles -= video_timing_read_b; cycles_lost += video_timing_read_b; egareads++; - + if (svga->chain4 || svga->fb_only) - { + { 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]; } else if (svga->chain2_read) { @@ -1224,10 +1234,10 @@ uint8_t svga_read_linear(uint32_t addr, void *p) addr<<=2; addr &= svga->decode_mask; - + if (addr >= svga->vram_max) return 0xff; - + addr &= svga->vram_mask; svga->la = svga->vram[addr]; @@ -1294,7 +1304,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + p[j] = svga_color_transform(svga->overscan_color); } /* Draw (overscan_size + scroll size) lines of overscan on the bottom. */ @@ -1302,15 +1312,15 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) p = &((uint32_t *)buffer32->line[(ysize + (y_add >> 1) + i) & 0x7ff])[32]; for (j = 0; j < (xsize + x_add); j++) - p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + p[j] = svga_color_transform(svga->overscan_color); } for (i = (y_add >> 1); i < (ysize + (y_add >> 1)); i ++) { p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < 8; j++) { - p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); - p[xsize + (x_add >> 1) + j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + p[j] = svga->pallook[svga->overscan_color]; + p[xsize + (x_add >> 1) + j] = svga_color_transform(svga->overscan_color); } } } @@ -1328,7 +1338,7 @@ void svga_writew(uint32_t addr, uint16_t val, void *p) svga_write(addr + 1, val >> 8, p); return; } - + egawrites += 2; cycles -= video_timing_write_w; @@ -1348,7 +1358,7 @@ void svga_writew(uint32_t addr, uint16_t val, void *p) void svga_writel(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) { svga_write(addr, val, p); @@ -1357,7 +1367,7 @@ void svga_writel(uint32_t addr, uint32_t val, void *p) svga_write(addr + 3, val >> 24, p); return; } - + egawrites += 4; cycles -= video_timing_write_l; @@ -1370,7 +1380,7 @@ void svga_writel(uint32_t addr, uint32_t val, void *p) return; addr &= svga->vram_mask; if (svga_output) pclog("%08X (%i, %i) %08X\n", addr, addr & 1023, addr >> 10, val); - + svga->changedvram[addr >> 12] = changeframecount; *(uint32_t *)&svga->vram[addr] = val; } @@ -1378,10 +1388,10 @@ void svga_writel(uint32_t addr, uint32_t val, void *p) uint16_t svga_readw(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) return svga_read(addr, p) | (svga_read(addr + 1, p) << 8); - + egareads += 2; cycles -= video_timing_read_w; @@ -1393,17 +1403,17 @@ uint16_t svga_readw(uint32_t addr, void *p) // pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); if (addr >= svga->vram_max) return 0xffff; - + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } uint32_t svga_readl(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) return svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | (svga_read(addr + 3, p) << 24); - + egareads += 4; cycles -= video_timing_read_l; @@ -1415,20 +1425,20 @@ uint32_t svga_readl(uint32_t addr, void *p) // pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); if (addr >= svga->vram_max) return 0xffffffff; - + return *(uint32_t *)&svga->vram[addr & svga->vram_mask]; } void svga_writeb_linear(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) { svga_write_linear(addr, val, p); return; } - + egawrites++; if (svga_output) pclog("Write LFBb %08X %04X\n", addr, val); @@ -1443,14 +1453,14 @@ void svga_writeb_linear(uint32_t addr, uint8_t val, void *p) void svga_writew_linear(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) { svga_write_linear(addr, val & 0xff, p); svga_write_linear(addr + 1, val >> 8, p); return; } - + egawrites += 2; cycles -= video_timing_write_w; @@ -1468,7 +1478,7 @@ void svga_writew_linear(uint32_t addr, uint16_t val, void *p) void svga_writel_linear(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) { svga_write_linear(addr, val, p); @@ -1477,7 +1487,7 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p) svga_write_linear(addr + 3, val >> 24, p); return; } - + egawrites += 4; cycles -= video_timing_write_l; @@ -1495,26 +1505,26 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p) uint8_t svga_readb_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) return svga_read_linear(addr, p); - + egareads++; addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xff; - + return *(uint8_t *)&svga->vram[addr & svga->vram_mask]; } uint16_t svga_readw_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8); - + egareads += 2; cycles -= video_timing_read_w; @@ -1523,17 +1533,17 @@ uint16_t svga_readw_linear(uint32_t addr, void *p) addr &= svga->decode_mask; if (addr >= svga->vram_max) return 0xffff; - + return *(uint16_t *)&svga->vram[addr & svga->vram_mask]; } uint32_t svga_readl_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; - + if (!svga->fast) return svga_read_linear(addr, p) | (svga_read_linear(addr + 1, p) << 8) | (svga_read_linear(addr + 2, p) << 16) | (svga_read_linear(addr + 3, p) << 24); - + egareads += 4; cycles -= video_timing_read_l; @@ -1551,7 +1561,7 @@ void svga_add_status_info(char *s, int max_len, void *p) { svga_t *svga = (svga_t *)p; char temps[128]; - + if (svga->chain4) strcpy(temps, "SVGA chained (possibly mode 13h)\n"); else strcpy(temps, "SVGA unchained (possibly mode-X)\n"); strncat(s, temps, max_len); @@ -1559,10 +1569,10 @@ void svga_add_status_info(char *s, int max_len, void *p) if (!svga->video_bpp) strcpy(temps, "SVGA in text mode\n"); else sprintf(temps, "SVGA colour depth : %i bpp\n", svga->video_bpp); strncat(s, temps, max_len); - + sprintf(temps, "SVGA resolution : %i x %i\n", svga->video_res_x, svga->video_res_y); strncat(s, temps, max_len); - + sprintf(temps, "SVGA refresh rate : %i Hz\n\n", svga->frames); svga->frames = 0; strncat(s, temps, max_len); diff --git a/src/video/vid_svga.h b/src/video/vid_svga.h index b7e0406..fc9f98c 100644 --- a/src/video/vid_svga.h +++ b/src/video/vid_svga.h @@ -8,7 +8,7 @@ * * Definitions for the generic SVGA driver. * - * Version: @(#)vid_svga.h 1.0.3 2018/03/04 + * Version: @(#)vid_svga.h 1.0.4 2018/03/26 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -46,7 +46,6 @@ typedef struct svga_t int enabled; - uint8_t crtcreg; uint8_t crtc[128]; uint8_t gdcreg[64]; @@ -56,7 +55,7 @@ typedef struct svga_t int attr_palette_enable; uint8_t seqregs[64]; int seqaddr; - + uint8_t miscout; int vidclock; @@ -65,7 +64,7 @@ typedef struct svga_t 1MB-2MB - VRAM mirror 2MB-4MB - open bus 4MB-xMB - mirror of above - + For the example memory map, decode_mask would be 4MB-1 (4MB address space), vram_max would be 2MB (present video memory only responds to first 2MB), vram_mask would be 1MB-1 (video memory wraps at 1MB) */ @@ -74,17 +73,17 @@ typedef struct svga_t uint32_t vram_mask; uint8_t la, lb, lc, ld; - + uint8_t dac_mask, dac_status; int dac_read, dac_write, dac_pos; int dac_r, dac_g; - + uint8_t cgastat; - + uint8_t plane_mask; - + int fb_only; - + int fast; uint8_t colourcompare, colournocare; int readmode, writemode, readplane; @@ -93,13 +92,13 @@ typedef struct svga_t int extvram; uint8_t writemask; uint32_t charseta, charsetb; - + int set_reset_disabled; uint8_t egapal[16]; uint32_t pallook[256]; PALETTE vgapal; - + int ramdac_type; int vtotal, dispend, vsyncstart, split, vblankstart; @@ -109,12 +108,12 @@ typedef struct svga_t double clock; uint32_t ma_latch; int bpp; - + int64_t dispontime, dispofftime; int64_t vidtime; - + uint8_t scrblank; - + int dispon; int hdisp_on; @@ -124,20 +123,20 @@ typedef struct svga_t int linepos, vslines, linecountff, oddeven; int con, cursoron, blink; int scrollcache; - + int firstline, lastline; int firstline_draw, lastline_draw; int displine; - + uint8_t *vram; uint8_t *changedvram; int vram_display_mask; uint32_t banked_mask; uint32_t write_bank, read_bank; - + int fullchange; - + int video_res_x, video_res_y, video_bpp; int frames, fps; @@ -151,13 +150,21 @@ typedef struct svga_t uint32_t pitch; int v_acc, h_acc; } hwcursor, hwcursor_latch, overlay, overlay_latch; - + int hwcursor_on; int overlay_on; - + int hwcursor_oddeven; int overlay_oddeven; - + + /*If set then another device is driving the monitor output and the SVGA + card should not attempt to display anything */ + int override; + void *p; + + uint32_t linear_base; + uint32_t overscan_color; + void (*render)(struct svga_t *svga); void (*recalctimings_ex)(struct svga_t *svga); @@ -167,15 +174,8 @@ typedef struct svga_t void (*hwcursor_draw)(struct svga_t *svga, int displine); void (*overlay_draw)(struct svga_t *svga, int displine); - + void (*vblank_start)(struct svga_t *svga); - - /*If set then another device is driving the monitor output and the SVGA - card should not attempt to display anything */ - int override; - void *p; - - uint32_t linear_base; } svga_t; extern int svga_init(svga_t *svga, void *p, int memsize,