Now up to date with current dev version.
Changes since v0.7 : - Major CPU reorganisation. This has possibly broken some stuff, though I fixed all the regressions I could find - Lazy flags. This brought 10% speed improvement at one point, but that's probably been lost now - 430 VX chipset emulation - IDT Winchip emulation (currently sans MMX). Timing is probably wrong - Fixed a few FPU bugs - Timer reorganisation - Sound reorganisation - Other general reorganisation - AdLib Gold emulation - Windows Sound System emulation - Pro Audio Spectrum 16 emulation. This currently works with most DOS stuff, but not in Windows - Major improvements to GUS emulation. Has the downside that it now conflicts with SB emulation, so probably best to not enable both simultaneously - New graphics cards : - ATI-18800 (VGA Edge-16) - ATI-28800 (VGA Charger) - ATI Mach64GX (Graphics Pro Turbo). Quite a few features missing, but Windows doesn't seem to use half the features of this card - Cirrus Logic CL-GD5429. Blitter is a bit broken - Oak OTI-067 - S3 Trio64 (Number Nine 9FX) - S3 Virge. Only framebuffer stuff at the minute, Windows won't recognise the card - Trident TGUI-9440 - VGA. Doesn't work yet - Beginnings of 3DFX emulation, however this is in extremely early stages and doesn't do anything useful - Fixed DMA bug stopping floppy drives working in Windows 3.x - Fixed some other stuff probably - Broke some other stuff probably as well
This commit is contained in:
parent
3c253c2cf8
commit
9312de19ac
87 changed files with 4528 additions and 9373 deletions
208
src/io.c
208
src/io.c
|
|
@ -1,89 +1,112 @@
|
|||
#include "ibm.h"
|
||||
#include "ide.h"
|
||||
#include "io.h"
|
||||
#include "video.h"
|
||||
#include "cpu.h"
|
||||
|
||||
uint8_t (*port_inb[0x10000][2])(uint16_t addr);
|
||||
uint16_t (*port_inw[0x10000][2])(uint16_t addr);
|
||||
uint32_t (*port_inl[0x10000][2])(uint16_t addr);
|
||||
uint8_t (*port_inb[0x10000][2])(uint16_t addr, void *priv);
|
||||
uint16_t (*port_inw[0x10000][2])(uint16_t addr, void *priv);
|
||||
uint32_t (*port_inl[0x10000][2])(uint16_t addr, void *priv);
|
||||
|
||||
void (*port_outb[0x10000][2])(uint16_t addr, uint8_t val);
|
||||
void (*port_outw[0x10000][2])(uint16_t addr, uint16_t val);
|
||||
void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val);
|
||||
void (*port_outb[0x10000][2])(uint16_t addr, uint8_t val, void *priv);
|
||||
void (*port_outw[0x10000][2])(uint16_t addr, uint16_t val, void *priv);
|
||||
void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val, void *priv);
|
||||
|
||||
void *port_priv[0x10000][2];
|
||||
|
||||
void io_init()
|
||||
{
|
||||
int c;
|
||||
pclog("io_init\n");
|
||||
for (c = 0; c < 0x10000; c++)
|
||||
{
|
||||
port_inb[c][0] = port_inw[c][0] = port_inl[c][0] = NULL;
|
||||
port_outb[c][0] = port_outw[c][0] = port_outl[c][0] = NULL;
|
||||
port_inb[c][1] = port_inw[c][1] = port_inl[c][1] = NULL;
|
||||
port_outb[c][1] = port_outw[c][1] = port_outl[c][1] = NULL;
|
||||
port_priv[c][0] = port_priv[c][1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void io_sethandler(uint16_t base, int size,
|
||||
uint8_t (*inb)(uint16_t addr),
|
||||
uint16_t (*inw)(uint16_t addr),
|
||||
uint32_t (*inl)(uint16_t addr),
|
||||
void (*outb)(uint16_t addr, uint8_t val),
|
||||
void (*outw)(uint16_t addr, uint16_t val),
|
||||
void (*outl)(uint16_t addr, uint32_t val))
|
||||
uint8_t (*inb)(uint16_t addr, void *priv),
|
||||
uint16_t (*inw)(uint16_t addr, void *priv),
|
||||
uint32_t (*inl)(uint16_t addr, void *priv),
|
||||
void (*outb)(uint16_t addr, uint8_t val, void *priv),
|
||||
void (*outw)(uint16_t addr, uint16_t val, void *priv),
|
||||
void (*outl)(uint16_t addr, uint32_t val, void *priv),
|
||||
void *priv)
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < size; c++)
|
||||
{
|
||||
if (!port_inb[ base + c][0]) port_inb[ base + c][0] = inb;
|
||||
else if (!port_inb[ base + c][1]) port_inb[ base + c][1] = inb;
|
||||
if (!port_inw[ base + c][0]) port_inw[ base + c][0] = inw;
|
||||
else if (!port_inw[ base + c][1]) port_inw[ base + c][1] = inw;
|
||||
if (!port_inl[ base + c][0]) port_inl[ base + c][0] = inl;
|
||||
else if (!port_inl[ base + c][1]) port_inl[ base + c][1] = inl;
|
||||
if (!port_outb[base + c][0]) port_outb[base + c][0] = outb;
|
||||
else if (!port_outb[base + c][1]) port_outb[base + c][1] = outb;
|
||||
if (!port_outw[base + c][0]) port_outw[base + c][0] = outw;
|
||||
else if (!port_outw[base + c][1]) port_outw[base + c][1] = outw;
|
||||
if (!port_outl[base + c][0]) port_outl[base + c][0] = outl;
|
||||
else if (!port_outl[base + c][1]) port_outl[base + c][1] = outl;
|
||||
if (!port_inb[ base + c][0] && !port_inw[ base + c][0] && !port_inl[ base + c][0] &&
|
||||
!port_outb[base + c][0] && !port_outw[base + c][0] && !port_outl[base + c][0])
|
||||
{
|
||||
port_inb[ base + c][0] = inb;
|
||||
port_inw[ base + c][0] = inw;
|
||||
port_inl[ base + c][0] = inl;
|
||||
port_outb[base + c][0] = outb;
|
||||
port_outw[base + c][0] = outw;
|
||||
port_outl[base + c][0] = outl;
|
||||
port_priv[base + c][0] = priv;
|
||||
}
|
||||
else if (!port_inb[ base + c][1] && !port_inw[ base + c][1] && !port_inl[ base + c][1] &&
|
||||
!port_outb[base + c][1] && !port_outw[base + c][1] && !port_outl[base + c][1])
|
||||
{
|
||||
port_inb[ base + c][1] = inb;
|
||||
port_inw[ base + c][1] = inw;
|
||||
port_inl[ base + c][1] = inl;
|
||||
port_outb[base + c][1] = outb;
|
||||
port_outw[base + c][1] = outw;
|
||||
port_outl[base + c][1] = outl;
|
||||
port_priv[base + c][1] = priv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void io_removehandler(uint16_t base, int size,
|
||||
uint8_t (*inb)(uint16_t addr),
|
||||
uint16_t (*inw)(uint16_t addr),
|
||||
uint32_t (*inl)(uint16_t addr),
|
||||
void (*outb)(uint16_t addr, uint8_t val),
|
||||
void (*outw)(uint16_t addr, uint16_t val),
|
||||
void (*outl)(uint16_t addr, uint32_t val))
|
||||
uint8_t (*inb)(uint16_t addr, void *priv),
|
||||
uint16_t (*inw)(uint16_t addr, void *priv),
|
||||
uint32_t (*inl)(uint16_t addr, void *priv),
|
||||
void (*outb)(uint16_t addr, uint8_t val, void *priv),
|
||||
void (*outw)(uint16_t addr, uint16_t val, void *priv),
|
||||
void (*outl)(uint16_t addr, uint32_t val, void *priv),
|
||||
void *priv)
|
||||
{
|
||||
int c;
|
||||
for (c = 0; c < size; c++)
|
||||
{
|
||||
if (port_inb[ base + c][0] == inb)
|
||||
port_inb[ base + c][0] = NULL;
|
||||
if (port_inb[ base + c][1] == inb)
|
||||
port_inb[ base + c][1] = NULL;
|
||||
if (port_inw[ base + c][0] == inw)
|
||||
port_inw[ base + c][0] = NULL;
|
||||
if (port_inw[ base + c][1] == inw)
|
||||
port_inw[ base + c][1] = NULL;
|
||||
if (port_inl[ base + c][0] == inl)
|
||||
port_inl[ base + c][0] = NULL;
|
||||
if (port_inl[ base + c][1] == inl)
|
||||
port_inl[ base + c][1] = NULL;
|
||||
if (port_outb[ base + c][0] == outb)
|
||||
port_outb[ base + c][0] = NULL;
|
||||
if (port_outb[ base + c][1] == outb)
|
||||
port_outb[ base + c][1] = NULL;
|
||||
if (port_outw[ base + c][0] == outw)
|
||||
port_outw[ base + c][0] = NULL;
|
||||
if (port_outw[ base + c][1] == outw)
|
||||
port_outw[ base + c][1] = NULL;
|
||||
if (port_outl[ base + c][0] == outl)
|
||||
port_outl[ base + c][0] = NULL;
|
||||
if (port_outl[ base + c][1] == outl)
|
||||
port_outl[ base + c][1] = NULL;
|
||||
if (port_priv[base + c][0] == priv)
|
||||
{
|
||||
if (port_inb[ base + c][0] == inb)
|
||||
port_inb[ base + c][0] = NULL;
|
||||
if (port_inw[ base + c][0] == inw)
|
||||
port_inw[ base + c][0] = NULL;
|
||||
if (port_inl[ base + c][0] == inl)
|
||||
port_inl[ base + c][0] = NULL;
|
||||
if (port_outb[ base + c][0] == outb)
|
||||
port_outb[ base + c][0] = NULL;
|
||||
if (port_outw[ base + c][0] == outw)
|
||||
port_outw[ base + c][0] = NULL;
|
||||
if (port_outl[ base + c][0] == outl)
|
||||
port_outl[ base + c][0] = NULL;
|
||||
}
|
||||
if (port_priv[base + c][1] == priv)
|
||||
{
|
||||
if (port_inb[ base + c][1] == inb)
|
||||
port_inb[ base + c][1] = NULL;
|
||||
if (port_inw[ base + c][1] == inw)
|
||||
port_inw[ base + c][1] = NULL;
|
||||
if (port_inl[ base + c][1] == inl)
|
||||
port_inl[ base + c][1] = NULL;
|
||||
if (port_outb[ base + c][1] == outb)
|
||||
port_outb[ base + c][1] = NULL;
|
||||
if (port_outw[ base + c][1] == outw)
|
||||
port_outw[ base + c][1] = NULL;
|
||||
if (port_outl[ base + c][1] == outl)
|
||||
port_outl[ base + c][1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,63 +118,39 @@ int t237=0;
|
|||
uint8_t inb(uint16_t port)
|
||||
{
|
||||
uint8_t temp = 0xff;
|
||||
int tempi;
|
||||
if (port_inb[port][0])
|
||||
temp &= port_inb[port][0](port);
|
||||
if (port_inb[port][1])
|
||||
temp &= port_inb[port][1](port);
|
||||
return temp;
|
||||
|
||||
if (port&0x80) sw9=2;
|
||||
// if ((port&0x3F0)==0x3D0) printf("Video access read %03X %04X:%04X\n",port,cs>>4,pc);
|
||||
// if (cs<0xF0000 || cs>0x100000) printf("IN %04X %04X(%06X):%08X\n",port,CS,cs,pc);
|
||||
// /*if (output==3) */printf("IN %04X %04X:%04X\n",port,CS,pc);
|
||||
// if (port == 0x23) pclog("IN %04X %04X:%08X\n", port, CS, pc);
|
||||
switch (port)
|
||||
{
|
||||
case 0x220: case 0x221: case 0x222: case 0x223: /*Gameblaster*/
|
||||
if (sbtype>=SBPRO) return readsb(port);
|
||||
if (GAMEBLASTER) return readcms(port);
|
||||
return 0xFF;
|
||||
}
|
||||
// printf("Bad IN port %04X %04X:%04X\n",port,cs>>4,pc);
|
||||
return 0xff;
|
||||
/*dumpregs();
|
||||
exit(-1);*/
|
||||
}
|
||||
|
||||
/*uint8_t inb(uint16_t port)
|
||||
{
|
||||
uint8_t temp = _inb(port);
|
||||
// if (port != 0x61) pclog("IN %04X %02X %04X(%08X):%08X %f %04X %i %i\n", port, temp, CS, cs, pc, pit.c[1], CX, keybsenddelay, GetTickCount());
|
||||
if (port_inb[port][0])
|
||||
temp &= port_inb[port][0](port, port_priv[port][0]);
|
||||
if (port_inb[port][1])
|
||||
temp &= port_inb[port][1](port, port_priv[port][1]);
|
||||
|
||||
/* if (!port_inb[port][0] && !port_inb[port][1])
|
||||
pclog("Bad INB %04X %04X:%04X\n", port, CS, pc);*/
|
||||
|
||||
return temp;
|
||||
}*/
|
||||
}
|
||||
|
||||
uint8_t cpu_readport(uint32_t port) { return inb(port); }
|
||||
|
||||
void outb(uint16_t port, uint8_t val)
|
||||
{
|
||||
// /*if (output==3) */printf("OUT %04X %02X %04X(%08X):%08X %i %i\n", port, val, CS, cs, pc, ins, GetTickCount());
|
||||
if (port_outb[port][0])
|
||||
port_outb[port][0](port, val);
|
||||
port_outb[port][0](port, val, port_priv[port][0]);
|
||||
if (port_outb[port][1])
|
||||
port_outb[port][1](port, val);
|
||||
port_outb[port][1](port, val, port_priv[port][1]);
|
||||
|
||||
/* if (!port_outb[port][0] && !port_outb[port][1])
|
||||
pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, pc);*/
|
||||
return;
|
||||
switch (port)
|
||||
{
|
||||
case 0x220: case 0x221: case 0x222: case 0x223: /*Gameblaster*/
|
||||
if (GAMEBLASTER) writecms(port,val);
|
||||
return;
|
||||
}
|
||||
pclog("OUT %04X %02X %04X:%08X\n",port,val,CS,pc);
|
||||
}
|
||||
|
||||
uint16_t inw(uint16_t port)
|
||||
{
|
||||
// pclog("INW %04X\n", port);
|
||||
if (port_inw[port][0])
|
||||
return port_inw[port][0](port);
|
||||
return port_inw[port][0](port, port_priv[port][0]);
|
||||
if (port_inw[port][1])
|
||||
return port_inw[port][1](port);
|
||||
return port_inw[port][1](port, port_priv[port][1]);
|
||||
|
||||
return inb(port) | (inb(port + 1) << 8);
|
||||
}
|
||||
|
|
@ -159,10 +158,13 @@ uint16_t inw(uint16_t port)
|
|||
void outw(uint16_t port, uint16_t val)
|
||||
{
|
||||
// printf("OUTW %04X %04X %04X:%08X\n",port,val, CS, pc);
|
||||
/* if ((port & ~0xf) == 0xf000)
|
||||
pclog("OUTW %04X %04X\n", port, val);*/
|
||||
|
||||
if (port_outw[port][0])
|
||||
port_outw[port][0](port, val);
|
||||
port_outw[port][0](port, val, port_priv[port][0]);
|
||||
if (port_outw[port][1])
|
||||
port_outw[port][1](port, val);
|
||||
port_outw[port][1](port, val, port_priv[port][1]);
|
||||
|
||||
if (port_outw[port][0] || port_outw[port][1])
|
||||
return;
|
||||
|
|
@ -173,20 +175,24 @@ void outw(uint16_t port, uint16_t val)
|
|||
|
||||
uint32_t inl(uint16_t port)
|
||||
{
|
||||
// pclog("INL %04X\n", port);
|
||||
if (port_inl[port][0])
|
||||
return port_inl[port][0](port);
|
||||
return port_inl[port][0](port, port_priv[port][0]);
|
||||
if (port_inl[port][1])
|
||||
return port_inl[port][1](port);
|
||||
return port_inl[port][1](port, port_priv[port][1]);
|
||||
|
||||
return inw(port) | (inw(port + 2) << 16);
|
||||
}
|
||||
|
||||
void outl(uint16_t port, uint32_t val)
|
||||
{
|
||||
/* if ((port & ~0xf) == 0xf000)
|
||||
pclog("OUTL %04X %08X\n", port, val);*/
|
||||
|
||||
if (port_outl[port][0])
|
||||
port_outl[port][0](port, val);
|
||||
port_outl[port][0](port, val, port_priv[port][0]);
|
||||
if (port_outl[port][1])
|
||||
port_outl[port][1](port, val);
|
||||
port_outl[port][1](port, val, port_priv[port][1]);
|
||||
|
||||
if (port_outl[port][0] || port_outl[port][1])
|
||||
return;
|
||||
|
|
|
|||
Loading…
Reference in a new issue