Reverted EGA emulation to be in line with mainline PCem except for the overscan, as there were some problems;

Added write port 3C1 to EGA and (S)VGA, fixed Microsoft Word 2.0 for DOS;
The RTL8029AS now correctly enables I/O port range when base address is changed via PCI registers with I/O access enabled;
Tentative fix for DirectDraw <-> Direct3D switching issues based on proposal from TheCollector1995;
Fixed 64-bit makefile;
Fixed LZF_C.C so it can compile for 64-bit Windows;
Applied all mainline PCem commits.
This commit is contained in:
OBattler
2017-02-14 23:46:50 +01:00
parent 07f1e37d26
commit 711f09e17b
11 changed files with 350 additions and 321 deletions

View File

@@ -44,9 +44,9 @@ OP_XCHG_EAX_(EBP)
static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{ {
#ifdef __amd64__ // #ifdef __amd64__
return 0; // return 0;
#else // #else
int src_reg, dst_reg, temp_reg; int src_reg, dst_reg, temp_reg;
if ((fetchdat & 0xc0) != 0xc0) if ((fetchdat & 0xc0) != 0xc0)
@@ -59,7 +59,7 @@ static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7);
return op_pc + 1; return op_pc + 1;
#endif // #endif
} }
static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{ {

View File

@@ -34,6 +34,8 @@
* either the BSD or the GPL. * either the BSD or the GPL.
*/ */
#include <stdint.h>
#include "lzfP.h" #include "lzfP.h"
#define HSIZE (1 << (HLOG)) #define HSIZE (1 << (HLOG))
@@ -120,7 +122,7 @@ lzf_compress (const void *const in_data, unsigned int in_len,
* special workaround for it. * special workaround for it.
*/ */
#if defined (WIN32) && defined (_M_X64) #if defined (WIN32) && defined (_M_X64)
unsigned _int64 off; /* workaround for missing POSIX compliance */ uint64_t off; /* workaround for missing POSIX compliance */
#else #else
unsigned long off; unsigned long off;
#endif #endif

View File

@@ -1873,6 +1873,10 @@ void ne2000_pci_write(int func, int addr, uint8_t val, void *p)
/* Log the new base. */ /* Log the new base. */
ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address);
/* We're done, so get out of the here. */ /* We're done, so get out of the here. */
if (val & PCI_COMMAND_IO)
{
ne2000_io_set(ne2000->base_address, ne2000);
}
return; return;
case 0x30: case 0x31: case 0x32: case 0x33: case 0x30: case 0x31: case 0x32: case 0x33:

View File

@@ -1,6 +1,3 @@
/* Copyright holders: Sarah Walker, Tenshi
see COPYING for more details
*/
/*EGA emulation*/ /*EGA emulation*/
#include <stdlib.h> #include <stdlib.h>
#include "ibm.h" #include "ibm.h"
@@ -21,10 +18,6 @@ static uint32_t pallook16[256], pallook64[256];
/*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/ /*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/
int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/ int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/
static uint8_t mask_gdc[9] = {0x0F, 0x0F, 0x0F, 0x1F, 0x03, 0x3B, 0x0F, 0x0F, 0xFF};
static uint8_t ega_mask_crtc[0x19] = {0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x1F, 0xFF, 0x1F, 0x7F, 0xFF};
static uint8_t mask_seq[5] = {0x03, 0x1F, 0x0F, 0x0F, 0x06};
static int old_overscan_color = 0; static int old_overscan_color = 0;
void ega_out(uint16_t addr, uint8_t val, void *p) void ega_out(uint16_t addr, uint8_t val, void *p)
@@ -39,72 +32,36 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
switch (addr) switch (addr)
{ {
case 0x3c0: case 0x3c0:
case 0x3c1:
if (!ega->attrff) if (!ega->attrff)
{
ega->attraddr = val & 31; ega->attraddr = val & 31;
if ((val & 0x20) != ega->attr_palette_enable)
{
fullchange = 3;
ega->attr_palette_enable = val & 0x20;
ega_recalctimings(ega);
}
}
else else
{ {
o = ega->attrregs[ega->attraddr & 31];
ega->attrregs[ega->attraddr & 31] = val; ega->attrregs[ega->attraddr & 31] = val;
ega->attrregs[0x11] &= 0x3F;
if (ega->attraddr < 16) if (ega->attraddr < 16)
fullchange = changeframecount; fullchange = changeframecount;
if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10)
{ {
for (c = 0; c < 16; c++) for (c = 0; c < 16; c++)
{ {
/* if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4);
else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); */ else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4);
if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0x3) << 4);
else ega->egapal[c] = (ega->attrregs[c] & 0x3f);
// if ((ega->attrregs[0x10] & 0x40) && gfxcard != GFX_EGA) ega->egapal[c] |= ((ega->attrregs[0x14] & 0xc) << 4);
if (gfxcard != GFX_EGA) ega->egapal[c] |= ((ega->attrregs[0x14] & 0xc) << 4);
} }
} }
if ((ega->attraddr == 0x10) || (ega->attraddr == 0x11))
{
if (o != val) ega_recalctimings(ega);
}
} }
ega->attrff ^= 1; ega->attrff ^= 1;
break; break;
case 0x3c2: case 0x3c2:
egaswitchread = val & 0xc; egaswitchread = val & 0xc;
ega->vres = !(val & 0x80); ega->vres = !(val & 0x80);
if (gfxcard == GFX_EGA)
ega->pallook = ega->vres ? pallook16 : pallook64; ega->pallook = ega->vres ? pallook16 : pallook64;
else
ega->pallook = pallook64;
ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/ ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/
ega->enablevram = (val & 2) ? 1 : 0;
ega->oddeven_page = (val & 0x20) ? 0 : 1;
ega->miscout=val; ega->miscout=val;
if (val & 1)
{
// pclog("Remove mono handler\n");
io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
}
else
{
// pclog("Set mono handler\n");
io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega);
}
ega_recalctimings(ega);
break; break;
case 0x3c4: case 0x3c4:
ega->seqaddr = val; ega->seqaddr = val;
break; break;
case 0x3c5: case 0x3c5:
if (ega->seqaddr <= 4) val &= mask_seq[ega->seqaddr];
o = ega->seqregs[ega->seqaddr & 0xf]; o = ega->seqregs[ega->seqaddr & 0xf];
ega->seqregs[ega->seqaddr & 0xf] = val; ega->seqregs[ega->seqaddr & 0xf] = val;
if (o != val && (ega->seqaddr & 0xf) == 1) if (o != val && (ega->seqaddr & 0xf) == 1)
@@ -132,7 +89,6 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
ega->gdcaddr = val; ega->gdcaddr = val;
break; break;
case 0x3cf: case 0x3cf:
if (ega->seqaddr <= 8) val &= mask_gdc[ega->gdcaddr];
ega->gdcreg[ega->gdcaddr & 15] = val; ega->gdcreg[ega->gdcaddr & 15] = val;
switch (ega->gdcaddr & 15) switch (ega->gdcaddr & 15)
{ {
@@ -170,15 +126,16 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
break; break;
} }
break; break;
case 0x3d0:
case 0x3d4: case 0x3d4:
// pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc);
ega->crtcreg = val & 31; ega->crtcreg = val & 31;
return; return;
case 0x3d1:
case 0x3d5: case 0x3d5:
// pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]);
// if (ega->crtcreg == 1 && val == 0x14) // if (ega->crtcreg == 1 && val == 0x14)
// fatal("Here\n"); // fatal("Here\n");
if (ega->crtcreg <= 0x18) val &= ega_mask_crtc[ega->crtcreg];
if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return;
old = ega->crtc[ega->crtcreg]; old = ega->crtc[ega->crtcreg];
ega->crtc[ega->crtcreg] = val; ega->crtc[ega->crtcreg] = val;
@@ -194,12 +151,34 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
} }
} }
/*
* Get the input status register 0
*
* Note by Tohka: Code from PCE.
*/
static uint8_t ega_get_input_status_0(ega_t *ega)
{
unsigned bit;
uint8_t status0 = 0;
bit = (egaswitchread >> 2) & 3;
if (egaswitches & (0x08 >> bit)) {
status0 |= EGA_STATUS0_SS;
}
else {
status0 &= ~EGA_STATUS0_SS;
}
return status0;
}
uint8_t ega_in(uint16_t addr, void *p) uint8_t ega_in(uint16_t addr, void *p)
{ {
ega_t *ega = (ega_t *)p; ega_t *ega = (ega_t *)p;
/* if (addr != 0x3da && addr != 0x3ba) if (addr != 0x3da && addr != 0x3ba)
pclog("ega_in %04X\n", addr); */ pclog("ega_in %04X\n", addr);
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1))
addr ^= 0x60; addr ^= 0x60;
@@ -208,44 +187,35 @@ uint8_t ega_in(uint16_t addr, void *p)
case 0x3c0: case 0x3c0:
return ega->attraddr; return ega->attraddr;
case 0x3c1: case 0x3c1:
if (ega->attraddr == 0x10) return ((ega->attrregs[ega->attraddr] & 0x7F) | (ega->attrff << 7));
return ega->attrregs[ega->attraddr]; return ega->attrregs[ega->attraddr];
case 0x3c2: case 0x3c2:
// printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA); // printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA);
switch (egaswitchread) return ega_get_input_status_0(ega);
{
case 0xc: return (egaswitches & 1) ? 0x10 : 0;
case 0x8: return (egaswitches & 2) ? 0x10 : 0;
case 0x4: return (egaswitches & 4) ? 0x10 : 0;
case 0x0: return (egaswitches & 8) ? 0x10 : 0;
}
break; break;
case 0x3c4: case 0x3c4:
return ega->seqaddr; return ega->seqaddr;
case 0x3c5: case 0x3c5:
return ega->seqregs[ega->seqaddr & 0xf]; return ega->seqregs[ega->seqaddr & 0xf];
case 0x3c8:
return 2;
case 0x3cc:
return ega->miscout;
case 0x3ce: case 0x3ce:
return ega->gdcaddr; return ega->gdcaddr;
case 0x3cf: case 0x3cf:
if (ega->gdcaddr == 0xF8) return ega->la;
if (ega->gdcaddr == 0xF9) return ega->lb;
if (ega->gdcaddr == 0xFA) return ega->lc;
if (ega->gdcaddr == 0xFB) return ega->ld;
return ega->gdcreg[ega->gdcaddr & 0xf]; return ega->gdcreg[ega->gdcaddr & 0xf];
case 0x3d0:
case 0x3d4: case 0x3d4:
return ega->crtcreg; return ega->crtcreg;
case 0x3d1:
case 0x3d5: case 0x3d5:
return ega->crtc[ega->crtcreg]; return ega->crtc[ega->crtcreg];
case 0x3da: case 0x3da:
ega->attrff = 0; ega->attrff = 0;
// ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/
if (ega->stat & 0x01)
ega->stat &= ~0x30;
else
ega->stat ^= 0x30;
return ega->stat; return ega->stat;
} }
// printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); // printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc);
return 0xff; return 0xff;
} }
@@ -258,50 +228,50 @@ void ega_recalctimings(ega_t *ega)
ega->dispend = ega->crtc[0x12]; ega->dispend = ega->crtc[0x12];
ega->vsyncstart = ega->crtc[0x10]; ega->vsyncstart = ega->crtc[0x10];
ega->split = ega->crtc[0x18]; ega->split = ega->crtc[0x18];
ega->vblankstart = ega->crtc[0x15];
if (ega->crtc[7] & 1) ega->vtotal |= 0x100; if (ega->crtc[7] & 1) ega->vtotal |= 0x100;
if (ega->crtc[7] & 32) ega->vtotal |= 0x200;
ega->vtotal++; ega->vtotal++;
if (ega->crtc[7] & 2) ega->dispend |= 0x100; if (ega->crtc[7] & 2) ega->dispend |= 0x100;
if (ega->crtc[7] & 64) ega->dispend |= 0x200;
ega->dispend++; ega->dispend++;
if (ega->crtc[7] & 4) ega->vsyncstart |= 0x100; if (ega->crtc[7] & 4) ega->vsyncstart |= 0x100;
if (ega->crtc[7] & 128) ega->vsyncstart |= 0x200;
ega->vsyncstart++; ega->vsyncstart++;
if (ega->crtc[7] & 0x10) ega->split |= 0x100; if (ega->crtc[7] & 0x10) ega->split |= 0x100;
if (ega->crtc[9] & 0x40) ega->split |= 0x200;
ega->split+=2; ega->split+=2;
if (ega->crtc[7] & 0x08) ega->vblankstart |= 0x100;
ega->vblankstart++;
ega->hdisp = ega->crtc[1]; ega->hdisp = ega->crtc[1];
ega->hdisp++; ega->hdisp++;
ega->rowoffset = ega->crtc[0x13]; ega->rowoffset = ega->crtc[0x13];
// printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]);
if (ega->vblankstart < ega->dispend)
ega->dispend = ega->vblankstart;
if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0));
else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0));
disptime = ega->crtc[0] + 2; disptime = ega->crtc[0] + 2;
_dispontime = ega->hdisp; _dispontime = ega->crtc[1] + 1;
// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8);
if (ega->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; } if (ega->seqregs[1] & 8)
{
disptime*=2;
_dispontime*=2;
}
_dispofftime = disptime - _dispontime; _dispofftime = disptime - _dispontime;
_dispontime *= crtcconst; _dispontime *= crtcconst;
_dispofftime *= crtcconst; _dispofftime *= crtcconst;
ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT),
/* pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT), ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT));
ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT)); */
// printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); // printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4));
// printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); // printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart);
// printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]); // printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]);
@@ -359,17 +329,15 @@ void ega_poll(void *p)
} }
} }
} }
else if (!ega->scrblank && ega->attr_palette_enable) else if (!(ega->gdcreg[6] & 1))
{
if (!(ega->gdcreg[6] & 1))
{ {
if (fullchange) if (fullchange)
{ {
for (x = 0; x < ega->hdisp; x++) for (x = 0; x < ega->hdisp; x++)
{ {
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
chr = ega->vram[ega->ma << 1]; chr = ega->vram[(ega->ma << 1) & ega->vrammask];
attr = ega->vram[(ega->ma << 1) + 1]; attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask];
if (attr & 8) charaddr = ega->charsetb + (chr * 128); if (attr & 8) charaddr = ega->charsetb + (chr * 128);
else charaddr = ega->charseta + (chr * 128); else charaddr = ega->charseta + (chr * 128);
@@ -542,7 +510,6 @@ void ega_poll(void *p)
break; break;
} }
} }
}
if (ega->lastline < ega->displine) if (ega->lastline < ega->displine)
ega->lastline = ega->displine; ega->lastline = ega->displine;
} }
@@ -605,8 +572,7 @@ void ega_poll(void *p)
} }
if (ega->vc == ega->vsyncstart) if (ega->vc == ega->vsyncstart)
{ {
int wx = 0; int wx, wy;
int wy = 0;
ega->dispon = 0; ega->dispon = 0;
// printf("Vsync on at line %i %i\n",displine,vc); // printf("Vsync on at line %i %i\n",displine,vc);
ega->stat |= 8; ega->stat |= 8;
@@ -619,7 +585,7 @@ void ega_poll(void *p)
{ {
xsize = x; xsize = x;
ysize = ega->lastline - ega->firstline; ysize = ega->lastline - ega->firstline;
if (xsize < 64) xsize = 640; if (xsize < 64) xsize = 656;
if (ysize < 32) ysize = 200; if (ysize < 32) ysize = 200;
if (ega->vres) if (ega->vres)
updatewindowsize(xsize + x_add_ex, (ysize << 1) + y_add_ex); updatewindowsize(xsize + x_add_ex, (ysize << 1) + y_add_ex);
@@ -707,35 +673,23 @@ void ega_poll(void *p)
} }
} }
void ega_write(uint32_t addr, uint8_t val, void *p) void ega_write(uint32_t addr, uint8_t val, void *p)
{ {
ega_t *ega = (ega_t *)p; ega_t *ega = (ega_t *)p;
uint8_t vala, valb, valc, vald; uint8_t vala, valb, valc, vald;
int writemask2 = ega->writemask; int writemask2 = ega->writemask;
uint32_t raddr = addr;
int plane, mask;
egawrites++; egawrites++;
cycles -= video_timing_b; cycles -= video_timing_b;
cycles_lost += video_timing_b; cycles_lost += video_timing_b;
/* Horrible hack, I know, but it's the only way to fix the 440FX BIOS filling the VRAM with garbage until Tom fixes the memory emulation. */
if ((cs == 0xE0000) && (cpu_state.pc == 0xBF2F) && (romset == ROM_440FX)) return;
if ((cs == 0xE0000) && (cpu_state.pc == 0xBF77) && (romset == ROM_440FX)) return;
if (addr >= 0xB0000) addr &= 0x7fff; if (addr >= 0xB0000) addr &= 0x7fff;
else addr &= 0xffff; else addr &= 0xffff;
if (ega->chain2_write) if (ega->chain2_write)
{
if ((ega->gdcreg[6] & 0xC) == 0x4)
{
writemask2 &= (ega->oddeven_page ? ~0xe : ~0xb);
}
else
{ {
writemask2 &= ~0xa; writemask2 &= ~0xa;
}
if (addr & 1) if (addr & 1)
writemask2 <<= 1; writemask2 <<= 1;
addr &= ~1; addr &= ~1;
@@ -858,7 +812,6 @@ uint8_t ega_read(uint32_t addr, void *p)
ega_t *ega = (ega_t *)p; ega_t *ega = (ega_t *)p;
uint8_t temp, temp2, temp3, temp4; uint8_t temp, temp2, temp3, temp4;
int readplane = ega->readplane; int readplane = ega->readplane;
int plane;
egareads++; egareads++;
cycles -= video_timing_b; cycles -= video_timing_b;
@@ -937,6 +890,7 @@ void ega_init(ega_t *ega)
pallook16[c] = makecol32(0xaa, 0x55, 0); pallook16[c] = makecol32(0xaa, 0x55, 0);
} }
ega->pallook = pallook16; ega->pallook = pallook16;
old_overscan_color = 0;
} }
void ega_common_defaults(ega_t *ega) void ega_common_defaults(ega_t *ega)

View File

@@ -21,8 +21,8 @@ extern uint8_t edatlookup[4][4];
uint8_t svga_rotate[8][256]; uint8_t svga_rotate[8][256];
static uint8_t mask_gdc[9] = {0x0F, 0x0F, 0x0F, 0x1F, 0x03, 0x7B, 0x0F, 0x0F, 0xFF}; static uint8_t mask_gdc[9] = {0x0F, 0x0F, 0x0F, 0x1F, 0x03, 0x7B, 0xFF, 0x0F, 0xFF};
uint8_t mask_crtc[0x19] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0xEF, 0xFF}; uint8_t mask_crtc[0x19] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0xEF, 0xFF};
static uint8_t mask_seq[5] = {0x03, 0x3D, 0x0F, 0x3F, 0x0E}; static uint8_t mask_seq[5] = {0x03, 0x3D, 0x0F, 0x3F, 0x0E};
/*Primary SVGA device. As multiple video cards are not yet supported this is the /*Primary SVGA device. As multiple video cards are not yet supported this is the
@@ -102,6 +102,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
return; return;
case 0x3C0: case 0x3C0:
case 0x3C1:
if (!svga->attrff) if (!svga->attrff)
{ {
svga->attraddr = val & 31; svga->attraddr = val & 31;
@@ -295,6 +296,46 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
} }
} }
/*
* Get the switch sense input
*
* This is reverse engineered from the IBM VGA BIOS. I have no
* idea how and why this works.
*
* Note by Tohka: This code is from PCE, modified to be 86Box-compatible.
*/
static int svga_get_input_status_0_ss(svga_t *svga)
{
const unsigned char *p;
unsigned char dac[3];
static unsigned char vals[] = {
0x12, 0x12, 0x12, 0x10,
0x14, 0x14, 0x14, 0x10,
0x2d, 0x14, 0x14, 0x00,
0x14, 0x2d, 0x14, 0x00,
0x14, 0x14, 0x2d, 0x00,
0x2d, 0x2d, 0x2d, 0x00,
0x00, 0x00, 0x00, 0xff
};
dac[0] = svga->vgapal[0].r >> 2;
dac[1] = svga->vgapal[0].g >> 2;
dac[2] = svga->vgapal[0].b >> 2;
p = vals;
while (p[3] != 0xff) {
if ((p[0] == dac[0]) && (p[1] == dac[1]) && (p[2] == dac[2])) {
return (p[3] != 0);
}
p += 4;
}
return (1);
}
uint8_t svga_in(uint16_t addr, void *p) uint8_t svga_in(uint16_t addr, void *p)
{ {
svga_t *svga = (svga_t *)p; svga_t *svga = (svga_t *)p;
@@ -347,8 +388,15 @@ uint8_t svga_in(uint16_t addr, void *p)
else else
temp = 0x10; temp = 0x10;
#endif #endif
temp = sense_switches & (1 << ((svga->miscout >> 2) & 3)); if (svga_get_input_status_0_ss(svga))
return temp ? 0 : 0x10; {
temp |= 0x10;
}
else
{
temp &= ~0x10;
}
return temp;
case 0x3C4: case 0x3C4:
return svga->seqaddr; return svga->seqaddr;
case 0x3C5: case 0x3C5:
@@ -1483,6 +1531,16 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
// pclog("doblit %i %i\n", y1, y2); // pclog("doblit %i %i\n", y1, y2);
// pclog("svga_doblit %i %i\n", wx, svga->hdisp); // pclog("svga_doblit %i %i\n", wx, svga->hdisp);
if ((xsize > 2032) || (ysize > 2032))
{
x_add = 0;
y_add = 0;
suppress_overscan = 1;
}
else
{
suppress_overscan = 0;
}
if (y1 > y2) if (y1 > y2)
{ {
@@ -1497,15 +1555,15 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
if (xsize<64) xsize=640; if (xsize<64) xsize=640;
if (ysize<32) ysize=200; if (ysize<32) ysize=200;
if (xsize > 2032) if ((xsize > 2032) || (ysize > 2032))
{ {
x_add = 0; x_add = 0;
y_add = 0; y_add = 0;
suppress_overscan = 0; suppress_overscan = 1;
} }
else else
{ {
suppress_overscan = 1; suppress_overscan = 0;
} }
updatewindowsize(xsize + x_add,ysize + y_add); updatewindowsize(xsize + x_add,ysize + y_add);
@@ -1514,6 +1572,17 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
{ {
xsize = wx; xsize = wx;
ysize = wy + 1; ysize = wy + 1;
if ((xsize > 2032) || (ysize > 2032))
{
x_add = 0;
y_add = 0;
suppress_overscan = 1;
}
else
{
suppress_overscan = 0;
}
} }
if (enable_overscan && !suppress_overscan) if (enable_overscan && !suppress_overscan)

View File

@@ -160,13 +160,13 @@ typedef struct voodoo_params_t
uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2]; uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2];
uint32_t tex_base[2][LOD_MAX+1]; uint32_t tex_base[2][LOD_MAX+2];
int tex_width[2]; int tex_width[2];
int tex_w_mask[2][LOD_MAX+1]; int tex_w_mask[2][LOD_MAX+2];
int tex_w_nmask[2][LOD_MAX+1]; int tex_w_nmask[2][LOD_MAX+2];
int tex_h_mask[2][LOD_MAX+1]; int tex_h_mask[2][LOD_MAX+2];
int tex_shift[2][LOD_MAX+1]; int tex_shift[2][LOD_MAX+2];
int tex_lod[2][LOD_MAX+1]; int tex_lod[2][LOD_MAX+2];
int tex_entry[2]; int tex_entry[2];
int detail_max[2], detail_bias[2], detail_scale[2]; int detail_max[2], detail_bias[2], detail_scale[2];
@@ -1122,7 +1122,7 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu)
tex_lod++; tex_lod++;
} }
for (lod = 0; lod <= LOD_MAX; lod++) for (lod = 0; lod <= LOD_MAX+1; lod++)
{ {
if (!width) if (!width)
width = 1; width = 1;
@@ -3649,9 +3649,9 @@ static void triangle_setup(voodoo_t *voodoo)
} }
if (voodoo->sSetupMode & SETUPMODE_W1) if (voodoo->sSetupMode & SETUPMODE_W1)
{ {
voodoo->params.tmu[1].startW = (int64_t)(voodoo->verts[va].sW0 * 4294967296.0f); voodoo->params.tmu[1].startW = (int64_t)(voodoo->verts[va].sW1 * 4294967296.0f);
voodoo->params.tmu[1].dWdX = (int64_t)(((voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dyBC - (voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dyAB) * 4294967296.0f); voodoo->params.tmu[1].dWdX = (int64_t)(((voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dyBC - (voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dyAB) * 4294967296.0f);
voodoo->params.tmu[1].dWdY = (int64_t)(((voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dxAB - (voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dxBC) * 4294967296.0f); voodoo->params.tmu[1].dWdY = (int64_t)(((voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dxAB - (voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dxBC) * 4294967296.0f);
} }
if (voodoo->sSetupMode & SETUPMODE_S1_T1) if (voodoo->sSetupMode & SETUPMODE_S1_T1)
{ {

View File

@@ -164,18 +164,18 @@ static void d3d_fs_init_objects()
d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
r.top = r.left = 0; // r.top = r.left = 0;
r.bottom = 2047; r.bottom = 2047;
r.right = 2047; r.right = 2047;
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
fatal("LockRect failed\n"); fatal("LockRect failed\n");
for (y = 0; y < 2048; y++) /* for (y = 0; y < 2048; y++)
{ {
uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch));
memset(p, 0, 2048 * 4); memset(p, 0, 2048 * 4);
} } */
d3dTexture->UnlockRect(0); d3dTexture->UnlockRect(0);

View File

@@ -137,17 +137,17 @@ void d3d_init_objects()
d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
r.top = r.left = 0; // r.top = r.left = 0;
r.bottom = r.right = 2047; r.bottom = r.right = 2047;
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
fatal("LockRect failed\n"); fatal("LockRect failed\n");
for (y = 0; y < 2048; y++) /* for (y = 0; y < 2048; y++)
{ {
uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch));
memset(p, 0, 2048 * 4); memset(p, 0, 2048 * 4);
} } */
d3dTexture->UnlockRect(0); d3dTexture->UnlockRect(0);

View File

@@ -86,8 +86,8 @@ void ddraw_fs_init(HWND h)
if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0)))
fatal("SetDisplayMode failed\n"); fatal("SetDisplayMode failed\n");
memset(&ddsd, 0, sizeof(ddsd)); // memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); // ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1; ddsd.dwBackBufferCount = 1;

View File

@@ -87,8 +87,8 @@ void ddraw_init(HWND h)
if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL)))
fatal("CreateSurface failed\n"); fatal("CreateSurface failed\n");
memset(&ddsd, 0, sizeof(ddsd)); // memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd); // ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.dwWidth = 2048; ddsd.dwWidth = 2048;