diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h
index 9022a4a86..4380e041b 100644
--- a/src/include/86box/vid_svga.h
+++ b/src/include/86box/vid_svga.h
@@ -226,6 +226,8 @@ extern void ati68860_hwcursor_draw(svga_t *svga, int displine);
extern void att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga);
extern uint8_t att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga);
+extern void att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga);
+extern uint8_t att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga);
extern float av9194_getclock(int clock, void *p);
extern void bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga);
@@ -278,6 +280,7 @@ extern const device_t ati68860_ramdac_device;
extern const device_t att490_ramdac_device;
extern const device_t att491_ramdac_device;
extern const device_t att492_ramdac_device;
+extern const device_t att498_ramdac_device;
extern const device_t av9194_device;
extern const device_t bt484_ramdac_device;
extern const device_t att20c504_ramdac_device;
diff --git a/src/include/86box/video.h b/src/include/86box/video.h
index 166770154..3e0c74ce9 100644
--- a/src/include/86box/video.h
+++ b/src/include/86box/video.h
@@ -226,24 +226,28 @@ extern const device_t compaq_ati28800_device;
extern const device_t ati28800_wonderxl24_device;
#endif
-/* Cirrus Logic CL-GD 54xx */
+/* Cirrus Logic GD54xx */
extern const device_t gd5401_isa_device;
extern const device_t gd5402_isa_device;
extern const device_t gd5402_onboard_device;
extern const device_t gd5420_isa_device;
extern const device_t gd5422_isa_device;
extern const device_t gd5424_vlb_device;
+extern const device_t gd5426_isa_device;
+extern const device_t gd5426_diamond_speedstar_pro_a1_isa_device;
extern const device_t gd5426_vlb_device;
extern const device_t gd5426_onboard_device;
extern const device_t gd5428_isa_device;
extern const device_t gd5428_vlb_device;
+extern const device_t gd5428_diamond_speedstar_pro_b1_vlb_device;
extern const device_t gd5428_mca_device;
extern const device_t gd5428_onboard_device;
extern const device_t gd5429_isa_device;
extern const device_t gd5429_vlb_device;
-extern const device_t gd5430_vlb_device;
+extern const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device;
extern const device_t gd5430_pci_device;
extern const device_t gd5434_isa_device;
+extern const device_t gd5434_diamond_speedstar_64_a3_isa_device;
extern const device_t gd5434_onboard_pci_device;
extern const device_t gd5434_vlb_device;
extern const device_t gd5434_pci_device;
@@ -369,6 +373,7 @@ extern const device_t s3_mirocrystal_20sv_964_pci_device;
extern const device_t s3_mirocrystal_20sd_864_vlb_device;
extern const device_t s3_phoenix_vision864_pci_device;
extern const device_t s3_phoenix_vision864_vlb_device;
+extern const device_t s3_9fx_531_pci_device;
extern const device_t s3_phoenix_vision868_pci_device;
extern const device_t s3_phoenix_vision868_vlb_device;
extern const device_t s3_diamond_stealth64_pci_device;
@@ -376,6 +381,7 @@ extern const device_t s3_diamond_stealth64_vlb_device;
extern const device_t s3_diamond_stealth64_964_pci_device;
extern const device_t s3_diamond_stealth64_964_vlb_device;
extern const device_t s3_mirovideo_40sv_ergo_968_pci_device;
+extern const device_t s3_9fx_771_pci_device;
extern const device_t s3_phoenix_vision968_pci_device;
extern const device_t s3_phoenix_vision968_vlb_device;
extern const device_t s3_spea_mercury_p64v_pci_device;
diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt
index 0c3befa62..b42bd21cb 100644
--- a/src/video/CMakeLists.txt
+++ b/src/video/CMakeLists.txt
@@ -24,7 +24,7 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c
vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c vid_rtg310x.c
vid_f82c425.c vid_ti_cf62011.c vid_tvga.c vid_tgui9440.c vid_tkd8001_ramdac.c
vid_att20c49x_ramdac.c vid_s3.c vid_s3_virge.c vid_ibm_rgb528_ramdac.c
- vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c)
+ vid_sdac_ramdac.c vid_ogc.c vid_nga.c vid_tvp3026_ramdac.c vid_att2xc498_ramdac.c)
if(MGA)
target_compile_definitions(vid PRIVATE USE_MGA)
diff --git a/src/video/vid_att2xc498_ramdac.c b/src/video/vid_att2xc498_ramdac.c
new file mode 100644
index 000000000..747ffe75c
--- /dev/null
+++ b/src/video/vid_att2xc498_ramdac.c
@@ -0,0 +1,186 @@
+/*
+ * 86Box A hypervisor and IBM PC system emulator that specializes in
+ * running old operating systems and software designed for IBM
+ * PC systems and compatibles from 1981 through fairly recent
+ * system designs based on the PCI bus.
+ *
+ * This file is part of the 86Box distribution.
+ *
+ * Emulation of a AT&T 2xc498 RAMDAC.
+ *
+ *
+ *
+ * Authors: Sarah Walker,
+ * Miran Grca,
+ *
+ * Copyright 2008-2018 Sarah Walker.
+ * Copyright 2016-2018 Miran Grca.
+ */
+#include
+#include
+#include
+#include
+#include
+#include <86box/86box.h>
+#include <86box/device.h>
+#include <86box/mem.h>
+#include <86box/timer.h>
+#include <86box/video.h>
+#include <86box/vid_svga.h>
+
+
+typedef struct
+{
+ 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;
+
+ 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;
+ }
+
+ 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);
+ 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;
+ }
+}
+
+
+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);
+ 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;
+ }
+
+ return temp;
+}
+
+
+static void *
+att498_ramdac_init(const device_t *info)
+{
+ att498_ramdac_t *ramdac = (att498_ramdac_t *) malloc(sizeof(att498_ramdac_t));
+ memset(ramdac, 0, sizeof(att498_ramdac_t));
+
+ ramdac->type = info->local;
+
+ return ramdac;
+}
+
+
+static void
+att498_ramdac_close(void *priv)
+{
+ att498_ramdac_t *ramdac = (att498_ramdac_t *) priv;
+
+ if (ramdac)
+ free(ramdac);
+}
+
+
+const device_t att498_ramdac_device =
+{
+ "AT&T 22c498 RAMDAC",
+ 0, 0,
+ att498_ramdac_init, att498_ramdac_close,
+ NULL, { NULL }, NULL, NULL
+};
\ No newline at end of file
diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c
index 7ba2efb3c..3055de90a 100644
--- a/src/video/vid_cl54xx.c
+++ b/src/video/vid_cl54xx.c
@@ -45,13 +45,15 @@
#define BIOS_GD5402_ONBOARD_PATH "roms/machines/cbm_sl386sx25/c000.rom"
#define BIOS_GD5420_PATH "roms/video/cirruslogic/5420.vbi"
#define BIOS_GD5422_PATH "roms/video/cirruslogic/cl5422.bin"
-#define BIOS_GD5426_PATH "roms/video/cirruslogic/Diamond SpeedStar PRO VLB v3.04.bin"
+#define BIOS_GD5426_DIAMOND_A1_ISA_PATH "roms/video/cirruslogic/diamond5426.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_GD5429_PATH "roms/video/cirruslogic/5429.vbi"
-#define BIOS_GD5430_VLB_PATH "roms/video/cirruslogic/diamondvlbus.bin"
-#define BIOS_GD5430_PCI_PATH "roms/video/cirruslogic/pci.bin"
+#define BIOS_GD5430_DIAMOND_A8_VLB_PATH "roms/video/cirruslogic/diamondvlbus.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"
@@ -1209,11 +1211,62 @@ gd54xx_in(uint16_t addr, void *p)
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->gdcreg[0x17] & ~(7 << 3);
+ 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)
@@ -3844,17 +3897,29 @@ static void
case CIRRUS_ID_CLGD5426:
if (info->local & 0x200)
romfn = NULL;
- else
- romfn = BIOS_GD5426_PATH;
+ else {
+ if (info->local & 0x100)
+ romfn = BIOS_GD5426_DIAMOND_A1_ISA_PATH;
+ else {
+ if (gd54xx->vlb)
+ romfn = BIOS_GD5428_PATH;
+ else
+ romfn = BIOS_GD5428_ISA_PATH;
+ }
+ }
break;
case CIRRUS_ID_CLGD5428:
- if (gd54xx->vlb)
- romfn = BIOS_GD5428_PATH;
- else if (gd54xx->mca)
- romfn = BIOS_GD5428_MCA_PATH;
- else
- romfn = BIOS_GD5428_ISA_PATH;
+ if (info->local & 0x100)
+ romfn = BIOS_GD5428_DIAMOND_B1_VLB_PATH;
+ 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:
@@ -3873,8 +3938,12 @@ static void
if (info->local & 0x200) {
romfn = NULL;
gd54xx->has_bios = 0;
- } else
- romfn = BIOS_GD5434_PATH;
+ } else {
+ if (info->local & 0x100)
+ romfn = BIOS_GD5434_DIAMOND_A3_ISA_PATH;
+ else
+ romfn = BIOS_GD5434_PATH;
+ }
break;
case CIRRUS_ID_CLGD5436:
@@ -3896,9 +3965,9 @@ static void
romfn = NULL;
gd54xx->has_bios = 0;
} else if (gd54xx->pci)
- romfn = BIOS_GD5430_PCI_PATH;
+ romfn = BIOS_GD5430_PATH;
else
- romfn = BIOS_GD5430_VLB_PATH;
+ romfn = BIOS_GD5430_DIAMOND_A8_VLB_PATH;
}
break;
@@ -3915,23 +3984,24 @@ static void
}
if (info->flags & DEVICE_MCA) {
- vram = 1;
- gd54xx->vram_size = 1 << 20;
+ vram = 1024;
+ gd54xx->vram_size = vram << 10;
} else {
- if (id >= CIRRUS_ID_CLGD5420) {
+ if (id <= CIRRUS_ID_CLGD5428) {
if ((id == CIRRUS_ID_CLGD5426) && (info->local & 0x200))
- vram = 1;
+ 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");
- } else
- vram = 0;
-
- if (vram)
- gd54xx->vram_size = vram << 20;
- else
- gd54xx->vram_size = 1 << 19;
+ 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)
@@ -3955,8 +4025,8 @@ static void
}
svga->vblank_start = gd54xx_vblank_start;
svga->ven_write = gd54xx_write_modes45;
- if (vram <= 1)
- svga->decode_mask = gd54xx->vram_mask;
+ 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);
@@ -4039,6 +4109,7 @@ static void
svga->crtc[0x27] = id;
svga->seqregs[6] = 0x0f;
+
if (svga->crtc[0x27] >= CIRRUS_ID_CLGD5429)
gd54xx->unlocked = 1;
@@ -4089,9 +4160,9 @@ gd5422_available(void)
}
static int
-gd5426_available(void)
+gd5426_diamond_a1_available(void)
{
- return rom_present(BIOS_GD5426_PATH);
+ return rom_present(BIOS_GD5426_DIAMOND_A1_ISA_PATH);
}
static int
@@ -4100,6 +4171,12 @@ gd5428_available(void)
return rom_present(BIOS_GD5428_PATH);
}
+static int
+gd5428_diamond_b1_available(void)
+{
+ return rom_present(BIOS_GD5428_DIAMOND_B1_VLB_PATH);
+}
+
static int
gd5428_isa_available(void)
{
@@ -4119,15 +4196,15 @@ gd5429_available(void)
}
static int
-gd5430_vlb_available(void)
+gd5430_diamond_a8_available(void)
{
- return rom_present(BIOS_GD5430_VLB_PATH);
+ return rom_present(BIOS_GD5430_DIAMOND_A8_VLB_PATH);
}
static int
-gd5430_pci_available(void)
+gd5430_available(void)
{
- return rom_present(BIOS_GD5430_PCI_PATH);
+ return rom_present(BIOS_GD5430_PATH);
}
static int
@@ -4136,6 +4213,12 @@ gd5434_available(void)
return rom_present(BIOS_GD5434_PATH);
}
+static int
+gd5434_diamond_a3_available(void)
+{
+ return rom_present(BIOS_GD5434_DIAMOND_A3_ISA_PATH);
+}
+
static int
gd5436_available(void)
{
@@ -4199,28 +4282,96 @@ gd54xx_force_redraw(void *p)
gd54xx->svga.fullchange = changeframecount;
}
-static const device_config_t gd5422_config[] =
+static const device_config_t gd542x_config[] =
{
{
- "memory","Memory size",CONFIG_SELECTION,"", 1, "", { 0 },
+ .name = "memory",
+ .description = "Memory size",
+ .type = CONFIG_SELECTION,
+ .selection =
{
{
- "512 KB", 0
+ .description = "512 KB",
+ .value = 512
},
{
- "1 MB", 1
+ .description = "1 MB",
+ .value = 1024
},
{
- ""
+ .description = ""
}
},
+ .default_int = 512
},
{
- "", "", -1
+ .type = -1
}
};
-static const device_config_t gd5428_config[] =
+static const device_config_t gd5426_config[] =
+{
+ {
+ .name = "memory",
+ .description = "Memory size",
+ .type = CONFIG_SELECTION,
+ .selection =
+ {
+ {
+ .description = "512 KB",
+ .value = 512
+ },
+ {
+ .description = "1 MB",
+ .value = 1024
+ },
+ {
+ .description = "2 MB",
+ .value = 2048
+ },
+ {
+ .description = ""
+ }
+ },
+ .default_int = 2048
+ },
+ {
+ .type = -1
+ }
+};
+
+static const device_config_t gd5428_onboard_config[] =
+{
+ {
+ .name = "memory",
+ .description = "Onboard memory size",
+ .type = CONFIG_SELECTION,
+ .selection =
+ {
+ {
+ .description = "512 KB",
+ .value = 512
+ },
+ {
+ .description = "1 MB",
+ .value = 1024
+ },
+ {
+ .description = "2 MB",
+ .value = 2048
+ },
+ {
+ .description = ""
+ }
+ },
+ .default_int = 2048
+ },
+ {
+ .type = -1
+ }
+};
+
+static const device_config_t gd5429_config[] =
{
{
.name = "memory",
@@ -4247,38 +4398,11 @@ static const device_config_t gd5428_config[] =
}
};
-static const device_config_t gd5428_onboard_config[] =
-{
- {
- .name = "memory",
- .description = "Onboard Video RAM size",
- .type = CONFIG_SELECTION,
- .selection =
- {
- {
- .description = "1 MB",
- .value = 1
- },
- {
- .description = "2 MB",
- .value = 2
- },
- {
- .description = ""
- }
- },
- .default_int = 2
- },
- {
- .type = -1
- }
-};
-
static const device_config_t gd5440_onboard_config[] =
{
{
.name = "memory",
- .description = "Video memory size",
+ .description = "Onboard memory size",
.type = CONFIG_SELECTION,
.selection =
{
@@ -4302,6 +4426,68 @@ static const device_config_t gd5440_onboard_config[] =
};
static const device_config_t gd5434_config[] =
+{
+ {
+ .name = "memory",
+ .description = "Memory size",
+ .type = CONFIG_SELECTION,
+ .selection =
+ {
+ {
+ .description = "1 MB",
+ .value = 1
+ },
+ {
+ .description = "2 MB",
+ .value = 2
+ },
+ {
+ .description = "4 MB",
+ .value = 4
+ },
+ {
+ .description = ""
+ }
+ },
+ .default_int = 4
+ },
+ {
+ .type = -1
+ }
+};
+
+static const device_config_t gd5434_onboard_config[] =
+{
+ {
+ .name = "memory",
+ .description = "Onboard memory size",
+ .type = CONFIG_SELECTION,
+ .selection =
+ {
+ {
+ .description = "1 MB",
+ .value = 1
+ },
+ {
+ .description = "2 MB",
+ .value = 2
+ },
+ {
+ .description = "4 MB",
+ .value = 4
+ },
+ {
+ .description = ""
+ }
+ },
+ .default_int = 4
+ },
+ {
+ .type = -1
+ }
+};
+
+static const device_config_t gd5480_config[] =
{
{
.name = "memory",
@@ -4330,7 +4516,7 @@ static const device_config_t gd5434_config[] =
const device_t gd5401_isa_device =
{
- "Cirrus Logic GD-5401 (ACUMOS AVGA1)",
+ "Cirrus Logic GD5401 (ISA) (ACUMOS AVGA1)",
DEVICE_ISA,
CIRRUS_ID_CLGD5401,
gd54xx_init, gd54xx_close,
@@ -4343,7 +4529,7 @@ const device_t gd5401_isa_device =
const device_t gd5402_isa_device =
{
- "Cirrus Logic GD-5402 (ACUMOS AVGA2)",
+ "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2)",
DEVICE_ISA,
CIRRUS_ID_CLGD5402,
gd54xx_init, gd54xx_close,
@@ -4356,7 +4542,7 @@ const device_t gd5402_isa_device =
const device_t gd5402_onboard_device =
{
- "Cirrus Logic GD-5402 (ACUMOS AVGA2) (On-Board)",
+ "Cirrus Logic GD5402 (ISA) (ACUMOS AVGA2) (On-Board)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5402 | 0x200,
gd54xx_init, gd54xx_close,
@@ -4369,7 +4555,7 @@ const device_t gd5402_onboard_device =
const device_t gd5420_isa_device =
{
- "Cirrus Logic GD-5420",
+ "Cirrus Logic GD5420 (ISA)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5420,
gd54xx_init, gd54xx_close,
@@ -4377,11 +4563,11 @@ const device_t gd5420_isa_device =
{ gd5420_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5422_config,
+ gd542x_config,
};
const device_t gd5422_isa_device = {
- "Cirrus Logic GD-5422",
+ "Cirrus Logic GD5422 (ISA)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5422,
gd54xx_init, gd54xx_close,
@@ -4389,11 +4575,11 @@ const device_t gd5422_isa_device = {
{ gd5422_available }, /* Common BIOS between 5422 and 5424 */
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5422_config,
+ gd542x_config,
};
const device_t gd5424_vlb_device = {
- "Cirrus Logic GD-5424",
+ "Cirrus Logic GD5424 (VLB)",
DEVICE_VLB,
CIRRUS_ID_CLGD5424,
gd54xx_init, gd54xx_close,
@@ -4401,26 +4587,57 @@ const device_t gd5424_vlb_device = {
{ gd5422_available }, /* Common BIOS between 5422 and 5424 */
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5422_config,
+ gd542x_config,
+};
+
+const device_t gd5426_isa_device =
+{
+ "Cirrus Logic GD5426 (ISA)",
+ DEVICE_AT | DEVICE_ISA,
+ CIRRUS_ID_CLGD5426,
+ gd54xx_init,
+ gd54xx_close,
+ gd54xx_reset,
+ { gd5428_isa_available },
+ gd54xx_speed_changed,
+ gd54xx_force_redraw,
+ gd5426_config
+};
+
+
+/*According to a Diamond bios file listing and vgamuseum*/
+const device_t gd5426_diamond_speedstar_pro_a1_isa_device =
+{
+ "Cirrus Logic GD5426 (ISA) (Diamond SpeedStar Pro Rev. A1)",
+ DEVICE_AT | DEVICE_ISA,
+ CIRRUS_ID_CLGD5426 | 0x100,
+ gd54xx_init,
+ gd54xx_close,
+ gd54xx_reset,
+ { gd5426_diamond_a1_available },
+ gd54xx_speed_changed,
+ gd54xx_force_redraw,
+ gd5426_config
};
const device_t gd5426_vlb_device =
{
- "Cirrus Logic CL-GD 5426 (VLB)",
+ "Cirrus Logic GD5426 (VLB)",
DEVICE_VLB,
CIRRUS_ID_CLGD5426,
gd54xx_init,
gd54xx_close,
gd54xx_reset,
- { gd5426_available },
+ { gd5428_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5426_config
};
+
const device_t gd5426_onboard_device =
{
- "Cirrus Logic CL-GD 5426 (On-board)",
+ "Cirrus Logic GD5426 (VLB) (On-Board)",
DEVICE_VLB,
CIRRUS_ID_CLGD5426 | 0x200,
gd54xx_init,
@@ -4434,7 +4651,7 @@ const device_t gd5426_onboard_device =
const device_t gd5428_isa_device =
{
- "Cirrus Logic CL-GD 5428 (ISA)",
+ "Cirrus Logic GD5428 (ISA)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5428,
gd54xx_init,
@@ -4443,12 +4660,12 @@ const device_t gd5428_isa_device =
{ gd5428_isa_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5426_config
};
const device_t gd5428_vlb_device =
{
- "Cirrus Logic CL-GD 5428 (VLB)",
+ "Cirrus Logic GD5428 (VLB)",
DEVICE_VLB,
CIRRUS_ID_CLGD5428,
gd54xx_init,
@@ -4457,12 +4674,27 @@ const device_t gd5428_vlb_device =
{ gd5428_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5426_config
+};
+
+/*According to a Diamond bios file listing and vgamuseum*/
+const device_t gd5428_diamond_speedstar_pro_b1_vlb_device =
+{
+ "Cirrus Logic GD5428 (VLB) (Diamond SpeedStar Pro Rev. B1)",
+ DEVICE_VLB,
+ CIRRUS_ID_CLGD5428 | 0x100,
+ gd54xx_init,
+ gd54xx_close,
+ gd54xx_reset,
+ { gd5428_diamond_b1_available },
+ gd54xx_speed_changed,
+ gd54xx_force_redraw,
+ gd5426_config
};
const device_t gd5428_mca_device =
{
- "Cirrus Logic CL-GD 5428 (IBM SVGA Adapter/A)",
+ "Cirrus Logic GD5428 (MCA) (IBM SVGA Adapter/A)",
DEVICE_MCA,
CIRRUS_ID_CLGD5428,
gd54xx_init,
@@ -4476,7 +4708,7 @@ const device_t gd5428_mca_device =
const device_t gd5428_onboard_device =
{
- "Cirrus Logic CL-GD 5428 (On-Board)",
+ "Cirrus Logic GD5428 (ISA) (On-Board)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5428,
gd54xx_init,
@@ -4490,7 +4722,7 @@ const device_t gd5428_onboard_device =
const device_t gd5429_isa_device =
{
- "Cirrus Logic CL-GD 5429 (ISA)",
+ "Cirrus Logic GD5429 (ISA)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5429,
gd54xx_init,
@@ -4499,12 +4731,12 @@ const device_t gd5429_isa_device =
{ gd5429_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5429_config
};
const device_t gd5429_vlb_device =
{
- "Cirrus Logic CL-GD 5429 (VLB)",
+ "Cirrus Logic GD5429 (VLB)",
DEVICE_VLB,
CIRRUS_ID_CLGD5429,
gd54xx_init,
@@ -4513,40 +4745,41 @@ const device_t gd5429_vlb_device =
{ gd5429_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5429_config
};
-const device_t gd5430_vlb_device =
+/*According to a Diamond bios file listing and vgamuseum*/
+const device_t gd5430_diamond_speedstar_pro_se_a8_vlb_device =
{
- "Cirrus Logic CL-GD 5430 (VLB)",
+ "Cirrus Logic GD5430 (VLB) (Diamond SpeedStar Pro SE Rev. A8)",
DEVICE_VLB,
CIRRUS_ID_CLGD5430,
gd54xx_init,
gd54xx_close,
gd54xx_reset,
- { gd5430_vlb_available },
+ { gd5430_diamond_a8_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5429_config
};
const device_t gd5430_pci_device =
{
- "Cirrus Logic CL-GD 5430 (PCI)",
+ "Cirrus Logic GD5430 (PCI)",
DEVICE_PCI,
CIRRUS_ID_CLGD5430,
gd54xx_init,
gd54xx_close,
gd54xx_reset,
- { gd5430_pci_available },
+ { gd5430_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5429_config
};
const device_t gd5434_isa_device =
{
- "Cirrus Logic CL-GD 5434 (ISA)",
+ "Cirrus Logic GD5434 (ISA)",
DEVICE_AT | DEVICE_ISA,
CIRRUS_ID_CLGD5434,
gd54xx_init,
@@ -4558,9 +4791,24 @@ const device_t gd5434_isa_device =
gd5434_config
};
+/*According to a Diamond bios file listing and vgamuseum*/
+const device_t gd5434_diamond_speedstar_64_a3_isa_device =
+{
+ "Cirrus Logic GD5434 (ISA) (Diamond SpeedStar 64 Rev. A3)",
+ DEVICE_AT | DEVICE_ISA,
+ CIRRUS_ID_CLGD5434 | 0x100,
+ gd54xx_init,
+ gd54xx_close,
+ gd54xx_reset,
+ { gd5434_diamond_a3_available },
+ gd54xx_speed_changed,
+ gd54xx_force_redraw,
+ gd5429_config
+};
+
const device_t gd5434_onboard_pci_device =
{
- "Cirrus Logic CL-GD 5434-4 (On-Board PCI)",
+ "Cirrus Logic GD5434-4 (PCI) (On-Board)",
DEVICE_PCI,
CIRRUS_ID_CLGD5434 | 0x200,
gd54xx_init,
@@ -4569,12 +4817,12 @@ const device_t gd5434_onboard_pci_device =
{ NULL },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5434_config
+ gd5434_onboard_config
};
const device_t gd5434_vlb_device =
{
- "Cirrus Logic CL-GD 5434 (VLB)",
+ "Cirrus Logic GD5434 (VLB)",
DEVICE_VLB,
CIRRUS_ID_CLGD5434,
gd54xx_init,
@@ -4588,7 +4836,7 @@ const device_t gd5434_vlb_device =
const device_t gd5434_pci_device =
{
- "Cirrus Logic CL-GD 5434 (PCI)",
+ "Cirrus Logic GD5434 (PCI)",
DEVICE_PCI,
CIRRUS_ID_CLGD5434,
gd54xx_init,
@@ -4602,7 +4850,7 @@ const device_t gd5434_pci_device =
const device_t gd5436_pci_device =
{
- "Cirrus Logic CL-GD 5436 (PCI)",
+ "Cirrus Logic GD5436 (PCI)",
DEVICE_PCI,
CIRRUS_ID_CLGD5436,
gd54xx_init,
@@ -4616,7 +4864,7 @@ const device_t gd5436_pci_device =
const device_t gd5440_onboard_pci_device =
{
- "Cirrus Logic CL-GD 5440 (On-Board PCI)",
+ "Cirrus Logic GD5440 (PCI) (On-Board)",
DEVICE_PCI,
CIRRUS_ID_CLGD5440 | 0x600,
gd54xx_init,
@@ -4630,7 +4878,7 @@ const device_t gd5440_onboard_pci_device =
const device_t gd5440_pci_device =
{
- "Cirrus Logic CL-GD 5440 (PCI)",
+ "Cirrus Logic GD5440 (PCI)",
DEVICE_PCI,
CIRRUS_ID_CLGD5440 | 0x400,
gd54xx_init,
@@ -4639,12 +4887,12 @@ const device_t gd5440_pci_device =
{ gd5440_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5428_config
+ gd5429_config
};
const device_t gd5446_pci_device =
{
- "Cirrus Logic CL-GD 5446 (PCI)",
+ "Cirrus Logic GD5446 (PCI)",
DEVICE_PCI,
CIRRUS_ID_CLGD5446,
gd54xx_init,
@@ -4658,7 +4906,7 @@ const device_t gd5446_pci_device =
const device_t gd5446_stb_pci_device =
{
- "STB Nitro 64V (PCI)",
+ "Cirrus Logic GD5446 (PCI) (STB Nitro 64V)",
DEVICE_PCI,
CIRRUS_ID_CLGD5446 | 0x100,
gd54xx_init,
@@ -4672,7 +4920,7 @@ const device_t gd5446_stb_pci_device =
const device_t gd5480_pci_device =
{
- "Cirrus Logic CL-GD 5480 (PCI)",
+ "Cirrus Logic GD5480 (PCI)",
DEVICE_PCI,
CIRRUS_ID_CLGD5480,
gd54xx_init,
@@ -4681,5 +4929,5 @@ const device_t gd5480_pci_device =
{ gd5480_available },
gd54xx_speed_changed,
gd54xx_force_redraw,
- gd5434_config
+ gd5480_config
};
diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c
index 65dced875..1c2ca794e 100644
--- a/src/video/vid_et4000w32.c
+++ b/src/video/vid_et4000w32.c
@@ -78,9 +78,9 @@ typedef struct et4000w32p_t
uint8_t regs[256], pci_regs[256];
int index, vlb, pci, interleaved,
- bank, blitter_busy, type;
+ bank, type;
- uint32_t linearbase, linearbase_old;
+ uint32_t linearbase;
uint32_t vram_mask;
/* Accelerator */
@@ -97,12 +97,13 @@ typedef struct et4000w32p_t
uint32_t pattern_addr, source_addr, dest_addr, mix_addr;
} queued, internal;
- uint8_t osr;
+ 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, queue;
+ cpu_input_num, fifo_queue;
uint32_t pattern_addr, source_addr, dest_addr, mix_addr,
pattern_back, source_back, dest_back, mix_back,
@@ -115,6 +116,8 @@ typedef struct et4000w32p_t
uint32_t base[3];
uint8_t ctrl;
} mmu;
+
+ volatile int busy;
} et4000w32p_t;
@@ -131,12 +134,13 @@ static video_timings_t timing_et4000w32_isa = {VIDEO_ISA, 4, 4, 4, 10, 10, 10
void et4000w32p_recalcmapping(et4000w32p_t *et4000);
-uint8_t et4000w32p_mmu_read(uint32_t addr, void *p);
-void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p);
+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 et4000w32_blit_start(et4000w32p_t *et4000);
-void et4000w32p_blit_start(et4000w32p_t *et4000);
-void et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000);
+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);
@@ -213,7 +217,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p)
}
break;
case 0x3d4:
- svga->crtcreg = val & 63;
+ svga->crtcreg = val & 0x3f;
return;
case 0x3d5:
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
@@ -333,12 +337,16 @@ et4000w32p_in(uint16_t addr, void *p)
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;
- /*Bit 1 of the Input Status Register is required by OS/2 ET4000W32/I drivers to be set otherwise
+ /*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;
@@ -397,6 +405,24 @@ et4000w32p_recalctimings(svga_t *svga)
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 */
@@ -550,6 +576,7 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000)
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);
@@ -587,12 +614,8 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000)
svga->banked_mask = 0x7fff;
break;
}
-
- mem_mapping_disable(&et4000->linear_mapping);
}
- et4000->linearbase_old = et4000->linearbase;
-
if (!et4000->interleaved && (svga->crtc[0x32] & 0x80))
mem_mapping_disable(&svga->mapping);
}
@@ -601,128 +624,208 @@ et4000w32p_recalcmapping(et4000w32p_t *et4000)
static void
et4000w32p_accel_write_fifo(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
{
- switch (addr & 0x7fff) {
- case 0x7f80: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFFFF00) | val; break;
- case 0x7f81: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFFFF00FF) | (val << 8); break;
- case 0x7f82: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0xFF00FFFF) | (val << 16); break;
- case 0x7f83: et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break;
- case 0x7f84: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFFFF00) | val; break;
- case 0x7f85: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFFFF00FF) | (val << 8); break;
- case 0x7f86: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0xFF00FFFF) | (val << 16); break;
- case 0x7f87: et4000->acl.queued.source_addr = (et4000->acl.queued.source_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break;
- case 0x7f88: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0xFF00) | val; break;
- case 0x7f89: et4000->acl.queued.pattern_off = (et4000->acl.queued.pattern_off & 0x00FF) | (val << 8); et4000->acl.queue++; break;
- case 0x7f8a: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0xFF00) | val; break;
- case 0x7f8b: et4000->acl.queued.source_off = (et4000->acl.queued.source_off & 0x00FF) | (val << 8); et4000->acl.queue++;break;
- case 0x7f8c: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0xFF00) | val; break;
- case 0x7f8d: et4000->acl.queued.dest_off = (et4000->acl.queued.dest_off & 0x00FF) | (val << 8); et4000->acl.queue++; break;
- case 0x7f8e:
- et4000->acl.queue++;
- if (et4000->type >= ET4000W32P_REVC)
- et4000->acl.queued.pixel_depth = val;
- else
- et4000->acl.queued.vbus = val;
+ et4000->acl.fifo_queue++;
+ switch (addr & 0xff) {
+ case 0x80:
+ et4000->acl.queued.pattern_addr = (et4000->acl.queued.pattern_addr & 0x3fff00) | val;
break;
- case 0x7f8f: et4000->acl.queued.xy_dir = val; et4000->acl.queue++; break;
- case 0x7f90: et4000->acl.queued.pattern_wrap = val; et4000->acl.queue++; break;
- case 0x7f92: et4000->acl.queued.source_wrap = val; et4000->acl.queue++; break;
- case 0x7f98: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0xFF00) | val; break;
- case 0x7f99: et4000->acl.queued.count_x = (et4000->acl.queued.count_x & 0x00FF) | (val << 8); et4000->acl.queue++; break;
- case 0x7f9a: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0xFF00) | val; break;
- case 0x7f9b: et4000->acl.queued.count_y = (et4000->acl.queued.count_y & 0x00FF) | (val << 8); et4000->acl.queue++; break;
- case 0x7f9c: et4000->acl.queued.ctrl_routing = val; et4000->acl.queue++; break;
- case 0x7f9d: et4000->acl.queued.ctrl_reload = val; et4000->acl.queue++; break;
- case 0x7f9e: et4000->acl.queued.rop_bg = val; et4000->acl.queue++; break;
- case 0x7f9f: et4000->acl.queued.rop_fg = val; et4000->acl.queue++; break;
- case 0x7fa0: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFFFF00) | val; break;
- case 0x7fa1: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFFFF00FF) | (val << 8); break;
- case 0x7fa2: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0xFF00FFFF) | (val << 16); break;
- case 0x7fa3: et4000->acl.queued.dest_addr = (et4000->acl.queued.dest_addr & 0x00FFFFFF) | (val << 24);
- et4000->acl.queue++;
+ 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) {
- if (et4000->acl.osr & 0x10) {
- et4000w32p_blit_start(et4000);
- 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);
- }
+ 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))
- et4000w32p_blit(0xffffff, ~0, 0, 0, et4000);
+ if (!(et4000->acl.queued.ctrl_routing & 0x37)) {
+ et4000w32_blit(-1, 0, 0, 0xffffffff, et4000);
+ }
}
break;
- case 0x7fa4: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFFFF00) | val; break;
- case 0x7fa5: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFFFF00FF) | (val << 8); break;
- case 0x7fa6: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0xFF00FFFF) | (val << 16); break;
- case 0x7fa7: et4000->acl.queued.mix_addr = (et4000->acl.queued.mix_addr & 0x00FFFFFF) | (val << 24); et4000->acl.queue++; break;
- case 0x7fa8: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0xFF00) | val; break;
- case 0x7fa9: et4000->acl.queued.mix_off = (et4000->acl.queued.mix_off & 0x00FF) | (val << 8); et4000->acl.queue++; break;
- case 0x7faa: et4000->acl.queued.error = (et4000->acl.queued.error & 0xFF00) | val; break;
- case 0x7fab: et4000->acl.queued.error = (et4000->acl.queued.error & 0x00FF) | (val << 8); et4000->acl.queue++; break;
- case 0x7fac: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0xFF00) | val; break;
- case 0x7fad: et4000->acl.queued.dmin = (et4000->acl.queued.dmin & 0x00FF) | (val << 8); et4000->acl.queue++; break;
- case 0x7fae: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0xFF00) | val; break;
- case 0x7faf: et4000->acl.queued.dmaj = (et4000->acl.queued.dmaj & 0x00FF) | (val << 8); et4000->acl.queue++; 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;
}
}
-
static void
-et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint8_t val)
+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))
+ if (!(et4000->acl.status & ACL_XYST)) {
+ et4000w32_log("XY MMU block not started\n");
return;
+ }
if (et4000->acl.internal.ctrl_routing & 3) {
- et4000->acl.queue++;
- if ((et4000->acl.internal.ctrl_routing & 3) == 2) {
+ 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) {
+ 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.queue++;
- et4000->acl.queued.dest_addr = (addr & 0x1FFF) + et4000->mmu.base[et4000->bank];
+ 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);
- if (!(et4000->acl.internal.ctrl_routing & 0x37))
- et4000w32p_blit(0xFFFFFF, ~0, 0, 0, et4000);
+ et4000w32_log("Accelerated MMU aperture = %i and start XY Block (Implicit), xcnt = %i, ycnt = %i\n", bank, et4000->acl.x_count + 1, et4000->acl.y_count + 1);
et4000->acl.cpu_input_num = 0;
+ if (!(et4000->acl.queued.ctrl_routing & 0x37)) {
+ et4000w32_blit(-1, 0, 0, 0xffffffff, et4000);
+ }
}
if (et4000->acl.internal.ctrl_routing & 7) {
- et4000->acl.queue++;
- et4000->acl.cpu_input = (et4000->acl.cpu_input &~ (0xFF << (et4000->acl.cpu_input_num << 3))) |
+ 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 & 3]) {
- if ((et4000->acl.internal.ctrl_routing & 7) == 2)
- et4000w32p_blit(et4000->acl.cpu_input_num << 3, et4000->acl.cpu_input, 0, 1, et4000);
- else if ((et4000->acl.internal.ctrl_routing & 7) == 1)
- et4000w32p_blit(et4000->acl.cpu_input_num, ~0, et4000->acl.cpu_input, 2, et4000);
- else if ((et4000->acl.internal.ctrl_routing & 7) == 4)
- et4000w32p_blit(et4000->acl.cpu_input_num, ~0, et4000->acl.internal.count_x, 2, et4000);
- else if ((et4000->acl.internal.ctrl_routing & 7) == 5)
- et4000w32p_blit(et4000->acl.cpu_input_num, ~0, et4000->acl.internal.count_y, 2, 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;
}
+
+ 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);
}
}
}
-
-void
+static void
et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
{
et4000w32p_t *et4000 = (et4000w32p_t *)p;
@@ -734,7 +837,7 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
case 0x4000: /* MMU 2 */
et4000->bank = (addr >> 13) & 3;
if (et4000->mmu.ctrl & (1 << et4000->bank)) {
- et4000w32p_accel_write_mmu(et4000, addr & 0x7fff, val);
+ 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]] = val;
@@ -743,43 +846,65 @@ et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p)
}
break;
case 0x6000:
- if ((addr & 0x7fff) >= 0x7f80) {
+ if ((addr & 0xff) >= 0x80) {
et4000w32p_accel_write_fifo(et4000, addr & 0x7fff, val);
- } else switch (addr & 0x7fff) {
- case 0x7f00: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFFFF00) | val; break;
- case 0x7f01: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFFFF00FF) | (val << 8); break;
- case 0x7f02: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0xFF00FFFF) | (val << 16); break;
- case 0x7f03: et4000->mmu.base[0] = (et4000->mmu.base[0] & 0x00FFFFFF) | (val << 24); break;
- case 0x7f04: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFFFF00) | val; break;
- case 0x7f05: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFFFF00FF) | (val << 8); break;
- case 0x7f06: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0xFF00FFFF) | (val << 16); break;
- case 0x7f07: et4000->mmu.base[1] = (et4000->mmu.base[1] & 0x00FFFFFF) | (val << 24); break;
- case 0x7f08: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFFFF00) | val; break;
- case 0x7f09: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFFFF00FF) | (val << 8); break;
- case 0x7f0a: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0xFF00FFFF) | (val << 16); break;
- case 0x7f0b: et4000->mmu.base[2] = (et4000->mmu.base[2] & 0x00FFFFFF) | (val << 24); break;
- case 0x7f13: et4000->mmu.ctrl = val; break;
- case 0x7f31: et4000->acl.osr = val; break;
+ } 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;
}
}
-
-uint8_t
+static uint8_t
et4000w32p_mmu_read(uint32_t addr, void *p)
{
et4000w32p_t *et4000 = (et4000w32p_t *)p;
svga_t *svga = &et4000->svga;
- int bank;
uint8_t temp;
switch (addr & 0x6000) {
case 0x0000: /* MMU 0 */
case 0x2000: /* MMU 1 */
case 0x4000: /* MMU 2 */
- bank = (addr >> 13) & 3;
- if (et4000->mmu.ctrl & (1 << bank)) {
+ 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--;
@@ -793,84 +918,97 @@ et4000w32p_mmu_read(uint32_t addr, void *p)
return temp;
}
- if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_max)
+ if ((addr & 0x1fff) + et4000->mmu.base[et4000->bank] >= svga->vram_max)
return 0xff;
- return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]];
+ return svga->vram[(addr & 0x1fff) + et4000->mmu.base[et4000->bank]];
case 0x6000:
- switch (addr & 0x7fff) {
- case 0x7f00: return et4000->mmu.base[0];
- case 0x7f01: return et4000->mmu.base[0] >> 8;
- case 0x7f02: return et4000->mmu.base[0] >> 16;
- case 0x7f03: return et4000->mmu.base[0] >> 24;
- case 0x7f04: return et4000->mmu.base[1];
- case 0x7f05: return et4000->mmu.base[1] >> 8;
- case 0x7f06: return et4000->mmu.base[1] >> 16;
- case 0x7f07: return et4000->mmu.base[1] >> 24;
- case 0x7f08: return et4000->mmu.base[2];
- case 0x7f09: return et4000->mmu.base[2] >> 8;
- case 0x7f0a: return et4000->mmu.base[2] >> 16;
- case 0x7f0b: return et4000->mmu.base[2] >> 24;
- case 0x7f13: return et4000->mmu.ctrl;
+ 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 0x7f36:
- if (et4000->type >= ET4000W32P_REVC) {
- if (et4000->acl.queue) {
- et4000->acl.status |= ACL_RDST;
- et4000->acl.queue = 0;
- } else
- et4000->acl.status &= ~ACL_RDST;
-
- temp = et4000->acl.status;
- } else {
- et4000->acl.status &= ~(ACL_XYST | ACL_SSO);
+ 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;
- if (et4000->acl.queue) {
- et4000->acl.status |= ACL_RDST;
- et4000->acl.queue = 0;
- } else
- et4000->acl.status &= ~ACL_RDST;
-
- temp = et4000->acl.status;
- }
- return temp;
-
- case 0x7f80: return et4000->acl.internal.pattern_addr;
- case 0x7f81: return et4000->acl.internal.pattern_addr >> 8;
- case 0x7f82: return et4000->acl.internal.pattern_addr >> 16;
- case 0x7f83: return et4000->acl.internal.pattern_addr >> 24;
- case 0x7f84: return et4000->acl.internal.source_addr;
- case 0x7f85: return et4000->acl.internal.source_addr >> 8;
- case 0x7f86: return et4000->acl.internal.source_addr >> 16;
- case 0x7f87: return et4000->acl.internal.source_addr >> 24;
- case 0x7f88: return et4000->acl.internal.pattern_off;
- case 0x7f89: return et4000->acl.internal.pattern_off >> 8;
- case 0x7f8a: return et4000->acl.internal.source_off;
- case 0x7f8b: return et4000->acl.internal.source_off >> 8;
- case 0x7f8c: return et4000->acl.internal.dest_off;
- case 0x7f8d: return et4000->acl.internal.dest_off >> 8;
- case 0x7f8e:
+ 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 0x7f8f: return et4000->acl.internal.xy_dir;
- case 0x7f90: return et4000->acl.internal.pattern_wrap;
- case 0x7f92: return et4000->acl.internal.source_wrap;
- case 0x7f98: return et4000->acl.internal.count_x;
- case 0x7f99: return et4000->acl.internal.count_x >> 8;
- case 0x7f9a: return et4000->acl.internal.count_y;
- case 0x7f9b: return et4000->acl.internal.count_y >> 8;
- case 0x7f9c: return et4000->acl.internal.ctrl_routing;
- case 0x7f9d: return et4000->acl.internal.ctrl_reload;
- case 0x7f9e: return et4000->acl.internal.rop_bg;
- case 0x7f9f: return et4000->acl.internal.rop_fg;
- case 0x7fa0: return et4000->acl.internal.dest_addr;
- case 0x7fa1: return et4000->acl.internal.dest_addr >> 8;
- case 0x7fa2: return et4000->acl.internal.dest_addr >> 16;
- case 0x7fa3: return et4000->acl.internal.dest_addr >> 24;
+ 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;
@@ -883,16 +1021,19 @@ et4000w32p_mmu_read(uint32_t addr, void *p)
void
et4000w32_blit_start(et4000w32p_t *et4000)
{
- 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.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.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_x = et4000->acl.source_x = et4000->acl.pattern_y = et4000->acl.source_y = 0;
et4000->acl.status |= ACL_XYST;
+ et4000->acl.status &= ~ACL_SSO;
- if (!(et4000->acl.internal.ctrl_routing & 7))
+ if (!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4))
et4000->acl.status |= ACL_SSO;
if (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7]) {
@@ -900,10 +1041,11 @@ et4000w32_blit_start(et4000w32p_t *et4000)
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)
+ 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
+ } 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);
}
@@ -913,13 +1055,12 @@ et4000w32_blit_start(et4000w32p_t *et4000)
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)
+ 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
+ } 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);
}
@@ -927,9 +1068,12 @@ et4000w32_blit_start(et4000w32p_t *et4000)
}
-void
+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;
+
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;
@@ -941,6 +1085,7 @@ et4000w32p_blit_start(et4000w32p_t *et4000)
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");
if ((!(et4000->acl.internal.ctrl_routing & 7) || (et4000->acl.internal.ctrl_routing & 4)) && !(et4000->acl.internal.ctrl_routing & 0x40))
et4000->acl.status |= ACL_SSO;
@@ -961,13 +1106,14 @@ et4000w32p_blit_start(et4000w32p_t *et4000)
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_x_back = et4000->acl.source_x;
- et4000w32_max_x[2] = ((et4000->acl.internal.pixel_depth & 0x30) == 0x20) ? 3 : 4;
+ et4000w32_max_x[2] = (et4000->acl.internal.pixel_depth == 0x20) ? 3 : 4;
et4000->acl.internal.count_x += (et4000->acl.internal.pixel_depth >> 4) & 3;
et4000->acl.cpu_dat_pos = 0;
@@ -1040,24 +1186,393 @@ et4000w32_decy(et4000w32p_t *et4000)
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_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));
}
}
-void
+#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)
+{
+ svga_t *svga = &et4000->svga;
+ uint8_t pattern, source, dest;
+ uint8_t rop;
+ int mixmap;
+
+ 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];
+
+ 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;
+
+ ROPMIX(rop, dest, pattern, source, dest);
+
+ /*Write the data*/
+ svga->vram[et4000->acl.dest_addr & et4000->vram_mask] = dest;
+ 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);
+ }
+
+ 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);
+ }
+
+ 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;
+ }
+
+ if (cpu_input)
+ return;
+ }
+ }
+}
+
+static void
et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32p_t *et4000)
{
svga_t *svga = &et4000->svga;
- int c, d;
uint8_t pattern, source, dest, out;
uint8_t rop;
int mixdat;
- if (!(et4000->acl.status & ACL_XYST) && (et4000->type >= ET4000W32P_REVC))
- return;
+ if (!(et4000->acl.status & ACL_XYST)) {
+ 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];
@@ -1080,12 +1595,9 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32
}
et4000->acl.mix_addr++;
rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
- for (c = 0; c < 8; c++) {
- d = (dest & (1 << c)) ? 1 : 0;
- if (source & (1 << c)) d |= 2;
- if (pattern & (1 << c)) d |= 4;
- if (rop & (1 << d)) out |= (1 << c);
- }
+
+ 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;
@@ -1157,80 +1669,77 @@ et4000w32p_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et4000w32
}
}
} else {
- while (count--) {
- et4000w32_log("%i,%i : ", et4000->acl.internal.pos_x, et4000->acl.internal.pos_y);
+ 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];
- 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("%i %06X %06X %02X %02X ", et4000->acl.pattern_y, (et4000->acl.pattern_addr + et4000->acl.pattern_x) & et4000->vram_mask, (et4000->acl.source_addr + et4000->acl.source_x) & et4000->vram_mask, pattern, source);
-
- if (cpu_input == 2) {
- source = sdat & 0xff;
- sdat >>= 8;
- }
- dest = svga->vram[et4000->acl.dest_addr & et4000->vram_mask];
- out = 0;
- et4000w32_log("%06X %02X %i %08X %08X ", dest, et4000->acl.dest_addr, mix & 1, mix, et4000->acl.mix_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;
- }
-
- rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
- for (c = 0; c < 8; c++) {
- d = (dest & (1 << c)) ? 1 : 0;
- if (source & (1 << c)) d |= 2;
- if (pattern & (1 << c)) d |= 4;
- if (rop & (1 << d)) out |= (1 << c);
- }
- 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++;
- }
-
- if (et4000->acl.internal.xy_dir & 1) et4000w32_decx(1, et4000);
- else et4000w32_incx(1, et4000);
-
- et4000->acl.internal.pos_x++;
- if (et4000->acl.internal.pos_x > et4000->acl.internal.count_x) {
- 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);
+ 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;
+
+ 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 {
- 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;
+ mixdat = mix & 1;
+ mix >>= 1;
+ mix |= 0x80000000;
}
- et4000->acl.pattern_x = et4000->acl.pattern_x_back;
- et4000->acl.source_x = et4000->acl.source_x_back;
+ rop = mixdat ? et4000->acl.internal.rop_fg : et4000->acl.internal.rop_bg;
- et4000->acl.internal.pos_y++;
- et4000->acl.internal.pos_x = 0;
- if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y) {
- et4000->acl.status &= ~(ACL_XYST | ACL_SSO);
- return;
+ 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 (cpu_input)
- return;
+ 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;
+ }
- 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;
+ 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;
+ }
+
+ 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;
+ }
}
}
- }
}
}
diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c
index 107a1773f..d32871c22 100644
--- a/src/video/vid_paradise.c
+++ b/src/video/vid_paradise.c
@@ -40,7 +40,7 @@ typedef struct paradise_t
rom_t bios_rom;
- uint8_t pr0a, pr0b, pr1, pr5, bank_mask;
+ uint8_t bank_mask;
enum
{
@@ -54,7 +54,7 @@ typedef struct paradise_t
uint32_t read_bank[4], write_bank[4];
int interlace;
- int check;
+ int check, check2;
struct {
uint8_t reg_block_ptr;
@@ -81,7 +81,7 @@ 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, o;
+ uint8_t old;
if (paradise->vram_mask <= ((512 << 10) - 1))
paradise->bank_mask = 0x7f;
@@ -94,15 +94,14 @@ void paradise_out(uint16_t addr, uint8_t val, void *p)
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;
+ 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;
@@ -115,53 +114,45 @@ void paradise_out(uint16_t addr, uint8_t val, void *p)
case 0x3cf:
if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) {
- if ((paradise->pr5 & 7) != 5)
+ if ((svga->gdcreg[0x0f] & 7) != 5)
return;
}
+
switch (svga->gdcaddr) {
case 6:
- if (val & 8)
- svga->banked_mask = 0x7fff;
- else
- svga->banked_mask = 0xffff;
- if (svga->gdcreg[6] != val)
- svga->gdcreg[6] = val;
+ 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);
- break;
+ return;
case 9:
- paradise->pr0a = val & paradise->bank_mask;
- paradise_remap(paradise);
- break;
case 0x0a:
- paradise->pr0b = val & paradise->bank_mask;
+ svga->gdcreg[svga->gdcaddr] = val & paradise->bank_mask;
paradise_remap(paradise);
- break;
+ return;
case 0x0b:
- paradise->pr1 = val;
+ svga->gdcreg[0x0b] = val;
paradise_remap(paradise);
- break;
- case 0x0d:
- o = svga->gdcreg[0x0d];
- svga->gdcreg[0x0d] = val;
- if ((o ^ val) & 0x18)
- svga_recalctimings(svga);
- break;
- case 0x0e:
- o = svga->gdcreg[0x0e];
- svga->gdcreg[0x0e] = val;
- if ((o ^ val) & 0x01)
- svga_recalctimings(svga);
- break;
- case 0x0c:
- svga->gdcreg[0x0c] = val;
- break;
- case 0x0f:
- paradise->pr5 = val;
- break;
- default:
- svga->gdcreg[svga->gdcaddr] = val;
- break;
+ return;
}
break;
@@ -216,10 +207,8 @@ uint8_t paradise_in(uint16_t addr, void *p)
{
if (paradise->type < WD90C11 || svga->seqregs[6] != 0x48)
return 0xff;
- if (paradise->type < WD90C30) {
- if (svga->seqaddr > 0x12)
+ if (svga->seqaddr > 0x12)
return 0xff;
- }
return svga->seqregs[svga->seqaddr & 0x1f];
}
break;
@@ -231,36 +220,21 @@ uint8_t paradise_in(uint16_t addr, void *p)
case 0x3cf:
if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) {
- if (paradise->pr5 & 0x10)
+ if (svga->gdcreg[0x0f] & 0x10)
return 0xff;
}
switch (svga->gdcaddr) {
- case 9:
- return paradise->pr0a;
- case 0x0a:
- return paradise->pr0b;
case 0x0b:
- if (paradise->vram_mask == (512 << 10) - 1) {
- paradise->pr1 |= 0xc0;
- paradise->pr1 &= ~0x40;
- } else if (paradise->vram_mask == (1024 << 10) - 1) {
- paradise->pr1 |= 0xc0;
- /*The following is a horrible tweak, but needed to get around black corruption in 1M mode*/
- if (svga->bpp >= 8 && (svga->gdcreg[0x0e] & 0x01) && paradise->check)
- paradise->pr1 &= ~0x40;
- else if (!(svga->gdcreg[0x0e] & 0x01) && !(svga->crtc[0x14] & 0x40) && paradise->check)
- paradise->check = 0;
+ if (paradise->type == WD90C30) {
+ if (paradise->vram_mask == ((512 << 10) - 1)) {
+ svga->gdcreg[0x0b] |= 0xc0;
+ svga->gdcreg[0x0b] &= ~0x40;
+ }
}
- return paradise->pr1;
- case 6:
- case 0x0c:
- case 0x0d:
- case 0x0e:
- return svga->gdcreg[svga->gdcaddr];
+ return svga->gdcreg[0x0b];
+
case 0x0f:
- return (paradise->pr5 & 0x17) | 0x80;
- default:
- return svga->gdcreg[svga->gdcaddr];
+ return (svga->gdcreg[0x0f] & 0x17) | 0x80;
}
break;
@@ -278,61 +252,46 @@ uint8_t paradise_in(uint16_t addr, void *p)
void paradise_remap(paradise_t *paradise)
{
- svga_t *svga = ¶dise->svga;
+ svga_t *svga = ¶dise->svga;
+ paradise->check = 0;
- if (svga->seqregs[0x11] & 0x80) {
- paradise->read_bank[0] = (paradise->pr0a) << 12;
- paradise->read_bank[1] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->read_bank[2] = paradise->read_bank[0];
- paradise->read_bank[3] = paradise->read_bank[1];
- paradise->write_bank[0] = (paradise->pr0b) << 12;
- paradise->write_bank[1] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->write_bank[2] = paradise->write_bank[0];
- paradise->write_bank[3] = paradise->write_bank[1];
- } else if (paradise->pr1 & 8) {
- if (svga->gdcreg[6] & 0x0c) {
- paradise->read_bank[0] = (paradise->pr0b) << 12;
- paradise->read_bank[1] = ((paradise->pr0a) << 12) + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->read_bank[2] = paradise->read_bank[0];
- paradise->read_bank[3] = paradise->read_bank[1];
- paradise->write_bank[0] = (paradise->pr0b) << 12;
- paradise->write_bank[1] = ((paradise->pr0a) << 12) + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->write_bank[2] = paradise->write_bank[0];
- paradise->write_bank[3] = paradise->write_bank[1];
- } else {
- paradise->read_bank[0] = (paradise->pr0b) << 12;
- paradise->read_bank[1] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->read_bank[2] = (paradise->pr0a) << 12;
- paradise->read_bank[3] = paradise->read_bank[2] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->write_bank[0] = (paradise->pr0b) << 12;
- paradise->write_bank[1] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->write_bank[2] = (paradise->pr0a) << 12;
- paradise->write_bank[3] = paradise->write_bank[2] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- }
- } else {
- paradise->read_bank[0] = (paradise->pr0a) << 12;
- paradise->write_bank[0] = (paradise->pr0a) << 12;
- paradise->read_bank[1] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->write_bank[1] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->read_bank[2] = paradise->read_bank[0];
- paradise->write_bank[2] = paradise->write_bank[0];
- paradise->read_bank[3] = paradise->read_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- paradise->write_bank[3] = paradise->write_bank[0] + ((svga->gdcreg[6] & 8) ? 0 : 0x8000);
- }
-
- if (paradise->bank_mask == 0x7f) {
- paradise->read_bank[1] &= 0x7ffff;
- paradise->write_bank[1] &= 0x7ffff;
+ 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);
+ }
+
+ 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_recalctimings(svga_t *svga)
{
paradise_t *paradise = (paradise_t *) svga->p;
- if (svga->gdcreg[0x0d] & 0x08) svga->ma_latch |= 0x10000;
- if (svga->gdcreg[0x0d] & 0x10) svga->ma_latch |= 0x20000;
-
svga->lowres = !(svga->gdcreg[0x0e] & 0x01);
if (paradise->type == WD90C30) {
@@ -355,8 +314,6 @@ void paradise_recalctimings(svga_t *svga)
if (paradise->type < WD90C30) {
if (svga->bpp >= 8 && !svga->lowres) {
- if ((svga->crtc[0x17] == 0xc2) && (svga->crtc[0x14] & 0x40))
- paradise->check = 1;
svga->render = svga_render_8bpp_highres;
}
} else {
@@ -368,8 +325,6 @@ void paradise_recalctimings(svga_t *svga)
svga->render = svga_render_15bpp_highres;
svga->hdisp >>= 1;
} else {
- if ((svga->crtc[0x17] == 0xc2) && (svga->crtc[0x14] & 0x40))
- paradise->check = 1;
svga->render = svga_render_8bpp_highres;
}
}
@@ -380,20 +335,94 @@ static void paradise_write(uint32_t addr, uint8_t val, void *p)
{
paradise_t *paradise = (paradise_t *)p;
svga_t *svga = ¶dise->svga;
+ uint32_t prev_addr, prev_addr2;
- addr &= svga->banked_mask;
- addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
-
+ addr = (addr & 0x7fff) + paradise->write_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;
+ }
+ }
+ }
+
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;
- addr &= svga->banked_mask;
addr = (addr & 0x7fff) + paradise->write_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;
+ }
+ }
+ }
+
svga_writew_linear(addr, val, svga);
}
@@ -401,9 +430,46 @@ static uint8_t paradise_read(uint32_t addr, void *p)
{
paradise_t *paradise = (paradise_t *)p;
svga_t *svga = ¶dise->svga;
-
- addr &= svga->banked_mask;
+ uint32_t prev_addr, prev_addr2;
+
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;
+ }
+ }
+ }
return svga_read_linear(addr, svga);
}
@@ -411,11 +477,48 @@ static uint16_t paradise_readw(uint32_t addr, void *p)
{
paradise_t *paradise = (paradise_t *)p;
svga_t *svga = ¶dise->svga;
-
- addr &= svga->banked_mask;
+ uint32_t prev_addr, prev_addr2;
+
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;
+ }
+ }
+ }
- return svga_readw_linear(addr, svga);
+ return svga_readw_linear(addr, svga);
}
void *paradise_init(const device_t *info, uint32_t memsize)
@@ -653,9 +756,6 @@ static const device_config_t paradise_pvga1a_config[] =
{
"512 kB", 512
},
- {
- "1 MB", 1024
- },
{
""
}
diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c
index 7dff04e4a..30c0df216 100644
--- a/src/video/vid_s3.c
+++ b/src/video/vid_s3.c
@@ -62,9 +62,11 @@
#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
@@ -100,7 +102,9 @@ enum
S3_MIROCRYSTAL20SV_964,
S3_MIROCRYSTAL20SD_864,
S3_PHOENIX_VISION968,
- S3_MIROCRYSTAL8S_805
+ S3_MIROCRYSTAL8S_805,
+ S3_NUMBER9_9FX_531,
+ S3_NUMBER9_9FX_771
};
@@ -1140,18 +1144,30 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val)
break;
s3->accel.pix_trans[0] = val;
if (s3->accel.cmd & 0x100) {
- if (!(s3->accel.cmd & 0x600)) {
- 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);
- }
+ 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 {
+ s3_accel_start(2, 1, 0xffffffff, s3->accel.pix_trans[0] | (s3->accel.pix_trans[0] << 8), s3);
+ }
+ break;
}
}
break;
@@ -2442,7 +2458,7 @@ s3_out(uint16_t addr, uint8_t val, void *p)
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_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);
@@ -2451,7 +2467,9 @@ s3_out(uint16_t addr, uint8_t val, void *p)
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
+ } else if (s3->card_type == S3_NUMBER9_9FX_531)
+ att498_ramdac_out(addr, rs2, val, svga->ramdac, svga);
+ else
sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga);
return;
@@ -2728,7 +2746,7 @@ s3_in(uint16_t addr, void *p)
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_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);
@@ -2737,6 +2755,8 @@ s3_in(uint16_t addr, void *p)
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
return sdac_ramdac_in(addr, rs2, svga->ramdac, svga);
break;
@@ -2839,7 +2859,7 @@ static void s3_recalctimings(svga_t *svga)
else
ibm_rgb528_recalctimings(svga->ramdac, svga);
} else
- svga->interlace = svga->crtc[0x42] & 0x20;
+ svga->interlace = !!(svga->crtc[0x42] & 0x20);
if ((((svga->miscout >> 2) & 3) == 3) && s3->chip < S3_TRIO32)
clk_sel = svga->crtc[0x42] & 0x0f;
@@ -2856,10 +2876,25 @@ static void s3_recalctimings(svga_t *svga)
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_SPEA_MIRAGE_86C805 || s3->card_type == S3_MIROCRYSTAL8S_805 ||
+ s3->card_type == S3_NUMBER9_9FX_531) {
+ 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) {
@@ -2889,15 +2924,16 @@ static void s3_recalctimings(svga_t *svga)
if (s3->chip != S3_VISION868) {
if (s3->chip == S3_86C928) {
if (s3->width == 2048 || s3->width == 1280 || s3->width == 1600)
- svga->hdisp *= 2;
+ 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 *= 2;
+ svga->hdisp <<= 1;
} else if (s3->card_type == S3_SPEA_MERCURY_P64V) {
if (s3->width == 1280 || s3->width == 1600)
- svga->hdisp *= 2;
- }
+ 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) {
@@ -2948,19 +2984,21 @@ static void s3_recalctimings(svga_t *svga)
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 *= 2;
+ svga->hdisp <<= 1;
else if (s3->chip != S3_VISION968)
- svga->hdisp /= 2;
+ 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 *= 2;
+ 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 /= 2;
+ svga->hdisp >>= 1;
else
svga->hdisp = s3->width;
}
@@ -2973,21 +3011,22 @@ static void s3_recalctimings(svga_t *svga)
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 *= 2;
+ svga->hdisp <<= 1;
else if (s3->chip != S3_VISION968)
- svga->hdisp /= 2;
- } else if ((s3->card_type == S3_SPEA_MIRAGE_86C801) || (s3->card_type == S3_SPEA_MIRAGE_86C805)) {
- svga->hdisp /= 2;
- }
+ 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 *= 2;
+ 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 /= 2;
+ svga->hdisp >>= 1;
else
svga->hdisp = s3->width;
}
@@ -3013,12 +3052,13 @@ static void s3_recalctimings(svga_t *svga)
if ((s3->chip < S3_TRIO32) && (s3->chip != S3_VISION964) &&
(s3->chip != S3_VISION968) && (s3->chip != S3_86C928)) {
if (s3->chip == S3_VISION868)
- svga->hdisp /= 2;
+ svga->hdisp >>= 1;
else
- svga->hdisp /= 4;
+ svga->hdisp >>= 2;
}
- if (s3->width == 1280 || s3->width == 1600 || (s3->card_type == S3_SPEA_MERCURY_P64V))
- 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_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) {
@@ -3110,11 +3150,11 @@ static void s3_trio64v_recalctimings(svga_t *svga)
break;
case 15:
svga->render = svga_render_15bpp_highres;
- svga->hdisp /= 2;
+ svga->hdisp >>= 1;
break;
case 16:
svga->render = svga_render_16bpp_highres;
- svga->hdisp /= 2;
+ svga->hdisp >>= 1;
break;
case 24:
svga->render = svga_render_24bpp_highres;
@@ -6530,6 +6570,7 @@ static void s3_reset(void *priv)
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;
@@ -6544,6 +6585,7 @@ static void s3_reset(void *priv)
}
break;
+ case S3_NUMBER9_9FX_531:
case S3_PHOENIX_VISION868:
if (s3->pci) {
svga->crtc[0x53] = 0x18;
@@ -6679,6 +6721,11 @@ static void *s3_init(const device_t *info)
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;
@@ -6710,6 +6757,11 @@ static void *s3_init(const device_t *info)
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;
@@ -6887,7 +6939,7 @@ static void *s3_init(const device_t *info)
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_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;
@@ -7048,7 +7100,7 @@ static void *s3_init(const device_t *info)
case S3_PARADISE_BAHAMAS64:
case S3_PHOENIX_VISION864:
- case S3_MIROCRYSTAL20SD_864:
+ 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*/
@@ -7085,6 +7137,7 @@ static void *s3_init(const device_t *info)
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*/
@@ -7102,7 +7155,8 @@ static void *s3_init(const device_t *info)
svga->crtc[0x5a] = 0x0a;
}
- if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968)
+ if (info->local == S3_ELSAWIN2KPROX || info->local == S3_PHOENIX_VISION968 ||
+ info->local == S3_NUMBER9_9FX_771)
svga->ramdac = device_add(&ibm_rgb528_ramdac_device);
else
svga->ramdac = device_add(&tvp3026_ramdac_device);
@@ -7111,6 +7165,7 @@ static void *s3_init(const device_t *info)
svga->getclock = icd2061_getclock;
break;
+ case S3_NUMBER9_9FX_531:
case S3_PHOENIX_VISION868:
svga->decode_mask = (8 << 20) - 1;
s3->id = 0xe1; /*Vision868*/
@@ -7128,10 +7183,16 @@ static void *s3_init(const device_t *info)
svga->crtc[0x59] = 0x00;
svga->crtc[0x5a] = 0x0a;
}
-
- svga->ramdac = device_add(&sdac_ramdac_device);
- svga->clock_gen = svga->ramdac;
- svga->getclock = sdac_getclock;
+
+ 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:
@@ -7261,6 +7322,11 @@ static int s3_phoenix_vision864_available(void)
return rom_present(ROM_PHOENIX_VISION864);
}
+static int s3_9fx_531_available(void)
+{
+ return rom_present(ROM_NUMBER9_9FX_531);
+}
+
static int s3_phoenix_vision868_available(void)
{
return rom_present(ROM_PHOENIX_VISION868);
@@ -7286,6 +7352,11 @@ static int s3_mirovideo_40sv_ergo_968_pci_available(void)
return rom_present(ROM_MIROVIDEO40SV_ERGO_968_PCI);
}
+static int s3_9fx_771_available(void)
+{
+ return rom_present(ROM_NUMBER9_9FX_771);
+}
+
static int s3_phoenix_vision968_available(void)
{
return rom_present(ROM_PHOENIX_VISION968);
@@ -7448,7 +7519,7 @@ static const device_config_t s3_phoenix_trio32_config[] =
static const device_config_t s3_standard_config[] =
{
{
- "memory", "Video memory size", CONFIG_SELECTION, "", 4, "", { 0 },
+ "memory", "Memory size", CONFIG_SELECTION, "", 4, "", { 0 },
{
{
"1 MB", 1
@@ -7750,6 +7821,20 @@ const device_t s3_diamond_stealth64_964_pci_device =
s3_standard_config
};
+const device_t s3_9fx_771_pci_device =
+{
+ "S3 Vision968 PCI (Number 9 9FX 771)",
+ DEVICE_PCI,
+ S3_NUMBER9_9FX_771,
+ s3_init,
+ s3_close,
+ s3_reset,
+ { s3_9fx_771_available },
+ s3_speed_changed,
+ s3_force_redraw,
+ s3_standard_config
+};
+
const device_t s3_phoenix_vision968_pci_device =
{
"S3 Vision968 PCI (Phoenix)",
@@ -7989,6 +8074,20 @@ const device_t s3_phoenix_vision864_pci_device =
s3_standard_config
};
+const device_t s3_9fx_531_pci_device =
+{
+ "S3 Vision868 PCI (Number 9 9FX 531)",
+ DEVICE_PCI,
+ S3_NUMBER9_9FX_531,
+ s3_init,
+ s3_close,
+ s3_reset,
+ { s3_9fx_531_available },
+ s3_speed_changed,
+ s3_force_redraw,
+ s3_9fx_config
+};
+
const device_t s3_phoenix_vision868_vlb_device =
{
"S3 Vision868 VLB (Phoenix)",
diff --git a/src/video/vid_table.c b/src/video/vid_table.c
index 32865df01..f1752d611 100644
--- a/src/video/vid_table.c
+++ b/src/video/vid_table.c
@@ -72,9 +72,12 @@ video_cards[] = {
{ "cl_gd5402_isa", &gd5402_isa_device },
{ "cl_gd5420_isa", &gd5420_isa_device },
{ "cl_gd5422_isa", &gd5422_isa_device },
+ { "cl_gd5426_isa", &gd5426_isa_device },
+ { "cl_gd5426_diamond_a1_isa", &gd5426_diamond_speedstar_pro_a1_isa_device },
{ "cl_gd5428_isa", &gd5428_isa_device },
{ "cl_gd5429_isa", &gd5429_isa_device },
{ "cl_gd5434_isa", &gd5434_isa_device },
+ { "cl_gd5434_diamond_a3_isa", &gd5434_diamond_speedstar_64_a3_isa_device },
{ "compaq_cga", &compaq_cga_device },
{ "compaq_cga_2", &compaq_cga_2_device },
{ "compaq_ega", &cpqega_device },
@@ -123,14 +126,15 @@ video_cards[] = {
{ "radius_mc", &radius_svga_multiview_mca_device },
{ "mach64gx_pci", &mach64gx_pci_device },
{ "mach64vt2", &mach64vt2_device },
+ { "et4000w32p_revc_pci", &et4000w32p_revc_pci_device },
{ "et4000w32p_pci", &et4000w32p_cardex_pci_device },
{ "et4000w32p_nc_pci", &et4000w32p_noncardex_pci_device },
- { "et4000w32p_revc_pci", &et4000w32p_revc_pci_device },
{ "cl_gd5430_pci", &gd5430_pci_device, },
{ "cl_gd5434_pci", &gd5434_pci_device },
{ "cl_gd5436_pci", &gd5436_pci_device },
{ "cl_gd5440_pci", &gd5440_pci_device },
{ "cl_gd5446_pci", &gd5446_pci_device },
+ { "cl_gd5446_stb_pci", &gd5446_stb_pci_device },
{ "cl_gd5480_pci", &gd5480_pci_device },
{ "ctl3d_banshee_pci", &creative_voodoo_banshee_device },
{ "stealth32_pci", &et4000w32p_pci_device },
@@ -146,8 +150,10 @@ video_cards[] = {
{ "px_trio64_pci", &s3_phoenix_trio64_pci_device },
{ "elsawin2kprox_pci", &s3_elsa_winner2000_pro_x_pci_device },
{ "mirovideo40sv_pci", &s3_mirovideo_40sv_ergo_968_pci_device },
+ { "n9_9fx_771_pci", &s3_9fx_771_pci_device },
{ "px_vision968_pci", &s3_phoenix_vision968_pci_device },
{ "spea_mercury64p_pci", &s3_spea_mercury_p64v_pci_device },
+ { "n9_9fx_531_pci", &s3_9fx_531_pci_device },
{ "px_vision868_pci", &s3_phoenix_vision868_pci_device },
{ "px_trio64vplus_pci", &s3_phoenix_trio64vplus_pci_device },
{ "trio64v2dx_pci", &s3_trio64v2_dx_pci_device },
@@ -164,7 +170,6 @@ video_cards[] = {
{ "mystique", &mystique_device },
{ "mystique_220", &mystique_220_device },
#endif
- { "cl_gd5446_stb_pci", &gd5446_stb_pci_device },
{ "tgui9440_pci", &tgui9440_pci_device },
{ "tgui9660_pci", &tgui9660_pci_device },
{ "tgui9680_pci", &tgui9680_pci_device },
@@ -173,16 +178,17 @@ video_cards[] = {
{ "voodoo3_3k_pci", &voodoo_3_3000_device },
{ "mach64gx_vlb", &mach64gx_vlb_device },
{ "et4000w32i_vlb", &et4000w32i_vlb_device },
- { "et4000w32p_vlb", &et4000w32p_cardex_vlb_device },
- { "et4000w32p_nc_vlb", &et4000w32p_noncardex_vlb_device },
{ "et4000w32p_revc_vlb", &et4000w32p_revc_vlb_device },
- { "cl_gd5424_vlb", &gd5424_vlb_device },
- { "cl_gd5428_vlb", &gd5428_vlb_device },
- { "cl_gd5429_vlb", &gd5429_vlb_device },
- { "cl_gd5434_vlb", &gd5434_vlb_device },
+ { "et4000w32p_vlb", &et4000w32p_cardex_vlb_device },
{ "stealth32_vlb", &et4000w32p_vlb_device },
+ { "et4000w32p_nc_vlb", &et4000w32p_noncardex_vlb_device },
+ { "cl_gd5424_vlb", &gd5424_vlb_device },
{ "cl_gd5426_vlb", &gd5426_vlb_device },
- { "cl_gd5430_vlb", &gd5430_vlb_device },
+ { "cl_gd5428_vlb", &gd5428_vlb_device },
+ { "cl_gd5428_diamond_b1_vlb", &gd5428_diamond_speedstar_pro_b1_vlb_device },
+ { "cl_gd5429_vlb", &gd5429_vlb_device },
+ { "cl_gd5430_vlb", &gd5430_diamond_speedstar_pro_se_a8_vlb_device },
+ { "cl_gd5434_vlb", &gd5434_vlb_device },
{ "metheus928_vlb", &s3_metheus_86c928_vlb_device },
{ "mirocrystal8s_vlb", &s3_mirocrystal_8s_805_vlb_device },
{ "mirocrystal10sd_vlb", &s3_mirocrystal_10sd_805_vlb_device },
diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw
index d678e2699..2d2ad272f 100644
--- a/src/win/Makefile.mingw
+++ b/src/win/Makefile.mingw
@@ -730,6 +730,7 @@ VIDOBJ := agpgart.o video.o \
vid_tvga.o \
vid_tgui9440.o vid_tkd8001_ramdac.o \
vid_att20c49x_ramdac.o \
+ vid_att2xc498_ramdac.o \
vid_s3.o vid_s3_virge.o \
vid_ibm_rgb528_ramdac.o vid_sdac_ramdac.o \
vid_ogc.o \