};
#endif
+static const struct expansionboardsettings merlin_settings[] = {
+ {
+ _T("Serial number\0"),
+ _T("serial\0"),
+ 2, false, 0
+ },
+ {
+ NULL
+ }
+};
static const struct expansionboardsettings voodoo_settings[] = {
{
_T("Direct VRAM access in little endian modes"), _T("directvram")
NULL, 0,
false, EXPANSIONTYPE_RTG
},
+ {
+ _T("merlin"), _T("Merlin"), _T("X-Pert Computer Services"),
+ NULL, NULL, NULL, NULL, ROMTYPE_MERLIN | ROMTYPE_NOT, 0, 0, BOARD_IGNORE, true,
+ NULL, 0,
+ false, EXPANSIONTYPE_RTG,
+ 0, 0, 0, false, NULL,
+ false, 0, merlin_settings
+ },
{
_T("vooodoo3_3k"), _T("Voodoo 3 3000"), _T("3dfx"),
NULL, NULL, NULL, NULL, ROMTYPE_VOODOO3 | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, false,
_T("Merlin [Zorro II]"), _T("X-Pert Computer Services"), _T("MerlinZ2"),
2117, 3, 4, 0,
0x00000000, 0x00200000, 0x00200000, 0x00200000, 0, 2, 6, false, true,
- 0, 0, NULL, &et4000w32_merlin_z2_device
+ ROMTYPE_MERLIN,
+ 0, NULL, &et4000w32_merlin_z2_device
},
{
GFXBOARD_ID_MERLIN_Z3,
_T("Merlin [Zorro III]"), _T("X-Pert Computer Services"), _T("MerlinZ3"),
2117, 3, 4, 0,
0x00000000, 0x00200000, 0x00400000, 0x02000000, 0, 3, 6, false, true,
- 0, 0, NULL, &et4000w32_merlin_z3_device
+ ROMTYPE_MERLIN,
+ 0, NULL, &et4000w32_merlin_z3_device
},
{
GFXBOARD_ID_GRAFFITY_Z2,
int vga_width, vga_height, vga_width_mult, vga_height_mult;
bool vga_refresh_active;
int device_settings;
- uae_u8 extradata[16];
+ uae_u32 extradata[16];
uae_u32 vgaioregionptr, vgavramregionptr, vgabank0regionptr, vgabank1regionptr;
device_add_rethink(gfxboard_rethink);
}
+static void merlin_init(struct rtggfxboard *gb)
+{
+ struct boardromconfig *brc = get_device_rom(&currprefs, ROMTYPE_MERLIN, 0, NULL);
+ if (brc) {
+ const TCHAR *ser = brc->roms[0].configtext;
+ gb->extradata[0] = _tstol(ser);
+ } else {
+ gb->extradata[0] = 1;
+ }
+ gb->extradata[0] ^= 0x5554452A;
+}
+
static int GetBytesPerPixel(RGBFTYPE RGBfmt)
{
switch (RGBfmt)
map_banks_z3(&gb->gfxboard_bank_special_pcem, (start + 0x1000000) >> 16, 0x1000000 >> 16);
gb->configured_regs = gb->gfxmem_bank->start >> 16;
gb->gfxboard_intena = 1;
+ merlin_init(gb);
} else if (boardnum == GFXBOARD_ID_GRAFFITY_Z3) {
gb->pcem_mmio_mask = 0x1fffff;
gb->pcem_io_mask = 0xffff;
gb->gfxboard_intena = 1;
+ merlin_init(gb);
} else if (boardnum == GFXBOARD_ID_OMNIBUS_ET4000W32) {
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI || gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) {
gb->pcibs = pci_board_add(b, &voodoo3_pci_board, -1, -1, aci, gb);
} else if (gb->rbc->rtgmem_type == GFXBOARD_ID_PERMEDIA2_PCI) {
- gb->pcibs = pci_board_add(b, &permedia2_pci_board, -1, -1, aci, gb);
+ if (is_device_rom(p, ROMTYPE_GREX, 0) >= 0) {
+ gb->pcibs = pci_board_add(b, &permedia2_pci_board, 0, -1, aci, gb);
+ } else {
+ gb->pcibs = pci_board_add(b, &permedia2_pci_board, -1, -1, aci, gb);
+ }
} else if (gb->rbc->rtgmem_type == GFXBOARD_ID_GD5446_PCI) {
gb->pcibs = pci_board_add(b, &gd5446_pci_board, -1, -1, aci, gb);
} else if (gb->rbc->rtgmem_type == GFXBOARD_ID_S3TRIO64_PCI) {
put_mem_pcem(addr, l, 2);
}
+static uae_u8 get_io_merlin(struct rtggfxboard *gb, uae_u32 addr)
+{
+ uae_u8 v = 0;
+
+ if (addr < 0x5000) {
+ v = get_io_pcem(addr, 0);
+ }
+
+ // 2M vs 4M config bits
+ if (addr == 0x3ca) {
+ v &= ~0x0c;
+ if (gb->gfxboard_bank_vram_pcem.allocated_size >= 0x400000) {
+ v |= 4;
+ }
+ } else if (addr == 0x3c2) {
+ v |= 0x20;
+ }
+ // serial eeprom?
+ if (addr == 0x81 || addr == 0x01) {
+ gb->extradata[2] >>= 1;
+ gb->extradata[1]++;
+ if (gb->extradata[1] <= 10) {
+ if (addr == 0x81) {
+ gb->extradata[2] |= 0x200;
+ }
+ if (gb->extradata[1] == 10) {
+ v = 0;
+ uae_u16 a = gb->extradata[2];
+ uae_u8 aa = a >> 3;
+ uae_u8 d = 0xff;
+ if ((a & 7) == 3) {
+ uae_u8 ser[4] = { gb->extradata[0] >> 24, (uae_u8)(gb->extradata[0] >> 16), (uae_u8)(gb->extradata[0] >> 8), (uae_u8)(gb->extradata[0] >> 0) };
+ if (aa == 0x7c) {
+ d = ser[0];
+ } else if (aa == 0x7d) {
+ d = ser[1];
+ } else if (aa == 0x7b) {
+ d = ser[2];
+ } else if (aa == 0x7e) {
+ d = ser[3];
+ } else if (aa == 0x7f) {
+ // checksum
+ d = 0;
+ for (int i = 0; i < 0x7f; i++) {
+ if (i == 0x7c) {
+ d += ser[0];
+ } else if (i == 0x7d) {
+ d += ser[1];
+ } else if (i == 0x7b) {
+ d += ser[2];
+ } else if (i == 0x7e) {
+ d += ser[3];
+ } else {
+ d += 0xff;
+ }
+ }
+ d = 0x100 - d;
+ }
+ }
+ gb->extradata[3] = d;
+ write_log("Merlin serial eeprom read address %04x (%02x) = %02x\n", a, aa, d);
+ }
+ } else {
+ v = ((gb->extradata[3] >> 7) & 1) ? 2 : 0;
+ gb->extradata[3] <<= 1;
+ }
+ }
+ if (addr == 0x0401) {
+ gb->extradata[2] = 0;
+ gb->extradata[1] = 0;
+ }
+
+ return v;
+}
static void special_pcem_put(uaecptr addr, uae_u32 v, int size)
{
if (addr == 0x401) {
set_monswitch(gb, (v & 0x01) != 0);
+ gb->extradata[2] = 0;
}
- if (size) {
- put_io_pcem(addr + 0, (v >> 8) & 0xff, 0);
- put_io_pcem(addr + 1, (v >> 0) & 0xff, 0);
- } else if (size == 0) {
- put_io_pcem(addr, v & 0xff, 0);
+ if (addr < 0x5000) {
+ if (size) {
+ put_io_pcem(addr + 0, (v >> 8) & 0xff, 0);
+ put_io_pcem(addr + 1, (v >> 0) & 0xff, 0);
+ } else if (size == 0) {
+ put_io_pcem(addr, v & 0xff, 0);
+ }
}
} else if (boardnum == GFXBOARD_ID_OMNIBUS_ET4000W32) {
addr &= 0xffff;
if (size) {
- v = get_io_pcem(addr + 0, 0) << 8;
- v |= get_io_pcem(addr + 1, 0) << 0;
+ v = get_io_merlin(gb, addr + 0) << 8;
+ v |= get_io_merlin(gb, addr + 1) << 0;
} else if (size == 0) {
- v = get_io_pcem(addr, 0);
+ v = get_io_merlin(gb, addr);
}
} else if (boardnum == GFXBOARD_ID_OMNIBUS_ET4000W32) {
#define ROMTYPE_ALTAIS 0x00100090
#define ROMTYPE_PROMETHEUSFS 0x00100091
#define ROMTYPE_RAINBOWII 0x00100092
+#define ROMTYPE_MERLIN 0x00100093
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000
svga->swaprb = (ramdac->cmd_r0 & 2) == 0;
break;
case 0x09:
+ case 0x0b:
svga->bpp = 32;
svga->swaprb = (ramdac->cmd_r0 & 2) == 0;
break;
{
case 2: // command B
svga->ramdac_type = (val & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT;
+ ramdac->cmd_r1 = val;
break;
case 3: // cursor
ramdac->cursor_r = val;
case 0x00: /* Palette Write Index Register (RS value = 0000) */
temp = svga_in(addr, svga);
break;
+ case 0x02:
+ if (ramdac->cmd_r0 & 1) {
+ switch (svga->dac_addr)
+ {
+ case 2: // command B
+ temp = ramdac->cmd_r1;
+ break;
+ case 3: // cursor
+ temp = ramdac->cursor_r ;
+ break;
+ case 4: // cursor x low
+ temp = ramdac->hwc_x & 0xff;
+ break;
+ case 5: // cursor x high
+ temp = (ramdac->hwc_x >> 8) & 0xff;
+ break;
+ case 6: // cursor y low
+ temp = ramdac->hwc_y & 0xff;
+ break;
+ case 7: // cursor y high
+ temp = (ramdac->hwc_y >> 8) & 0xff;
+ break;
+ }
+ }
+ break;
case 0x03: /* Palette Read Index Register (RS value = 0011) */
temp = svga->dac_addr & 0xff;
break;
clr2 = ramdac->extpallook[2];
clr3 = ramdac->extpallook[3];
+ offset <<= svga->horizontal_linedbl;
+
/* The planes come in two parts, and each plane is 1bpp,
32x32 cursor has 4 bytes per line */
pitch = (svga->dac_hwcursor_latch.xsize >> 3); /* Bytes per line. */
break;
}
+ svga->horizontal_linedbl = svga->dispend * 9 / 10 >= svga->hdisp;
+
#if 0
if (dev->type == ET4000_TYPE_KOREAN || dev->type == ET4000_TYPE_TRIGEM || dev->type == ET4000_TYPE_KASAN) {
if ((svga->render == svga_render_text_80) && ((svga->crtc[0x37] & 0x0A) == 0x0A)) {
static int et4000w32_vbus[4] = { 1, 2, 4, 4 };
-static int et4000w32_max_x[8] = { 0, 0, 4, 8, 0x10, 0x20, 0x40, 0x70000000 };
-static int et4000w32_wrap_x[8] = { 0, 0, 3, 7, 0x0f, 0x1f, 0x3f, ~0 };
+// TW: At least W32 horizontal wrap 0 equals 1 (documentation says "reserved"). Fixes Amiga ProBench 2.x glitches.
+static int et4000w32_max_x[8] = { 1, 1, 4, 8, 0x10, 0x20, 0x40, 0x70000000 };
+static int et4000w32_wrap_x[8] = { 1, 1, 3, 7, 0x0f, 0x1f, 0x3f, ~0 };
static int et4000w32_wrap_y[8] = { 1, 2, 4, 8, ~0, ~0, ~0, ~0 };
//static video_timings_t timing_et4000w32_vlb = { .type = VIDEO_BUS, .write_b = 4, .write_w = 4, .write_l = 4, .read_b = 10, .read_w = 10, .read_l = 10 };
svga->cgastat &= ~0x32;
else
svga->cgastat ^= 0x32;
- return svga->cgastat;
+
+ ret = svga->cgastat;
+
+ if ((svga->fcr & 0x08) && svga->dispon)
+ ret |= 0x08;
+
+ if (ret & 0x08)
+ ret &= 0x7f;
+ else
+ ret |= 0x80;
+ return ret;
case 0x210a:
case 0x211a:
bt482_recalctimings(et4000->ramdac_bt, svga);
}
+ svga->interlace = svga->crtc[0x35] & 0x80;
+ if (svga->interlace) {
+ int shift = (svga->crtc[0x17] & 4) ? 2 : 1;
+ svga->vtotal >>= shift;
+ svga->vsyncstart >>= shift;
+ svga->vblankstart >>= shift;
+ svga->dispend >>= shift;
+ }
+
//svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock((svga->miscout >> 2) & 3, svga->clock_gen);
if (et4000->type != ET4000W32P_DIAMOND) {
case 24:
svga->clock /= 4;
break;
+ case 32:
+ svga->clock /= 4;
+ break;
default:
break;
svga->hdisp = 640;
}
break;
+ case 32:
+ svga->hdisp /= 4;
+ svga->dots_per_clock /= 4;
+ break;
default:
break;
}
+ svga->horizontal_linedbl = svga->dispend * 9 / 10 >= svga->hdisp;
+
svga->render = svga_render_blank;
if (!svga->scrblank && svga->attr_palette_enable) {
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /* Text mode */
uint8_t dat;
offset = svga->hwcursor_latch.xoff;
+ offset <<= svga->horizontal_linedbl;
if ((et4000->type == ET4000W32) && (pitch == 32)) {
switch (svga->bpp) {
case 24:
src += ar11 & 3;
break;
+ case 32:
+ src += ar11 & 3;
+ break;
default:
return;
}
{
int x;
int offset = svga->scrollcache_dst;
+ int shift = svga->scrollcache_src;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 4000)
{
for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + shift + (x << 2)) & svga->vram_display_mask]);
*p++ = dat & 0xffffff;
*p++ = dat & 0xffffff;
}
{
for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
{
- uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t addr = svga->remap_func(svga, svga->ma + shift);
uint32_t dat = *(uint32_t *)(&svga->vram[addr]);
*p++ = dat & 0xffffff;
*p++ = dat & 0xffffff;
{
int x;
int offset = svga->scrollcache_dst;
+ int shift = svga->scrollcache_src;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 4000)
{
for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + shift + (x << 2)) & svga->vram_display_mask]);
dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00));
*p++ = dat & 0xffffff;
*p++ = dat & 0xffffff;
{
for (x = 0; x <= svga->hdisp << svga->horizontal_linedbl; x++)
{
- uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t addr = svga->remap_func(svga, svga->ma + shift);
uint32_t dat = *(uint32_t *)(&svga->vram[addr]);
dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00));
*p++ = dat & 0xffffff;
{
int x;
int offset = svga->scrollcache_dst;
+ int shift = svga->scrollcache_src;
uint32_t *p = &((uint32_t *)buffer32->line[svga->displine])[offset];
if (svga->firstline_draw == 4000)
{
for (x = 0; x <= svga->hdisp; x++)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + shift + (x << 2)) & svga->vram_display_mask]);
*p++ = dat & 0xffffff;
}
svga->ma += x * 4;
{
for (x = 0; x <= svga->hdisp; x++)
{
- uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t addr = svga->remap_func(svga, svga->ma + shift);
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
*p++ = dat & 0xffffff;
svga->ma += 4;
{
for (x = 0; x <= svga->hdisp; x++)
{
- uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]);
+ uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + shift + (x << 2)) & svga->vram_display_mask]);
dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00));
*p++ = dat & 0xffffff;
}
{
for (x = 0; x <= svga->hdisp; x++)
{
- uint32_t addr = svga->remap_func(svga, svga->ma);
+ uint32_t addr = svga->remap_func(svga, svga->ma + shift);
uint32_t dat = *(uint32_t *)(&svga->vram[addr & svga->vram_display_mask]);
dat = ((dat & 0xff0000) >> 16) | ((dat & 0x0000ff) << 16) | ((dat & 0x00ff00));
*p++ = dat & 0xffffff;