mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 17:45:31 -07:00
Merge pull request #1 from OBattler/master
Merge remote-tracking branch 'refs/remotes/OBattler/master'
This commit is contained in:
16
README.md
16
README.md
@@ -5,3 +5,19 @@
|
||||
Keep in touch with the 86Box community:
|
||||
|
||||
[](https://kiwiirc.com/client/irc.rol.im/?nick=86box|?#softhistory) [](https://discord.gg/Es3TnUH)
|
||||
|
||||
---
|
||||
# Compilation
|
||||
In order to compile 86Box from this repository, please follow this step-by-step guide:
|
||||
1) Download the development environment from http://tinyurl.com/pcemude. Afterwards, extract it to your desired location. Of course, also clone the repository in your desired location. Downloading ZIPs is not recommended, as it makes it more inconvenient to keep the code up-to-date. To avoid issues, make sure neither path has spaces in it.
|
||||
2) In the extracted environment folder, you will find a script called **mingw32_shell.bat**. Launch it. There are other shell launching scripts in there, but you should not use them.
|
||||
3) Once launched, run **pacman -Syuu** in order to update the environment. Depending on the state of the downloaded DE, you may need to run it twice (once initially, and then again after re-entering the environment). Make sure to keep the enviroment up-to-date by re-running the command periodically.
|
||||
4) Once the environment is fully updated, **cd** into your cloned **86box\src** directory.
|
||||
5) Run **make -j*N* -fmakefile.mingw** to start the actual compilation process. Substitute *N* with the number of threads you want to use for the compilation process. The optimal number depends entirely on your processor, and it is up to you to determine the optimal number. A good starting point is the total number of threads (AKA Logical Processors) you have available.
|
||||
6) If the compilation succeeded (which it almost always should), you will find **86Box.exe** in the src directory.
|
||||
7) In order to test your fresh build, replace the **86Box.exe** in your current 86Box enviroment with your freshly built one. If you do not have a pre-existing 86Box environment, download the latest successful build from http://ci.86box.net, and the ROM set from http://tinyurl.com/roms2017.
|
||||
8) Enjoy using and testing the emulator! :)
|
||||
|
||||
If you encounter issues at any step or have additional questions, please join the IRC channel and wait patiently for someone to help you.
|
||||
|
||||
|
||||
|
||||
@@ -401,828 +401,6 @@ int checkio(int port)
|
||||
return d&(1<<(port&7));
|
||||
}
|
||||
|
||||
int rep386(int fv)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint32_t c;
|
||||
uint8_t temp2;
|
||||
uint16_t tempw,tempw2,of;
|
||||
uint32_t ipc = cpu_state.oldpc;
|
||||
uint32_t rep32 = cpu_state.op32;
|
||||
uint32_t templ,templ2;
|
||||
int tempz;
|
||||
int tempi;
|
||||
/*Limit the amount of time the instruction is uninterruptable for, so
|
||||
that high frequency timers still work okay. This amount is different
|
||||
for interpreter and recompiler*/
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100);
|
||||
int reads = 0, reads_l = 0, writes = 0, writes_l = 0, total_cycles = 0;
|
||||
|
||||
if (trap)
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/
|
||||
|
||||
cpu_reps++;
|
||||
|
||||
flags_rebuild();
|
||||
of = flags;
|
||||
startrep:
|
||||
temp=opcode2=readmemb(cs,cpu_state.pc); cpu_state.pc++;
|
||||
c=(rep32&0x200)?ECX:CX;
|
||||
switch (temp|rep32)
|
||||
{
|
||||
case 0xC3: case 0x1C3: case 0x2C3: case 0x3C3:
|
||||
cpu_state.pc--;
|
||||
break;
|
||||
case 0x08:
|
||||
cpu_state.pc=ipc+1;
|
||||
break;
|
||||
case 0x26: case 0x126: case 0x226: case 0x326: /*ES:*/
|
||||
cpu_state.ea_seg = &_es;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
break;
|
||||
case 0x2E: case 0x12E: case 0x22E: case 0x32E: /*CS:*/
|
||||
cpu_state.ea_seg = &_cs;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x36: case 0x136: case 0x236: case 0x336: /*SS:*/
|
||||
cpu_state.ea_seg = &_ss;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x3E: case 0x13E: case 0x23E: case 0x33E: /*DS:*/
|
||||
cpu_state.ea_seg = &_ds;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x64: case 0x164: case 0x264: case 0x364: /*FS:*/
|
||||
cpu_state.ea_seg = &_fs;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x65: case 0x165: case 0x265: case 0x365: /*GS:*/
|
||||
cpu_state.ea_seg = &_gs;
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x66: case 0x166: case 0x266: case 0x366: /*Data size prefix*/
|
||||
rep32 = (rep32 & 0x200) | ((use32 ^ 0x100) & 0x100);
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x67: case 0x167: case 0x267: case 0x367: /*Address size prefix*/
|
||||
rep32 = (rep32 & 0x100) | ((use32 ^ 0x200) & 0x200);
|
||||
PREFETCH_PREFIX();
|
||||
goto startrep;
|
||||
case 0x6C: case 0x16C: /*REP INSB*/
|
||||
if (c>0)
|
||||
{
|
||||
checkio_perm(DX);
|
||||
temp2=inb(DX);
|
||||
writememb(es,DI,temp2);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) DI--;
|
||||
else DI++;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x26C: case 0x36C: /*REP INSB*/
|
||||
if (c>0)
|
||||
{
|
||||
checkio_perm(DX);
|
||||
temp2=inb(DX);
|
||||
writememb(es,EDI,temp2);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) EDI--;
|
||||
else EDI++;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x6D: /*REP INSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw=inw(DX);
|
||||
writememw(es,DI,tempw);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) DI-=2;
|
||||
else DI+=2;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x16D: /*REP INSL*/
|
||||
if (c>0)
|
||||
{
|
||||
templ=inl(DX);
|
||||
writememl(es,DI,templ);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) DI-=4;
|
||||
else DI+=4;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads_l++; writes_l++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x26D: /*REP INSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw=inw(DX);
|
||||
writememw(es,EDI,tempw);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) EDI-=2;
|
||||
else EDI+=2;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads++; writes++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x36D: /*REP INSL*/
|
||||
if (c>0)
|
||||
{
|
||||
templ=inl(DX);
|
||||
writememl(es,EDI,templ);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) EDI-=4;
|
||||
else EDI+=4;
|
||||
c--;
|
||||
cycles-=15;
|
||||
reads_l++; writes_l++; total_cycles += 15;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x6E: case 0x16E: /*REP OUTSB*/
|
||||
if (c>0)
|
||||
{
|
||||
temp2 = readmemb(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt) break;
|
||||
checkio_perm(DX);
|
||||
outb(DX,temp2);
|
||||
if (flags&D_FLAG) SI--;
|
||||
else SI++;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x26E: case 0x36E: /*REP OUTSB*/
|
||||
if (c>0)
|
||||
{
|
||||
temp2 = readmemb(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt) break;
|
||||
checkio_perm(DX);
|
||||
outb(DX,temp2);
|
||||
if (flags&D_FLAG) ESI--;
|
||||
else ESI++;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x6F: /*REP OUTSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw = readmemw(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt) break;
|
||||
outw(DX,tempw);
|
||||
if (flags&D_FLAG) SI-=2;
|
||||
else SI+=2;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x16F: /*REP OUTSL*/
|
||||
if (c > 0)
|
||||
{
|
||||
templ = readmeml(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt) break;
|
||||
outl(DX, templ);
|
||||
if (flags & D_FLAG) SI -= 4;
|
||||
else SI += 4;
|
||||
c--;
|
||||
cycles -= 14;
|
||||
reads_l++; writes_l++; total_cycles += 14;
|
||||
}
|
||||
if (c > 0) { firstrepcycle = 0; cpu_state.pc = ipc; }
|
||||
else firstrepcycle = 1;
|
||||
break;
|
||||
case 0x26F: /*REP OUTSW*/
|
||||
if (c>0)
|
||||
{
|
||||
tempw = readmemw(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt) break;
|
||||
outw(DX,tempw);
|
||||
if (flags&D_FLAG) ESI-=2;
|
||||
else ESI+=2;
|
||||
c--;
|
||||
cycles-=14;
|
||||
reads++; writes++; total_cycles += 14;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x36F: /*REP OUTSL*/
|
||||
if (c > 0)
|
||||
{
|
||||
templ = readmeml(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt) break;
|
||||
outl(DX, templ);
|
||||
if (flags & D_FLAG) ESI -= 4;
|
||||
else ESI += 4;
|
||||
c--;
|
||||
cycles -= 14;
|
||||
reads_l++; writes_l++; total_cycles += 14;
|
||||
}
|
||||
if (c > 0) { firstrepcycle = 0; cpu_state.pc = ipc; }
|
||||
else firstrepcycle = 1;
|
||||
break;
|
||||
case 0x90: case 0x190: /*REP NOP*/
|
||||
case 0x290: case 0x390:
|
||||
break;
|
||||
case 0xA4: case 0x1A4: /*REP MOVSB*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI);
|
||||
temp2 = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break;
|
||||
writememb(es,DI,temp2); if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) { DI--; SI--; }
|
||||
else { DI++; SI++; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A4: case 0x3A4: /*REP MOVSB*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI);
|
||||
temp2 = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break;
|
||||
writememb(es,EDI,temp2); if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) { EDI--; ESI--; }
|
||||
else { EDI++; ESI++; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xA5: /*REP MOVSW*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI+1);
|
||||
tempw = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break;
|
||||
writememw(es,DI,tempw); if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) { DI-=2; SI-=2; }
|
||||
else { DI+=2; SI+=2; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1A5: /*REP MOVSL*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI+3);
|
||||
templ = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break;
|
||||
writememl(es,DI,templ); if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) { DI-=4; SI-=4; }
|
||||
else { DI+=4; SI+=4; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads_l++; writes_l++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A5: /*REP MOVSW*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+1);
|
||||
tempw = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break;
|
||||
writememw(es,EDI,tempw); if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) { EDI-=2; ESI-=2; }
|
||||
else { EDI+=2; ESI+=2; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3A5: /*REP MOVSL*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+3);
|
||||
templ = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break;
|
||||
writememl(es,EDI,templ); if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) { EDI-=4; ESI-=4; }
|
||||
else { EDI+=4; ESI+=4; }
|
||||
c--;
|
||||
cycles-=(is486)?3:4;
|
||||
ins++;
|
||||
reads_l++; writes_l++; total_cycles += is486 ? 3 : 4;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xA6: case 0x1A6: /*REP CMPSB*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
temp = readmemb(cpu_state.ea_seg->base, SI);
|
||||
temp2=readmemb(es,DI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { DI--; SI--; }
|
||||
else { DI++; SI++; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub8(temp,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A6: case 0x3A6: /*REP CMPSB*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
temp = readmemb(cpu_state.ea_seg->base, ESI);
|
||||
temp2=readmemb(es,EDI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { EDI--; ESI--; }
|
||||
else { EDI++; ESI++; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub8(temp,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xA7: /*REP CMPSW*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
tempw = readmemw(cpu_state.ea_seg->base, SI);
|
||||
tempw2=readmemw(es,DI);
|
||||
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { DI-=2; SI-=2; }
|
||||
else { DI+=2; SI+=2; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub16(tempw,tempw2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1A7: /*REP CMPSL*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
templ = readmeml(cpu_state.ea_seg->base, SI);
|
||||
templ2=readmeml(es,DI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { DI-=4; SI-=4; }
|
||||
else { DI+=4; SI+=4; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads_l += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub32(templ,templ2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2A7: /*REP CMPSW*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
tempw = readmemw(cpu_state.ea_seg->base, ESI);
|
||||
tempw2=readmemw(es,EDI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { EDI-=2; ESI-=2; }
|
||||
else { EDI+=2; ESI+=2; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub16(tempw,tempw2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3A7: /*REP CMPSL*/
|
||||
tempz = (fv) ? 1 : 0;
|
||||
if ((c>0) && (fv==tempz))
|
||||
{
|
||||
templ = readmeml(cpu_state.ea_seg->base, ESI);
|
||||
templ2=readmeml(es,EDI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
if (flags&D_FLAG) { EDI-=4; ESI-=4; }
|
||||
else { EDI+=4; ESI+=4; }
|
||||
c--;
|
||||
cycles-=(is486)?7:9;
|
||||
reads_l += 2; total_cycles += is486 ? 7 : 9;
|
||||
setsub32(templ,templ2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
}
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
|
||||
case 0xAA: case 0x1AA: /*REP STOSB*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI);
|
||||
writememb(es,DI,AL);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) DI--;
|
||||
else DI++;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AA: case 0x3AA: /*REP STOSB*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI);
|
||||
writememb(es,EDI,AL);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) EDI--;
|
||||
else EDI++;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAB: /*REP STOSW*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI+1);
|
||||
writememw(es,DI,AX);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) DI-=2;
|
||||
else DI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AB: /*REP STOSW*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+1);
|
||||
writememw(es,EDI,AX);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) EDI-=2;
|
||||
else EDI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1AB: /*REP STOSL*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, DI, DI+3);
|
||||
writememl(es,DI,EAX);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) DI-=4;
|
||||
else DI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes_l++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3AB: /*REP STOSL*/
|
||||
while (c > 0)
|
||||
{
|
||||
CHECK_WRITE_REP(&_es, EDI, EDI+3);
|
||||
writememl(es,EDI,EAX);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) EDI-=4;
|
||||
else EDI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?4:5;
|
||||
writes_l++; total_cycles += is486 ? 4 : 5;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAC: case 0x1AC: /*REP LODSB*/
|
||||
if (c>0)
|
||||
{
|
||||
AL = readmemb(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) SI--;
|
||||
else SI++;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AC: case 0x3AC: /*REP LODSB*/
|
||||
if (c>0)
|
||||
{
|
||||
AL = readmemb(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) ESI--;
|
||||
else ESI++;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAD: /*REP LODSW*/
|
||||
if (c>0)
|
||||
{
|
||||
AX = readmemw(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) SI-=2;
|
||||
else SI+=2;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1AD: /*REP LODSL*/
|
||||
if (c>0)
|
||||
{
|
||||
EAX = readmeml(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) SI-=4;
|
||||
else SI+=4;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads_l++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AD: /*REP LODSW*/
|
||||
if (c>0)
|
||||
{
|
||||
AX = readmemw(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) ESI-=2;
|
||||
else ESI+=2;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3AD: /*REP LODSL*/
|
||||
if (c>0)
|
||||
{
|
||||
EAX = readmeml(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt) break;
|
||||
if (flags&D_FLAG) ESI-=4;
|
||||
else ESI+=4;
|
||||
c--;
|
||||
cycles-=5;
|
||||
reads_l++; total_cycles += 5;
|
||||
}
|
||||
if (c>0) { firstrepcycle=0; cpu_state.pc=ipc; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAE: case 0x1AE: /*REP SCASB*/
|
||||
cpu_notreps++;
|
||||
tempz = (fv) ? 1 : 0;
|
||||
while ((c > 0) && (fv == tempz))
|
||||
{
|
||||
temp2=readmemb(es,DI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
setsub8(AL,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
if (flags&D_FLAG) DI--;
|
||||
else DI++;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AE: case 0x3AE: /*REP SCASB*/
|
||||
cpu_notreps++;
|
||||
tempz = (fv) ? 1 : 0;
|
||||
while ((c > 0) && (fv == tempz))
|
||||
{
|
||||
temp2=readmemb(es,EDI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
setsub8(AL,temp2);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
if (flags&D_FLAG) EDI--;
|
||||
else EDI++;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0xAF: /*REP SCASW*/
|
||||
cpu_notreps++;
|
||||
tempz = (fv) ? 1 : 0;
|
||||
while ((c > 0) && (fv == tempz))
|
||||
{
|
||||
tempw=readmemw(es,DI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
setsub16(AX,tempw);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
if (flags&D_FLAG) DI-=2;
|
||||
else DI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x1AF: /*REP SCASL*/
|
||||
cpu_notreps++;
|
||||
tempz = (fv) ? 1 : 0;
|
||||
while ((c > 0) && (fv == tempz))
|
||||
{
|
||||
templ=readmeml(es,DI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
setsub32(EAX,templ);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
if (flags&D_FLAG) DI-=4;
|
||||
else DI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads_l++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x2AF: /*REP SCASW*/
|
||||
cpu_notreps++;
|
||||
tempz = (fv) ? 1 : 0;
|
||||
while ((c > 0) && (fv == tempz))
|
||||
{
|
||||
tempw=readmemw(es,EDI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
setsub16(AX,tempw);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
if (flags&D_FLAG) EDI-=2;
|
||||
else EDI+=2;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
case 0x3AF: /*REP SCASL*/
|
||||
cpu_notreps++;
|
||||
tempz = (fv) ? 1 : 0;
|
||||
while ((c > 0) && (fv == tempz))
|
||||
{
|
||||
templ=readmeml(es,EDI);
|
||||
if (cpu_state.abrt) { flags=of; break; }
|
||||
setsub32(EAX,templ);
|
||||
tempz = (ZF_SET()) ? 1 : 0;
|
||||
if (flags&D_FLAG) EDI-=4;
|
||||
else EDI+=4;
|
||||
c--;
|
||||
cycles-=(is486)?5:8;
|
||||
reads_l++; total_cycles += is486 ? 5 : 8;
|
||||
ins++;
|
||||
if (cycles < cycles_end)
|
||||
break;
|
||||
}
|
||||
ins--;
|
||||
if ((c>0) && (fv==tempz)) { cpu_state.pc=ipc; firstrepcycle=0; }
|
||||
else firstrepcycle=1;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
cpu_state.pc = ipc+1;
|
||||
break;
|
||||
}
|
||||
if (rep32&0x200) ECX=c;
|
||||
else CX=c;
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, reads_l, writes, writes_l, 0);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
|
||||
int xout=0;
|
||||
|
||||
|
||||
|
||||
@@ -519,7 +519,7 @@ OpFn OP_TABLE(winchip_0f)[1024] =
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a16, opSHLD_w_i_a16, opSHLD_w_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a16, opSHRD_w_i_a16, opSHRD_w_CL_a16,ILLEGAL, opIMUL_w_w_a16,
|
||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_w_a16,opLSS_w_a16, opBTR_w_r_a16, opLFS_w_a16, opLGS_w_a16, opMOVZX_w_b_a16,opMOVZX_w_w_a16,ILLEGAL, ILLEGAL, opBA_w_a16, opBTC_w_r_a16, opBSF_w_a16, opBSR_w_a16, opMOVSX_w_b_a16,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*c0*/ opXADD_b_a16, opXADD_w_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16,
|
||||
/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16,
|
||||
/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL,
|
||||
@@ -541,7 +541,7 @@ OpFn OP_TABLE(winchip_0f)[1024] =
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a16, opSHLD_l_i_a16, opSHLD_l_CL_a16,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a16, opSHRD_l_i_a16, opSHRD_l_CL_a16,ILLEGAL, opIMUL_l_l_a16,
|
||||
/*b0*/ opCMPXCHG_b_a16,opCMPXCHG_l_a16,opLSS_l_a16, opBTR_l_r_a16, opLFS_l_a16, opLGS_l_a16, opMOVZX_l_b_a16,opMOVZX_l_w_a16,ILLEGAL, ILLEGAL, opBA_l_a16, opBTC_l_r_a16, opBSF_l_a16, opBSR_l_a16, opMOVSX_l_b_a16,opMOVSX_l_w_a16,
|
||||
|
||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*c0*/ opXADD_b_a16, opXADD_l_a16, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a16,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, opPSRLW_a16, opPSRLD_a16, opPSRLQ_a16, ILLEGAL, opPMULLW_a16, ILLEGAL, ILLEGAL, opPSUBUSB_a16, opPSUBUSW_a16, NULL, opPAND_a16, opPADDUSB_a16, opPADDUSW_a16, NULL, opPANDN_a16,
|
||||
/*e0*/ ILLEGAL, opPSRAW_a16, opPSRAD_a16, ILLEGAL, ILLEGAL, opPMULHW_a16, ILLEGAL, ILLEGAL, opPSUBSB_a16, opPSUBSW_a16, NULL, opPOR_a16, opPADDSB_a16, opPADDSW_a16, NULL, opPXOR_a16,
|
||||
/*f0*/ ILLEGAL, opPSLLW_a16, opPSLLD_a16, opPSLLQ_a16, ILLEGAL, opPMADDWD_a16, ILLEGAL, ILLEGAL, opPSUBB_a16, opPSUBW_a16, opPSUBD_a16, ILLEGAL, opPADDB_a16, opPADDW_a16, opPADDD_a16, ILLEGAL,
|
||||
@@ -563,7 +563,7 @@ OpFn OP_TABLE(winchip_0f)[1024] =
|
||||
/*a0*/ opPUSH_FS_w, opPOP_FS_w, opCPUID, opBT_w_r_a32, opSHLD_w_i_a32, opSHLD_w_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_w, opPOP_GS_w, ILLEGAL, opBTS_w_r_a32, opSHRD_w_i_a32, opSHRD_w_CL_a32,ILLEGAL, opIMUL_w_w_a32,
|
||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_w_a32,opLSS_w_a32, opBTR_w_r_a32, opLFS_w_a32, opLGS_w_a32, opMOVZX_w_b_a32,opMOVZX_w_w_a32,ILLEGAL, ILLEGAL, opBA_w_a32, opBTC_w_r_a32, opBSF_w_a32, opBSR_w_a32, opMOVSX_w_b_a32,ILLEGAL,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*c0*/ opXADD_b_a32, opXADD_w_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32,
|
||||
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
|
||||
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
||||
@@ -585,7 +585,7 @@ OpFn OP_TABLE(winchip_0f)[1024] =
|
||||
/*a0*/ opPUSH_FS_l, opPOP_FS_l, opCPUID, opBT_l_r_a32, opSHLD_l_i_a32, opSHLD_l_CL_a32,ILLEGAL, ILLEGAL, opPUSH_GS_l, opPOP_GS_l, ILLEGAL, opBTS_l_r_a32, opSHRD_l_i_a32, opSHRD_l_CL_a32,ILLEGAL, opIMUL_l_l_a32,
|
||||
/*b0*/ opCMPXCHG_b_a32,opCMPXCHG_l_a32,opLSS_l_a32, opBTR_l_r_a32, opLFS_l_a32, opLGS_l_a32, opMOVZX_l_b_a32,opMOVZX_l_w_a32,ILLEGAL, ILLEGAL, opBA_l_a32, opBTC_l_r_a32, opBSF_l_a32, opBSR_l_a32, opMOVSX_l_b_a32,opMOVSX_l_w_a32,
|
||||
|
||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*c0*/ opXADD_b_a32, opXADD_l_a32, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opCMPXCHG8B_a32,opBSWAP_EAX, opBSWAP_ECX, opBSWAP_EDX, opBSWAP_EBX, opBSWAP_ESP, opBSWAP_EBP, opBSWAP_ESI, opBSWAP_EDI,
|
||||
/*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32,
|
||||
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
|
||||
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
||||
@@ -1410,4 +1410,186 @@ OpFn OP_TABLE(386)[1024] =
|
||||
/*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32,
|
||||
/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX,
|
||||
/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32,
|
||||
};
|
||||
|
||||
OpFn OP_TABLE(REPE)[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_w_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPE_w_a16,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_w_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPE_w_a16,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPE_w_a16,opGS_REPE_w_a16,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_E,opREP_CMPSW_a16_E,0, 0, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_E,opREP_SCASW_a16_E,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_l_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPE_l_a16,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_l_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPE_l_a16,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPE_l_a16,opGS_REPE_l_a16,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_E,opREP_CMPSL_a16_E,0, 0, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_E,opREP_SCASL_a16_E,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_w_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPE_w_a32,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_w_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPE_w_a32,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPE_w_a32,opGS_REPE_w_a32,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_E,opREP_CMPSW_a32_E,0, 0, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_E,opREP_SCASW_a32_E,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPE_l_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPE_l_a32,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPE_l_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPE_l_a32,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPE_l_a32,opGS_REPE_l_a32,op_66_REPE, op_67_REPE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_E,opREP_CMPSL_a32_E,0, 0, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_E,opREP_SCASL_a32_E,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
OpFn OP_TABLE(REPNE)[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_w_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_w_a16,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_w_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_w_a16,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPNE_w_a16,opGS_REPNE_w_a16,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSW_a16, opREP_OUTSB_a16,opREP_OUTSW_a16,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSW_a16,opREP_CMPSB_a16_NE,opREP_CMPSW_a16_NE,0, 0, opREP_STOSB_a16,opREP_STOSW_a16,opREP_LODSB_a16,opREP_LODSW_a16,opREP_SCASB_a16_NE,opREP_SCASW_a16_NE,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*32-bit data, 16-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_l_a16,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_l_a16,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_l_a16,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_l_a16,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPNE_l_a16,opGS_REPNE_l_a16,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a16, opREP_INSL_a16, opREP_OUTSB_a16,opREP_OUTSL_a16,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a16,opREP_MOVSL_a16,opREP_CMPSB_a16_NE,opREP_CMPSL_a16_NE,0, 0, opREP_STOSB_a16,opREP_STOSL_a16,opREP_LODSB_a16,opREP_LODSL_a16,opREP_SCASB_a16_NE,opREP_SCASL_a16_NE,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*16-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_w_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_w_a32,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_w_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_w_a32,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPNE_w_a32,opGS_REPNE_w_a32,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSW_a32, opREP_OUTSB_a32,opREP_OUTSW_a32,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSW_a32,opREP_CMPSB_a32_NE,opREP_CMPSW_a32_NE,0, 0, opREP_STOSB_a32,opREP_STOSW_a32,opREP_LODSB_a32,opREP_LODSW_a32,opREP_SCASB_a32_NE,opREP_SCASW_a32_NE,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*32-bit data, 32-bit addr*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*20*/ 0, 0, 0, 0, 0, 0, opES_REPNE_l_a32,0, 0, 0, 0, 0, 0, 0, opCS_REPNE_l_a32,0,
|
||||
/*30*/ 0, 0, 0, 0, 0, 0, opSS_REPNE_l_a32,0, 0, 0, 0, 0, 0, 0, opDS_REPNE_l_a32,0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*50*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*60*/ 0, 0, 0, 0, opFS_REPNE_l_a32,opGS_REPNE_l_a32,op_66_REPNE, op_67_REPNE, 0, 0, 0, 0, opREP_INSB_a32, opREP_INSL_a32, opREP_OUTSB_a32,opREP_OUTSL_a32,
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*90*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*a0*/ 0, 0, 0, 0, opREP_MOVSB_a32,opREP_MOVSL_a32,opREP_CMPSB_a32_NE,opREP_CMPSL_a32_NE,0, 0, opREP_STOSB_a32,opREP_STOSL_a32,opREP_LODSB_a32,opREP_LODSL_a32,opREP_SCASB_a32_NE,opREP_SCASL_a32_NE,
|
||||
/*b0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*c0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
@@ -571,6 +571,7 @@ void resetx86()
|
||||
cpu_cur_status = 0;
|
||||
stack32=0;
|
||||
cpu_state.pc=0;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
msw=0;
|
||||
if (is486)
|
||||
cr0 = 1 << 30;
|
||||
@@ -609,6 +610,7 @@ void softresetx86()
|
||||
stack32=0;
|
||||
cpu_cur_status = 0;
|
||||
cpu_state.pc=0;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
msw=0;
|
||||
cr0=0;
|
||||
cr4 = 0;
|
||||
@@ -983,7 +985,7 @@ void execx86(int cycs)
|
||||
int8_t offset;
|
||||
int tempws;
|
||||
uint32_t templ;
|
||||
int c;
|
||||
unsigned int c;
|
||||
int tempi;
|
||||
int trap;
|
||||
|
||||
@@ -2439,6 +2441,12 @@ void execx86(int cycs)
|
||||
switch (rmdat&0x38)
|
||||
{
|
||||
case 0x00: /*ROL b,CL*/
|
||||
temp2=(temp&0x80)?1:0;
|
||||
if (!c)
|
||||
{
|
||||
cycles-=((cpu_mod==3)?8:28);
|
||||
break;
|
||||
}
|
||||
while (c>0)
|
||||
{
|
||||
temp2=(temp&0x80)?1:0;
|
||||
@@ -2454,6 +2462,12 @@ void execx86(int cycs)
|
||||
cycles-=((cpu_mod==3)?8:28);
|
||||
break;
|
||||
case 0x08: /*ROR b,CL*/
|
||||
temp2=temp&1;
|
||||
if (!c)
|
||||
{
|
||||
cycles-=((cpu_mod==3)?8:28);
|
||||
break;
|
||||
}
|
||||
while (c>0)
|
||||
{
|
||||
temp2=temp&1;
|
||||
@@ -2564,6 +2578,12 @@ void execx86(int cycs)
|
||||
cycles-=((cpu_mod==3)?8:28);
|
||||
break;
|
||||
case 0x08: /*ROR w,CL*/
|
||||
tempw2=(tempw&1)?0x8000:0;
|
||||
if (!c)
|
||||
{
|
||||
cycles-=((cpu_mod==3)?8:28);
|
||||
break;
|
||||
}
|
||||
while (c>0)
|
||||
{
|
||||
tempw2=(tempw&1)?0x8000:0;
|
||||
@@ -2596,6 +2616,13 @@ void execx86(int cycs)
|
||||
cycles-=((cpu_mod==3)?8:28);
|
||||
break;
|
||||
case 0x18: /*RCR w,CL*/
|
||||
templ=flags&C_FLAG;
|
||||
tempw2=(templ&1)?0x8000:0;
|
||||
if (!c)
|
||||
{
|
||||
cycles-=((cpu_mod==3)?8:28);
|
||||
break;
|
||||
}
|
||||
while (c>0)
|
||||
{
|
||||
templ=flags&C_FLAG;
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
#ifndef _CODEGEN_H_
|
||||
#define _CODEGEN_H_
|
||||
|
||||
#include "../mem.h"
|
||||
#include "x86_ops.h"
|
||||
|
||||
#ifdef __amd64__
|
||||
#include "codegen_x86-64.h"
|
||||
@@ -35,10 +39,10 @@
|
||||
|
||||
typedef struct codeblock_t
|
||||
{
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t page_mask, page_mask2;
|
||||
uint64_t *dirty_mask, *dirty_mask2;
|
||||
uint64_t cmp;
|
||||
|
||||
uint64_t cmp;
|
||||
|
||||
/*Previous and next pointers, for the codeblock list associated with
|
||||
each physical page. Two sets of pointers, as a codeblock can be
|
||||
present in two pages.*/
|
||||
@@ -59,7 +63,7 @@ typedef struct codeblock_t
|
||||
uint32_t _cs;
|
||||
uint32_t endpc;
|
||||
uint32_t phys, phys_2;
|
||||
uint32_t status;
|
||||
uint32_t status;
|
||||
uint32_t flags;
|
||||
|
||||
uint8_t data[2048];
|
||||
@@ -70,7 +74,7 @@ typedef struct codeblock_t
|
||||
/*Code block is always entered with the same FPU top-of-stack*/
|
||||
#define CODEBLOCK_STATIC_TOP 2
|
||||
|
||||
static __inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||
static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||
{
|
||||
codeblock_t *block = pages[phys >> 12].head;
|
||||
uint64_t a = _cs | ((uint64_t)phys << 32);
|
||||
@@ -88,7 +92,7 @@ static __inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
|
||||
return block;
|
||||
}
|
||||
|
||||
static __inline void codeblock_tree_add(codeblock_t *new_block)
|
||||
static inline void codeblock_tree_add(codeblock_t *new_block)
|
||||
{
|
||||
codeblock_t *block = pages[new_block->phys >> 12].head;
|
||||
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
|
||||
@@ -122,7 +126,7 @@ static __inline void codeblock_tree_add(codeblock_t *new_block)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void codeblock_tree_delete(codeblock_t *block)
|
||||
static inline void codeblock_tree_delete(codeblock_t *block)
|
||||
{
|
||||
codeblock_t *parent = block->parent;
|
||||
|
||||
@@ -252,6 +256,7 @@ void codegen_block_init(uint32_t phys_addr);
|
||||
void codegen_block_remove();
|
||||
void codegen_block_start_recompile(codeblock_t *block);
|
||||
void codegen_block_end_recompile(codeblock_t *block);
|
||||
void codegen_block_end();
|
||||
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc);
|
||||
void codegen_generate_seg_restore();
|
||||
void codegen_set_op32();
|
||||
@@ -300,7 +305,7 @@ extern int block_pos;
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
static __inline void addbyte(uint8_t val)
|
||||
static inline void addbyte(uint8_t val)
|
||||
{
|
||||
codeblock[block_current].data[block_pos++] = val;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
@@ -309,10 +314,10 @@ static __inline void addbyte(uint8_t val)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void addword(uint16_t val)
|
||||
static inline void addword(uint16_t val)
|
||||
{
|
||||
uint16_t *p = (uint16_t *)&codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 2;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
@@ -320,10 +325,10 @@ static __inline void addword(uint16_t val)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void addlong(uint32_t val)
|
||||
static inline void addlong(uint32_t val)
|
||||
{
|
||||
uint32_t *p = (uint32_t *)&codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 4;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
@@ -331,10 +336,10 @@ static __inline void addlong(uint32_t val)
|
||||
}
|
||||
}
|
||||
|
||||
static __inline void addquad(uint64_t val)
|
||||
static inline void addquad(uint64_t val)
|
||||
{
|
||||
uint64_t *p = (uint64_t *)&codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos];
|
||||
*p = val;
|
||||
block_pos += 8;
|
||||
if (block_pos >= BLOCK_MAX)
|
||||
{
|
||||
@@ -360,3 +365,5 @@ extern int codegen_fpu_loaded_iq[8];
|
||||
extern int codegen_reg_loaded[8];
|
||||
|
||||
extern int codegen_in_recompile;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -496,3 +496,97 @@ RecompOpFn recomp_opcodes_df[512] =
|
||||
/*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_REPE[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*32-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
RecompOpFn recomp_opcodes_REPNE[512] =
|
||||
{
|
||||
/*16-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*32-bit data*/
|
||||
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
|
||||
/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
|
||||
/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#ifndef _CODEGEN_OPS_H_
|
||||
#define _CODEGEN_OPS_H_
|
||||
|
||||
#include "codegen.h"
|
||||
|
||||
typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block);
|
||||
|
||||
extern RecompOpFn recomp_opcodes[512];
|
||||
@@ -10,6 +15,8 @@ extern RecompOpFn recomp_opcodes_dc[512];
|
||||
extern RecompOpFn recomp_opcodes_dd[512];
|
||||
extern RecompOpFn recomp_opcodes_de[512];
|
||||
extern RecompOpFn recomp_opcodes_df[512];
|
||||
RecompOpFn recomp_opcodes_REPE[512];
|
||||
RecompOpFn recomp_opcodes_REPNE[512];
|
||||
|
||||
#define REG_EAX 0
|
||||
#define REG_ECX 1
|
||||
@@ -35,3 +42,5 @@ extern RecompOpFn recomp_opcodes_df[512];
|
||||
#define REG_DH 6
|
||||
#define REG_BL 3
|
||||
#define REG_BH 7
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "../ibm.h"
|
||||
#include "../mem.h"
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include "../mem.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
#define CYCLES(c) (int *)c
|
||||
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
@@ -247,14 +249,27 @@ static int *opcode_timings_8x[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static __inline int COUNT(int *c, int op_32)
|
||||
static inline int COUNT(int *c, int op_32)
|
||||
{
|
||||
if ((uintptr_t)c <= 10000)
|
||||
return (int)c;
|
||||
return (int)(uintptr_t)c;
|
||||
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
@@ -266,6 +281,7 @@ static __inline int COUNT(int *c, int op_32)
|
||||
|
||||
void codegen_timing_486_block_start()
|
||||
{
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_486_start()
|
||||
@@ -283,82 +299,107 @@ void codegen_timing_486_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
void codegen_timing_486_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
int **timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x;
|
||||
if (!mod3)
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
void codegen_timing_486_block_end()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
- X/Y pairing
|
||||
- FPU/FXCH pairing
|
||||
- Prefix decode delay
|
||||
- AGI stalls
|
||||
Elements not taken into account :
|
||||
- Branch prediction (beyond most simplistic approximation)
|
||||
- FPU queue
|
||||
@@ -15,6 +16,7 @@
|
||||
#include "x87.h"
|
||||
#include "../mem.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
/*Instruction has different execution time for 16 and 32 bit data. Does not pair */
|
||||
#define CYCLES_HAS_MULTI (1 << 31)
|
||||
@@ -33,11 +35,6 @@
|
||||
|
||||
#define CYCLES_MASK ((1 << 7) - 1)
|
||||
|
||||
/*Instruction is MMX shift or pack/unpack instruction*/
|
||||
#define MMX_SHIFTPACK (1 << 7)
|
||||
/*Instruction is MMX multiply instruction*/
|
||||
#define MMX_MULTIPLY (1 << 8)
|
||||
|
||||
/*Instruction does not pair*/
|
||||
#define PAIR_NP (0 << 29)
|
||||
/*Instruction pairs in X pipe only*/
|
||||
@@ -49,35 +46,6 @@
|
||||
|
||||
#define PAIR_MASK (3 << 29)
|
||||
|
||||
/*Instruction has input dependency on register in REG field*/
|
||||
#define SRCDEP_REG (1 << 9)
|
||||
/*Instruction has input dependency on register in R/M field*/
|
||||
#define SRCDEP_RM (1 << 10)
|
||||
/*Instruction modifies register in REG field*/
|
||||
#define DSTDEP_REG (1 << 11)
|
||||
/*Instruction modifies register in R/M field*/
|
||||
#define DSTDEP_RM (1 << 12)
|
||||
|
||||
/*Instruction has input dependency on given register*/
|
||||
#define SRCDEP_EAX (1 << 13)
|
||||
#define SRCDEP_ECX (1 << 14)
|
||||
#define SRCDEP_EDX (1 << 15)
|
||||
#define SRCDEP_EBX (1 << 16)
|
||||
#define SRCDEP_ESP (1 << 17)
|
||||
#define SRCDEP_EBP (1 << 18)
|
||||
#define SRCDEP_ESI (1 << 19)
|
||||
#define SRCDEP_EDI (1 << 20)
|
||||
|
||||
/*Instruction modifies given register*/
|
||||
#define DSTDEP_EAX (1 << 21)
|
||||
#define DSTDEP_ECX (1 << 22)
|
||||
#define DSTDEP_EDX (1 << 23)
|
||||
#define DSTDEP_EBX (1 << 24)
|
||||
#define DSTDEP_ESP (1 << 25)
|
||||
#define DSTDEP_EBP (1 << 26)
|
||||
#define DSTDEP_ESI (1 << 27)
|
||||
#define DSTDEP_EDI (1 << 28)
|
||||
|
||||
#define INVALID 0
|
||||
|
||||
static int prev_full;
|
||||
@@ -85,119 +53,74 @@ static uint32_t prev_opcode;
|
||||
static uint32_t *prev_timings;
|
||||
static uint32_t prev_op_32;
|
||||
static uint32_t prev_regmask;
|
||||
static uint64_t *prev_deps;
|
||||
static uint32_t prev_fetchdat;
|
||||
|
||||
#define REGMASK_MMX (1 << 8)
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static uint32_t get_srcdep_mask(uint32_t data, uint32_t fetchdat, int bit8)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & SRCDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & SRCDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> 16) & 0xff);
|
||||
if (data & (MMX_SHIFTPACK | MMX_MULTIPLY))
|
||||
mask |= REGMASK_MMX;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static uint32_t get_dstdep_mask(uint32_t data, uint32_t fetchdat, int bit8)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & DSTDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & DSTDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> 24) & 0xff);
|
||||
if (data & (MMX_SHIFTPACK | MMX_MULTIPLY))
|
||||
mask |= REGMASK_MMX;
|
||||
|
||||
return mask;
|
||||
}
|
||||
static uint32_t opcode_timings[256] =
|
||||
{
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3),
|
||||
/* OR OR OR OR*/
|
||||
PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG,
|
||||
/* OR OR PUSH CS */
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, INVALID,
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
/* OR OR OR OR*/
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* OR OR PUSH CS */
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID,
|
||||
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3),
|
||||
/* SBB SBB SBB SBB*/
|
||||
PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3),
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
/* SBB SBB SBB SBB*/
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG,
|
||||
/* AND AND DAA*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* SUB SUB SUB SUB*/
|
||||
PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG,
|
||||
/* SUB SUB DAS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* AND AND DAA*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* SUB SUB SUB SUB*/
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* SUB SUB DAS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG | DSTDEP_REG,
|
||||
/* XOR XOR AAA*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* CMP CMP CMP CMP*/
|
||||
PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG,
|
||||
/* CMP CMP AAS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* XOR XOR AAA*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* CMP CMP CMP CMP*/
|
||||
PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM,
|
||||
/* CMP CMP AAS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(10), PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(10),
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14),
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(10),
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14),
|
||||
|
||||
/* Jxx*/
|
||||
/*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
@@ -205,37 +128,37 @@ static uint32_t opcode_timings[256] =
|
||||
PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
|
||||
/*80*/ INVALID, INVALID, INVALID, INVALID,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* MOV MOV MOV MOV*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG, PAIR_XY | CYCLES_REG | DSTDEP_REG, PAIR_XY | CYCLES_REG | DSTDEP_REG,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG | DSTDEP_REG, CYCLES(3), PAIR_XY | CYCLES(1),
|
||||
/*80*/ INVALID, INVALID, INVALID, INVALID,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES_RM, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* MOV MOV MOV MOV*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, CYCLES(3), PAIR_XY | CYCLES(1),
|
||||
|
||||
/* NOP XCHG XCHG XCHG*/
|
||||
/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* XCHG XCHG XCHG XCHG*/
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* CBW CWD CALL far WAIT*/
|
||||
PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5),
|
||||
/* PUSHF POPF SAHF LAHF*/
|
||||
PAIR_XY | CYCLES(2) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(9) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2),
|
||||
/* NOP XCHG XCHG XCHG*/
|
||||
/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* XCHG XCHG XCHG XCHG*/
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* CBW CWD CALL far WAIT*/
|
||||
PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5),
|
||||
/* PUSHF POPF SAHF LAHF*/
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2),
|
||||
|
||||
/* MOV MOV MOV MOV*/
|
||||
/*a0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX,
|
||||
/* MOVSB MOVSW CMPSB CMPSW*/
|
||||
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5),
|
||||
/* TEST TEST STOSB STOSW*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
|
||||
/* LODSB LODSW SCASB SCASW*/
|
||||
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
|
||||
/* MOV MOV MOV MOV*/
|
||||
/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* MOVSB MOVSW CMPSB CMPSW*/
|
||||
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5),
|
||||
/* TEST TEST STOSB STOSW*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
|
||||
/* LODSB LODSW SCASB SCASW*/
|
||||
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
|
||||
|
||||
/* MOV*/
|
||||
/*b0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_ESP, PAIR_XY | CYCLES_REG | DSTDEP_EBP, PAIR_XY | CYCLES_REG | DSTDEP_ESI, PAIR_XY | CYCLES_REG | DSTDEP_EDI,
|
||||
/*b0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
|
||||
/* RET imm RET*/
|
||||
/*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2),
|
||||
@@ -253,7 +176,7 @@ static uint32_t opcode_timings[256] =
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* LOOPNE LOOPE LOOP JCXZ*/
|
||||
/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX,
|
||||
/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14),
|
||||
/* CALL JMP JMP JMP*/
|
||||
@@ -273,68 +196,67 @@ static uint32_t opcode_timings[256] =
|
||||
|
||||
static uint32_t opcode_timings_mod3[256] =
|
||||
{
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3),
|
||||
/* OR OR OR OR*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* OR OR PUSH CS */
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, INVALID,
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
/* OR OR OR OR*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* OR OR PUSH CS */
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), INVALID,
|
||||
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3),
|
||||
/* SBB SBB SBB SBB*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, PAIR_NP | CYCLES(3),
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
/* SBB SBB SBB SBB*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3),
|
||||
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* AND AND DAA*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(9),
|
||||
/* SUB SUB SUB SUB*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* SUB SUB DAS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(9),
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* AND AND DAA*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* SUB SUB SUB SUB*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* SUB SUB DAS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* XOR XOR AAA*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* CMP CMP CMP CMP*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | SRCDEP_REG,
|
||||
/* CMP CMP AAS*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* XOR XOR AAA*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
/* CMP CMP CMP CMP*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* CMP CMP AAS*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, INVALID, PAIR_NP | CYCLES(7),
|
||||
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EBP | DSTDEP_EBP | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_ESI | DSTDEP_ESI | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES_REG | SRCDEP_EDI | DSTDEP_EDI | SRCDEP_ESP | DSTDEP_ESP,
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(10), PAIR_XY | CYCLES_REG | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(10),
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14),
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(9),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10), PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(10),
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14),
|
||||
|
||||
/* Jxx*/
|
||||
/*70*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
@@ -342,13 +264,13 @@ static uint32_t opcode_timings_mod3[256] =
|
||||
PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
|
||||
/*80*/ PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* MOV MOV MOV MOV*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_REG, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_REG,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG | DSTDEP_REG, PAIR_NP | CYCLES(3), PAIR_XY | CYCLES(1),
|
||||
/*80*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
/* MOV MOV MOV MOV*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
PAIR_XY | CYCLES(1), PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(3), PAIR_XY | CYCLES(1),
|
||||
|
||||
/* NOP XCHG XCHG XCHG*/
|
||||
/*90*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
@@ -357,22 +279,22 @@ static uint32_t opcode_timings_mod3[256] =
|
||||
/* CBW CWD CALL far WAIT*/
|
||||
PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(2), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5),
|
||||
/* PUSHF POPF SAHF LAHF*/
|
||||
PAIR_XY | CYCLES(2) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(9) | SRCDEP_ESP | DSTDEP_ESP, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2),
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(9), PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(2),
|
||||
|
||||
/* MOV MOV MOV MOV*/
|
||||
/*a0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX,
|
||||
/*a0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
/* MOVSB MOVSW CMPSB CMPSW*/
|
||||
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(5), PAIR_NP | CYCLES(5),
|
||||
/* TEST TEST STOSB STOSW*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_XY | CYCLES_REG | SRCDEP_EAX, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
|
||||
/* LODSB LODSW SCASB SCASW*/
|
||||
PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2),
|
||||
|
||||
/* MOV*/
|
||||
/*b0*/ PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_EAX, PAIR_XY | CYCLES_REG | DSTDEP_ECX, PAIR_XY | CYCLES_REG | DSTDEP_EDX, PAIR_XY | CYCLES_REG | DSTDEP_EBX,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_ESP, PAIR_XY | CYCLES_REG | DSTDEP_EBP, PAIR_XY | CYCLES_REG | DSTDEP_ESI, PAIR_XY | CYCLES_REG | DSTDEP_EDI,
|
||||
/*b0*/ PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
|
||||
/* RET imm RET*/
|
||||
/*c0*/ INVALID, INVALID, PAIR_X_BRANCH | CYCLES(3), PAIR_X_BRANCH | CYCLES(2),
|
||||
@@ -391,7 +313,7 @@ static uint32_t opcode_timings_mod3[256] =
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
/* LOOPNE LOOPE LOOP JCXZ*/
|
||||
/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX, PAIR_X_BRANCH | CYCLES_BRANCH | SRCDEP_ECX,
|
||||
/*e0*/ PAIR_X_BRANCH| CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14), PAIR_NP | CYCLES(14),
|
||||
/* CALL JMP JMP JMP*/
|
||||
@@ -441,15 +363,15 @@ static uint32_t opcode_timings_0f[256] =
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
/*60*/ PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
/*60*/ PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
|
||||
/*70*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES(1),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
/*70*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES(1),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
|
||||
/*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
@@ -476,20 +398,20 @@ static uint32_t opcode_timings_0f[256] =
|
||||
PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4),
|
||||
PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4), PAIR_XY | CYCLES(4),
|
||||
|
||||
/*d0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM,
|
||||
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
/*d0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
|
||||
/*e0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, INVALID,
|
||||
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
/*e0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
|
||||
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID, PAIR_X | CYCLES_RM,
|
||||
|
||||
/*f0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM, PAIR_X | MMX_SHIFTPACK | CYCLES_RM,
|
||||
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
|
||||
/*f0*/ INVALID, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM,
|
||||
INVALID, PAIR_X | CYCLES_RM, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
|
||||
PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, PAIR_X | CYCLES_RM, INVALID,
|
||||
};
|
||||
static uint32_t opcode_timings_0f_mod3[256] =
|
||||
{
|
||||
@@ -523,15 +445,15 @@ static uint32_t opcode_timings_0f_mod3[256] =
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
|
||||
/*60*/ PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
/*60*/ PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
|
||||
/*70*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES(1),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
/*70*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES(1),
|
||||
INVALID, INVALID, INVALID, INVALID,
|
||||
INVALID, INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
|
||||
/*80*/ PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH, PAIR_X_BRANCH | CYCLES_BRANCH,
|
||||
@@ -557,20 +479,20 @@ static uint32_t opcode_timings_0f_mod3[256] =
|
||||
PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1),
|
||||
PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1),
|
||||
|
||||
/*d0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG,
|
||||
INVALID, PAIR_X | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
/*d0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
|
||||
/*e0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, INVALID,
|
||||
INVALID, PAIR_X | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
/*e0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
|
||||
INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID, PAIR_X | CYCLES_REG,
|
||||
|
||||
/*f0*/ INVALID, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG, PAIR_X | MMX_SHIFTPACK | CYCLES_REG,
|
||||
INVALID, PAIR_X | MMX_MULTIPLY | CYCLES_REG, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
|
||||
/*f0*/ INVALID, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG,
|
||||
INVALID, PAIR_X | CYCLES_REG, INVALID, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
|
||||
PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, PAIR_X | CYCLES_REG, INVALID,
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_shift[8] =
|
||||
@@ -580,8 +502,8 @@ static uint32_t opcode_timings_shift[8] =
|
||||
};
|
||||
static uint32_t opcode_timings_shift_mod3[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES(3) | DSTDEP_RM, PAIR_XY | CYCLES(4) | DSTDEP_RM,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
};
|
||||
static uint32_t opcode_timings_shift_imm[8] =
|
||||
{
|
||||
@@ -590,18 +512,18 @@ static uint32_t opcode_timings_shift_imm[8] =
|
||||
};
|
||||
static uint32_t opcode_timings_shift_imm_mod3[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES(3) | DSTDEP_RM, PAIR_XY | CYCLES(4) | DSTDEP_RM,
|
||||
PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM, PAIR_XY | CYCLES_REG | DSTDEP_RM,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES(3), PAIR_XY | CYCLES(4),
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
};
|
||||
static uint32_t opcode_timings_shift_cl[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(8) | SRCDEP_ECX, PAIR_XY | CYCLES(9) | SRCDEP_ECX,
|
||||
PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX, PAIR_XY | CYCLES(2) | SRCDEP_ECX,
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
};
|
||||
static uint32_t opcode_timings_shift_cl_mod3[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(8) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(9) | DSTDEP_RM | SRCDEP_ECX,
|
||||
PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX, PAIR_XY | CYCLES(2) | DSTDEP_RM | SRCDEP_ECX,
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(8), PAIR_XY | CYCLES(9),
|
||||
PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2), PAIR_XY | CYCLES(2),
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_f6[8] =
|
||||
@@ -613,22 +535,22 @@ static uint32_t opcode_timings_f6[8] =
|
||||
};
|
||||
static uint32_t opcode_timings_f6_mod3[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(18), PAIR_NP | CYCLES(18)
|
||||
};
|
||||
static uint32_t opcode_timings_f7[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
|
||||
};
|
||||
static uint32_t opcode_timings_f7_mod3[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
PAIR_XY | CYCLES_REG, INVALID, PAIR_XY | CYCLES(1), PAIR_XY | CYCLES(1),
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(4,10), PAIR_NP | CYCLES_MULTI(19,27), PAIR_NP | CYCLES_MULTI(22,30)
|
||||
};
|
||||
@@ -637,14 +559,14 @@ static uint32_t opcode_timings_ff[8] =
|
||||
/* INC DEC CALL CALL far*/
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5),
|
||||
/* JMP JMP far PUSH*/
|
||||
PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1) | SRCDEP_ESP | DSTDEP_ESP, INVALID
|
||||
PAIR_X_BRANCH | CYCLES(3), PAIR_NP | CYCLES(5), PAIR_XY | CYCLES(1), INVALID
|
||||
};
|
||||
static uint32_t opcode_timings_ff_mod3[8] =
|
||||
{
|
||||
/* INC DEC CALL CALL far*/
|
||||
PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_XY | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5),
|
||||
/* JMP JMP far PUSH*/
|
||||
PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2) | SRCDEP_ESP | DSTDEP_ESP, INVALID
|
||||
/* INC DEC CALL CALL far*/
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5),
|
||||
/* JMP JMP far PUSH*/
|
||||
PAIR_X_BRANCH | CYCLES(1), PAIR_XY | CYCLES(5), PAIR_XY | CYCLES(2), INVALID
|
||||
};
|
||||
|
||||
static uint32_t opcode_timings_d8[8] =
|
||||
@@ -812,8 +734,23 @@ static uint32_t opcode_timings_df_mod3[8] =
|
||||
|
||||
static uint32_t opcode_timings_8x[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG,
|
||||
PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RMW | SRCDEP_REG, PAIR_XY | CYCLES_RM | SRCDEP_REG
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
|
||||
};
|
||||
static uint32_t opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
|
||||
};
|
||||
static uint32_t opcode_timings_81[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW,
|
||||
PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RMW, PAIR_XY | CYCLES_RM
|
||||
};
|
||||
static uint32_t opcode_timings_81_mod3[8] =
|
||||
{
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG,
|
||||
PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG, PAIR_XY | CYCLES_REG
|
||||
};
|
||||
|
||||
static int decode_delay;
|
||||
@@ -836,6 +773,7 @@ static inline int COUNT(uint32_t c, int op_32)
|
||||
void codegen_timing_686_block_start()
|
||||
{
|
||||
prev_full = decode_delay = 0;
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_686_start()
|
||||
@@ -853,9 +791,20 @@ void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
last_prefix = prefix;
|
||||
}
|
||||
|
||||
static int check_agi(uint64_t *deps, uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
uint32_t addr_regmask = get_addr_regmask(deps[opcode], fetchdat, op_32);
|
||||
|
||||
if (addr_regmask & IMPL_ESP)
|
||||
addr_regmask |= (1 << REG_ESP);
|
||||
|
||||
return regmask_modified & addr_regmask;
|
||||
}
|
||||
|
||||
void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
uint32_t *timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
@@ -863,80 +812,101 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x;
|
||||
if (!mod3)
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1:
|
||||
timings = mod3 ? opcode_timings_shift_imm_mod3 : opcode_timings_shift_imm;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
|
||||
case 0xd0: case 0xd1:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
|
||||
case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_cl_mod3 : opcode_timings_shift_cl;
|
||||
deps = mod3 ? opcode_deps_shift_cl_mod3 : opcode_deps_shift_cl;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -946,33 +916,43 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
|
||||
if (prev_full)
|
||||
{
|
||||
uint8_t regmask = get_srcdep_mask(timings[opcode], fetchdat, bit8);
|
||||
|
||||
uint32_t regmask = get_srcdep_mask(deps[opcode], fetchdat, bit8, op_32);
|
||||
int agi_stall = 0;
|
||||
|
||||
if (regmask & IMPL_ESP)
|
||||
regmask |= SRCDEP_ESP | DSTDEP_ESP;
|
||||
|
||||
if (check_agi(prev_deps, prev_opcode, prev_fetchdat, prev_op_32))
|
||||
agi_stall = 2;
|
||||
|
||||
/*Second instruction in the pair*/
|
||||
if ((timings[opcode] & PAIR_MASK) == PAIR_NP)
|
||||
{
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1;
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
regmask_modified = prev_regmask;
|
||||
}
|
||||
else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
|
||||
&& (prev_timings[opcode] & PAIR_MASK) == PAIR_X)
|
||||
{
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1;
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
regmask_modified = prev_regmask;
|
||||
}
|
||||
else if (prev_regmask & regmask)
|
||||
{
|
||||
/*Instruction can not pair with previous*/
|
||||
/*Run previous now*/
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1;
|
||||
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1 + agi_stall;
|
||||
prev_full = 0;
|
||||
regmask_modified = prev_regmask;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -982,9 +962,14 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
|
||||
if (!t_pair)
|
||||
fatal("Pairable 0 cycles! %02x %02x\n", opcode, prev_opcode);
|
||||
codegen_block_cycles += t_pair;
|
||||
decode_delay = (-t_pair) + 1;
|
||||
|
||||
if (check_agi(deps, opcode, fetchdat, op_32))
|
||||
agi_stall = 2;
|
||||
|
||||
codegen_block_cycles += t_pair + agi_stall;
|
||||
decode_delay = (-t_pair) + 1 + agi_stall;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8) | prev_regmask;
|
||||
prev_full = 0;
|
||||
return;
|
||||
}
|
||||
@@ -996,8 +981,14 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
if ((timings[opcode] & PAIR_MASK) == PAIR_NP || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
|
||||
{
|
||||
/*Instruction not pairable*/
|
||||
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay;
|
||||
decode_delay = (-COUNT(timings[opcode], op_32)) + 1;
|
||||
int agi_stall = 0;
|
||||
|
||||
if (check_agi(deps, opcode, fetchdat, op_32))
|
||||
agi_stall = 2;
|
||||
|
||||
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay + agi_stall;
|
||||
decode_delay = (-COUNT(timings[opcode], op_32)) + 1 + agi_stall;
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1006,7 +997,11 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
prev_opcode = opcode;
|
||||
prev_timings = timings;
|
||||
prev_op_32 = op_32;
|
||||
prev_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8);
|
||||
prev_regmask = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
if (prev_regmask & IMPL_ESP)
|
||||
prev_regmask |= SRCDEP_ESP | DSTDEP_ESP;
|
||||
prev_deps = deps;
|
||||
prev_fetchdat = fetchdat;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
678
src/CPU/codegen_timing_common.c
Normal file
678
src/CPU/codegen_timing_common.c
Normal file
@@ -0,0 +1,678 @@
|
||||
#include "../ibm.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
uint64_t opcode_deps[256] =
|
||||
{
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* OR OR OR OR*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* OR OR PUSH CS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0,
|
||||
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* SBB SBB SBB SBB*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* AND AND DAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* SUB SUB SUB SUB*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* SUB SUB DAS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* XOR XOR AAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* CMP CMP CMP CMP*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | MODRM,
|
||||
/* CMP CMP AAS*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP,
|
||||
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ IMPL_ESP, IMPL_ESP, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
IMPL_ESP, DSTDEP_REG | MODRM, IMPL_ESP, DSTDEP_REG | MODRM,
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* Jxx*/
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM, SRCDEP_REG | DSTDEP_REG | MODRM,
|
||||
/* MOV MOV MOV MOV*/
|
||||
SRCDEP_REG | MODRM, SRCDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_REG | MODRM,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
MODRM, DSTDEP_REG | MODRM, MODRM, IMPL_ESP | MODRM,
|
||||
|
||||
/* NOP XCHG XCHG XCHG*/
|
||||
/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* XCHG XCHG XCHG XCHG*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* CBW CWD CALL far WAIT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0,
|
||||
/* PUSHF POPF SAHF LAHF*/
|
||||
IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX,
|
||||
|
||||
/* MOV MOV MOV MOV*/
|
||||
/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* MOVSB MOVSW CMPSB CMPSW*/
|
||||
0, 0, 0, 0,
|
||||
/* TEST TEST STOSB STOSW*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, 0,
|
||||
/* LODSB LODSW SCASB SCASW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* MOV*/
|
||||
/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI,
|
||||
|
||||
/* RET imm RET*/
|
||||
/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP,
|
||||
/* LES LDS MOV MOV*/
|
||||
DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, MODRM, MODRM,
|
||||
/* ENTER LEAVE RETF RETF*/
|
||||
IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP,
|
||||
/* INT3 INT INTO IRET*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
|
||||
/*d0*/ 0, 0, 0, 0,
|
||||
/* AAM AAD SETALC XLAT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* LOOPNE LOOPE LOOP JCXZ*/
|
||||
/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* CALL JMP JMP JMP*/
|
||||
IMPL_ESP, 0, 0, 0,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX,
|
||||
|
||||
/* REPNE REPE*/
|
||||
/*f0*/ 0, 0, 0, 0,
|
||||
/* HLT CMC*/
|
||||
0, 0, 0, 0,
|
||||
/* CLC STC CLI STI*/
|
||||
0, 0, 0, 0,
|
||||
/* CLD STD INCDEC*/
|
||||
0, 0, MODRM, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_mod3[256] =
|
||||
{
|
||||
/* ADD ADD ADD ADD*/
|
||||
/*00*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* ADD ADD PUSH ES POP ES*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* OR OR OR OR*/
|
||||
SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* OR OR PUSH CS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, 0,
|
||||
|
||||
/* ADC ADC ADC ADC*/
|
||||
/*10*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* ADC ADC PUSH SS POP SS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
/* SBB SBB SBB SBB*/
|
||||
SRCDEP_REG |SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* SBB SBB PUSH DS POP DS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, IMPL_ESP, IMPL_ESP,
|
||||
|
||||
/* AND AND AND AND*/
|
||||
/*20*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* AND AND DAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* SUB SUB SUB SUB*/
|
||||
SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* SUB SUB DAS*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* XOR XOR XOR XOR*/
|
||||
/*30*/ SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* XOR XOR AAA*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX | MODRM, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
/* CMP CMP CMP CMP*/
|
||||
SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* CMP CMP AAS*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, SRCDEP_EAX | DSTDEP_EAX,
|
||||
|
||||
/* INC EAX INC ECX INC EDX INC EBX*/
|
||||
/*40*/ SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* INC ESP INC EBP INC ESI INC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* DEC EAX DEC ECX DEC EDX DEC EBX*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* DEC ESP DEC EBP DEC ESI DEC EDI*/
|
||||
SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EBP | DSTDEP_EBP, SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EDI | DSTDEP_EDI,
|
||||
|
||||
/* PUSH EAX PUSH ECX PUSH EDX PUSH EBX*/
|
||||
/*50*/ SRCDEP_EAX | IMPL_ESP, SRCDEP_ECX | IMPL_ESP, SRCDEP_EDX | IMPL_ESP, SRCDEP_EBX | IMPL_ESP,
|
||||
/* PUSH ESP PUSH EBP PUSH ESI PUSH EDI*/
|
||||
SRCDEP_ESP | IMPL_ESP, SRCDEP_EBP | IMPL_ESP, SRCDEP_ESI | IMPL_ESP, SRCDEP_EDI | IMPL_ESP,
|
||||
/* POP EAX POP ECX POP EDX POP EBX*/
|
||||
DSTDEP_EAX | IMPL_ESP, DSTDEP_ECX | IMPL_ESP, DSTDEP_EDX | IMPL_ESP, DSTDEP_EBX | IMPL_ESP,
|
||||
/* POP ESP POP EBP POP ESI POP EDI*/
|
||||
DSTDEP_ESP | IMPL_ESP, DSTDEP_EBP | IMPL_ESP, DSTDEP_ESI | IMPL_ESP, DSTDEP_EDI | IMPL_ESP,
|
||||
|
||||
/* PUSHA POPA BOUND ARPL*/
|
||||
/*60*/ IMPL_ESP, IMPL_ESP, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
/* PUSH imm IMUL PUSH imm IMUL*/
|
||||
IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM, IMPL_ESP, DSTDEP_REG | SRCDEP_RM | MODRM,
|
||||
/* INSB INSW OUTSB OUTSW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* Jxx*/
|
||||
/*70*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
/* TEST TEST XCHG XCHG*/
|
||||
SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | SRCDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_REG | SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MOV MOV MOV MOV*/
|
||||
SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_REG | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM, SRCDEP_RM | DSTDEP_REG | MODRM,
|
||||
/* MOV from seg LEA MOV to seg POP*/
|
||||
DSTDEP_RM | MODRM, DSTDEP_REG | MODRM, SRCDEP_RM | MODRM, IMPL_ESP | DSTDEP_RM | MODRM,
|
||||
|
||||
/* NOP XCHG XCHG XCHG*/
|
||||
/*90*/ 0, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ECX | DSTDEP_ECX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDX | DSTDEP_EDX, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBX | DSTDEP_EBX,
|
||||
/* XCHG XCHG XCHG XCHG*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESP | DSTDEP_ESP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EBP | DSTDEP_EBP, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_ESI | DSTDEP_ESI, SRCDEP_EAX | DSTDEP_EAX | SRCDEP_EDI | DSTDEP_EDI,
|
||||
/* CBW CWD CALL far WAIT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EDX, 0, 0,
|
||||
/* PUSHF POPF SAHF LAHF*/
|
||||
IMPL_ESP, IMPL_ESP, SRCDEP_EAX, DSTDEP_EAX,
|
||||
|
||||
/* MOV MOV MOV MOV*/
|
||||
/*a0*/ DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* MOVSB MOVSW CMPSB CMPSW*/
|
||||
0, 0, 0, 0,
|
||||
/* TEST TEST STOSB STOSW*/
|
||||
SRCDEP_EAX, SRCDEP_EAX, 0, 0,
|
||||
/* LODSB LODSW SCASB SCASW*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* MOV*/
|
||||
/*b0*/ DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_EAX, DSTDEP_ECX, DSTDEP_EDX, DSTDEP_EBX,
|
||||
DSTDEP_ESP, DSTDEP_EBP, DSTDEP_ESI, DSTDEP_EDI,
|
||||
|
||||
/* RET imm RET*/
|
||||
/*c0*/ 0, 0, SRCDEP_ESP | DSTDEP_ESP, IMPL_ESP,
|
||||
/* LES LDS MOV MOV*/
|
||||
DSTDEP_REG | MODRM, DSTDEP_REG | MODRM, DSTDEP_RM | MODRM, DSTDEP_RM | MODRM,
|
||||
/* ENTER LEAVE RETF RETF*/
|
||||
IMPL_ESP, IMPL_ESP, IMPL_ESP, IMPL_ESP,
|
||||
/* INT3 INT INTO IRET*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
|
||||
/*d0*/ 0, 0, 0, 0,
|
||||
/* AAM AAD SETALC XLAT*/
|
||||
SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX | DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX | SRCDEP_EBX,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/* LOOPNE LOOPE LOOP JCXZ*/
|
||||
/*e0*/ SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX | DSTDEP_ECX, SRCDEP_ECX,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
DSTDEP_EAX, DSTDEP_EAX, SRCDEP_EAX, SRCDEP_EAX,
|
||||
/* CALL JMP JMP JMP*/
|
||||
IMPL_ESP, 0, 0, 0,
|
||||
/* IN AL IN AX OUT_AL OUT_AX*/
|
||||
SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | DSTDEP_EAX, SRCDEP_EDX | SRCDEP_EAX, SRCDEP_EDX | SRCDEP_EAX,
|
||||
|
||||
/* REPNE REPE*/
|
||||
/*f0*/ 0, 0, 0, 0,
|
||||
/* HLT CMC*/
|
||||
0, 0, 0, 0,
|
||||
/* CLC STC CLI STI*/
|
||||
0, 0, 0, 0,
|
||||
/* CLD STD INCDEC*/
|
||||
0, 0, SRCDEP_RM | DSTDEP_RM | MODRM, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_0f[256] =
|
||||
{
|
||||
/*00*/ MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*10*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*20*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*30*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*50*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*90*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*a0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*b0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*c0*/ MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
};
|
||||
uint64_t opcode_deps_0f_mod3[256] =
|
||||
{
|
||||
/*00*/ MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*10*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*20*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*30*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*40*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*50*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*60*/ MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*70*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, MODRM, MODRM,
|
||||
|
||||
/*80*/ 0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*90*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*a0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*b0*/ MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
0, 0, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
|
||||
/*c0*/ MODRM, MODRM, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
|
||||
/*d0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*e0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, 0,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
MODRM, MODRM, 0, MODRM,
|
||||
|
||||
/*f0*/ 0, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK, MODRM | MMX_SHIFTPACK,
|
||||
0, MODRM | MMX_MULTIPLY, 0, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
MODRM, MODRM, MODRM, 0,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_shift[8] =
|
||||
{
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
};
|
||||
uint64_t opcode_deps_shift_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_shift_cl[8] =
|
||||
{
|
||||
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
|
||||
MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX, MODRM | SRCDEP_ECX,
|
||||
};
|
||||
uint64_t opcode_deps_shift_cl_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX, SRCDEP_RM | DSTDEP_RM | MODRM | SRCDEP_ECX,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_f6[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_f6_mod3[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_f7[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
MODRM, 0, MODRM, MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_f7_mod3[8] =
|
||||
{
|
||||
/* TST NOT NEG*/
|
||||
SRCDEP_RM | MODRM, 0, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
/* MUL IMUL DIV IDIV*/
|
||||
SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | SRCDEP_RM | MODRM, SRCDEP_EAX | SRCDEP_EDX | DSTDEP_EAX | DSTDEP_EDX | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_ff[8] =
|
||||
{
|
||||
/* INC DEC CALL CALL far*/
|
||||
MODRM, MODRM, MODRM | IMPL_ESP, MODRM,
|
||||
/* JMP JMP far PUSH*/
|
||||
MODRM, MODRM, MODRM | IMPL_ESP, 0
|
||||
};
|
||||
uint64_t opcode_deps_ff_mod3[8] =
|
||||
{
|
||||
/* INC DEC CALL CALL far*/
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM | IMPL_ESP, MODRM,
|
||||
/* JMP JMP far PUSH*/
|
||||
SRCDEP_RM | MODRM, MODRM, SRCDEP_RM | MODRM | IMPL_ESP, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_d8[8] =
|
||||
{
|
||||
/* FADDs FMULs FCOMs FCOMPs*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_POP | FPU_READ_ST0 | MODRM,
|
||||
/* FSUBs FSUBRs FDIVs FDIVRs*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_d8_mod3[8] =
|
||||
{
|
||||
/* FADD FMUL FCOM FCOMP*/
|
||||
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG, FPU_POP | FPU_READ_ST0 | FPU_READ_STREG,
|
||||
/* FSUB FSUBR FDIV FDIVR*/
|
||||
FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG, FPU_RW_ST0 | FPU_READ_STREG
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_d9[8] =
|
||||
{
|
||||
/* FLDs FSTs FSTPs*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_POP | MODRM,
|
||||
/* FLDENV FLDCW FSTENV FSTCW*/
|
||||
MODRM, MODRM, MODRM, MODRM
|
||||
};
|
||||
uint64_t opcode_deps_d9_mod3[64] =
|
||||
{
|
||||
/*FLD*/
|
||||
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
|
||||
FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG, FPU_PUSH | FPU_READ_STREG,
|
||||
/*FXCH*/
|
||||
FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH,
|
||||
FPU_FXCH, FPU_FXCH, FPU_FXCH, FPU_FXCH,
|
||||
/*FNOP*/
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/*FSTP*/
|
||||
FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
|
||||
FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
|
||||
/* opFCHS opFABS*/
|
||||
0, 0, 0, 0,
|
||||
/* opFTST opFXAM*/
|
||||
0, 0, 0, 0,
|
||||
/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/
|
||||
FPU_PUSH, FPU_PUSH, FPU_PUSH, FPU_PUSH,
|
||||
/* opFLDEG2 opFLDLN2 opFLDZ*/
|
||||
FPU_PUSH, FPU_PUSH, FPU_PUSH, 0,
|
||||
/* opF2XM1 opFYL2X opFPTAN opFPATAN*/
|
||||
0, 0, 0, 0,
|
||||
/* opFDECSTP opFINCSTP,*/
|
||||
0, 0, 0, 0,
|
||||
/* opFPREM opFSQRT opFSINCOS*/
|
||||
0, 0, 0, 0,
|
||||
/* opFRNDINT opFSCALE opFSIN opFCOS*/
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_da[8] =
|
||||
{
|
||||
/* FIADDl FIMULl FICOMl FICOMPl*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FISUBl FISUBRl FIDIVl FIDIVRl*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_da_mod3[8] =
|
||||
{
|
||||
0, 0, 0, 0,
|
||||
/* FCOMPP*/
|
||||
0, FPU_POP2, 0, 0
|
||||
};
|
||||
|
||||
|
||||
uint64_t opcode_deps_db[8] =
|
||||
{
|
||||
/* FLDil FSTil FSTPil*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FLDe FSTPe*/
|
||||
0, FPU_PUSH | MODRM, 0, FPU_READ_ST0 | FPU_POP | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_db_mod3[64] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
/* opFNOP opFCLEX opFINIT*/
|
||||
0, 0, 0, 0,
|
||||
/* opFNOP opFNOP*/
|
||||
0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_dc[8] =
|
||||
{
|
||||
/* FADDd FMULd FCOMd FCOMPd*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FSUBd FSUBRd FDIVd FDIVRd*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_dc_mod3[8] =
|
||||
{
|
||||
/* opFADDr opFMULr*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, 0, 0,
|
||||
/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG, FPU_READ_ST0 | FPU_RW_STREG
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_dd[8] =
|
||||
{
|
||||
/* FLDd FSTd FSTPd*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FRSTOR FSAVE FSTSW*/
|
||||
MODRM, 0, MODRM, MODRM
|
||||
};
|
||||
uint64_t opcode_deps_dd_mod3[8] =
|
||||
{
|
||||
/* FFFREE FST FSTP*/
|
||||
0, 0, FPU_READ_ST0 | FPU_WRITE_STREG, FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP,
|
||||
/* FUCOM FUCOMP*/
|
||||
FPU_READ_ST0 | FPU_READ_STREG, FPU_READ_ST0 | FPU_READ_STREG | FPU_POP, 0, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_de[8] =
|
||||
{
|
||||
/* FIADDw FIMULw FICOMw FICOMPw*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FISUBw FISUBRw FIDIVw FIDIVRw*/
|
||||
FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM, FPU_RW_ST0 | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_de_mod3[8] =
|
||||
{
|
||||
/* FADDP FMULP FCOMPP*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, 0, FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2,
|
||||
/* FSUBP FSUBRP FDIVP FDIVRP*/
|
||||
FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP, FPU_READ_ST0 | FPU_RW_STREG | FPU_POP
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_df[8] =
|
||||
{
|
||||
/* FILDiw FISTiw FISTPiw*/
|
||||
FPU_PUSH | MODRM, 0, FPU_READ_ST0 | MODRM, FPU_READ_ST0 | FPU_POP | MODRM,
|
||||
/* FILDiq FBSTP FISTPiq*/
|
||||
0, FPU_PUSH | MODRM, FPU_READ_ST0 | FPU_POP | MODRM, FPU_READ_ST0 | FPU_POP | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_df_mod3[8] =
|
||||
{
|
||||
0, 0, 0, 0,
|
||||
/* FSTSW AX*/
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
uint64_t opcode_deps_81[8] =
|
||||
{
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM
|
||||
};
|
||||
uint64_t opcode_deps_81_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM
|
||||
};
|
||||
uint64_t opcode_deps_8x[8] =
|
||||
{
|
||||
MODRM, MODRM, MODRM, MODRM,
|
||||
MODRM, MODRM, MODRM, MODRM
|
||||
};
|
||||
uint64_t opcode_deps_8x_mod3[8] =
|
||||
{
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM,
|
||||
SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | DSTDEP_RM | MODRM, SRCDEP_RM | MODRM
|
||||
};
|
||||
226
src/CPU/codegen_timing_common.h
Normal file
226
src/CPU/codegen_timing_common.h
Normal file
@@ -0,0 +1,226 @@
|
||||
#include "codegen_ops.h"
|
||||
|
||||
/*Instruction has input dependency on register in REG field*/
|
||||
#define SRCDEP_REG (1ull << 0)
|
||||
/*Instruction has input dependency on register in R/M field*/
|
||||
#define SRCDEP_RM (1ull << 1)
|
||||
/*Instruction modifies register in REG field*/
|
||||
#define DSTDEP_REG (1ull << 2)
|
||||
/*Instruction modifies register in R/M field*/
|
||||
#define DSTDEP_RM (1ull << 3)
|
||||
|
||||
#define SRCDEP_SHIFT 4
|
||||
#define DSTDEP_SHIFT 12
|
||||
|
||||
/*Instruction has input dependency on given register*/
|
||||
#define SRCDEP_EAX (1ull << 4)
|
||||
#define SRCDEP_ECX (1ull << 5)
|
||||
#define SRCDEP_EDX (1ull << 6)
|
||||
#define SRCDEP_EBX (1ull << 7)
|
||||
#define SRCDEP_ESP (1ull << 8)
|
||||
#define SRCDEP_EBP (1ull << 9)
|
||||
#define SRCDEP_ESI (1ull << 10)
|
||||
#define SRCDEP_EDI (1ull << 11)
|
||||
|
||||
/*Instruction modifies given register*/
|
||||
#define DSTDEP_EAX (1ull << 12)
|
||||
#define DSTDEP_ECX (1ull << 13)
|
||||
#define DSTDEP_EDX (1ull << 14)
|
||||
#define DSTDEP_EBX (1ull << 15)
|
||||
#define DSTDEP_ESP (1ull << 16)
|
||||
#define DSTDEP_EBP (1ull << 17)
|
||||
#define DSTDEP_ESI (1ull << 18)
|
||||
#define DSTDEP_EDI (1ull << 19)
|
||||
|
||||
/*Instruction has ModR/M byte*/
|
||||
#define MODRM (1ull << 20)
|
||||
/*Instruction implicitly uses ESP*/
|
||||
#define IMPL_ESP (1ull << 21)
|
||||
|
||||
/*Instruction is MMX shift or pack/unpack instruction*/
|
||||
#define MMX_SHIFTPACK (1ull << 22)
|
||||
/*Instruction is MMX multiply instruction*/
|
||||
#define MMX_MULTIPLY (1ull << 23)
|
||||
|
||||
/*Instruction pops the FPU stack*/
|
||||
#define FPU_POP (1ull << 24)
|
||||
/*Instruction pops the FPU stack twice*/
|
||||
#define FPU_POP2 (1ull << 25)
|
||||
/*Instruction pushes onto the FPU stack*/
|
||||
#define FPU_PUSH (1ull << 26)
|
||||
|
||||
/*Instruction writes to ST(0)*/
|
||||
#define FPU_WRITE_ST0 (1ull << 27)
|
||||
/*Instruction reads from ST(0)*/
|
||||
#define FPU_READ_ST0 (1ull << 28)
|
||||
/*Instruction reads from and writes to ST(0)*/
|
||||
#define FPU_RW_ST0 (3ull << 27)
|
||||
|
||||
/*Instruction reads from ST(1)*/
|
||||
#define FPU_READ_ST1 (1ull << 29)
|
||||
/*Instruction writes to ST(1)*/
|
||||
#define FPU_WRITE_ST1 (1ull << 30)
|
||||
/*Instruction reads from and writes to ST(1)*/
|
||||
#define FPU_RW_ST1 (3ull << 29)
|
||||
|
||||
/*Instruction reads from ST(reg)*/
|
||||
#define FPU_READ_STREG (1ull << 31)
|
||||
/*Instruction writes to ST(reg)*/
|
||||
#define FPU_WRITE_STREG (1ull << 32)
|
||||
/*Instruction reads from and writes to ST(reg)*/
|
||||
#define FPU_RW_STREG (3ull << 30)
|
||||
|
||||
#define FPU_FXCH (1ull << 33)
|
||||
|
||||
|
||||
#define REGMASK_IMPL_ESP (1 << 8)
|
||||
#define REGMASK_SHIFTPACK (1 << 9)
|
||||
#define REGMASK_MULTIPLY (1 << 9)
|
||||
|
||||
|
||||
extern uint64_t opcode_deps[256];
|
||||
extern uint64_t opcode_deps_mod3[256];
|
||||
extern uint64_t opcode_deps_0f[256];
|
||||
extern uint64_t opcode_deps_0f_mod3[256];
|
||||
extern uint64_t opcode_deps_shift[8];
|
||||
extern uint64_t opcode_deps_shift_mod3[8];
|
||||
extern uint64_t opcode_deps_shift_cl[8];
|
||||
extern uint64_t opcode_deps_shift_cl_mod3[8];
|
||||
extern uint64_t opcode_deps_f6[8];
|
||||
extern uint64_t opcode_deps_f6_mod3[8];
|
||||
extern uint64_t opcode_deps_f7[8];
|
||||
extern uint64_t opcode_deps_f7_mod3[8];
|
||||
extern uint64_t opcode_deps_ff[8];
|
||||
extern uint64_t opcode_deps_ff_mod3[8];
|
||||
extern uint64_t opcode_deps_d8[8];
|
||||
extern uint64_t opcode_deps_d8_mod3[8];
|
||||
extern uint64_t opcode_deps_d9[8];
|
||||
extern uint64_t opcode_deps_d9_mod3[64];
|
||||
extern uint64_t opcode_deps_da[8];
|
||||
extern uint64_t opcode_deps_da_mod3[8];
|
||||
extern uint64_t opcode_deps_db[8];
|
||||
extern uint64_t opcode_deps_db_mod3[64];
|
||||
extern uint64_t opcode_deps_dc[8];
|
||||
extern uint64_t opcode_deps_dc_mod3[8];
|
||||
extern uint64_t opcode_deps_dd[8];
|
||||
extern uint64_t opcode_deps_dd_mod3[8];
|
||||
extern uint64_t opcode_deps_de[8];
|
||||
extern uint64_t opcode_deps_de_mod3[8];
|
||||
extern uint64_t opcode_deps_df[8];
|
||||
extern uint64_t opcode_deps_df_mod3[8];
|
||||
extern uint64_t opcode_deps_81[8];
|
||||
extern uint64_t opcode_deps_81_mod3[8];
|
||||
extern uint64_t opcode_deps_8x[8];
|
||||
extern uint64_t opcode_deps_8x_mod3[8];
|
||||
|
||||
|
||||
|
||||
static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
uint32_t addr_regmask = 0;
|
||||
|
||||
if (data & MODRM)
|
||||
{
|
||||
uint8_t modrm = fetchdat & 0xff;
|
||||
|
||||
if ((modrm & 0xc0) != 0xc0)
|
||||
{
|
||||
if (op_32 & 0x200)
|
||||
{
|
||||
if ((modrm & 0x7) == 4)
|
||||
{
|
||||
uint8_t sib = (fetchdat >> 8) & 0xff;
|
||||
|
||||
if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5)
|
||||
{
|
||||
addr_regmask = 1 << (sib & 7);
|
||||
if ((sib & 0x38) != 0x20)
|
||||
addr_regmask |= 1 << ((sib >> 3) & 7);
|
||||
}
|
||||
}
|
||||
else if ((modrm & 0xc7) != 5)
|
||||
{
|
||||
addr_regmask = 1 << (modrm & 7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) != 0x06)
|
||||
{
|
||||
switch (modrm & 7)
|
||||
{
|
||||
case 0: addr_regmask = REG_BX | REG_SI; break;
|
||||
case 1: addr_regmask = REG_BX | REG_DI; break;
|
||||
case 2: addr_regmask = REG_BP | REG_SI; break;
|
||||
case 3: addr_regmask = REG_BP | REG_DI; break;
|
||||
case 4: addr_regmask = REG_SI; break;
|
||||
case 5: addr_regmask = REG_DI; break;
|
||||
case 6: addr_regmask = REG_BP; break;
|
||||
case 7: addr_regmask = REG_BX; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data & IMPL_ESP)
|
||||
addr_regmask |= REGMASK_IMPL_ESP;
|
||||
|
||||
return addr_regmask;
|
||||
}
|
||||
|
||||
static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & SRCDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & SRCDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> SRCDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
|
||||
mask |= get_addr_regmask(data, fetchdat, op_32);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
if (data & DSTDEP_REG)
|
||||
{
|
||||
int reg = (fetchdat >> 3) & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
if (data & DSTDEP_RM)
|
||||
{
|
||||
int reg = fetchdat & 7;
|
||||
if (bit8)
|
||||
reg &= 3;
|
||||
mask |= (1 << reg);
|
||||
}
|
||||
mask |= ((data >> DSTDEP_SHIFT) & 0xff);
|
||||
if (data & MMX_SHIFTPACK)
|
||||
mask |= REGMASK_SHIFTPACK;
|
||||
if (data & MMX_MULTIPLY)
|
||||
mask |= REGMASK_MULTIPLY;
|
||||
if (data & IMPL_ESP)
|
||||
mask |= REGMASK_IMPL_ESP | (1 << REG_ESP);
|
||||
|
||||
return mask;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,12 @@
|
||||
#include "../ibm.h"
|
||||
#include "../mem.h"
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include "../mem.h"
|
||||
#include "codegen.h"
|
||||
#include "codegen_ops.h"
|
||||
#include "codegen_timing_common.h"
|
||||
|
||||
#define CYCLES(c) (int *)c
|
||||
#define CYCLES2(c16, c32) (int *)((-1 & ~0xffff) | c16 | (c32 << 8))
|
||||
@@ -72,7 +74,7 @@ static int *opcode_timings_0f[256] =
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*e0*/ NULL, &timing_rm, &timing_rm, NULL, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm,
|
||||
/*f0*/ NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, NULL, NULL, &timing_rm, &timing_rm, &timing_rm, NULL, &timing_rm, &timing_rm, &timing_rm, NULL,
|
||||
@@ -94,7 +96,7 @@ static int *opcode_timings_0f_mod3[256] =
|
||||
/*a0*/ CYCLES(3), CYCLES(3), CYCLES(14), CYCLES(8), CYCLES(3), CYCLES(4), NULL, NULL, CYCLES(3), CYCLES(3), NULL, CYCLES(13), CYCLES(3), CYCLES(3), NULL, CYCLES2(18,30),
|
||||
/*b0*/ CYCLES(10), CYCLES(10), CYCLES(6), CYCLES(13), CYCLES(6), CYCLES(6), CYCLES(3), CYCLES(3), NULL, NULL, CYCLES(6), CYCLES(13), CYCLES(7), CYCLES(7), CYCLES(3), CYCLES(3),
|
||||
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, NULL, CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*c0*/ CYCLES(4), CYCLES(4), NULL, NULL, NULL, NULL, NULL, CYCLES(3), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1), CYCLES(1),
|
||||
/*d0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*e0*/ NULL, &timing_rr, &timing_rr, NULL, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr,
|
||||
/*f0*/ NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, NULL, NULL, &timing_rr, &timing_rr, &timing_rr, NULL, &timing_rr, &timing_rr, &timing_rr, NULL,
|
||||
@@ -247,14 +249,27 @@ static int *opcode_timings_8x[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_8x_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
static int *opcode_timings_81_mod3[8] =
|
||||
{
|
||||
&timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_mr, &timing_rm
|
||||
};
|
||||
|
||||
static int timing_count;
|
||||
static uint8_t last_prefix;
|
||||
static uint32_t regmask_modified;
|
||||
|
||||
static __inline int COUNT(int *c, int op_32)
|
||||
static inline int COUNT(int *c, int op_32)
|
||||
{
|
||||
if ((uintptr_t)c <= 10000)
|
||||
return (int)c;
|
||||
return (int)(uintptr_t)c;
|
||||
if (((uintptr_t)c & ~0xffff) == (-1 & ~0xffff))
|
||||
{
|
||||
if (op_32 & 0x100)
|
||||
@@ -266,6 +281,7 @@ static __inline int COUNT(int *c, int op_32)
|
||||
|
||||
void codegen_timing_winchip_block_start()
|
||||
{
|
||||
regmask_modified = 0;
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_start()
|
||||
@@ -283,82 +299,107 @@ void codegen_timing_winchip_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
void codegen_timing_winchip_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
{
|
||||
int **timings;
|
||||
uint64_t *deps;
|
||||
int mod3 = ((fetchdat & 0xc0) == 0xc0);
|
||||
int bit8 = !(opcode & 1);
|
||||
|
||||
switch (last_prefix)
|
||||
{
|
||||
case 0x0f:
|
||||
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
|
||||
deps = mod3 ? opcode_deps_0f_mod3 : opcode_deps_0f;
|
||||
break;
|
||||
|
||||
case 0xd8:
|
||||
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
|
||||
deps = mod3 ? opcode_deps_d8_mod3 : opcode_deps_d8;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xd9:
|
||||
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
|
||||
deps = mod3 ? opcode_deps_d9_mod3 : opcode_deps_d9;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xda:
|
||||
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
|
||||
deps = mod3 ? opcode_deps_da_mod3 : opcode_deps_da;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdb:
|
||||
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
|
||||
deps = mod3 ? opcode_deps_db_mod3 : opcode_deps_db;
|
||||
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdc:
|
||||
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
|
||||
deps = mod3 ? opcode_deps_dc_mod3 : opcode_deps_dc;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdd:
|
||||
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
|
||||
deps = mod3 ? opcode_deps_dd_mod3 : opcode_deps_dd;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xde:
|
||||
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
|
||||
deps = mod3 ? opcode_deps_de_mod3 : opcode_deps_de;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
case 0xdf:
|
||||
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
|
||||
deps = mod3 ? opcode_deps_df_mod3 : opcode_deps_df;
|
||||
opcode = (opcode >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
switch (opcode)
|
||||
{
|
||||
case 0x80: case 0x81: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x;
|
||||
if (!mod3)
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
case 0x80: case 0x82: case 0x83:
|
||||
timings = mod3 ? opcode_timings_8x_mod3 : opcode_timings_8x;
|
||||
deps = mod3 ? opcode_deps_8x_mod3 : opcode_deps_8x_mod3;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0x81:
|
||||
timings = mod3 ? opcode_timings_81_mod3 : opcode_timings_81;
|
||||
deps = mod3 ? opcode_deps_81_mod3 : opcode_deps_81;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||
timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift;
|
||||
deps = mod3 ? opcode_deps_shift_mod3 : opcode_deps_shift;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
case 0xf6:
|
||||
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
|
||||
deps = mod3 ? opcode_deps_f6_mod3 : opcode_deps_f6;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xf7:
|
||||
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
|
||||
deps = mod3 ? opcode_deps_f7_mod3 : opcode_deps_f7;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
case 0xff:
|
||||
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
|
||||
deps = mod3 ? opcode_deps_ff_mod3 : opcode_deps_ff;
|
||||
opcode = (fetchdat >> 3) & 7;
|
||||
break;
|
||||
|
||||
default:
|
||||
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
|
||||
deps = mod3 ? opcode_deps_mod3 : opcode_deps;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
timing_count += COUNT(timings[opcode], op_32);
|
||||
if (regmask_modified & get_addr_regmask(deps[opcode], fetchdat, op_32))
|
||||
timing_count++; /*AGI stall*/
|
||||
codegen_block_cycles += timing_count;
|
||||
|
||||
regmask_modified = get_dstdep_mask(deps[opcode], fetchdat, bit8);
|
||||
}
|
||||
|
||||
void codegen_timing_winchip_block_end()
|
||||
|
||||
@@ -1049,6 +1049,15 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
case 0xf0: /*LOCK*/
|
||||
break;
|
||||
|
||||
case 0xf2: /*REPNE*/
|
||||
op_table = x86_dynarec_opcodes_REPNE;
|
||||
recomp_op_table = recomp_opcodes_REPNE;
|
||||
break;
|
||||
case 0xf3: /*REPE*/
|
||||
op_table = x86_dynarec_opcodes_REPE;
|
||||
recomp_op_table = recomp_opcodes_REPE;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto generate_call;
|
||||
}
|
||||
@@ -1089,6 +1098,13 @@ generate_call:
|
||||
codegen_block_ins = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32])
|
||||
{
|
||||
op_table = x86_dynarec_opcodes;
|
||||
recomp_op_table = recomp_opcodes;
|
||||
}
|
||||
|
||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff])
|
||||
{
|
||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
@@ -1977,6 +1977,15 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
|
||||
case 0xf0: /*LOCK*/
|
||||
break;
|
||||
|
||||
case 0xf2: /*REPNE*/
|
||||
op_table = x86_dynarec_opcodes_REPNE;
|
||||
recomp_op_table = recomp_opcodes_REPNE;
|
||||
break;
|
||||
case 0xf3: /*REPE*/
|
||||
op_table = x86_dynarec_opcodes_REPE;
|
||||
recomp_op_table = recomp_opcodes_REPE;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto generate_call;
|
||||
@@ -2030,6 +2039,12 @@ generate_call:
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32])
|
||||
{
|
||||
op_table = x86_dynarec_opcodes;
|
||||
recomp_op_table = recomp_opcodes;
|
||||
}
|
||||
|
||||
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff])
|
||||
{
|
||||
uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block);
|
||||
|
||||
@@ -48,6 +48,8 @@ OpFn *x86_dynarec_opcodes_de_a16;
|
||||
OpFn *x86_dynarec_opcodes_de_a32;
|
||||
OpFn *x86_dynarec_opcodes_df_a16;
|
||||
OpFn *x86_dynarec_opcodes_df_a32;
|
||||
OpFn *x86_dynarec_opcodes_REPE;
|
||||
OpFn *x86_dynarec_opcodes_REPNE;
|
||||
|
||||
OpFn *x86_opcodes;
|
||||
OpFn *x86_opcodes_0f;
|
||||
@@ -67,6 +69,8 @@ OpFn *x86_opcodes_de_a16;
|
||||
OpFn *x86_opcodes_de_a32;
|
||||
OpFn *x86_opcodes_df_a16;
|
||||
OpFn *x86_opcodes_df_a32;
|
||||
OpFn *x86_opcodes_REPE;
|
||||
OpFn *x86_opcodes_REPNE;
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -158,13 +162,7 @@ int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
|
||||
int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
|
||||
int timing_misaligned;
|
||||
|
||||
static struct
|
||||
{
|
||||
uint32_t tr1, tr12;
|
||||
uint32_t cesr;
|
||||
uint32_t fcr;
|
||||
uint64_t fcr2, fcr3;
|
||||
} msr;
|
||||
msr_t msr;
|
||||
|
||||
/*Available cpuspeeds :
|
||||
0 = 16 MHz
|
||||
@@ -490,8 +488,8 @@ CPU cpus_PentiumS5[] =
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7},
|
||||
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
@@ -510,8 +508,8 @@ CPU cpus_Pentium[] =
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x525, 0x525, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4},
|
||||
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6},
|
||||
{"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7},
|
||||
@@ -679,6 +677,10 @@ void cpu_set()
|
||||
pclog("is486 - %i %i\n",is486,cpu_s->cpu_type);
|
||||
|
||||
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
|
||||
x86_opcodes_REPE = ops_REPE;
|
||||
x86_opcodes_REPNE = ops_REPNE;
|
||||
x86_dynarec_opcodes_REPE = dynarec_ops_REPE;
|
||||
x86_dynarec_opcodes_REPNE = dynarec_ops_REPNE;
|
||||
|
||||
if (hasfpu)
|
||||
{
|
||||
@@ -1663,6 +1665,8 @@ void cpu_CPUID()
|
||||
EAX = 0x540;
|
||||
EBX = ECX = 0;
|
||||
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
|
||||
if (msr.fcr & (1 << 1))
|
||||
EDX |= CPUID_CMPXCHG8B;
|
||||
if (msr.fcr & (1 << 9))
|
||||
EDX |= CPUID_MMX;
|
||||
}
|
||||
|
||||
@@ -187,4 +187,14 @@ extern int isa_cycles;
|
||||
void cpu_update_waitstates();
|
||||
void cpu_set();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t tr1, tr12;
|
||||
uint32_t cesr;
|
||||
uint32_t fcr;
|
||||
uint64_t fcr2, fcr3;
|
||||
} msr_t;
|
||||
|
||||
extern msr_t msr;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,6 +26,8 @@ extern OpFn *x86_dynarec_opcodes_de_a16;
|
||||
extern OpFn *x86_dynarec_opcodes_de_a32;
|
||||
extern OpFn *x86_dynarec_opcodes_df_a16;
|
||||
extern OpFn *x86_dynarec_opcodes_df_a32;
|
||||
extern OpFn *x86_dynarec_opcodes_REPE;
|
||||
extern OpFn *x86_dynarec_opcodes_REPNE;
|
||||
|
||||
extern OpFn dynarec_ops_286[1024];
|
||||
extern OpFn dynarec_ops_286_0f[1024];
|
||||
@@ -87,6 +89,9 @@ extern OpFn dynarec_ops_fpu_686_db_a32[256];
|
||||
extern OpFn dynarec_ops_fpu_686_df_a16[256];
|
||||
extern OpFn dynarec_ops_fpu_686_df_a32[256];
|
||||
|
||||
extern OpFn dynarec_ops_REPE[1024];
|
||||
extern OpFn dynarec_ops_REPNE[1024];
|
||||
|
||||
extern OpFn *x86_opcodes;
|
||||
extern OpFn *x86_opcodes_0f;
|
||||
extern OpFn *x86_opcodes_d8_a16;
|
||||
@@ -105,6 +110,8 @@ extern OpFn *x86_opcodes_de_a16;
|
||||
extern OpFn *x86_opcodes_de_a32;
|
||||
extern OpFn *x86_opcodes_df_a16;
|
||||
extern OpFn *x86_opcodes_df_a32;
|
||||
extern OpFn *x86_opcodes_REPE;
|
||||
extern OpFn *x86_opcodes_REPNE;
|
||||
|
||||
extern OpFn ops_286[1024];
|
||||
extern OpFn ops_286_0f[1024];
|
||||
@@ -167,4 +174,7 @@ extern OpFn ops_fpu_686_db_a32[256];
|
||||
extern OpFn ops_fpu_686_df_a16[256];
|
||||
extern OpFn ops_fpu_686_df_a32[256];
|
||||
|
||||
extern OpFn ops_REPE[1024];
|
||||
extern OpFn ops_REPNE[1024];
|
||||
|
||||
#endif /*_X86_OPS_H*/
|
||||
|
||||
@@ -136,7 +136,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#define op_seg(name, seg) \
|
||||
#define op_seg(name, seg, opcode_table, normal_opcode_table) \
|
||||
static int op ## name ## _w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetchdat = fastreadl(cs + cpu_state.pc); \
|
||||
@@ -10,7 +10,9 @@ static int op ## name ## _w_a16(uint32_t fetchdat) \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
return x86_opcodes[fetchdat & 0xff](fetchdat >> 8); \
|
||||
if (opcode_table[fetchdat & 0xff]) \
|
||||
return opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _l_a16(uint32_t fetchdat) \
|
||||
@@ -24,7 +26,9 @@ static int op ## name ## _l_a16(uint32_t fetchdat) \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
return x86_opcodes[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x100]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _w_a32(uint32_t fetchdat) \
|
||||
@@ -38,7 +42,9 @@ static int op ## name ## _w_a32(uint32_t fetchdat) \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
return x86_opcodes[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x200]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _l_a32(uint32_t fetchdat) \
|
||||
@@ -52,15 +58,31 @@ static int op ## name ## _l_a32(uint32_t fetchdat) \
|
||||
CLOCK_CYCLES(4); \
|
||||
PREFETCH_PREFIX(); \
|
||||
\
|
||||
return x86_opcodes[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
if (opcode_table[(fetchdat & 0xff) | 0x300]) \
|
||||
return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
}
|
||||
|
||||
op_seg(CS, _cs)
|
||||
op_seg(DS, _ds)
|
||||
op_seg(ES, _es)
|
||||
op_seg(FS, _fs)
|
||||
op_seg(GS, _gs)
|
||||
op_seg(SS, _ss)
|
||||
op_seg(CS, _cs, x86_opcodes, x86_opcodes)
|
||||
op_seg(DS, _ds, x86_opcodes, x86_opcodes)
|
||||
op_seg(ES, _es, x86_opcodes, x86_opcodes)
|
||||
op_seg(FS, _fs, x86_opcodes, x86_opcodes)
|
||||
op_seg(GS, _gs, x86_opcodes, x86_opcodes)
|
||||
op_seg(SS, _ss, x86_opcodes, x86_opcodes)
|
||||
|
||||
op_seg(CS_REPE, _cs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(DS_REPE, _ds, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(ES_REPE, _es, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(FS_REPE, _fs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(GS_REPE, _gs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(SS_REPE, _ss, x86_opcodes_REPE, x86_opcodes)
|
||||
|
||||
op_seg(CS_REPNE, _cs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(DS_REPNE, _ds, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(ES_REPNE, _es, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(FS_REPNE, _fs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(GS_REPNE, _gs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(SS_REPNE, _ss, x86_opcodes_REPNE, x86_opcodes)
|
||||
|
||||
static int op_66(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
@@ -84,3 +106,56 @@ static int op_67(uint32_t fetchdat) /*Address size select*/
|
||||
PREFETCH_PREFIX();
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
|
||||
static int op_66_REPE(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int op_67_REPE(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/
|
||||
{
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100);
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,643 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
extern int trap;
|
||||
|
||||
#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \
|
||||
static int opREP_INSB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint8_t temp; \
|
||||
\
|
||||
check_io_perm(DX); \
|
||||
temp = inb(DX); \
|
||||
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) DEST_REG--; \
|
||||
else DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
reads++; writes++; total_cycles += 15; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_INSW_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint16_t temp; \
|
||||
\
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
temp = inw(DX); \
|
||||
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) DEST_REG -= 2; \
|
||||
else DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
reads++; writes++; total_cycles += 15; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_INSL_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint32_t temp; \
|
||||
\
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
check_io_perm(DX+2); \
|
||||
check_io_perm(DX+3); \
|
||||
temp = inl(DX); \
|
||||
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) DEST_REG -= 4; \
|
||||
else DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
reads++; writes++; total_cycles += 15; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_OUTSB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
check_io_perm(DX); \
|
||||
outb(DX, temp); \
|
||||
if (flags & D_FLAG) SRC_REG--; \
|
||||
else SRC_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
reads++; writes++; total_cycles += 14; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_OUTSW_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
outw(DX, temp); \
|
||||
if (flags & D_FLAG) SRC_REG -= 2; \
|
||||
else SRC_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
reads++; writes++; total_cycles += 14; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_OUTSL_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
check_io_perm(DX+2); \
|
||||
check_io_perm(DX+3); \
|
||||
outl(DX, temp); \
|
||||
if (flags & D_FLAG) SRC_REG -= 4; \
|
||||
else SRC_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
reads++; writes++; total_cycles += 14; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_MOVSB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
uint8_t temp; \
|
||||
\
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
|
||||
else { DEST_REG++; SRC_REG++; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_MOVSW_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
uint16_t temp; \
|
||||
\
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
|
||||
else { DEST_REG += 2; SRC_REG += 2; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_MOVSL_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
uint32_t temp; \
|
||||
\
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
|
||||
else { DEST_REG += 4; SRC_REG += 4; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
ins++; \
|
||||
reads++; writes++; total_cycles += is486 ? 3 : 4; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
static int opREP_STOSB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) DEST_REG--; \
|
||||
else DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_STOSW_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \
|
||||
writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) DEST_REG -= 2; \
|
||||
else DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_STOSL_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int writes = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \
|
||||
writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) DEST_REG -= 4; \
|
||||
else DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
writes++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_LODSB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) SRC_REG--; \
|
||||
else SRC_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_LODSW_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) SRC_REG -= 2; \
|
||||
else SRC_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_LODSL_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) SRC_REG -= 4; \
|
||||
else SRC_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
reads++; total_cycles += is486 ? 4 : 5; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
|
||||
|
||||
#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \
|
||||
static int opREP_CMPSB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
\
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
|
||||
uint8_t temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
|
||||
else { DEST_REG++; SRC_REG++; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
reads += 2; total_cycles += is486 ? 7 : 9; \
|
||||
setsub8(temp, temp2); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_CMPSW_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
\
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
|
||||
uint16_t temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
|
||||
else { DEST_REG += 2; SRC_REG += 2; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
reads += 2; total_cycles += is486 ? 7 : 9; \
|
||||
setsub16(temp, temp2); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_CMPSL_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
\
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
|
||||
uint32_t temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
|
||||
else { DEST_REG += 4; SRC_REG += 4; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
reads += 2; total_cycles += is486 ? 7 : 9; \
|
||||
setsub32(temp, temp2); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
} \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
\
|
||||
static int opREP_SCASB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\
|
||||
setsub8(AL, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (flags & D_FLAG) DEST_REG--; \
|
||||
else DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_SCASW_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\
|
||||
setsub16(AX, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (flags & D_FLAG) DEST_REG -= 2; \
|
||||
else DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
} \
|
||||
static int opREP_SCASL_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
int reads = 0, total_cycles = 0, tempz; \
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\
|
||||
setsub32(EAX, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (flags & D_FLAG) DEST_REG -= 4; \
|
||||
else DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
reads++; total_cycles += is486 ? 5 : 8; \
|
||||
ins++; \
|
||||
if (cycles < cycles_end) \
|
||||
break; \
|
||||
} \
|
||||
ins--; \
|
||||
PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CPU_BLOCK_END(); \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
return 1; \
|
||||
} \
|
||||
return cpu_state.abrt; \
|
||||
}
|
||||
|
||||
REP_OPS(a16, CX, SI, DI)
|
||||
REP_OPS(a32, ECX, ESI, EDI)
|
||||
REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0)
|
||||
REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1)
|
||||
REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0)
|
||||
REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1)
|
||||
|
||||
static int opREPNE(uint32_t fetchdat)
|
||||
{
|
||||
return rep386(0);
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
static int opREPE(uint32_t fetchdat)
|
||||
{
|
||||
return rep386(1);
|
||||
}
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc++;
|
||||
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_PREFIX();
|
||||
if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32])
|
||||
return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
}
|
||||
|
||||
149
src/CPU/x86seg.c
149
src/CPU/x86seg.c
@@ -2133,7 +2133,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
|
||||
base=segdat[1]|((segdat[2]&0xFF)<<16);
|
||||
limit=segdat[0];
|
||||
|
||||
if(is386)
|
||||
{
|
||||
base |= (segdat[3]>>8)<<24;
|
||||
@@ -2144,7 +2143,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
{
|
||||
if (limit < 103)
|
||||
{
|
||||
pclog("32-bit TSS %04X limit less than 103.\n", seg);
|
||||
x86ts(NULL, seg);
|
||||
return;
|
||||
}
|
||||
@@ -2161,7 +2159,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
if (cpu_state.abrt) return;
|
||||
|
||||
if (optype==IRET) flags&=~NT_FLAG;
|
||||
|
||||
|
||||
cpu_386_flags_rebuild();
|
||||
writememl(tr.base,0x1C,cr3);
|
||||
writememl(tr.base,0x20,cpu_state.pc);
|
||||
@@ -2200,14 +2198,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
if (cpu_state.abrt)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
new_cr3=readmeml(base,0x1C);
|
||||
new_pc=readmeml(base,0x20);
|
||||
new_flags=readmeml(base,0x24);
|
||||
|
||||
if (optype == OPTYPE_INT || optype == CALL)
|
||||
new_flags |= NT_FLAG;
|
||||
|
||||
|
||||
new_eax=readmeml(base,0x28);
|
||||
new_ecx=readmeml(base,0x2C);
|
||||
new_edx=readmeml(base,0x30);
|
||||
@@ -2245,70 +2243,72 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24);
|
||||
|
||||
if (eflags&VM_FLAG)
|
||||
if (eflags & VM_FLAG)
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(new_cs&~3))
|
||||
{
|
||||
x86ts(NULL,0);
|
||||
return;
|
||||
}
|
||||
addr=new_cs&~7;
|
||||
if (new_cs&4)
|
||||
{
|
||||
if (addr>=ldt.limit)
|
||||
{
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
addr+=ldt.base;
|
||||
loadcs(new_cs);
|
||||
set_use32(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr>=gdt.limit)
|
||||
if (!(new_cs&~3))
|
||||
{
|
||||
x86ts(NULL,0);
|
||||
return;
|
||||
}
|
||||
addr=new_cs&~7;
|
||||
if (new_cs&4)
|
||||
{
|
||||
if (addr>=ldt.limit)
|
||||
{
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
addr+=ldt.base;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr>=gdt.limit)
|
||||
{
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
addr+=gdt.base;
|
||||
}
|
||||
segdat2[0]=readmemw(0,addr);
|
||||
segdat2[1]=readmemw(0,addr+2);
|
||||
segdat2[2]=readmemw(0,addr+4);
|
||||
segdat2[3]=readmemw(0,addr+6);
|
||||
if (!(segdat2[2]&0x8000))
|
||||
{
|
||||
x86np("TS loading CS not present\n", new_cs & 0xfffc);
|
||||
return;
|
||||
}
|
||||
switch (segdat2[2]&0x1F00)
|
||||
{
|
||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
||||
if ((new_cs&3) != DPL2)
|
||||
{
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||
if ((new_cs&3) < DPL2)
|
||||
{
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
addr+=gdt.base;
|
||||
}
|
||||
segdat2[0]=readmemw(0,addr);
|
||||
segdat2[1]=readmemw(0,addr+2);
|
||||
segdat2[2]=readmemw(0,addr+4);
|
||||
segdat2[3]=readmemw(0,addr+6);
|
||||
if (!(segdat2[2]&0x8000))
|
||||
{
|
||||
x86np("TS loading CS not present\n", new_cs & 0xfffc);
|
||||
return;
|
||||
}
|
||||
switch (segdat2[2]&0x1F00)
|
||||
{
|
||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
||||
if ((new_cs&3) != DPL2)
|
||||
{
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||
if ((new_cs&3) < DPL2)
|
||||
{
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
|
||||
CS=new_cs;
|
||||
do_seg_load(&_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat2[3] & 0x40);
|
||||
CS=new_cs;
|
||||
do_seg_load(&_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat2[3] & 0x40);
|
||||
}
|
||||
|
||||
EAX=new_eax;
|
||||
ECX=new_ecx;
|
||||
@@ -2319,28 +2319,20 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ESI=new_esi;
|
||||
EDI=new_edi;
|
||||
|
||||
if (output) pclog("Load ES %04X\n",new_es);
|
||||
loadseg(new_es,&_es);
|
||||
if (output) pclog("Load SS %04X\n",new_ss);
|
||||
loadseg(new_ss,&_ss);
|
||||
if (output) pclog("Load DS %04X\n",new_ds);
|
||||
loadseg(new_ds,&_ds);
|
||||
if (output) pclog("Load FS %04X\n",new_fs);
|
||||
loadseg(new_fs,&_fs);
|
||||
if (output) pclog("Load GS %04X\n",new_gs);
|
||||
loadseg(new_gs,&_gs);
|
||||
|
||||
if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (limit < 43)
|
||||
{
|
||||
pclog("16-bit TSS %04X limit less than 43.\n", seg);
|
||||
x86ts(NULL, seg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (optype==JMP || optype==CALL || optype==OPTYPE_INT)
|
||||
{
|
||||
if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4);
|
||||
@@ -2353,7 +2345,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
if (cpu_state.abrt) return;
|
||||
|
||||
if (optype==IRET) flags&=~NT_FLAG;
|
||||
|
||||
|
||||
cpu_386_flags_rebuild();
|
||||
writememw(tr.base,0x0E,cpu_state.pc);
|
||||
writememw(tr.base,0x10,flags);
|
||||
@@ -2392,15 +2384,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
|
||||
new_pc=readmemw(base,0x0E);
|
||||
new_flags=readmemw(base,0x10);
|
||||
|
||||
if (optype == OPTYPE_INT || optype == CALL)
|
||||
new_flags |= NT_FLAG;
|
||||
|
||||
|
||||
new_eax=readmemw(base,0x12);
|
||||
new_ecx=readmemw(base,0x14);
|
||||
new_edx=readmemw(base,0x16);
|
||||
new_ebx=readmemw(base,0x18);
|
||||
|
||||
new_esp=readmemw(base,0x1A);
|
||||
new_ebp=readmemw(base,0x1C);
|
||||
new_esi=readmemw(base,0x1E);
|
||||
@@ -2434,7 +2424,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
|
||||
if (!(new_cs&~3))
|
||||
{
|
||||
pclog("TS loading null CS\n");
|
||||
x86ts(NULL,0);
|
||||
return;
|
||||
}
|
||||
@@ -2443,7 +2432,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
{
|
||||
if (addr>=ldt.limit)
|
||||
{
|
||||
pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr);
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
@@ -2453,7 +2441,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
{
|
||||
if (addr>=gdt.limit)
|
||||
{
|
||||
pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit);
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
@@ -2465,7 +2452,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
segdat2[3]=readmemw(0,addr+6);
|
||||
if (!(segdat2[2]&0x8000))
|
||||
{
|
||||
pclog("TS loading CS not present\n");
|
||||
x86np("TS loading CS not present\n", new_cs & 0xfffc);
|
||||
return;
|
||||
}
|
||||
@@ -2474,7 +2460,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
|
||||
if ((new_cs&3) != DPL2)
|
||||
{
|
||||
pclog("TS load CS non-conforming RPL != DPL");
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
@@ -2482,13 +2467,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||
if ((new_cs&3) < DPL2)
|
||||
{
|
||||
pclog("TS load CS non-conforming RPL < DPL");
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pclog("TS load CS not code segment\n");
|
||||
x86ts(NULL,new_cs&~3);
|
||||
return;
|
||||
}
|
||||
@@ -2507,19 +2490,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ESI=new_esi | 0xFFFF0000;
|
||||
EDI=new_edi | 0xFFFF0000;
|
||||
|
||||
if (output) pclog("Load ES %04X\n",new_es);
|
||||
loadseg(new_es,&_es);
|
||||
if (output) pclog("Load SS %04X\n",new_ss);
|
||||
loadseg(new_ss,&_ss);
|
||||
if (output) pclog("Load DS %04X\n",new_ds);
|
||||
loadseg(new_ds,&_ds);
|
||||
if (is386)
|
||||
{
|
||||
loadseg(0,&_fs);
|
||||
loadseg(0,&_gs);
|
||||
}
|
||||
|
||||
if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc);
|
||||
}
|
||||
|
||||
tr.seg=seg;
|
||||
@@ -2527,4 +2505,3 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
tr.limit=limit;
|
||||
tr.access=segdat[2]>>8;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# Modified Makefile for Win32 (MinGW32) environment.
|
||||
#
|
||||
# Version: @(#)Makefile.mingw 1.0.31 2017/06/19
|
||||
# Version: @(#)Makefile.mingw 1.0.35 2017/08/10
|
||||
#
|
||||
# Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
# Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -22,9 +22,7 @@ endif
|
||||
# Various compile-time options.
|
||||
# -DROM_TRACE=0xcd800 traces ROM access from segment C800
|
||||
# -DIO_TACE=0x66 traces I/O on port 0x66
|
||||
ifndef STUFF
|
||||
STUFF =
|
||||
endif
|
||||
|
||||
# Add feature selections here.
|
||||
# -DANSI_CFG forces the config file to ANSI encoding.
|
||||
@@ -54,6 +52,12 @@ endif
|
||||
ifndef USB
|
||||
USB = n
|
||||
endif
|
||||
ifndef DEV_BRANCH
|
||||
DEV_BRANCH = n
|
||||
endif
|
||||
ifndef FLUIDSYNTH
|
||||
FLUIDSYNTH = y
|
||||
endif
|
||||
ifndef X64
|
||||
X64 = n
|
||||
endif
|
||||
@@ -123,14 +127,31 @@ ifeq ($(VRAMDUMP), y)
|
||||
CFLAGS += -DENABLE_VRAM_DUMP
|
||||
RFLAGS += -DENABLE_VRAM_DUMP
|
||||
endif
|
||||
|
||||
ifeq ($(FLUIDSYNTH), y)
|
||||
CFLAGS += -DUSE_FLUIDSYNTH
|
||||
FSYNTHOBJ = midi_fluidsynth.o
|
||||
endif
|
||||
ifeq ($(X64), y)
|
||||
PLATCG = codegen_x86-64.o
|
||||
CGOPS = codegen_ops_x86-64.h
|
||||
VCG = vid_voodoo_codegen_x86-64.h
|
||||
else
|
||||
PLATCG = codegen_x86.o
|
||||
CGOPS = codegen_ops_x86.h
|
||||
VCG = vid_voodoo_codegen_x86.h
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(DEV_BRANCH), y)
|
||||
DBFLAGS = -DDEV_BRANCH
|
||||
else
|
||||
DBFLAGS =
|
||||
endif
|
||||
|
||||
ifeq ($(DEV_BRANCH), y)
|
||||
CFLAGS += -DDEV_BRANCH
|
||||
endif
|
||||
|
||||
ifeq ($(WALTJE), y)
|
||||
OPENDIR = win_opendir.o
|
||||
SERIAL = serial.o
|
||||
@@ -146,7 +167,8 @@ MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \
|
||||
memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o
|
||||
CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \
|
||||
codegen.o \
|
||||
codegen_ops.o codegen_timing_486.o \
|
||||
codegen_ops.o \
|
||||
codegen_timing_common.o codegen_timing_486.o \
|
||||
codegen_timing_686.o codegen_timing_pentium.o \
|
||||
codegen_timing_winchip.o $(PLATCG) \
|
||||
x86seg.o x87.o
|
||||
@@ -159,13 +181,13 @@ SYSOBJ = model.o \
|
||||
scat.o \
|
||||
sis496.o \
|
||||
wd76c10.o \
|
||||
acer386sx.o acerm3a.o amstrad.o \
|
||||
acer386sx.o amstrad.o \
|
||||
compaq.o laserxt.o jim.o \
|
||||
olivetti_m24.o ps1.o ps2.o ps2_mca.o \
|
||||
tandy_eeprom.o tandy_rom.o
|
||||
DEVOBJ = bugger.o lpt.o $(SERIAL) \
|
||||
fdc37c665.o fdc37c669.o fdc37c932fr.o \
|
||||
pc87306.o sis85c471.o w83877f.o \
|
||||
fdc37c665.o fdc37c669.o fdc37c932fr.o \
|
||||
pc87306.o sis85c471.o w83877f.o \
|
||||
keyboard.o \
|
||||
keyboard_xt.o keyboard_at.o keyboard_pcjr.o \
|
||||
keyboard_amstrad.o keyboard_olim24.o \
|
||||
@@ -200,13 +222,13 @@ SNDOBJ = sound.o \
|
||||
wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \
|
||||
wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \
|
||||
wave8580_PST.o wave.o \
|
||||
midi.o \
|
||||
midi.o $(FSYNTHOBJ) \
|
||||
midi_mt32.o \
|
||||
Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \
|
||||
LA32FloatWaveGenerator.o LA32WaveGenerator.o \
|
||||
MidiStreamParser.o Part.o Partial.o PartialManager.o \
|
||||
Poly.o ROMInfo.o Synth.o Tables.o TVA.o TVF.o TVP.o \
|
||||
sha1.o c_interface.o \
|
||||
Poly.o ROMInfo.o SampleRateConverter_dummy.o Synth.o \
|
||||
Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o \
|
||||
midi_system.o \
|
||||
snd_speaker.o snd_ps1.o snd_pssj.o \
|
||||
snd_adlib.o snd_adlibgold.o snd_ad1848.o \
|
||||
@@ -230,9 +252,9 @@ VIDOBJ = video.o \
|
||||
vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \
|
||||
vid_ati68860_ramdac.o vid_ati_mach64.o \
|
||||
vid_ics2595.o \
|
||||
vid_sc1502x_ramdac.o \
|
||||
vid_sdac_ramdac.o \
|
||||
vid_stg_ramdac.o \
|
||||
vid_unk_ramdac.o \
|
||||
vid_wy700.o \
|
||||
vid_voodoo.o \
|
||||
vid_pcjr.o vid_ps1_svga.o \
|
||||
@@ -247,8 +269,13 @@ WINOBJ = win.o \
|
||||
win_iodev.o win_joystick.o win_midi.o \
|
||||
win_settings.o win_deviceconfig.o win_joystickconfig.o \
|
||||
86Box.res
|
||||
ifeq ($(DEV_BRANCH), y)
|
||||
DEVBRANCHOBJ = vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o \
|
||||
vid_nv_riva128.o
|
||||
endif
|
||||
OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \
|
||||
$(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ)
|
||||
$(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) \
|
||||
$(DEVBRANCHOBJ)
|
||||
|
||||
LZFOBJ = lzf_c.o lzf_d.o
|
||||
|
||||
@@ -308,8 +335,6 @@ pcap_if.res: pcap_if.rc
|
||||
# Module dependencies.
|
||||
acer386sx.o: ibm.h cpu/cpu.h io.h device.h model.h
|
||||
|
||||
acerm3a.o: ibm.h cpu/cpu.h io.h device.h model.h
|
||||
|
||||
ali1429.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h
|
||||
|
||||
amstrad.o: ibm.h cpu/cpu.h io.h device.h model.h keyboard.h lpt.h mouse.h
|
||||
@@ -319,6 +344,10 @@ bugger.o: ibm.h io.h bugger.h
|
||||
cdrom.o: 86box.h cdrom.h ibm.h ide.h piix.h scsi.h timer.h \
|
||||
win/plat_iodev.h
|
||||
|
||||
cdrom_dosbox.o: cdrom_dosbox.h
|
||||
|
||||
cdrom_image.o: config.h cdrom_dosbox.h cdrom.h cdrom_image.h cdrom_null.h
|
||||
|
||||
cdrom_ioctl.o: ibm.h cdrom.h cdrom_ioctl.h scsi.h
|
||||
|
||||
cdrom_null.o: ibm.h cdrom.h cdrom_ioctl.h
|
||||
@@ -330,7 +359,7 @@ config.o: cdrom.h config.h device.h disc.h fdc.h fdd.h ibm.h \
|
||||
network/network.h nvr.h scsi.h win/plat_joystick.h \
|
||||
win/plat_midi.h sound/snd_dbopl.h sound/snd_mpu401.h \
|
||||
sound/snd_opl.h sound/sound.h video/video.h win/win.h \
|
||||
win/win_language.h
|
||||
win/resource.h win/win_language.h
|
||||
|
||||
device.o: ibm.h cpu/cpu.h config.h device.h model.h sound/sound.h
|
||||
|
||||
@@ -350,6 +379,9 @@ disc_td0.o: ibm.h disc.h disc_td0.h fdc.h fdd.h
|
||||
|
||||
dma.o: ibm.h cpu/x86.h mem.h io.h dma.h
|
||||
|
||||
esdi_at.o: ibm.h device.h hdd_image.h io.h mem.h pic.h rom.h timer.h \
|
||||
esdi_at.h
|
||||
|
||||
fdc.o: ibm.h disc.h dma.h fdc.h fdd.h io.h pic.h timer.h
|
||||
|
||||
fdc37c665.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h \
|
||||
@@ -367,8 +399,8 @@ gameport.o: ibm.h cpu/cpu.h device.h io.h timer.h gameport.h \
|
||||
joystick_ch_flightstick_pro.h joystick_standard.h \
|
||||
joystick_sw_pad.h joystick_tm_fcs.h plat_joystick.h
|
||||
|
||||
hdd.o: ibm.h cpu/cpu.h device.h hdd.h model.h hdd_esdi.h \
|
||||
mfm_at.h mfm_xebec.h xtide.h
|
||||
hdd.o: ibm.h cpu/cpu.h device.h hdd.h model.h esdi_at.h \
|
||||
hdd_esdi.h mfm_at.h mfm_xebec.h xtide.h
|
||||
|
||||
hdd_image.o: ibm.h ide.h hdd_image.h
|
||||
|
||||
@@ -389,8 +421,6 @@ i430vx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h
|
||||
|
||||
i440fx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h
|
||||
|
||||
i82335.o: ibm.h io.h mem.h
|
||||
|
||||
ide.o: 86box.h cdrom.h hdd_image.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h
|
||||
|
||||
intel.o: ibm.h cpu/cpu.h io.h mem.h pit.h timer.h intel.h
|
||||
@@ -449,9 +479,9 @@ mfm_at.o: ibm.h device.h hdd_image.h io.h pic.h timer.h mfm_at.h
|
||||
mfm_xebec.o: ibm.h device.h dma.h hdd_image.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h
|
||||
|
||||
model.o: ibm.h io.h mem.h rom.h device.h model.h cpu/cpu.h \
|
||||
mouse.h mouse_ps2.h cdrom.h disc.h dma.h fdc.h \
|
||||
mouse.h cdrom.h disc.h dma.h fdc.h \
|
||||
fdc37c665.h fdc37c669.h fdc37c932fr.h \
|
||||
gameport.h i82335.h ide.h intel.h intel_flash.h \
|
||||
gameport.h ide.h intel.h intel_flash.h \
|
||||
keyboard_amstrad.h keyboard_at.h keyboard_olim24.h \
|
||||
keyboard_pcjr.h keyboard_xt.h lpt.h mem.h memregs.h \
|
||||
nmi.h nvr.h pc87306.h pci.h pic.h piix.h pit.h ps2_mca.h \
|
||||
@@ -460,14 +490,13 @@ model.o: ibm.h io.h mem.h rom.h device.h model.h cpu/cpu.h \
|
||||
video/vid_pcjr.h video/vid_tandy.h w83877f.h wd76c10.h \
|
||||
xtide.h bugger.h
|
||||
|
||||
mouse.o: ibm.h cpu/cpu.h device.h model.h \
|
||||
mouse.h mouse_serial.h mouse_ps2.h mouse_bus.h keyboard_olim24.h
|
||||
mouse.o: ibm.h cpu/cpu.h device.h model.h mouse.h keyboard_olim24.h
|
||||
|
||||
mouse_bus.o: ibm.h io.h pic.h mouse.h mouse_bus.h plat_mouse.h
|
||||
mouse_bus.o: ibm.h io.h pic.h timer.h mouse.h
|
||||
|
||||
mouse_ps2.o: ibm.h keyboard_at.h mouse.h mouse_ps2.h plat_mouse.h
|
||||
mouse_ps2.o: ibm.h keyboard_at.h mouse.h plat_mouse.h
|
||||
|
||||
mouse_serial.o: ibm.h timer.h serial.h mouse.h mouse_serial.h
|
||||
mouse_serial.o: ibm.h timer.h serial.h mouse.h
|
||||
|
||||
neat.o: ibm.h cpu/cpu.h io.h device.h model.h
|
||||
|
||||
@@ -534,6 +563,8 @@ scsi_disk.o: 86box.h cdrom.h hdd_image.h ibm.h ide.h piix.h scsi.h \
|
||||
|
||||
serial.o: ibm.h io.h pic.h timer.h serial.h plat_serial.h
|
||||
|
||||
serial_old.o: ibm.h io.h mouse.h pic.h serial.h timer.h
|
||||
|
||||
sio.o: ibm.h cdrom.h disc.h dma.h fdc.h keyboard_at.h ide.h \
|
||||
io.h mem.h pci.h sio.h
|
||||
|
||||
@@ -543,6 +574,8 @@ sis50x.o: ibm.h device.h io.h mem.h pci.h sis50x.h
|
||||
|
||||
sis85c471.o: ibm.h ide.h disc.h fdc.h fdd.h io.h lpt.h serial.h sis85c471.h
|
||||
|
||||
superio_detect.o: ibm.h io.h disc.h fdd.h fdc.h superio_detect.h
|
||||
|
||||
tandy_eeprom.o: ibm.h device.h mem.h io.h rom.h tandy_eeprom.h
|
||||
|
||||
tandy_rom.o: ibm.h device.h io.h mem.h rom.h tandy_rom.h
|
||||
@@ -557,5 +590,233 @@ wd76c10.o: ibm.h disc.h fdc.h io.h mem.h serial.h wd76c10.h
|
||||
|
||||
xtide.o: ibm.h io.h mem.h rom.h device.h ide.h xtide.h
|
||||
|
||||
# cpu/
|
||||
386.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x87.h mem.h disc.h fdc.h pic.h timer.h cpu/386_common.h
|
||||
|
||||
386_dynarec.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x86_ops.h cpu/x87.h mem.h cpu/codegen.h disc.h fdc.h pic.h timer.h cpu/386_common.h \
|
||||
cpu/x86_ops.h cpu/x86seg.h cpu/x86_ops_arith.h cpu/x86_ops_atomic.h cpu/x86_ops_bcd.h cpu/x86_ops_bit.h \
|
||||
cpu/x86_ops_bitscan.h cpu/x86_ops_call.h cpu/x86_ops_flag.h cpu/x86_ops_fpu.h cpu/x86_ops_inc_dec.h cpu/x86_ops_int.h \
|
||||
cpu/x86_ops_io.h cpu/x86_ops_jump.h cpu/x86_ops_misc.h \
|
||||
cpu/x87_ops_arith.h cpu/x87_ops_misc.h cpu/x87_ops_loadstore.h \
|
||||
cpu/x87_ops.h cpu/x86_ops_i686.h cpu/x86_ops_mmx.h \
|
||||
cpu/x86_ops_mmx_arith.h cpu/x86_ops_mmx_cmp.h cpu/x86_ops_mmx_logic.h cpu/x86_ops_mmx_pack.h cpu/x86_ops_mmx_shift.h \
|
||||
cpu/x86_ops_mov.h cpu/x86_ops_mov_ctrl.h cpu/x86_ops_mov_seg.h cpu/x86_ops_movx.h cpu/x86_ops_msr.h cpu/x86_ops_mul.h \
|
||||
cpu/x86_ops_pmode.h cpu/x86_ops_prefix.h cpu/x86_ops_rep.h cpu/x86_ops_ret.h cpu/x86_ops_set.h cpu/x86_ops_shift.h \
|
||||
cpu/x86_ops_stack.h cpu/x86_ops_string.h cpu/x86_ops_xchg.h \
|
||||
cpu/386_ops.h
|
||||
|
||||
386_dynarec_ops.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x86_ops.h cpu/x87.h cpu/x86_flags.h mem.h cpu/codegen.h pic.h cpu/386_common.h \
|
||||
cpu/x86_ops.h cpu/x86seg.h cpu/x86_ops_arith.h cpu/x86_ops_atomic.h cpu/x86_ops_bcd.h cpu/x86_ops_bit.h \
|
||||
cpu/x86_ops_bitscan.h cpu/x86_ops_call.h cpu/x86_ops_flag.h cpu/x86_ops_fpu.h cpu/x86_ops_inc_dec.h cpu/x86_ops_int.h \
|
||||
cpu/x86_ops_io.h cpu/x86_ops_jump.h cpu/x86_ops_misc.h \
|
||||
cpu/x87_ops_arith.h cpu/x87_ops_misc.h cpu/x87_ops_loadstore.h \
|
||||
cpu/x87_ops.h cpu/x86_ops_i686.h cpu/x86_ops_mmx.h \
|
||||
cpu/x86_ops_mmx_arith.h cpu/x86_ops_mmx_cmp.h cpu/x86_ops_mmx_logic.h cpu/x86_ops_mmx_pack.h cpu/x86_ops_mmx_shift.h \
|
||||
cpu/x86_ops_mov.h cpu/x86_ops_mov_ctrl.h cpu/x86_ops_mov_seg.h cpu/x86_ops_movx.h cpu/x86_ops_msr.h cpu/x86_ops_mul.h \
|
||||
cpu/x86_ops_pmode.h cpu/x86_ops_prefix.h cpu/x86_ops_rep.h cpu/x86_ops_ret.h cpu/x86_ops_set.h cpu/x86_ops_shift.h \
|
||||
cpu/x86_ops_stack.h cpu/x86_ops_string.h cpu/x86_ops_xchg.h \
|
||||
cpu/386_ops.h
|
||||
|
||||
808x.o: ibm.h cpu/cpu.h cpu/x86.h keyboard.h mem.h nmi.h pic.h scsi.h timer.h
|
||||
|
||||
codegen.o: ibm.h cpu/x86_ops.h mem.h cpu/codegen.h
|
||||
|
||||
codegen_ops.o: ibm.h mem.h cpu/x86.h cpu/x86_ops.h cpu/x86_flags.h cpu/x87.h cpu/386_common.h cpu/cpu.h cpu/codegen.h cpu/codegen_ops.h \
|
||||
cpu/$(CGOPS) cpu/codegen_ops_arith.h cpu/codegen_ops_fpu.h cpu/codegen_ops_jump.h cpu/codegen_ops_logic.h cpu/codegen_ops_misc.h \
|
||||
cpu/codegen_ops_mmx.h cpu/codegen_ops_mov.h cpu/codegen_ops_shift.h cpu/codegen_ops_stack.h cpu/codegen_ops_xchg.h
|
||||
|
||||
codegen_timing_486.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x87_ops.h cpu/x87.h mem.h cpu/codegen.h cpu/codegen_ops.h cpu/codegen_timing_common.h
|
||||
|
||||
codegen_timing_686.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x87_ops.h cpu/x87.h mem.h cpu/codegen.h cpu/codegen_timing_common.h
|
||||
|
||||
codegen_timing_common.o: ibm.h cpu/codegen_timing_common.h
|
||||
|
||||
codegen_timing_pentium.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x87_ops.h cpu/x87.h mem.h cpu/codegen.h cpu/codegen_ops.h cpu/codegen_timing_common.h
|
||||
|
||||
codegen_timing_winchip.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x87_ops.h cpu/x87.h mem.h cpu/codegen.h cpu/codegen_ops.h cpu/codegen_timing_common.h
|
||||
|
||||
codegen_x86.o: ibm.h cpu/cpu.h cpu/x86.h cpu/x86_flags.h cpu/x86_ops.h cpu/x87.h mem.h cpu/386_common.h cpu/codegen.h cpu/codegen_ops.h \
|
||||
cpu/codegen_ops_x86.h
|
||||
|
||||
codegen_x86-64.o: ibm.h mem.h cpu/cpu.h cpu/x86.h cpu/x86_flags.h cpu/x86_ops.h cpu/x87.h cpu/386_common.h cpu/codegen.h cpu/codegen_ops.h \
|
||||
cpu/codegen_ops_x86-64.h
|
||||
|
||||
cpu.o: ibm.h cpu/cpu.h device.h model.h io.h cpu/x86_ops.h mem.h pci.h cpu/codegen.h
|
||||
|
||||
x86seg.o: ibm.h mem.h nvr.h cpu/x86.h cpu/386.h cpu/386_common.h cpu/cpu.h
|
||||
|
||||
x87.o: ibm.h pic.h cpu/x86.h cpu/x86_flags.h cpu/x86_ops.h cpu/x87.h cpu/386_common.h
|
||||
|
||||
# network/
|
||||
net_ne2000.o: ibm.h io.h mem.h rom.h pci.h pic.h device.h config.h disc_random.h network/network.h network/net_ne2000.h network/bswap.h
|
||||
|
||||
net_pcap.o: ibm.h config.h device.h network/network.h win/plat_dynld.h win/plat_thread.h
|
||||
|
||||
net_slirp.o: network/slirp/slirp.h network/slirp/queue.h ibm.h config.h device.h network/network.h win/plat_thread.h
|
||||
|
||||
network.o: ibm.h device.h network/network.h network/net_ne2000.h win/plat_ui.h
|
||||
|
||||
# video/
|
||||
vid_ati_eeprom.o: ibm.h mem.h rom.h video/vid_ati_eeprom.h
|
||||
|
||||
vid_ati_mach64.o: ibm.h device.h io.h mem.h pci.h rom.h win/plat_thread.h video/video.h video/vid_svga.h video/vid_svga_render.h \
|
||||
video/vid_ati68860_ramdac.h video/vid_ati_eeprom.h video/vid_ics2595.h
|
||||
|
||||
vid_ati18800.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_ati18800.h video/vid_ati_eeprom.h video/vid_svga.h
|
||||
|
||||
vid_ati28800.o: ibm.h io.h mem.h rom.h device.h timer.h video/video.h video/vid_ati28800.h video/vid_ati_eeprom.h video/vid_svga.h \
|
||||
video/vid_svga_render.h
|
||||
|
||||
vid_ati68860_ramdac.o: ibm.h mem.h video/video.h video/vid_svga.h video/vid_ati68860_ramdac.h video/vid_svga_render.h
|
||||
|
||||
vid_cga.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_cga.h video/vid_cga_comp.h win/win_cgapal.h
|
||||
|
||||
vid_cga_comp.o: ibm.h device.h mem.h video/vid_cga.h video/vid_cga_comp.h
|
||||
|
||||
vid_cl_gd.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_svga.h video/vid_svga_render.h video/vid_cl_ramdac.h \
|
||||
video/vid_cl_gd.h video/vid_cl_gd_blit.h
|
||||
|
||||
vid_cl_gd_blit.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_svga.h video/vid_svga_render.h video/vid_cl_ramdac.h \
|
||||
video/vid_cl_gd.h video/vid_cl_gd_blit.h video/vid_cl_gd_vga_rop.h
|
||||
|
||||
vid_cl_gd_ramdac.o: ibm.h mem.h rom.h device.h video/video.h video/vid_svga.h video/vid_cl_ramdac.h video/vid_cl_gd.h \
|
||||
video/vid_cl_gd_blit.h
|
||||
|
||||
vid_colorplus.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_cga.h video/vid_colorplus.h video/vid_cga_comp.h
|
||||
|
||||
vid_ega.o: ibm.h io.h mem.h rom.h timer.h device.h video/video.h video/vid_ega.h video/vid_ega_render.h
|
||||
|
||||
vid_ega_render.o: ibm.h device.h mem.h rom.h video/video.h video/vid_ega.h video/vid_ega_render.h
|
||||
|
||||
vid_et4000.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_svga.h video/vid_sc1502x_ramdac.h video/vid_et4000.h
|
||||
|
||||
vid_et4000w32.o: ibm.h io.h mem.h pci.h rom.h device.h win/plat_thread.h video/video.h video/vid_svga.h video/vid_icd2061.h \
|
||||
video/vid_stg_ramdac.h
|
||||
|
||||
vid_genius.o: ibm.h io.h mem.h rom.h timer.h device.h video/video.h video/vid_genius.h
|
||||
|
||||
vid_hercules.o: ibm.h mem.h io.h timer.h device.h video/video.h video/vid_hercules.h win/win_cgapal.h
|
||||
|
||||
vid_herculesplus.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_herculesplus.h
|
||||
|
||||
vid_icd2061.o: ibm.h video/vid_icd2061.h
|
||||
|
||||
vid_ics2595.o: ibm.h video/vid_ics2595.h
|
||||
|
||||
vid_incolor.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_incolor.h
|
||||
|
||||
vid_mda.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_mda.h win/win_cgapal.h
|
||||
|
||||
vid_nv_riva128.o: ibm.h io.h mem.h pci.h pic.h rom.h timer.h device.h win/plat_thread.h video/video.h video/vid_svga.h \
|
||||
video/vid_svga_render.h
|
||||
|
||||
vid_olivetti_m24.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_olivetti_m24.h
|
||||
|
||||
vid_oti067.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_oti067.h video/vid_svga.h
|
||||
|
||||
vid_paradise.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_paradise.h video/vid_svga.h video/vid_svga_render.h
|
||||
|
||||
vid_pc200.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_cga.h video/vid_pc200.h
|
||||
|
||||
vid_pc1512.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_pc1512.h
|
||||
|
||||
vid_pc1640.o: ibm.h io.h mem.h rom.h timer.h device.h video/video.h video/vid_cga.h video/vid_ega.h video/vid_pc1640.h
|
||||
|
||||
vid_pcjr.o: ibm.h io.h mem.h pic.h timer.h device.h video/video.h video/vid_cga_comp.h video/vid_pcjr.h
|
||||
|
||||
vid_ps1_svga.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_svga.h video/vid_vga.h
|
||||
|
||||
vid_s3.o: ibm.h device.h io.h mem.h pci.h rom.h win/plat_thread.h video/video.h video/vid_s3.h video/vid_svga.h \
|
||||
video/vid_svga_render.h video/vid_sdac_ramdac.h
|
||||
|
||||
vid_s3_virge.o: ibm.h io.h mem.h pci.h rom.h device.h win/plat_thread.h video/video.h video/vid_s3_virge.h video/vid_svga.h \
|
||||
video/vid_svga_render.h
|
||||
|
||||
vid_sc1502x_ramdac.o: ibm.h mem.h video/video.h video/vid_svga.h video/vid_sc1502x_ramdac.h
|
||||
|
||||
vid_sdac_ramdac.o: ibm.h mem.h video/video.h video/vid_svga.h video/vid_sdac_ramdac.h
|
||||
|
||||
vid_stg_ramdac.o: ibm.h mem.h video/video.h video/vid_svga.h video/vid_stg_ramdac.h
|
||||
|
||||
vid_svga.o: ibm.h io.h mem.h rom.h timer.h video/video.h video/vid_svga.h video/vid_svga_render.h
|
||||
|
||||
vid_svga_render.o: ibm.h mem.h video/video.h video/vid_svga.h video/vid_svga_render.h
|
||||
|
||||
vid_tandy.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_tandy.h video/vid_cga_comp.h
|
||||
|
||||
vid_tandysl.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_tandysl.h
|
||||
|
||||
vid_tgui9440.o: ibm.h io.h mem.h pci.h rom.h device.h win/plat_thread.h video/video.h video/vid_svga.h video/vid_svga_render.h \
|
||||
video/vid_tkd8001_ramdac.h video/vid_tgui9440.h
|
||||
|
||||
vid_tkd8001_ramdac.o: ibm.h mem.h video/video.h video/vid_svga.h video/vid_tkd8001_ramdac.h
|
||||
|
||||
vid_tvga.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_svga.h video/vid_svga_render.h video/vid_tkd8001_ramdac.h \
|
||||
video/vid_tvga.h
|
||||
|
||||
vid_vga.o: ibm.h io.h mem.h rom.h device.h video/video.h video/vid_svga.h video/vid_vga.h
|
||||
|
||||
vid_voodoo.o: ibm.h cpu/cpu.h mem.h rom.h pci.h timer.h device.h win/plat_thread.h video/video.h video/vid_svga.h \
|
||||
video/vid_voodoo.h video/vid_voodoo_dither.h video/$(VCG)
|
||||
|
||||
vid_wy700.o: ibm.h io.h mem.h timer.h device.h video/video.h video/vid_wy700.h
|
||||
|
||||
video.o: ibm.h cpu/cpu.h io.h mem.h rom.h config.h device.h timer.h win/plat_thread.h video/video.h video/vid_svga.h \
|
||||
win/resource.h win/win.h win/win_cgapal.h \
|
||||
video/vid_ati18800.h video/vid_ati28800.h video/vid_ati_mach64.h video/vid_cga.h \
|
||||
video/vid_cl_ramdac.h video/vid_cl_gd.h \
|
||||
video/vid_ega.h video/vid_et4000.h video/vid_et4000w32.h video/vid_genius.h video/vid_hercules.h \
|
||||
video/vid_herculesplus.h video/vid_incolor.h video/vid_colorplus.h video/vid_mda.h \
|
||||
video/vid_nv_riva128.h \
|
||||
video/vid_olivetti_m24.h video/vid_oti067.h video/vid_paradise.h video/vid_pc1512.h video/vid_pc1640.h \
|
||||
video/vid_pc200.h video/vid_pcjr.h video/vid_ps1_svga.h video/vid_s3.h video/vid_s3_virge.h video/vid_tandy.h \
|
||||
video/vid_tandysl.h video/vid_tgui9440.h video/vid_tvga.h video/vid_vga.h video/vid_wy700.h
|
||||
|
||||
# win/
|
||||
win.o: 86box.h device.h disc.h fdd.h hdd.h ibm.h cpu/cpu.h mem.h rom.h nvr.h config.h model.h ide.h cdrom.h cdrom_null.h \
|
||||
cdrom_ioctl.h cdrom_image.h scsi.h scsi_disk.h video/video.h video/vid_ega.h mouse.h sound/sound.h sound/snd_dbopl.h \
|
||||
win/plat_keyboard.h win/plat_iodev.h win/plat_mouse.h win/plat_midi.h win/plat_thread.h win/plat_ticks.h win/plat_ui.h \
|
||||
win/resource.h win/win.h win/win_cgapal.h win/win_ddraw.h win/win_d3d.h win/win_language.h
|
||||
|
||||
win_d3d.o: video/video.h win/win.h win/resource.h win/win_d3d.h win/win_cgapal.h
|
||||
|
||||
win_d3d_fs.o: 86box.h video/video.h win/win.h win/resource.h win/win_d3d.h win/win_cgapal.h
|
||||
|
||||
win_ddraw.o: video/video.h win/resource.h win/win_ddraw.h win/win_cgapal.h
|
||||
|
||||
win_ddraw_fs.o: video/video.h win/resource.h win/win_ddraw.h win/win_cgapal.h
|
||||
|
||||
win_ddraw_screenshot.o: video/video.h win/resource.h win/win.h win/win_ddraw.h win/win_language.h
|
||||
|
||||
win_deviceconfig.o: win/plat_midi.h win/resource.h win/win.h win/win_language.h
|
||||
|
||||
win_dynld.o: win/plat_dynld.h win/resource.h ibm.h
|
||||
|
||||
win_iodev.o: ibm.h device.h cdrom.h cdrom_image.h cdrom_ioctl.h cdrom_null.h scsi_disk.h win/plat_iodev.h win/resource.h win/win.h
|
||||
|
||||
win_joystick.o: device.h gameport.h win/plat_joystick.h win/resource.h win/win.h
|
||||
|
||||
win_joystickconfig.o: ibm.h config.h device.h gameport.h win/plat_joystick.h win/resource.h win/win.h
|
||||
|
||||
win_keyboard.o: device.h win/plat_keyboard.h win/resource.h win/win.h
|
||||
|
||||
win_language.o: ibm.h device.h ide.h win/plat_ui.h win/resource.h win/win.h win/win_language.h io.h mem.h rom.h device.h ide.h xtide.h
|
||||
|
||||
win_midi.o: ibm.h config.h sound/midi.h win/plat_midi.h win/resource.h
|
||||
|
||||
win_mouse.o: win/plat_mouse.h win/resource.h win/win.h
|
||||
|
||||
win_opendir.o: ibm.h win/plat_dir.h win/resource.h
|
||||
|
||||
win_serial.o: win/plat_thread.h win/plat_serial.h win/resource.h
|
||||
|
||||
win_settings.o: ibm.h mem.h cpu/cpu.h nvr.h device.h model.h cdrom.h disc.h fdd.h hdd.h ide.h scsi.h network/network.h sound/midi.h \
|
||||
sound/sound.h sound/snd_dbopl.h sound/snd_mpu401.h video/video.h video/vid_voodoo.h gameport.h mouse.h win/plat_midi.h \
|
||||
win/resource.h win/win.h win/win_language.h
|
||||
|
||||
win_status.o: ibm.h mem.h cpu/x86_ops.h cpu/codegen.h device.h win/resource.h win/win.h
|
||||
|
||||
win_video.o: video/video.h win/resource.h win/win_cgapal.h
|
||||
|
||||
|
||||
# End of Makefile.mingw.
|
||||
|
||||
@@ -28,6 +28,6 @@ EXTRAS =
|
||||
DEBUG = n
|
||||
OPTIM = n
|
||||
X64 = y
|
||||
|
||||
DEV_BRANCH = n
|
||||
|
||||
# End of Makefile.mingw64.
|
||||
|
||||
@@ -217,6 +217,7 @@ typedef struct {
|
||||
uint8_t eeprom[128]; /* for RTL8029AS */
|
||||
rom_t bios_rom;
|
||||
int card; /* PCI card slot */
|
||||
int has_bios;
|
||||
} nic_t;
|
||||
|
||||
|
||||
@@ -1426,19 +1427,23 @@ nic_update_bios(nic_t *dev)
|
||||
int reg_bios_enable;
|
||||
|
||||
reg_bios_enable = 1;
|
||||
|
||||
if (!dev->has_bios) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (PCI && dev->is_pci) {
|
||||
reg_bios_enable = dev->pci_bar[1].addr_regs[0] & 0x01;
|
||||
}
|
||||
|
||||
/* PCI BIOS stuff, just enable_disable. */
|
||||
if ((dev->bios_addr > 0) && reg_bios_enable) {
|
||||
mem_mapping_enable(&dev->bios_rom.mapping);
|
||||
if (reg_bios_enable) {
|
||||
mem_mapping_set_addr(&dev->bios_rom.mapping,
|
||||
dev->bios_addr, dev->bios_size);
|
||||
nelog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr);
|
||||
} else {
|
||||
nelog(1, "%s: BIOS disabled\n", dev->name);
|
||||
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||
dev->bios_addr = 0;
|
||||
if (dev->is_pci)
|
||||
dev->pci_bar[1].addr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1527,7 +1532,7 @@ nic_pci_read(int func, int addr, void *priv)
|
||||
ret = dev->pci_bar[1].addr_regs[0] & 0x01;
|
||||
break;
|
||||
case 0x31: /* PCI_ROMBAR 15:11 */
|
||||
ret = (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18;
|
||||
ret = (dev->pci_bar[1].addr_regs[1] & dev->bios_mask);
|
||||
break;
|
||||
case 0x32: /* PCI_ROMBAR 23:16 */
|
||||
ret = dev->pci_bar[1].addr_regs[2];
|
||||
@@ -1632,9 +1637,8 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv)
|
||||
case 0x33: /* PCI_ROMBAR */
|
||||
dev->pci_bar[1].addr_regs[addr & 3] = val;
|
||||
dev->pci_bar[1].addr_regs[1] &= dev->bios_mask;
|
||||
dev->pci_bar[1].addr &= 0xffffe000;
|
||||
dev->pci_bar[1].addr &= 0xffffe001;
|
||||
dev->bios_addr = dev->pci_bar[1].addr;
|
||||
dev->pci_bar[1].addr |= 0x1801;
|
||||
nic_update_bios(dev);
|
||||
return;
|
||||
|
||||
@@ -1917,10 +1921,19 @@ nic_init(int board)
|
||||
dev->base_irq = 10;
|
||||
} else {
|
||||
dev->base_address = device_get_config_hex16("base");
|
||||
dev->bios_addr = device_get_config_hex20("bios_addr");
|
||||
dev->base_irq = device_get_config_int("irq");
|
||||
}
|
||||
|
||||
dev->bios_addr = device_get_config_hex20("bios_addr");
|
||||
if (dev->bios_addr)
|
||||
{
|
||||
dev->has_bios = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev->has_bios = 0;
|
||||
}
|
||||
|
||||
/* See if we have a local MAC address configured. */
|
||||
mac = device_get_config_mac("mac", -1);
|
||||
|
||||
@@ -1962,11 +1975,13 @@ nic_init(int board)
|
||||
if (dev->bios_addr > 0) {
|
||||
dev->pci_bar[1].addr = 0x000F8000;
|
||||
dev->pci_bar[1].addr_regs[1] = dev->bios_mask;
|
||||
dev->pci_bar[1].addr |= 0x1801;
|
||||
} else {
|
||||
dev->pci_bar[1].addr = 0;
|
||||
dev->bios_size = 0;
|
||||
}
|
||||
|
||||
mem_mapping_disable(&dev->bios_rom.mapping);
|
||||
|
||||
/* Initialize the RTL8029 EEPROM. */
|
||||
memset(dev->eeprom, 0x00, sizeof(dev->eeprom));
|
||||
dev->eeprom[0x76] =
|
||||
@@ -2225,7 +2240,6 @@ static device_config_t ne2000_config[] =
|
||||
|
||||
static device_config_t rtl8029as_config[] =
|
||||
{
|
||||
#if 1
|
||||
/*
|
||||
* WTF.
|
||||
* Even though it is PCI, the user should still have control
|
||||
@@ -2252,7 +2266,6 @@ static device_config_t rtl8029as_config[] =
|
||||
}
|
||||
},
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"mac", "MAC Address", CONFIG_MAC, "", -1
|
||||
},
|
||||
|
||||
@@ -111,7 +111,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx)
|
||||
case NET_TYPE_PCAP:
|
||||
ret = network_pcap_setup(mac, rx, dev);
|
||||
if (ret < 0) {
|
||||
plat_msgbox_error(IDS_2219);
|
||||
plat_msgbox_error(IDS_2139);
|
||||
network_type = NET_TYPE_NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -253,9 +253,10 @@ int slirp_select_fill(int *pnfds,
|
||||
/*
|
||||
* See if we need a tcp_fasttimo
|
||||
*/
|
||||
if(so->so_tcpcb!=0x0){
|
||||
if(&so->so_tcpcb->t_flags!=0x0){ //This is to prevent a common lockup.
|
||||
if (time_fasttimo == 0 && so->so_tcpcb->t_flags & TF_DELACK)
|
||||
time_fasttimo = curtime; }/* Flag when we want a fasttimo */
|
||||
time_fasttimo = curtime; } } /* Flag when we want a fasttimo */
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
#include "../WIN/plat_midi.h"
|
||||
#include "../WIN/plat_ticks.h"
|
||||
#include "midi_system.h"
|
||||
#ifdef USE_FLUIDSYNTH
|
||||
# include "midi_fluidsynth.h"
|
||||
#endif
|
||||
#include "midi_mt32.h"
|
||||
#include "midi_system.h"
|
||||
|
||||
int midi_device_current = 0;
|
||||
static int midi_device_last = 0;
|
||||
@@ -24,9 +27,12 @@ typedef struct
|
||||
static MIDI_DEVICE devices[] =
|
||||
{
|
||||
{"None", "none", NULL},
|
||||
{SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device},
|
||||
#ifdef USE_FLUIDSYNTH
|
||||
{"FluidSynth", "fluidsynth", &fluidsynth_device},
|
||||
#endif
|
||||
{"Roland MT-32 Emulation", "mt32", &mt32_device},
|
||||
{"Roland CM-32L Emulation", "cm32l", &cm32l_device},
|
||||
{SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device},
|
||||
{"", "", NULL}
|
||||
};
|
||||
|
||||
|
||||
546
src/SOUND/midi_fluidsynth.c
Normal file
546
src/SOUND/midi_fluidsynth.c
Normal file
@@ -0,0 +1,546 @@
|
||||
/* some code borrowed from scummvm */
|
||||
#ifdef USE_FLUIDSYNTH
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fluidsynth.h>
|
||||
#include "../config.h"
|
||||
#include "../WIN/plat_dynld.h"
|
||||
#include "../WIN/plat_thread.h"
|
||||
#include "../WIN/plat_ui.h"
|
||||
#include "../device.h"
|
||||
#include "midi_fluidsynth.h"
|
||||
#include "midi.h"
|
||||
#include "sound.h"
|
||||
|
||||
#define RENDER_RATE 100
|
||||
#define BUFFER_SEGMENTS 10
|
||||
|
||||
extern void givealbuffer_midi(void *buf, uint32_t size);
|
||||
extern void pclog(const char *format, ...);
|
||||
extern void al_set_midi(int freq, int buf_size);
|
||||
extern int soundon;
|
||||
|
||||
static void *fluidsynth_handle; /* handle to FluidSynth DLL */
|
||||
|
||||
/* Pointers to the real functions. */
|
||||
static fluid_settings_t*(*f_new_fluid_settings)(void);
|
||||
static void (*f_delete_fluid_settings)(fluid_settings_t *settings);
|
||||
static int (*f_fluid_settings_setnum)(fluid_settings_t *settings, const char *name, double val);
|
||||
static int (*f_fluid_settings_getnum)(fluid_settings_t *settings, const char *name, double *val);
|
||||
static fluid_synth_t * (*f_new_fluid_synth)(fluid_settings_t *settings);
|
||||
static int (*f_delete_fluid_synth)(fluid_synth_t *synth);
|
||||
static int (*f_fluid_synth_noteon)(fluid_synth_t *synth, int chan, int key, int vel);
|
||||
static int (*f_fluid_synth_noteoff)(fluid_synth_t *synth, int chan, int key);
|
||||
static int (*f_fluid_synth_cc)(fluid_synth_t *synth, int chan, int ctrl, int val);
|
||||
static int (*f_fluid_synth_sysex)(fluid_synth_t *synth, const char *data, int len, char *response, int *response_len, int *handled, int dryrun);
|
||||
static int (*f_fluid_synth_pitch_bend)(fluid_synth_t *synth, int chan, int val);
|
||||
static int (*f_fluid_synth_program_change)(fluid_synth_t *synth, int chan, int program);
|
||||
static int (*f_fluid_synth_sfload)(fluid_synth_t *synth, const char *filename, int reset_presets);
|
||||
static int (*f_fluid_synth_sfunload)(fluid_synth_t *synth, unsigned int id, int reset_presets);
|
||||
static int (*f_fluid_synth_set_interp_method)(fluid_synth_t *synth, int chan, int interp_method);
|
||||
static void (*f_fluid_synth_set_reverb)(fluid_synth_t *synth, double roomsize, double damping, double width, double level);
|
||||
static void (*f_fluid_synth_set_reverb_on)(fluid_synth_t *synth, int on);
|
||||
static void (*f_fluid_synth_set_chorus)(fluid_synth_t *synth, int nr, double level, double speed, double depth_ms, int type);
|
||||
static void (*f_fluid_synth_set_chorus_on)(fluid_synth_t *synth, int on);
|
||||
static int (*f_fluid_synth_write_s16)(fluid_synth_t *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr);
|
||||
static int (*f_fluid_synth_write_float)(fluid_synth_t *synth, int len, void *lout, int loff, int lincr, void *rout, int roff, int rincr);
|
||||
static char* (*f_fluid_version_str)(void);
|
||||
static dllimp_t fluidsynth_imports[] = {
|
||||
{ "new_fluid_settings", &f_new_fluid_settings },
|
||||
{ "delete_fluid_settings", &f_delete_fluid_settings },
|
||||
{ "fluid_settings_setnum", &f_fluid_settings_setnum },
|
||||
{ "fluid_settings_getnum", &f_fluid_settings_getnum },
|
||||
{ "new_fluid_synth", &f_new_fluid_synth },
|
||||
{ "delete_fluid_synth", &f_delete_fluid_synth },
|
||||
{ "fluid_synth_noteon", &f_fluid_synth_noteon },
|
||||
{ "fluid_synth_noteoff", &f_fluid_synth_noteoff },
|
||||
{ "fluid_synth_cc", &f_fluid_synth_cc },
|
||||
{ "fluid_synth_sysex", &f_fluid_synth_sysex },
|
||||
{ "fluid_synth_pitch_bend", &f_fluid_synth_pitch_bend },
|
||||
{ "fluid_synth_program_change", &f_fluid_synth_program_change },
|
||||
{ "fluid_synth_sfload", &f_fluid_synth_sfload },
|
||||
{ "fluid_synth_sfunload", &f_fluid_synth_sfunload },
|
||||
{ "fluid_synth_set_interp_method", &f_fluid_synth_set_interp_method },
|
||||
{ "fluid_synth_set_reverb", &f_fluid_synth_set_reverb },
|
||||
{ "fluid_synth_set_reverb_on", &f_fluid_synth_set_reverb_on },
|
||||
{ "fluid_synth_set_chorus", &f_fluid_synth_set_chorus },
|
||||
{ "fluid_synth_set_chorus_on", &f_fluid_synth_set_chorus_on },
|
||||
{ "fluid_synth_write_s16", &f_fluid_synth_write_s16 },
|
||||
{ "fluid_synth_write_float", &f_fluid_synth_write_float },
|
||||
{ "fluid_version_str", &f_fluid_version_str },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
||||
typedef struct fluidsynth
|
||||
{
|
||||
fluid_settings_t* settings;
|
||||
fluid_synth_t* synth;
|
||||
int samplerate;
|
||||
int sound_font;
|
||||
|
||||
thread_t* thread_h;
|
||||
event_t* event;
|
||||
int buf_size;
|
||||
float* buffer;
|
||||
int16_t* buffer_int16;
|
||||
int midi_pos;
|
||||
|
||||
} fluidsynth_t;
|
||||
|
||||
fluidsynth_t fsdev;
|
||||
|
||||
int fluidsynth_available(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void fluidsynth_poll(void)
|
||||
{
|
||||
fluidsynth_t* data = &fsdev;
|
||||
data->midi_pos++;
|
||||
if (data->midi_pos == 48000/RENDER_RATE)
|
||||
{
|
||||
data->midi_pos = 0;
|
||||
thread_set_event(data->event);
|
||||
}
|
||||
}
|
||||
|
||||
static void fluidsynth_thread(void *param)
|
||||
{
|
||||
fluidsynth_t* data = (fluidsynth_t*)param;
|
||||
int buf_pos = 0;
|
||||
int buf_size = data->buf_size / BUFFER_SEGMENTS;
|
||||
while (1)
|
||||
{
|
||||
thread_wait_event(data->event, -1);
|
||||
if (sound_is_float)
|
||||
{
|
||||
float *buf = (float*)((uint8_t*)data->buffer + buf_pos);
|
||||
memset(buf, 0, buf_size);
|
||||
if (data->synth)
|
||||
f_fluid_synth_write_float(data->synth, buf_size/(2 * sizeof(float)), buf, 0, 2, buf, 1, 2);
|
||||
buf_pos += buf_size;
|
||||
if (buf_pos >= data->buf_size)
|
||||
{
|
||||
if (soundon)
|
||||
givealbuffer_midi(data->buffer, data->buf_size / sizeof(float));
|
||||
buf_pos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int16_t *buf = (int16_t*)((uint8_t*)data->buffer_int16 + buf_pos);
|
||||
memset(buf, 0, buf_size);
|
||||
if (data->synth)
|
||||
f_fluid_synth_write_s16(data->synth, buf_size/(2 * sizeof(int16_t)), buf, 0, 2, buf, 1, 2);
|
||||
buf_pos += buf_size;
|
||||
if (buf_pos >= data->buf_size)
|
||||
{
|
||||
if (soundon)
|
||||
givealbuffer_midi(data->buffer_int16, data->buf_size / sizeof(int16_t));
|
||||
buf_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (sound_is_float)
|
||||
{
|
||||
memset(data->buffer, 0, data->buf_size * sizeof(float));
|
||||
if (data->synth)
|
||||
f_fluid_synth_write_float(data->synth, data->buf_size/2, data->buffer, 0, 2, data->buffer, 1, 2);
|
||||
if (soundon)
|
||||
givealbuffer_midi(data->buffer, data->buf_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(data->buffer, 0, data->buf_size * sizeof(int16_t));
|
||||
if (data->synth)
|
||||
f_fluid_synth_write_s16(data->synth, data->buf_size/2, data->buffer_int16, 0, 2, data->buffer_int16, 1, 2);
|
||||
if (soundon)
|
||||
givealbuffer_midi(data->buffer_int16, data->buf_size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void fluidsynth_msg(uint8_t *msg)
|
||||
{
|
||||
fluidsynth_t* data = &fsdev;
|
||||
|
||||
uint32_t val = *((uint32_t*)msg);
|
||||
|
||||
uint32_t param2 = (uint8_t) ((val >> 16) & 0xFF);
|
||||
uint32_t param1 = (uint8_t) ((val >> 8) & 0xFF);
|
||||
uint8_t cmd = (uint8_t) (val & 0xF0);
|
||||
uint8_t chan = (uint8_t) (val & 0x0F);
|
||||
|
||||
switch (cmd) {
|
||||
case 0x80: /* Note Off */
|
||||
f_fluid_synth_noteoff(data->synth, chan, param1);
|
||||
break;
|
||||
case 0x90: /* Note On */
|
||||
f_fluid_synth_noteon(data->synth, chan, param1, param2);
|
||||
break;
|
||||
case 0xA0: /* Aftertouch */
|
||||
break;
|
||||
case 0xB0: /* Control Change */
|
||||
f_fluid_synth_cc(data->synth, chan, param1, param2);
|
||||
break;
|
||||
case 0xC0: /* Program Change */
|
||||
f_fluid_synth_program_change(data->synth, chan, param1);
|
||||
break;
|
||||
case 0xD0: /* Channel Pressure */
|
||||
break;
|
||||
case 0xE0: /* Pitch Bend */
|
||||
f_fluid_synth_pitch_bend(data->synth, chan, (param2 << 7) | param1);
|
||||
break;
|
||||
case 0xF0: /* SysEx */
|
||||
break;
|
||||
default:
|
||||
pclog("fluidsynth: unknown send() command 0x%02X", cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void fluidsynth_sysex(uint8_t* data, unsigned int len)
|
||||
{
|
||||
fluidsynth_t* d = &fsdev;
|
||||
|
||||
f_fluid_synth_sysex(d->synth, (const char *) data, len, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void* fluidsynth_init(void)
|
||||
{
|
||||
fluidsynth_t* data = &fsdev;
|
||||
memset(data, 0, sizeof(fluidsynth_t));
|
||||
|
||||
/* Try loading the DLL. */
|
||||
fluidsynth_handle = dynld_module("libfluidsynth.dll", fluidsynth_imports);
|
||||
if (fluidsynth_handle == NULL)
|
||||
{
|
||||
plat_msgbox_error(IDS_2171);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data->settings = f_new_fluid_settings();
|
||||
|
||||
f_fluid_settings_setnum(data->settings, "synth.sample-rate", 44100);
|
||||
f_fluid_settings_setnum(data->settings, "synth.gain", device_get_config_int("output_gain")/100.0f);
|
||||
|
||||
data->synth = f_new_fluid_synth(data->settings);
|
||||
|
||||
char* sound_font = device_get_config_string("sound_font");
|
||||
data->sound_font = f_fluid_synth_sfload(data->synth, sound_font, 1);
|
||||
|
||||
if (device_get_config_int("chorus"))
|
||||
{
|
||||
f_fluid_synth_set_chorus_on(data->synth, 1);
|
||||
|
||||
int chorus_voices = device_get_config_int("chorus_voices");
|
||||
double chorus_level = device_get_config_int("chorus_level") / 100.0;
|
||||
double chorus_speed = device_get_config_int("chorus_speed") / 100.0;
|
||||
double chorus_depth = device_get_config_int("chorus_depth") / 10.0;
|
||||
|
||||
int chorus_waveform = FLUID_CHORUS_MOD_SINE;
|
||||
if (device_get_config_int("chorus_waveform") == 0)
|
||||
chorus_waveform = FLUID_CHORUS_MOD_SINE;
|
||||
else
|
||||
chorus_waveform = FLUID_CHORUS_MOD_TRIANGLE;
|
||||
|
||||
f_fluid_synth_set_chorus(data->synth, chorus_voices, chorus_level, chorus_speed, chorus_depth, chorus_waveform);
|
||||
}
|
||||
else
|
||||
f_fluid_synth_set_chorus_on(data->synth, 0);
|
||||
|
||||
if (device_get_config_int("reverb"))
|
||||
{
|
||||
f_fluid_synth_set_reverb_on(data->synth, 1);
|
||||
|
||||
double reverb_room_size = device_get_config_int("reverb_room_size") / 100.0;
|
||||
double reverb_damping = device_get_config_int("reverb_damping") / 100.0;
|
||||
int reverb_width = device_get_config_int("reverb_width");
|
||||
double reverb_level = device_get_config_int("reverb_level") / 100.0;
|
||||
|
||||
f_fluid_synth_set_reverb(data->synth, reverb_room_size, reverb_damping, reverb_width, reverb_level);
|
||||
}
|
||||
else
|
||||
f_fluid_synth_set_reverb_on(data->synth, 0);
|
||||
|
||||
int interpolation = device_get_config_int("interpolation");
|
||||
int fs_interpolation = FLUID_INTERP_4THORDER;
|
||||
|
||||
if (interpolation == 0)
|
||||
fs_interpolation = FLUID_INTERP_NONE;
|
||||
else if (interpolation == 1)
|
||||
fs_interpolation = FLUID_INTERP_LINEAR;
|
||||
else if (interpolation == 2)
|
||||
fs_interpolation = FLUID_INTERP_4THORDER;
|
||||
else if (interpolation == 3)
|
||||
fs_interpolation = FLUID_INTERP_7THORDER;
|
||||
|
||||
f_fluid_synth_set_interp_method(data->synth, -1, fs_interpolation);
|
||||
|
||||
double samplerate;
|
||||
f_fluid_settings_getnum(data->settings, "synth.sample-rate", &samplerate);
|
||||
data->samplerate = (int)samplerate;
|
||||
if (sound_is_float)
|
||||
{
|
||||
data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(float)*BUFFER_SEGMENTS;
|
||||
data->buffer = malloc(data->buf_size);
|
||||
data->buffer_int16 = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
data->buf_size = (data->samplerate/RENDER_RATE)*2*sizeof(int16_t)*BUFFER_SEGMENTS;
|
||||
data->buffer = NULL;
|
||||
data->buffer_int16 = malloc(data->buf_size);
|
||||
}
|
||||
data->event = thread_create_event();
|
||||
data->thread_h = thread_create(fluidsynth_thread, data);
|
||||
|
||||
al_set_midi(data->samplerate, data->buf_size);
|
||||
|
||||
pclog("fluidsynth (%s) initialized, samplerate %d, buf_size %d\n", f_fluid_version_str(), data->samplerate, data->buf_size);
|
||||
|
||||
midi_device_t* dev = malloc(sizeof(midi_device_t));
|
||||
memset(dev, 0, sizeof(midi_device_t));
|
||||
|
||||
dev->play_msg = fluidsynth_msg;
|
||||
dev->play_sysex = fluidsynth_sysex;
|
||||
dev->poll = fluidsynth_poll;
|
||||
|
||||
midi_init(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
void fluidsynth_close(void* p)
|
||||
{
|
||||
if (!p) return;
|
||||
|
||||
fluidsynth_t* data = &fsdev;
|
||||
|
||||
if (data->sound_font != -1)
|
||||
f_fluid_synth_sfunload(data->synth, data->sound_font, 1);
|
||||
f_delete_fluid_synth(data->synth);
|
||||
f_delete_fluid_settings(data->settings);
|
||||
|
||||
midi_close();
|
||||
|
||||
if (data->buffer)
|
||||
{
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
}
|
||||
|
||||
if (data->buffer_int16)
|
||||
{
|
||||
free(data->buffer_int16);
|
||||
data->buffer_int16 = NULL;
|
||||
}
|
||||
|
||||
/* Unload the DLL if possible. */
|
||||
if (fluidsynth_handle != NULL)
|
||||
{
|
||||
dynld_close(fluidsynth_handle);
|
||||
fluidsynth_handle = NULL;
|
||||
}
|
||||
|
||||
pclog("fluidsynth closed\n");
|
||||
}
|
||||
|
||||
static device_config_t fluidsynth_config[] =
|
||||
{
|
||||
{
|
||||
.name = "sound_font",
|
||||
.description = "Sound Font",
|
||||
.type = CONFIG_FILE,
|
||||
.default_string = "",
|
||||
.file_filter =
|
||||
{
|
||||
{
|
||||
.description = "SF2 Sound Fonts",
|
||||
.extensions =
|
||||
{
|
||||
"sf2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "output_gain",
|
||||
.description = "Output Gain",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
.default_int = 100
|
||||
},
|
||||
{
|
||||
.name = "chorus",
|
||||
.description = "Chorus",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "chorus_voices",
|
||||
.description = "Chorus Voices",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 99
|
||||
},
|
||||
.default_int = 3
|
||||
},
|
||||
{
|
||||
.name = "chorus_level",
|
||||
.description = "Chorus Level",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
.default_int = 100
|
||||
},
|
||||
{
|
||||
.name = "chorus_speed",
|
||||
.description = "Chorus Speed",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 30,
|
||||
.max = 500
|
||||
},
|
||||
.default_int = 30
|
||||
},
|
||||
{
|
||||
.name = "chorus_depth",
|
||||
.description = "Chorus Depth",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 210
|
||||
},
|
||||
.default_int = 80
|
||||
},
|
||||
{
|
||||
.name = "chorus_waveform",
|
||||
.description = "Chorus Waveform",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "Sine",
|
||||
.value = 0
|
||||
},
|
||||
{
|
||||
.description = "Triangle",
|
||||
.value = 1
|
||||
}
|
||||
},
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "reverb",
|
||||
.description = "Reverb",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "reverb_room_size",
|
||||
.description = "Reverb Room Size",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 120
|
||||
},
|
||||
.default_int = 20
|
||||
},
|
||||
{
|
||||
.name = "reverb_damping",
|
||||
.description = "Reverb Damping",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "reverb_width",
|
||||
.description = "Reverb Width",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
.default_int = 1
|
||||
},
|
||||
{
|
||||
.name = "reverb_level",
|
||||
.description = "Reverb Level",
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
.default_int = 90
|
||||
},
|
||||
{
|
||||
.name = "interpolation",
|
||||
.description = "Interpolation Method",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "None",
|
||||
.value = 0
|
||||
},
|
||||
{
|
||||
.description = "Linear",
|
||||
.value = 1
|
||||
},
|
||||
{
|
||||
.description = "4th Order",
|
||||
.value = 2
|
||||
},
|
||||
{
|
||||
.description = "7th Order",
|
||||
.value = 3
|
||||
}
|
||||
},
|
||||
.default_int = 2
|
||||
},
|
||||
{
|
||||
.type = -1
|
||||
}
|
||||
};
|
||||
|
||||
device_t fluidsynth_device =
|
||||
{
|
||||
"FluidSynth",
|
||||
0,
|
||||
fluidsynth_init,
|
||||
fluidsynth_close,
|
||||
fluidsynth_available,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
fluidsynth_config
|
||||
};
|
||||
|
||||
|
||||
#endif /*USE_FLUIDSYNTH*/
|
||||
1
src/SOUND/midi_fluidsynth.h
Normal file
1
src/SOUND/midi_fluidsynth.h
Normal file
@@ -0,0 +1 @@
|
||||
extern device_t fluidsynth_device;
|
||||
@@ -83,7 +83,8 @@ int cm32l_available()
|
||||
static thread_t *thread_h = NULL;
|
||||
static event_t *event = NULL;
|
||||
|
||||
#define RENDER_RATE 30
|
||||
#define RENDER_RATE 100
|
||||
#define BUFFER_SEGMENTS 10
|
||||
|
||||
static uint32_t samplerate = 44100;
|
||||
static int buf_size = 0;
|
||||
@@ -115,22 +116,37 @@ extern int soundon;
|
||||
|
||||
static void mt32_thread(void *param)
|
||||
{
|
||||
int buf_pos = 0;
|
||||
int bsize = buf_size / BUFFER_SEGMENTS;
|
||||
while (1)
|
||||
{
|
||||
thread_wait_event(event, -1);
|
||||
|
||||
if (sound_is_float)
|
||||
{
|
||||
memset(buffer, 0, buf_size * sizeof(float));
|
||||
mt32_stream(buffer, (samplerate/RENDER_RATE));
|
||||
if (soundon)
|
||||
givealbuffer_midi(buffer, buf_size);
|
||||
float *buf = (float *) ((uint8_t*)buffer + buf_pos);
|
||||
memset(buf, 0, bsize);
|
||||
mt32_stream(buf, bsize / (2 * sizeof(float)));
|
||||
buf_pos += bsize;
|
||||
if (buf_pos >= buf_size)
|
||||
{
|
||||
if (soundon)
|
||||
givealbuffer_midi(buffer, buf_size / sizeof(float));
|
||||
buf_pos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(buffer_int16, 0, buf_size * sizeof(int16_t));
|
||||
mt32_stream_int16(buffer_int16, (samplerate/RENDER_RATE));
|
||||
if (soundon)
|
||||
givealbuffer_midi(buffer_int16, buf_size);
|
||||
int16_t *buf = (int16_t *) ((uint8_t*)buffer_int16 + buf_pos);
|
||||
memset(buf, 0, bsize);
|
||||
mt32_stream_int16(buf, bsize / (2 * sizeof(int16_t)));
|
||||
buf_pos += bsize;
|
||||
if (buf_pos >= buf_size)
|
||||
{
|
||||
if (soundon)
|
||||
givealbuffer_midi(buffer_int16, buf_size / sizeof(int16_t));
|
||||
buf_pos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,22 +178,25 @@ void* mt32emu_init(wchar_t *control_rom, wchar_t *pcm_rom)
|
||||
event = thread_create_event();
|
||||
thread_h = thread_create(mt32_thread, 0);
|
||||
samplerate = mt32emu_get_actual_stereo_output_samplerate(context);
|
||||
buf_size = samplerate/RENDER_RATE*2;
|
||||
/* buf_size = samplerate/RENDER_RATE*2; */
|
||||
if (sound_is_float)
|
||||
{
|
||||
buffer = malloc(buf_size * sizeof(float));
|
||||
buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(float);
|
||||
buffer = malloc(buf_size);
|
||||
buffer_int16 = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf_size = (samplerate/RENDER_RATE)*2*BUFFER_SEGMENTS*sizeof(int16_t);
|
||||
buffer = NULL;
|
||||
buffer_int16 = malloc(buf_size * sizeof(int16_t));
|
||||
buffer_int16 = malloc(buf_size);
|
||||
}
|
||||
|
||||
mt32emu_set_output_gain(context, device_get_config_int("output_gain")/100.0f);
|
||||
mt32emu_set_reverb_enabled(context, device_get_config_int("reverb"));
|
||||
mt32emu_set_reverb_output_gain(context, device_get_config_int("reverb_output_gain")/100.0f);
|
||||
mt32emu_set_reversed_stereo_enabled(context, device_get_config_int("reversed_stereo"));
|
||||
mt32emu_set_nice_amp_ramp_enabled(context, device_get_config_int("nice_ramp"));
|
||||
|
||||
pclog("mt32 output gain: %f\n", mt32emu_get_output_gain(context));
|
||||
pclog("mt32 reverb output gain: %f\n", mt32emu_get_reverb_output_gain(context));
|
||||
@@ -248,32 +267,11 @@ static device_config_t mt32_config[] =
|
||||
{
|
||||
.name = "output_gain",
|
||||
.description = "Output Gain",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
{
|
||||
.description = "100%",
|
||||
.value = 100
|
||||
},
|
||||
{
|
||||
.description = "75%",
|
||||
.value = 75
|
||||
},
|
||||
{
|
||||
.description = "50%",
|
||||
.value = 50
|
||||
},
|
||||
{
|
||||
.description = "25%",
|
||||
.value = 25
|
||||
},
|
||||
{
|
||||
.description = "0%",
|
||||
.value = 0
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
.default_int = 100
|
||||
},
|
||||
@@ -286,32 +284,11 @@ static device_config_t mt32_config[] =
|
||||
{
|
||||
.name = "reverb_output_gain",
|
||||
.description = "Reverb Output Gain",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
.type = CONFIG_SPINNER,
|
||||
.spinner =
|
||||
{
|
||||
{
|
||||
.description = "100%",
|
||||
.value = 100
|
||||
},
|
||||
{
|
||||
.description = "75%",
|
||||
.value = 75
|
||||
},
|
||||
{
|
||||
.description = "50%",
|
||||
.value = 50
|
||||
},
|
||||
{
|
||||
.description = "25%",
|
||||
.value = 25
|
||||
},
|
||||
{
|
||||
.description = "0%",
|
||||
.value = 0
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
.min = 0,
|
||||
.max = 100
|
||||
},
|
||||
.default_int = 100
|
||||
},
|
||||
@@ -321,6 +298,12 @@ static device_config_t mt32_config[] =
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 0
|
||||
},
|
||||
{
|
||||
.name = "nice_ramp",
|
||||
.description = "Nice ramp",
|
||||
.type = CONFIG_BINARY,
|
||||
.default_int = 1
|
||||
},
|
||||
{
|
||||
.type = -1
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class Analog {
|
||||
public:
|
||||
static Analog *createAnalog(const AnalogOutputMode mode, const bool oldMT32AnalogLPF, const RendererType rendererType);
|
||||
|
||||
virtual ~Analog() {};
|
||||
virtual ~Analog() {}
|
||||
virtual unsigned int getOutputSampleRate() const = 0;
|
||||
virtual Bit32u getDACStreamsLength(const Bit32u outputLength) const = 0;
|
||||
virtual void setSynthOutputGain(const float synthGain) = 0;
|
||||
|
||||
@@ -29,7 +29,7 @@ class BReverbModel {
|
||||
public:
|
||||
static BReverbModel *createBReverbModel(const ReverbMode mode, const bool mt32CompatibleModel, const RendererType rendererType);
|
||||
|
||||
virtual ~BReverbModel() {};
|
||||
virtual ~BReverbModel() {}
|
||||
virtual bool isOpen() const = 0;
|
||||
// After construction or a close(), open() must be called at least once before any other call (with the exception of close()).
|
||||
virtual void open() = 0;
|
||||
|
||||
@@ -85,7 +85,6 @@ enum MT32EMU_DAC_INPUT_MODE_NAME {
|
||||
* Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range)
|
||||
* Much less likely to overdrive than any other mode.
|
||||
* Half the volume of any of the other modes.
|
||||
* Output gain is ignored for both LA32 and reverb output.
|
||||
* Perfect for developers while debugging :)
|
||||
*/
|
||||
MT32EMU_DAC_INPUT_MODE(PURE),
|
||||
|
||||
@@ -165,12 +165,6 @@ float LA32FloatWaveGenerator::generateNextSample(const Bit32u ampVal, const Bit1
|
||||
hLen = 0.0f;
|
||||
}
|
||||
|
||||
// Ignore pulsewidths too high for given freq and cutoff
|
||||
float lLen = waveLen - hLen - 2 * cosineLen;
|
||||
if (lLen < 0.0f) {
|
||||
lLen = 0.0f;
|
||||
}
|
||||
|
||||
// Correct resAmp for cutoff in range 50..66
|
||||
if ((cutoffVal >= MIDDLE_CUTOFF_VALUE) && (cutoffVal < RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE)) {
|
||||
resAmp *= sin(FLOAT_PI * (cutoffVal - MIDDLE_CUTOFF_VALUE) / 32.0f);
|
||||
@@ -328,8 +322,13 @@ static inline float produceDistortedSample(float sample) {
|
||||
}
|
||||
|
||||
float LA32FloatPartialPair::nextOutSample() {
|
||||
// Note, LA32FloatWaveGenerator produces each sample normalised in terms of a single playing partial,
|
||||
// so the unity sample corresponds to the internal LA32 logarithmic fixed-point unity sample.
|
||||
// However, each logarithmic sample is then unlogged to a 14-bit signed integer value, i.e. the max absolute value is 8192.
|
||||
// Thus, considering that samples are further mapped to a 16-bit signed integer,
|
||||
// we apply a conversion factor 0.25 to produce properly normalised float samples.
|
||||
if (!ringModulated) {
|
||||
return masterOutputSample + slaveOutputSample;
|
||||
return 0.25f * (masterOutputSample + slaveOutputSample);
|
||||
}
|
||||
/*
|
||||
* SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion.
|
||||
@@ -340,7 +339,7 @@ float LA32FloatPartialPair::nextOutSample() {
|
||||
* Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning.
|
||||
*/
|
||||
float ringModulatedSample = produceDistortedSample(masterOutputSample) * produceDistortedSample(slaveOutputSample);
|
||||
return mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample;
|
||||
return 0.25f * (mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample);
|
||||
}
|
||||
|
||||
void LA32FloatPartialPair::deactivate(const PairType useMaster) {
|
||||
|
||||
@@ -56,8 +56,8 @@ We haven't fully explored:
|
||||
namespace MT32Emu {
|
||||
|
||||
// SEMI-CONFIRMED from sample analysis.
|
||||
const int TARGET_MULT = 0x40000;
|
||||
const unsigned int MAX_CURRENT = 0xFF * TARGET_MULT;
|
||||
const unsigned int TARGET_SHIFTS = 18;
|
||||
const unsigned int MAX_CURRENT = 0xFF << TARGET_SHIFTS;
|
||||
|
||||
// We simulate the delay in handling "target was reached" interrupts by waiting
|
||||
// this many samples before setting interruptRaised.
|
||||
@@ -96,7 +96,7 @@ void LA32Ramp::startRamp(Bit8u target, Bit8u increment) {
|
||||
largeIncrement++;
|
||||
}
|
||||
|
||||
largeTarget = target * TARGET_MULT;
|
||||
largeTarget = target << TARGET_SHIFTS;
|
||||
interruptCountdown = 0;
|
||||
interruptRaised = false;
|
||||
}
|
||||
@@ -152,4 +152,13 @@ void LA32Ramp::reset() {
|
||||
interruptRaised = false;
|
||||
}
|
||||
|
||||
// This is actually beyond the LA32 ramp interface.
|
||||
// Instead of polling the current value, MCU receives an interrupt when a ramp completes.
|
||||
// However, this is a simple way to work around the specific behaviour of TVA
|
||||
// when in sustain phase which one normally wants to avoid.
|
||||
// See TVA::recalcSustain() for details.
|
||||
bool LA32Ramp::isBelowCurrent(Bit8u target) const {
|
||||
return Bit32u(target << TARGET_SHIFTS) < current;
|
||||
}
|
||||
|
||||
} // namespace MT32Emu
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
Bit32u nextValue();
|
||||
bool checkInterrupt();
|
||||
void reset();
|
||||
bool isBelowCurrent(Bit8u target) const;
|
||||
};
|
||||
|
||||
} // namespace MT32Emu
|
||||
|
||||
@@ -378,22 +378,16 @@ Bit16s LA32IntPartialPair::unlogAndMixWGOutput(const LA32WaveGenerator &wg) {
|
||||
return firstSample + secondSample;
|
||||
}
|
||||
|
||||
static inline Bit16s produceDistortedSample(Bit16s sample) {
|
||||
return ((sample & 0x2000) == 0) ? Bit16s(sample & 0x1fff) : Bit16s(sample | ~0x1fff);
|
||||
}
|
||||
|
||||
Bit16s LA32IntPartialPair::nextOutSample() {
|
||||
if (!ringModulated) {
|
||||
return unlogAndMixWGOutput(master) + unlogAndMixWGOutput(slave);
|
||||
}
|
||||
|
||||
/*
|
||||
* SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion.
|
||||
* LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191.
|
||||
* This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case.
|
||||
* As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space,
|
||||
* it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication.
|
||||
* Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning.
|
||||
*/
|
||||
Bit16s nonOverdrivenMasterSample = unlogAndMixWGOutput(master); // Store master partial sample for further mixing
|
||||
Bit16s masterSample = nonOverdrivenMasterSample << 2;
|
||||
masterSample >>= 2;
|
||||
Bit16s masterSample = unlogAndMixWGOutput(master); // Store master partial sample for further mixing
|
||||
|
||||
/* SEMI-CONFIRMED from sample analysis:
|
||||
* We observe that for partial structures with ring modulation the interpolation is not applied to the slave PCM partial.
|
||||
@@ -401,10 +395,17 @@ Bit16s LA32IntPartialPair::nextOutSample() {
|
||||
* is borrowed by the ring modulation circuit (or the LA32 chip has a similar lack of resources assigned to each partial pair).
|
||||
*/
|
||||
Bit16s slaveSample = slave.isPCMWave() ? LA32Utilites::unlog(slave.getOutputLogSample(true)) : unlogAndMixWGOutput(slave);
|
||||
slaveSample <<= 2;
|
||||
slaveSample >>= 2;
|
||||
Bit16s ringModulatedSample = Bit16s((Bit32s(masterSample) * Bit32s(slaveSample)) >> 13);
|
||||
return mixed ? nonOverdrivenMasterSample + ringModulatedSample : ringModulatedSample;
|
||||
|
||||
/* SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion.
|
||||
* LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191.
|
||||
* This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case.
|
||||
* As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space,
|
||||
* it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication.
|
||||
* Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning.
|
||||
*/
|
||||
Bit16s ringModulatedSample = Bit16s((Bit32s(produceDistortedSample(masterSample)) * Bit32s(produceDistortedSample(slaveSample))) >> 13);
|
||||
|
||||
return mixed ? masterSample + ringModulatedSample : ringModulatedSample;
|
||||
}
|
||||
|
||||
void LA32IntPartialPair::deactivate(const PairType useMaster) {
|
||||
|
||||
@@ -119,7 +119,7 @@ void MidiStreamParserImpl::parseStream(const Bit8u *stream, Bit32u length) {
|
||||
|
||||
void MidiStreamParserImpl::processShortMessage(const Bit32u message) {
|
||||
// Adds running status to the MIDI message if it doesn't contain one
|
||||
Bit8u status = Bit8u(message);
|
||||
Bit8u status = Bit8u(message & 0xFF);
|
||||
if (0xF8 <= status) {
|
||||
midiReceiver.handleSystemRealtimeMessage(status);
|
||||
} else if (processStatusByte(status)) {
|
||||
|
||||
@@ -340,10 +340,13 @@ void RhythmPart::setPan(unsigned int midiPan) {
|
||||
void Part::setPan(unsigned int midiPan) {
|
||||
// NOTE: Panning is inverted compared to GM.
|
||||
|
||||
// CM-32L: Divide by 8.5
|
||||
patchTemp->panpot = Bit8u((midiPan << 3) / 68);
|
||||
// FIXME: MT-32: Divide by 9
|
||||
//patchTemp->panpot = Bit8u(midiPan / 9);
|
||||
if (synth->controlROMFeatures->quirkPanMult) {
|
||||
// MT-32: Divide by 9
|
||||
patchTemp->panpot = Bit8u(midiPan / 9);
|
||||
} else {
|
||||
// CM-32L: Divide by 8.5
|
||||
patchTemp->panpot = Bit8u((midiPan << 3) / 68);
|
||||
}
|
||||
|
||||
//synth->printDebug("%s (%s): Set pan to %d", name, currentInstr, panpot);
|
||||
}
|
||||
@@ -352,6 +355,10 @@ void Part::setPan(unsigned int midiPan) {
|
||||
* Applies key shift to a MIDI key and converts it into an internal key value in the range 12-108.
|
||||
*/
|
||||
unsigned int Part::midiKeyToKey(unsigned int midiKey) {
|
||||
if (synth->controlROMFeatures->quirkKeyShift) {
|
||||
// NOTE: On MT-32 GEN0, key isn't adjusted, and keyShift is applied further in TVP, unlike newer units:
|
||||
return midiKey;
|
||||
}
|
||||
int key = midiKey + patchTemp->patch.keyShift;
|
||||
if (key < 36) {
|
||||
// After keyShift is applied, key < 36, so move up by octaves
|
||||
|
||||
@@ -272,6 +272,10 @@ bool Partial::isRingModulatingSlave() const {
|
||||
return pair != NULL && structurePosition == 1 && (mixType == 1 || mixType == 2);
|
||||
}
|
||||
|
||||
bool Partial::isRingModulatingNoMix() const {
|
||||
return pair != NULL && ((structurePosition == 1 && mixType == 1) || mixType == 2);
|
||||
}
|
||||
|
||||
bool Partial::isPCM() const {
|
||||
return pcmWave != NULL;
|
||||
}
|
||||
@@ -368,7 +372,7 @@ bool Partial::doProduceOutput(Sample *leftBuf, Sample *rightBuf, Bit32u length,
|
||||
|
||||
bool Partial::produceOutput(IntSample *leftBuf, IntSample *rightBuf, Bit32u length) {
|
||||
if (floatMode) {
|
||||
synth->printDebug("Partial: Invalid call to produceOutput()!\n", synth->getSelectedRendererType());
|
||||
synth->printDebug("Partial: Invalid call to produceOutput()! Renderer = %d\n", synth->getSelectedRendererType());
|
||||
return false;
|
||||
}
|
||||
return doProduceOutput(leftBuf, rightBuf, length, static_cast<LA32IntPartialPair *>(la32Pair));
|
||||
@@ -376,7 +380,7 @@ bool Partial::produceOutput(IntSample *leftBuf, IntSample *rightBuf, Bit32u leng
|
||||
|
||||
bool Partial::produceOutput(FloatSample *leftBuf, FloatSample *rightBuf, Bit32u length) {
|
||||
if (!floatMode) {
|
||||
synth->printDebug("Partial: Invalid call to produceOutput()!\n", synth->getSelectedRendererType());
|
||||
synth->printDebug("Partial: Invalid call to produceOutput()! Renderer = %d\n", synth->getSelectedRendererType());
|
||||
return false;
|
||||
}
|
||||
return doProduceOutput(leftBuf, rightBuf, length, static_cast<LA32FloatPartialPair *>(la32Pair));
|
||||
|
||||
@@ -108,6 +108,7 @@ public:
|
||||
void startAbort();
|
||||
void startDecayAll();
|
||||
bool shouldReverb();
|
||||
bool isRingModulatingNoMix() const;
|
||||
bool hasRingModulatingSlave() const;
|
||||
bool isRingModulatingSlave() const;
|
||||
bool isPCM() const;
|
||||
|
||||
@@ -31,6 +31,7 @@ static const ROMInfo *getKnownROMInfoFromList(Bit32u index) {
|
||||
static const ROMInfo CTRL_MT32_V1_07 = {65536, "b083518fffb7f66b03c23b7eb4f868e62dc5a987", ROMInfo::Control, "ctrl_mt32_1_07", "MT-32 Control v1.07", ROMInfo::Full, NULL};
|
||||
static const ROMInfo CTRL_MT32_BLUER = {65536, "7b8c2a5ddb42fd0732e2f22b3340dcf5360edf92", ROMInfo::Control, "ctrl_mt32_bluer", "MT-32 Control BlueRidge", ROMInfo::Full, NULL};
|
||||
|
||||
static const ROMInfo CTRL_MT32_V2_04 = {131072, "2c16432b6c73dd2a3947cba950a0f4c19d6180eb", ROMInfo::Control, "ctrl_mt32_2_04", "MT-32 Control v2.04", ROMInfo::Full, NULL};
|
||||
static const ROMInfo CTRL_CM32L_V1_00 = {65536, "73683d585cd6948cc19547942ca0e14a0319456d", ROMInfo::Control, "ctrl_cm32l_1_00", "CM-32L/LAPC-I Control v1.00", ROMInfo::Full, NULL};
|
||||
static const ROMInfo CTRL_CM32L_V1_02 = {65536, "a439fbb390da38cada95a7cbb1d6ca199cd66ef8", ROMInfo::Control, "ctrl_cm32l_1_02", "CM-32L/LAPC-I Control v1.02", ROMInfo::Full, NULL};
|
||||
|
||||
@@ -43,6 +44,7 @@ static const ROMInfo *getKnownROMInfoFromList(Bit32u index) {
|
||||
&CTRL_MT32_V1_06,
|
||||
&CTRL_MT32_V1_07,
|
||||
&CTRL_MT32_BLUER,
|
||||
&CTRL_MT32_V2_04,
|
||||
&CTRL_CM32L_V1_00,
|
||||
&CTRL_CM32L_V1_02,
|
||||
&PCM_MT32,
|
||||
|
||||
60
src/SOUND/munt/SampleRateConverter_dummy.cpp
Normal file
60
src/SOUND/munt/SampleRateConverter_dummy.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
/* Copyright (C) 2015-2017 Sergey V. Mikayev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 2.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SampleRateConverter.h"
|
||||
|
||||
#include "Synth.h"
|
||||
|
||||
using namespace MT32Emu;
|
||||
|
||||
static inline void *createDelegate(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
AnalogOutputMode SampleRateConverter::getBestAnalogOutputMode(double targetSampleRate) {
|
||||
return AnalogOutputMode_COARSE;
|
||||
}
|
||||
|
||||
SampleRateConverter::SampleRateConverter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality useQuality) :
|
||||
synthInternalToTargetSampleRateRatio(SAMPLE_RATE / targetSampleRate),
|
||||
useSynthDelegate(useSynth.getStereoOutputSampleRate() == targetSampleRate),
|
||||
srcDelegate(useSynthDelegate ? &useSynth : createDelegate(useSynth, targetSampleRate, useQuality))
|
||||
{}
|
||||
|
||||
SampleRateConverter::~SampleRateConverter() {
|
||||
}
|
||||
|
||||
void SampleRateConverter::getOutputSamples(float *buffer, unsigned int length) {
|
||||
if (useSynthDelegate) {
|
||||
static_cast<Synth *>(srcDelegate)->render(buffer, length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SampleRateConverter::getOutputSamples(Bit16s *outBuffer, unsigned int length) {
|
||||
if (useSynthDelegate) {
|
||||
static_cast<Synth *>(srcDelegate)->render(outBuffer, length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double SampleRateConverter::convertOutputToSynthTimestamp(double outputTimestamp) const {
|
||||
return outputTimestamp * synthInternalToTargetSampleRateRatio;
|
||||
}
|
||||
|
||||
double SampleRateConverter::convertSynthToOutputTimestamp(double synthTimestamp) const {
|
||||
return synthTimestamp / synthInternalToTargetSampleRateRatio;
|
||||
}
|
||||
@@ -184,7 +184,13 @@ struct SoundGroup {
|
||||
#endif
|
||||
|
||||
struct ControlROMFeatureSet {
|
||||
unsigned int quirkBasePitchOverflow : 1;
|
||||
unsigned int quirkPitchEnvelopeOverflow : 1;
|
||||
unsigned int quirkRingModulationNoMix : 1;
|
||||
unsigned int quirkTVAZeroEnvLevels : 1;
|
||||
unsigned int quirkPanMult : 1;
|
||||
unsigned int quirkKeyShift : 1;
|
||||
unsigned int quirkTVFBaseCutoffLimit : 1;
|
||||
|
||||
// Features below don't actually depend on control ROM version, which is used to identify hardware model
|
||||
unsigned int defaultReverbMT32Compatible : 1;
|
||||
|
||||
@@ -32,25 +32,50 @@
|
||||
#include "ROMInfo.h"
|
||||
#include "TVA.h"
|
||||
|
||||
#if MT32EMU_MONITOR_SYSEX > 0
|
||||
#include "mmath.h"
|
||||
#endif
|
||||
|
||||
namespace MT32Emu {
|
||||
|
||||
// MIDI interface data transfer rate in samples. Used to simulate the transfer delay.
|
||||
static const double MIDI_DATA_TRANSFER_RATE = double(SAMPLE_RATE) / 31250.0 * 8.0;
|
||||
|
||||
// FIXME: there should be more specific feature sets for various MT-32 control ROM versions
|
||||
static const ControlROMFeatureSet OLD_MT32_COMPATIBLE = { true, true, true };
|
||||
static const ControlROMFeatureSet CM32L_COMPATIBLE = { false, false, false };
|
||||
static const ControlROMFeatureSet OLD_MT32_COMPATIBLE = {
|
||||
true, // quirkBasePitchOverflow
|
||||
true, // quirkPitchEnvelopeOverflow
|
||||
true, // quirkRingModulationNoMix
|
||||
true, // quirkTVAZeroEnvLevels
|
||||
true, // quirkPanMult
|
||||
true, // quirkKeyShift
|
||||
true, // quirkTVFBaseCutoffLimit
|
||||
true, // defaultReverbMT32Compatible
|
||||
true // oldMT32AnalogLPF
|
||||
};
|
||||
static const ControlROMFeatureSet CM32L_COMPATIBLE = {
|
||||
false, // quirkBasePitchOverflow
|
||||
false, // quirkPitchEnvelopeOverflow
|
||||
false, // quirkRingModulationNoMix
|
||||
false, // quirkTVAZeroEnvLevels
|
||||
false, // quirkPanMult
|
||||
false, // quirkKeyShift
|
||||
false, // quirkTVFBaseCutoffLimit
|
||||
false, // defaultReverbMT32Compatible
|
||||
false // oldMT32AnalogLPF
|
||||
};
|
||||
|
||||
static const ControlROMMap ControlROMMaps[7] = {
|
||||
static const ControlROMMap ControlROMMaps[8] = {
|
||||
// ID Features PCMmap PCMc tmbrA tmbrAO, tmbrAC tmbrB tmbrBO tmbrBC tmbrR trC rhythm rhyC rsrv panpot prog rhyMax patMax sysMax timMax sndGrp sGC
|
||||
{ "ctrl_mt32_1_04", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A, 0x7064, 19 },
|
||||
{ "ctrl_mt32_1_05", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A, 0x70CA, 19 },
|
||||
{ "ctrl_mt32_1_06", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57D9, 0x57F4, 0x57E2, 0x5264, 0x5270, 0x5280, 0x521C, 0x70CA, 19 },
|
||||
{ "ctrl_mt32_1_07", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73fe, 85, 0x57B1, 0x57CC, 0x57BA, 0x523C, 0x5248, 0x5258, 0x51F4, 0x70B0, 19 }, // MT-32 revision 1
|
||||
{"ctrl_mt32_bluer", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x741C, 85, 0x57E5, 0x5800, 0x57EE, 0x5270, 0x527C, 0x528C, 0x5228, 0x70CE, 19 }, // MT-32 Blue Ridge mod
|
||||
{"ctrl_mt32_2_04", CM32L_COMPATIBLE, 0x8100, 128, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 30, 0x8580, 85, 0x4F5D, 0x4F78, 0x4F66, 0x4899, 0x489D, 0x48B6, 0x48CD, 0x5A58, 19 },
|
||||
{"ctrl_cm32l_1_00", CM32L_COMPATIBLE, 0x8100, 256, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 64, 0x8580, 85, 0x4F65, 0x4F80, 0x4F6E, 0x48A1, 0x48A5, 0x48BE, 0x48D5, 0x5A6C, 19 },
|
||||
{"ctrl_cm32l_1_02", CM32L_COMPATIBLE, 0x8100, 256, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 64, 0x8580, 85, 0x4F93, 0x4FAE, 0x4F9C, 0x48CB, 0x48CF, 0x48E8, 0x48FF, 0x5A96, 19 } // CM-32L
|
||||
// (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp)
|
||||
// (Note that old MT-32 ROMs actually have 86 entries for rhythmTemp)
|
||||
};
|
||||
|
||||
static const PartialState PARTIAL_PHASE_TO_STATE[8] = {
|
||||
@@ -78,7 +103,7 @@ protected:
|
||||
Synth &synth;
|
||||
|
||||
void printDebug(const char *msg) const {
|
||||
synth.printDebug(msg);
|
||||
synth.printDebug("%s", msg);
|
||||
}
|
||||
|
||||
bool isActivated() const {
|
||||
@@ -168,6 +193,8 @@ public:
|
||||
class Extensions {
|
||||
public:
|
||||
RendererType selectedRendererType;
|
||||
Bit32s masterTunePitchDelta;
|
||||
bool niceAmpRamp;
|
||||
};
|
||||
|
||||
Bit32u Synth::getLibraryVersionInt() {
|
||||
@@ -222,6 +249,7 @@ Synth::Synth(ReportHandler *useReportHandler) :
|
||||
setOutputGain(1.0f);
|
||||
setReverbOutputGain(1.0f);
|
||||
setReversedStereoEnabled(false);
|
||||
setNiceAmpRampEnabled(true);
|
||||
selectRendererType(RendererType_BIT16S);
|
||||
|
||||
patchTempMemoryRegion = NULL;
|
||||
@@ -387,6 +415,14 @@ bool Synth::isReversedStereoEnabled() const {
|
||||
return reversedStereoEnabled;
|
||||
}
|
||||
|
||||
void Synth::setNiceAmpRampEnabled(bool enabled) {
|
||||
extensions.niceAmpRamp = enabled;
|
||||
}
|
||||
|
||||
bool Synth::isNiceAmpRampEnabled() const {
|
||||
return extensions.niceAmpRamp;
|
||||
}
|
||||
|
||||
bool Synth::loadControlROM(const ROMImage &controlROMImage) {
|
||||
File *file = controlROMImage.getFile();
|
||||
const ROMInfo *controlROMInfo = controlROMImage.getROMInfo();
|
||||
@@ -679,6 +715,7 @@ bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, B
|
||||
bool oldReverbOverridden = reverbOverridden;
|
||||
reverbOverridden = false;
|
||||
refreshSystem();
|
||||
resetMasterTunePitchDelta();
|
||||
reverbOverridden = oldReverbOverridden;
|
||||
|
||||
char(*writableSoundGroupNames)[9] = new char[controlROMMap->soundGroupsCount][9];
|
||||
@@ -865,13 +902,17 @@ Bit32u Synth::addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp) {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
Bit32u Synth::getInternalRenderedSampleCount() const {
|
||||
return renderedSampleCount;
|
||||
}
|
||||
|
||||
bool Synth::playMsg(Bit32u msg) {
|
||||
return playMsg(msg, renderedSampleCount);
|
||||
}
|
||||
|
||||
bool Synth::playMsg(Bit32u msg, Bit32u timestamp) {
|
||||
if ((msg & 0xF8) == 0xF8) {
|
||||
reportHandler->onMIDISystemRealtime(Bit8u(msg));
|
||||
reportHandler->onMIDISystemRealtime(Bit8u(msg & 0xFF));
|
||||
return true;
|
||||
}
|
||||
if (midiQueue == NULL) return false;
|
||||
@@ -1539,6 +1580,8 @@ void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u le
|
||||
}
|
||||
|
||||
void Synth::refreshSystemMasterTune() {
|
||||
// 171 is ~half a semitone.
|
||||
extensions.masterTunePitchDelta = ((mt32ram.system.masterTune - 64) * 171) >> 6; // PORTABILITY NOTE: Assumes arithmetic shift.
|
||||
#if MT32EMU_MONITOR_SYSEX > 0
|
||||
//FIXME:KG: This is just an educated guess.
|
||||
// The LAPC-I documentation claims a range of 427.5Hz-452.6Hz (similar to what we have here)
|
||||
@@ -1650,9 +1693,25 @@ void Synth::reset() {
|
||||
}
|
||||
}
|
||||
refreshSystem();
|
||||
resetMasterTunePitchDelta();
|
||||
isActive();
|
||||
}
|
||||
|
||||
void Synth::resetMasterTunePitchDelta() {
|
||||
// This effectively resets master tune to 440.0Hz.
|
||||
// Despite that the manual claims 442.0Hz is the default setting for master tune,
|
||||
// it doesn't actually take effect upon a reset due to a bug in the reset routine.
|
||||
// CONFIRMED: This bug is present in all supported Control ROMs.
|
||||
extensions.masterTunePitchDelta = 0;
|
||||
#if MT32EMU_MONITOR_SYSEX > 0
|
||||
printDebug(" Actual Master Tune reset to 440.0");
|
||||
#endif
|
||||
}
|
||||
|
||||
Bit32s Synth::getMasterTunePitchDelta() const {
|
||||
return extensions.masterTunePitchDelta;
|
||||
}
|
||||
|
||||
MidiEvent::~MidiEvent() {
|
||||
if (sysexData != NULL) {
|
||||
delete[] sysexData;
|
||||
@@ -2013,21 +2072,35 @@ void RendererImpl<IntSample>::convertSamplesToOutput(IntSample *buffer, Bit32u l
|
||||
}
|
||||
|
||||
static inline float produceDistortedSample(float sample) {
|
||||
if (sample < -2.0f) {
|
||||
return sample + 4.0f;
|
||||
} else if (2.0f < sample) {
|
||||
return sample - 4.0f;
|
||||
// Here we roughly simulate the distortion caused by the DAC bit shift.
|
||||
if (sample < -1.0f) {
|
||||
return sample + 2.0f;
|
||||
} else if (1.0f < sample) {
|
||||
return sample - 2.0f;
|
||||
}
|
||||
return sample;
|
||||
}
|
||||
|
||||
template <>
|
||||
void RendererImpl<FloatSample>::produceLA32Output(FloatSample *buffer, Bit32u len) {
|
||||
if (synth.getDACInputMode() == DACInputMode_GENERATION2) {
|
||||
switch (synth.getDACInputMode()) {
|
||||
case DACInputMode_NICE:
|
||||
// Note, we do not do any clamping for floats here to avoid introducing distortions.
|
||||
// This means that the output signal may actually overshoot the unity when the volume is set too high.
|
||||
// We leave it up to the consumer whether the output is to be clamped or properly normalised further on.
|
||||
while (len--) {
|
||||
*buffer = produceDistortedSample(*buffer);
|
||||
*buffer *= 2.0f;
|
||||
buffer++;
|
||||
}
|
||||
break;
|
||||
case DACInputMode_GENERATION2:
|
||||
while (len--) {
|
||||
*buffer = produceDistortedSample(2.0f * *buffer);
|
||||
buffer++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2035,7 +2108,7 @@ template <>
|
||||
void RendererImpl<FloatSample>::convertSamplesToOutput(FloatSample *buffer, Bit32u len) {
|
||||
if (synth.getDACInputMode() == DACInputMode_GENERATION1) {
|
||||
while (len--) {
|
||||
*buffer = produceDistortedSample(*buffer);
|
||||
*buffer = produceDistortedSample(2.0f * *buffer);
|
||||
buffer++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ friend class RhythmPart;
|
||||
friend class SamplerateAdapter;
|
||||
friend class SoxrAdapter;
|
||||
friend class TVA;
|
||||
friend class TVF;
|
||||
friend class TVP;
|
||||
|
||||
private:
|
||||
@@ -230,6 +231,9 @@ private:
|
||||
// partNum should be 0..7 for Part 1..8, or 8 for Rhythm
|
||||
const Part *getPart(Bit8u partNum) const;
|
||||
|
||||
void resetMasterTunePitchDelta();
|
||||
Bit32s getMasterTunePitchDelta() const;
|
||||
|
||||
public:
|
||||
static inline Bit16s clipSampleEx(Bit32s sampleEx) {
|
||||
// Clamp values above 32767 to 32767, and values below -32768 to -32768
|
||||
@@ -258,11 +262,11 @@ public:
|
||||
}
|
||||
|
||||
static inline Bit16s convertSample(float sample) {
|
||||
return Synth::clipSampleEx(Bit32s(sample * 16384.0f)); // This multiplier takes into account the DAC bit shift
|
||||
return Synth::clipSampleEx(Bit32s(sample * 32768.0f)); // This multiplier corresponds to normalised floats
|
||||
}
|
||||
|
||||
static inline float convertSample(Bit16s sample) {
|
||||
return float(sample) / 16384.0f; // This multiplier takes into account the DAC bit shift
|
||||
return float(sample) / 32768.0f; // This multiplier corresponds to normalised floats
|
||||
}
|
||||
|
||||
// Returns library version as an integer in format: 0x00MMmmpp, where:
|
||||
@@ -308,6 +312,10 @@ public:
|
||||
// Returns the actual queue size being used.
|
||||
MT32EMU_EXPORT Bit32u setMIDIEventQueueSize(Bit32u);
|
||||
|
||||
// Returns current value of the global counter of samples rendered since the synth was created (at the native sample rate 32000 Hz).
|
||||
// This method helps to compute accurate timestamp of a MIDI message to use with the methods below.
|
||||
MT32EMU_EXPORT Bit32u getInternalRenderedSampleCount() const;
|
||||
|
||||
// Enqueues a MIDI event for subsequent playback.
|
||||
// The MIDI event will be processed not before the specified timestamp.
|
||||
// The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz).
|
||||
@@ -382,7 +390,6 @@ public:
|
||||
// Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume,
|
||||
// it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with setReverbOutputGain()
|
||||
// it offers to the user a capability to control the gain of reverb and non-reverb output channels independently.
|
||||
// Ignored in DACInputMode_PURE
|
||||
MT32EMU_EXPORT void setOutputGain(float gain);
|
||||
// Returns current output gain factor for synth output channels.
|
||||
MT32EMU_EXPORT float getOutputGain() const;
|
||||
@@ -395,7 +402,6 @@ public:
|
||||
// corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic,
|
||||
// there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68
|
||||
// of that for LA32 analogue output. This factor is applied to the reverb output gain.
|
||||
// Ignored in DACInputMode_PURE
|
||||
MT32EMU_EXPORT void setReverbOutputGain(float gain);
|
||||
// Returns current output gain factor for reverb wet output channels.
|
||||
MT32EMU_EXPORT float getReverbOutputGain() const;
|
||||
@@ -405,6 +411,16 @@ public:
|
||||
// Returns whether left and right output channels are swapped.
|
||||
MT32EMU_EXPORT bool isReversedStereoEnabled() const;
|
||||
|
||||
// Allows to toggle the NiceAmpRamp mode.
|
||||
// In this mode, we want to ensure that amp ramp never jumps to the target
|
||||
// value and always gradually increases or decreases. It seems that real units
|
||||
// do not bother to always check if a newly started ramp leads to a jump.
|
||||
// We also prefer the quality improvement over the emulation accuracy,
|
||||
// so this mode is enabled by default.
|
||||
MT32EMU_EXPORT void setNiceAmpRampEnabled(bool enabled);
|
||||
// Returns whether NiceAmpRamp mode is enabled.
|
||||
MT32EMU_EXPORT bool isNiceAmpRampEnabled() const;
|
||||
|
||||
// Selects new type of the wave generator and renderer to be used during subsequent calls to open().
|
||||
// By default, RendererType_BIT16S is selected.
|
||||
// See RendererType for details.
|
||||
|
||||
@@ -43,7 +43,7 @@ void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) {
|
||||
phase = newPhase;
|
||||
ampRamp->startRamp(newTarget, newIncrement);
|
||||
#if MT32EMU_MONITOR_TVA >= 1
|
||||
partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,ramp,%d,%d,%d,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), (newIncrement & 0x80) ? -1 : 1, (newIncrement & 0x7F), newPhase);
|
||||
partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,ramp,%x,%s%x,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newTarget, (newIncrement & 0x80) ? "-" : "+", (newIncrement & 0x7F), newPhase);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -99,10 +99,10 @@ static int calcVeloAmpSubtraction(Bit8u veloSensitivity, unsigned int velocity)
|
||||
return absVelocityMult - (velocityMult >> 8); // PORTABILITY NOTE: Assumes arithmetic shift
|
||||
}
|
||||
|
||||
static int calcBasicAmp(const Tables *tables, const Partial *partial, const MemParams::System *system, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, const MemParams::RhythmTemp *rhythmTemp, int biasAmpSubtraction, int veloAmpSubtraction, Bit8u expression) {
|
||||
static int calcBasicAmp(const Tables *tables, const Partial *partial, const MemParams::System *system, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, const MemParams::RhythmTemp *rhythmTemp, int biasAmpSubtraction, int veloAmpSubtraction, Bit8u expression, bool hasRingModQuirk) {
|
||||
int amp = 155;
|
||||
|
||||
if (!partial->isRingModulatingSlave()) {
|
||||
if (!(hasRingModQuirk ? partial->isRingModulatingNoMix() : partial->isRingModulatingSlave())) {
|
||||
amp -= tables->masterVolToAmpSubtraction[system->masterVol];
|
||||
if (amp < 0) {
|
||||
return 0;
|
||||
@@ -169,7 +169,7 @@ void TVA::reset(const Part *newPart, const TimbreParam::PartialParam *newPartial
|
||||
biasAmpSubtraction = calcBiasAmpSubtractions(partialParam, key);
|
||||
veloAmpSubtraction = calcVeloAmpSubtraction(partialParam->tva.veloSensitivity, velocity);
|
||||
|
||||
int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, newRhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression());
|
||||
int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, newRhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression(), partial->getSynth()->controlROMFeatures->quirkRingModulationNoMix);
|
||||
int newPhase;
|
||||
if (partialParam->tva.envTime[0] == 0) {
|
||||
// Initially go to the TVA_PHASE_ATTACK target amp, and spend the next phase going from there to the TVA_PHASE_2 target amp
|
||||
@@ -221,18 +221,29 @@ void TVA::recalcSustain() {
|
||||
}
|
||||
// We're sustaining. Recalculate all the values
|
||||
const Tables *tables = &Tables::getInstance();
|
||||
int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression());
|
||||
int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression(), partial->getSynth()->controlROMFeatures->quirkRingModulationNoMix);
|
||||
newTarget += partialParam->tva.envLevel[3];
|
||||
// Since we're in TVA_PHASE_SUSTAIN at this point, we know that target has been reached and an interrupt fired, so we can rely on it being the current amp.
|
||||
|
||||
// Although we're in TVA_PHASE_SUSTAIN at this point, we cannot be sure that there is no active ramp at the moment.
|
||||
// In case the channel volume or the expression changes frequently, the previously started ramp may still be in progress.
|
||||
// Real hardware units ignore this possibility and rely on the assumption that the target is the current amp.
|
||||
// This is OK in most situations but when the ramp that is currently in progress needs to change direction
|
||||
// due to a volume/expression update, this leads to a jump in the amp that is audible as an unpleasant click.
|
||||
// To avoid that, we compare the newTarget with the the actual current ramp value and correct the direction if necessary.
|
||||
int targetDelta = newTarget - target;
|
||||
|
||||
// Calculate an increment to get to the new amp value in a short, more or less consistent amount of time
|
||||
Bit8u newIncrement;
|
||||
if (targetDelta >= 0) {
|
||||
bool descending = targetDelta < 0;
|
||||
if (!descending) {
|
||||
newIncrement = tables->envLogarithmicTime[Bit8u(targetDelta)] - 2;
|
||||
} else {
|
||||
newIncrement = (tables->envLogarithmicTime[Bit8u(-targetDelta)] - 2) | 0x80;
|
||||
}
|
||||
if (part->getSynth()->isNiceAmpRampEnabled() && (descending != ampRamp->isBelowCurrent(newTarget))) {
|
||||
newIncrement ^= 0x80;
|
||||
}
|
||||
|
||||
// Configure so that once the transition's complete and nextPhase() is called, we'll just re-enter sustain phase (or decay phase, depending on parameters at the time).
|
||||
startRamp(newTarget, newIncrement, TVA_PHASE_SUSTAIN - 1);
|
||||
}
|
||||
@@ -260,7 +271,7 @@ void TVA::nextPhase() {
|
||||
}
|
||||
|
||||
bool allLevelsZeroFromNowOn = false;
|
||||
if (partialParam->tva.envLevel[3] == 0) {
|
||||
if (!partial->getSynth()->controlROMFeatures->quirkTVAZeroEnvLevels && partialParam->tva.envLevel[3] == 0) {
|
||||
if (newPhase == TVA_PHASE_4) {
|
||||
allLevelsZeroFromNowOn = true;
|
||||
} else if (partialParam->tva.envLevel[2] == 0) {
|
||||
@@ -283,7 +294,7 @@ void TVA::nextPhase() {
|
||||
int envPointIndex = phase;
|
||||
|
||||
if (!allLevelsZeroFromNowOn) {
|
||||
newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression());
|
||||
newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression(), partial->getSynth()->controlROMFeatures->quirkRingModulationNoMix);
|
||||
|
||||
if (newPhase == TVA_PHASE_SUSTAIN || newPhase == TVA_PHASE_RELEASE) {
|
||||
if (partialParam->tva.envLevel[3] == 0) {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "LA32Ramp.h"
|
||||
#include "Partial.h"
|
||||
#include "Poly.h"
|
||||
#include "Synth.h"
|
||||
#include "Tables.h"
|
||||
|
||||
namespace MT32Emu {
|
||||
@@ -52,7 +53,7 @@ enum {
|
||||
PHASE_DONE = 7
|
||||
};
|
||||
|
||||
static int calcBaseCutoff(const TimbreParam::PartialParam *partialParam, Bit32u basePitch, unsigned int key) {
|
||||
static int calcBaseCutoff(const TimbreParam::PartialParam *partialParam, Bit32u basePitch, unsigned int key, bool quirkTVFBaseCutoffLimit) {
|
||||
// This table matches the values used by a real LAPC-I.
|
||||
static const Bit8s biasLevelToBiasMult[] = {85, 42, 21, 16, 10, 5, 2, 0, -2, -5, -10, -16, -21, -74, -85};
|
||||
// These values represent unique options with no consistent pattern, so we have to use something like a table in any case.
|
||||
@@ -90,8 +91,14 @@ static int calcBaseCutoff(const TimbreParam::PartialParam *partialParam, Bit32u
|
||||
if (pitchDeltaThing > 0) {
|
||||
baseCutoff -= pitchDeltaThing;
|
||||
}
|
||||
} else if (baseCutoff < -2048) {
|
||||
baseCutoff = -2048;
|
||||
} else if (quirkTVFBaseCutoffLimit) {
|
||||
if (baseCutoff <= -0x400) {
|
||||
baseCutoff = -400;
|
||||
}
|
||||
} else {
|
||||
if (baseCutoff < -2048) {
|
||||
baseCutoff = -2048;
|
||||
}
|
||||
}
|
||||
baseCutoff += 2056;
|
||||
baseCutoff >>= 4; // PORTABILITY NOTE: Hmm... Depends whether it could've been below -2056, but maybe arithmetic shift assumed?
|
||||
@@ -110,7 +117,7 @@ void TVF::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) {
|
||||
phase = newPhase;
|
||||
cutoffModifierRamp->startRamp(newTarget, newIncrement);
|
||||
#if MT32EMU_MONITOR_TVF >= 1
|
||||
partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,ramp,%d,%d,%d,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newTarget, (newIncrement & 0x80) ? -1 : 1, (newIncrement & 0x7F), newPhase);
|
||||
partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,ramp,%x,%s%x,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newTarget, (newIncrement & 0x80) ? "-" : "+", (newIncrement & 0x7F), newPhase);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -122,7 +129,7 @@ void TVF::reset(const TimbreParam::PartialParam *newPartialParam, unsigned int b
|
||||
|
||||
const Tables *tables = &Tables::getInstance();
|
||||
|
||||
baseCutoff = calcBaseCutoff(newPartialParam, basePitch, key);
|
||||
baseCutoff = calcBaseCutoff(newPartialParam, basePitch, key, partial->getSynth()->controlROMFeatures->quirkTVFBaseCutoffLimit);
|
||||
#if MT32EMU_MONITOR_TVF >= 1
|
||||
partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,base,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), baseCutoff);
|
||||
#endif
|
||||
|
||||
@@ -51,13 +51,15 @@ static Bit16u keyToPitchTable[] = {
|
||||
21845, 22187, 22528, 22869
|
||||
};
|
||||
|
||||
// We want to do processing 4000 times per second. FIXME: This is pretty arbitrary.
|
||||
static const int NOMINAL_PROCESS_TIMER_PERIOD_SAMPLES = SAMPLE_RATE / 4000;
|
||||
|
||||
// The timer runs at 500kHz. This is how much to increment it after 8 samples passes.
|
||||
// We multiply by 8 to get rid of the fraction and deal with just integers.
|
||||
static const int PROCESS_TIMER_INCREMENT_x8 = 8 * 500000 / SAMPLE_RATE;
|
||||
|
||||
TVP::TVP(const Partial *usePartial) :
|
||||
partial(usePartial), system(&usePartial->getSynth()->mt32ram.system) {
|
||||
// We want to do processing 4000 times per second. FIXME: This is pretty arbitrary.
|
||||
maxCounter = SAMPLE_RATE / 4000;
|
||||
// The timer runs at 500kHz. We only need to bother updating it every maxCounter samples, before we do processing.
|
||||
// This is how much to increment it by every maxCounter samples.
|
||||
processTimerIncrement = 500000 * maxCounter / SAMPLE_RATE;
|
||||
}
|
||||
|
||||
static Bit16s keyToPitch(unsigned int key) {
|
||||
@@ -76,13 +78,15 @@ static inline Bit32s fineToPitch(Bit8u fine) {
|
||||
return (fine - 50) * 4096 / 1200; // One cent per fine offset
|
||||
}
|
||||
|
||||
static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, unsigned int key) {
|
||||
static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, unsigned int key, const ControlROMFeatureSet *controlROMFeatures) {
|
||||
Bit32s basePitch = keyToPitch(key);
|
||||
basePitch = (basePitch * pitchKeyfollowMult[partialParam->wg.pitchKeyfollow]) >> 13; // PORTABILITY NOTE: Assumes arithmetic shift
|
||||
basePitch += coarseToPitch(partialParam->wg.pitchCoarse);
|
||||
basePitch += fineToPitch(partialParam->wg.pitchFine);
|
||||
// NOTE:Mok: This is done on MT-32, but not LAPC-I:
|
||||
//pitch += coarseToPitch(patchTemp->patch.keyShift + 12);
|
||||
if (controlROMFeatures->quirkKeyShift) {
|
||||
// NOTE:Mok: This is done on MT-32, but not LAPC-I:
|
||||
basePitch += coarseToPitch(patchTemp->patch.keyShift + 12);
|
||||
}
|
||||
basePitch += fineToPitch(patchTemp->patch.fineTune);
|
||||
|
||||
const ControlROMPCMStruct *controlROMPCMStruct = partial->getControlROMPCMStruct();
|
||||
@@ -97,7 +101,12 @@ static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialPa
|
||||
basePitch += 33037;
|
||||
}
|
||||
}
|
||||
if (basePitch < 0) {
|
||||
|
||||
// MT-32 GEN0 does 16-bit calculations here, allowing an integer overflow.
|
||||
// This quirk is observable playing the patch defined for timbre "HIT BOTTOM" in Larry 3.
|
||||
if (controlROMFeatures->quirkBasePitchOverflow) {
|
||||
basePitch = basePitch & 0xffff;
|
||||
} else if (basePitch < 0) {
|
||||
basePitch = 0;
|
||||
}
|
||||
if (basePitch > 59392) {
|
||||
@@ -107,18 +116,22 @@ static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialPa
|
||||
}
|
||||
|
||||
static Bit32u calcVeloMult(Bit8u veloSensitivity, unsigned int velocity) {
|
||||
if (veloSensitivity == 0 || veloSensitivity > 3) {
|
||||
// Note that on CM-32L/LAPC-I veloSensitivity is never > 3, since it's clipped to 3 by the max tables.
|
||||
if (veloSensitivity == 0) {
|
||||
return 21845; // aka floor(4096 / 12 * 64), aka ~64 semitones
|
||||
}
|
||||
unsigned int reversedVelocity = 127 - velocity;
|
||||
unsigned int scaledReversedVelocity;
|
||||
if (veloSensitivity > 3) {
|
||||
// Note that on CM-32L/LAPC-I veloSensitivity is never > 3, since it's clipped to 3 by the max tables.
|
||||
// MT-32 GEN0 has a bug here that leads to unspecified behaviour. We assume it is as follows.
|
||||
scaledReversedVelocity = (reversedVelocity << 8) >> ((3 - veloSensitivity) & 0x1f);
|
||||
} else {
|
||||
scaledReversedVelocity = reversedVelocity << (5 + veloSensitivity);
|
||||
}
|
||||
// When velocity is 127, the multiplier is 21845, aka ~64 semitones (regardless of veloSensitivity).
|
||||
// The lower the velocity, the lower the multiplier. The veloSensitivity determines the amount decreased per velocity value.
|
||||
// The minimum multiplier (with velocity 0, veloSensitivity 3) is 170 (~half a semitone).
|
||||
Bit32u veloMult = 32768;
|
||||
veloMult -= (127 - velocity) << (5 + veloSensitivity);
|
||||
veloMult *= 21845;
|
||||
veloMult >>= 15;
|
||||
return veloMult;
|
||||
// The minimum multiplier on CM-32L/LAPC-I (with velocity 0, veloSensitivity 3) is 170 (~half a semitone).
|
||||
return ((32768 - scaledReversedVelocity) * 21845) >> 15;
|
||||
}
|
||||
|
||||
static Bit32s calcTargetPitchOffsetWithoutLFO(const TimbreParam::PartialParam *partialParam, int levelIndex, unsigned int velocity) {
|
||||
@@ -139,7 +152,7 @@ void TVP::reset(const Part *usePart, const TimbreParam::PartialParam *usePartial
|
||||
// FIXME: We're using a per-TVP timer instead of a system-wide one for convenience.
|
||||
timeElapsed = 0;
|
||||
|
||||
basePitch = calcBasePitch(partial, partialParam, patchTemp, key);
|
||||
basePitch = calcBasePitch(partial, partialParam, patchTemp, key, partial->getSynth()->controlROMFeatures);
|
||||
currentPitchOffset = calcTargetPitchOffsetWithoutLFO(partialParam, 0, velocity);
|
||||
targetPitchOffsetWithoutLFO = currentPitchOffset;
|
||||
phase = 0;
|
||||
@@ -166,22 +179,23 @@ Bit32u TVP::getBasePitch() const {
|
||||
void TVP::updatePitch() {
|
||||
Bit32s newPitch = basePitch + currentPitchOffset;
|
||||
if (!partial->isPCM() || (partial->getControlROMPCMStruct()->len & 0x01) == 0) { // FIXME: Use !partial->pcmWaveEntry->unaffectedByMasterTune instead
|
||||
// FIXME: masterTune recalculation doesn't really happen here, and there are various bugs not yet emulated
|
||||
// FIXME: There are various bugs not yet emulated
|
||||
// 171 is ~half a semitone.
|
||||
newPitch += ((system->masterTune - 64) * 171) >> 6; // PORTABILITY NOTE: Assumes arithmetic shift.
|
||||
newPitch += partial->getSynth()->getMasterTunePitchDelta();
|
||||
}
|
||||
if ((partialParam->wg.pitchBenderEnabled & 1) != 0) {
|
||||
newPitch += part->getPitchBend();
|
||||
}
|
||||
if (newPitch < 0) {
|
||||
|
||||
// MT-32 GEN0 does 16-bit calculations here, allowing an integer overflow.
|
||||
// This quirk is exploited e.g. in Colonel's Bequest timbres "Lightning" and "SwmpBackgr".
|
||||
if (partial->getSynth()->controlROMFeatures->quirkPitchEnvelopeOverflow) {
|
||||
newPitch = newPitch & 0xffff;
|
||||
} else if (newPitch < 0) {
|
||||
newPitch = 0;
|
||||
}
|
||||
|
||||
// Skipping this check seems about right emulation of MT-32 GEN0 quirk exploited in Colonel's Bequest timbre "Lightning"
|
||||
if (partial->getSynth()->controlROMFeatures->quirkPitchEnvelopeOverflow == 0) {
|
||||
if (newPitch > 59392) {
|
||||
newPitch = 59392;
|
||||
}
|
||||
if (newPitch > 59392) {
|
||||
newPitch = 59392;
|
||||
}
|
||||
pitch = Bit16u(newPitch);
|
||||
|
||||
@@ -284,13 +298,19 @@ void TVP::startDecay() {
|
||||
}
|
||||
|
||||
Bit16u TVP::nextPitch() {
|
||||
// FIXME: Write explanation of counter and time increment
|
||||
// We emulate MCU software timer using these counter and processTimerIncrement variables.
|
||||
// The value of nominalProcessTimerPeriod approximates the period in samples
|
||||
// between subsequent firings of the timer that normally occur.
|
||||
// However, accurate emulation is quite complicated because the timer is not guaranteed to fire in time.
|
||||
// This makes pitch variations on real unit non-deterministic and dependent on various factors.
|
||||
if (counter == 0) {
|
||||
timeElapsed += processTimerIncrement;
|
||||
timeElapsed = timeElapsed & 0x00FFFFFF;
|
||||
timeElapsed = (timeElapsed + processTimerIncrement) & 0x00FFFFFF;
|
||||
// This roughly emulates pitch deviations observed on real units when playing a single partial that uses TVP/LFO.
|
||||
counter = NOMINAL_PROCESS_TIMER_PERIOD_SAMPLES + (rand() & 3);
|
||||
processTimerIncrement = (PROCESS_TIMER_INCREMENT_x8 * counter) >> 3;
|
||||
process();
|
||||
}
|
||||
counter = (counter + 1) % maxCounter;
|
||||
counter--;
|
||||
return pitch;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ private:
|
||||
const TimbreParam::PartialParam *partialParam;
|
||||
const MemParams::PatchTemp *patchTemp;
|
||||
|
||||
int maxCounter;
|
||||
int processTimerIncrement;
|
||||
int counter;
|
||||
Bit32u timeElapsed;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "../ROMInfo.h"
|
||||
#include "../Synth.h"
|
||||
#include "../MidiStreamParser.h"
|
||||
#include "../SampleRateConverter.h"
|
||||
|
||||
#include "c_types.h"
|
||||
#include "c_interface.h"
|
||||
@@ -30,11 +31,17 @@ using namespace MT32Emu;
|
||||
|
||||
namespace MT32Emu {
|
||||
|
||||
struct SamplerateConversionState {
|
||||
double outputSampleRate;
|
||||
SamplerateConversionQuality srcQuality;
|
||||
SampleRateConverter *src;
|
||||
};
|
||||
|
||||
static mt32emu_service_version getSynthVersionID(mt32emu_service_i) {
|
||||
return MT32EMU_SERVICE_VERSION_CURRENT;
|
||||
}
|
||||
|
||||
static const mt32emu_service_i_v0 SERVICE_VTABLE = {
|
||||
static const mt32emu_service_i_v2 SERVICE_VTABLE = {
|
||||
getSynthVersionID,
|
||||
mt32emu_get_supported_report_handler_version,
|
||||
mt32emu_get_supported_midi_receiver_version,
|
||||
@@ -95,7 +102,17 @@ static const mt32emu_service_i_v0 SERVICE_VTABLE = {
|
||||
mt32emu_get_partial_states,
|
||||
mt32emu_get_playing_notes,
|
||||
mt32emu_get_patch_name,
|
||||
mt32emu_read_memory
|
||||
mt32emu_read_memory,
|
||||
mt32emu_get_best_analog_output_mode,
|
||||
mt32emu_set_stereo_output_samplerate,
|
||||
mt32emu_set_samplerate_conversion_quality,
|
||||
mt32emu_select_renderer_type,
|
||||
mt32emu_get_selected_renderer_type,
|
||||
mt32emu_convert_output_to_synth_timestamp,
|
||||
mt32emu_convert_synth_to_output_timestamp,
|
||||
mt32emu_get_internal_rendered_sample_count,
|
||||
mt32emu_set_nice_amp_ramp_enabled,
|
||||
mt32emu_is_nice_amp_ramp_enabled
|
||||
};
|
||||
|
||||
} // namespace MT32Emu
|
||||
@@ -108,6 +125,7 @@ struct mt32emu_data {
|
||||
DefaultMidiStreamParser *midiParser;
|
||||
Bit32u partialCount;
|
||||
AnalogOutputMode analogOutputMode;
|
||||
SamplerateConversionState *srcState;
|
||||
};
|
||||
|
||||
// Internal C++ utility stuff
|
||||
@@ -305,7 +323,7 @@ extern "C" {
|
||||
|
||||
mt32emu_service_i mt32emu_get_service_i() {
|
||||
mt32emu_service_i i;
|
||||
i.v0 = &SERVICE_VTABLE;
|
||||
i.v2 = &SERVICE_VTABLE;
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -329,6 +347,10 @@ mt32emu_bit32u mt32emu_get_stereo_output_samplerate(const mt32emu_analog_output_
|
||||
return Synth::getStereoOutputSampleRate(static_cast<AnalogOutputMode>(analog_output_mode));
|
||||
}
|
||||
|
||||
mt32emu_analog_output_mode mt32emu_get_best_analog_output_mode(const double target_samplerate) {
|
||||
return mt32emu_analog_output_mode(SampleRateConverter::getBestAnalogOutputMode(target_samplerate));
|
||||
}
|
||||
|
||||
mt32emu_context mt32emu_create_context(mt32emu_report_handler_i report_handler, void *instance_data) {
|
||||
mt32emu_data *data = new mt32emu_data;
|
||||
data->reportHandler = (report_handler.v0 != NULL) ? new DelegatingReportHandlerAdapter(report_handler, instance_data) : new ReportHandler;
|
||||
@@ -339,12 +361,22 @@ mt32emu_context mt32emu_create_context(mt32emu_report_handler_i report_handler,
|
||||
data->partialCount = DEFAULT_MAX_PARTIALS;
|
||||
data->analogOutputMode = AnalogOutputMode_COARSE;
|
||||
|
||||
data->srcState = new SamplerateConversionState;
|
||||
data->srcState->outputSampleRate = 0.0;
|
||||
data->srcState->srcQuality = SamplerateConversionQuality_GOOD;
|
||||
data->srcState->src = NULL;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void mt32emu_free_context(mt32emu_context data) {
|
||||
if (data == NULL) return;
|
||||
|
||||
delete data->srcState->src;
|
||||
data->srcState->src = NULL;
|
||||
delete data->srcState;
|
||||
data->srcState = NULL;
|
||||
|
||||
if (data->controlROMImage != NULL) {
|
||||
delete data->controlROMImage->getFile();
|
||||
ROMImage::freeROMImage(data->controlROMImage);
|
||||
@@ -417,6 +449,16 @@ void mt32emu_set_analog_output_mode(mt32emu_context context, const mt32emu_analo
|
||||
context->analogOutputMode = static_cast<AnalogOutputMode>(analog_output_mode);
|
||||
}
|
||||
|
||||
void mt32emu_set_stereo_output_samplerate(mt32emu_context context, const double samplerate) {
|
||||
if (0.0 <= samplerate) {
|
||||
context->srcState->outputSampleRate = samplerate;
|
||||
}
|
||||
}
|
||||
|
||||
void mt32emu_set_samplerate_conversion_quality(mt32emu_context context, const mt32emu_samplerate_conversion_quality quality) {
|
||||
context->srcState->srcQuality = SamplerateConversionQuality(quality);
|
||||
}
|
||||
|
||||
void mt32emu_select_renderer_type(mt32emu_context context, const mt32emu_renderer_type renderer_type) {
|
||||
context->synth->selectRendererType(static_cast<RendererType>(renderer_type));
|
||||
}
|
||||
@@ -432,11 +474,16 @@ mt32emu_return_code mt32emu_open_synth(mt32emu_const_context context) {
|
||||
if (!context->synth->open(*context->controlROMImage, *context->pcmROMImage, context->partialCount, context->analogOutputMode)) {
|
||||
return MT32EMU_RC_FAILED;
|
||||
}
|
||||
SamplerateConversionState &srcState = *context->srcState;
|
||||
const double outputSampleRate = (0.0 < srcState.outputSampleRate) ? srcState.outputSampleRate : context->synth->getStereoOutputSampleRate();
|
||||
srcState.src = new SampleRateConverter(*context->synth, outputSampleRate, srcState.srcQuality);
|
||||
return MT32EMU_RC_OK;
|
||||
}
|
||||
|
||||
void mt32emu_close_synth(mt32emu_const_context context) {
|
||||
context->synth->close();
|
||||
delete context->srcState->src;
|
||||
context->srcState->src = NULL;
|
||||
}
|
||||
|
||||
mt32emu_boolean mt32emu_is_open(mt32emu_const_context context) {
|
||||
@@ -444,7 +491,24 @@ mt32emu_boolean mt32emu_is_open(mt32emu_const_context context) {
|
||||
}
|
||||
|
||||
mt32emu_bit32u mt32emu_get_actual_stereo_output_samplerate(mt32emu_const_context context) {
|
||||
return context->synth->getStereoOutputSampleRate();
|
||||
if (context->srcState->src == NULL) {
|
||||
return context->synth->getStereoOutputSampleRate();
|
||||
}
|
||||
return mt32emu_bit32u(0.5 + context->srcState->src->convertSynthToOutputTimestamp(SAMPLE_RATE));
|
||||
}
|
||||
|
||||
mt32emu_bit32u mt32emu_convert_output_to_synth_timestamp(mt32emu_const_context context, mt32emu_bit32u output_timestamp) {
|
||||
if (context->srcState->src == NULL) {
|
||||
return output_timestamp;
|
||||
}
|
||||
return mt32emu_bit32u(0.5 + context->srcState->src->convertOutputToSynthTimestamp(output_timestamp));
|
||||
}
|
||||
|
||||
mt32emu_bit32u mt32emu_convert_synth_to_output_timestamp(mt32emu_const_context context, mt32emu_bit32u synth_timestamp) {
|
||||
if (context->srcState->src == NULL) {
|
||||
return synth_timestamp;
|
||||
}
|
||||
return mt32emu_bit32u(0.5 + context->srcState->src->convertSynthToOutputTimestamp(synth_timestamp));
|
||||
}
|
||||
|
||||
void mt32emu_flush_midi_queue(mt32emu_const_context context) {
|
||||
@@ -460,6 +524,10 @@ void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i
|
||||
context->midiParser = (midi_receiver.v0 != NULL) ? new DelegatingMidiStreamParser(context, midi_receiver, instance_data) : new DefaultMidiStreamParser(*context->synth);
|
||||
}
|
||||
|
||||
mt32emu_bit32u mt32emu_get_internal_rendered_sample_count(mt32emu_const_context context) {
|
||||
return context->synth->getInternalRenderedSampleCount();
|
||||
}
|
||||
|
||||
void mt32emu_parse_stream(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length) {
|
||||
context->midiParser->resetTimestamp();
|
||||
context->midiParser->parseStream(stream, length);
|
||||
@@ -584,12 +652,28 @@ mt32emu_boolean mt32emu_is_reversed_stereo_enabled(mt32emu_const_context context
|
||||
return context->synth->isReversedStereoEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE;
|
||||
}
|
||||
|
||||
void mt32emu_set_nice_amp_ramp_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) {
|
||||
context->synth->setNiceAmpRampEnabled(enabled != MT32EMU_BOOL_FALSE);
|
||||
}
|
||||
|
||||
mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context) {
|
||||
return context->synth->isNiceAmpRampEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE;
|
||||
}
|
||||
|
||||
void mt32emu_render_bit16s(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len) {
|
||||
context->synth->render(stream, len);
|
||||
if (context->srcState->src != NULL) {
|
||||
context->srcState->src->getOutputSamples(stream, len);
|
||||
} else {
|
||||
context->synth->render(stream, len);
|
||||
}
|
||||
}
|
||||
|
||||
void mt32emu_render_float(mt32emu_const_context context, float *stream, mt32emu_bit32u len) {
|
||||
context->synth->render(stream, len);
|
||||
if (context->srcState->src != NULL) {
|
||||
context->srcState->src->getOutputSamples(stream, len);
|
||||
} else {
|
||||
context->synth->render(stream, len);
|
||||
}
|
||||
}
|
||||
|
||||
void mt32emu_render_bit16s_streams(mt32emu_const_context context, const mt32emu_dac_output_bit16s_streams *streams, mt32emu_bit32u len) {
|
||||
|
||||
@@ -209,6 +209,12 @@ MT32EMU_EXPORT mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_co
|
||||
*/
|
||||
MT32EMU_EXPORT void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data);
|
||||
|
||||
/**
|
||||
* Returns current value of the global counter of samples rendered since the synth was created (at the native sample rate 32000 Hz).
|
||||
* This method helps to compute accurate timestamp of a MIDI message to use with the methods below.
|
||||
*/
|
||||
MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_internal_rendered_sample_count(mt32emu_const_context context);
|
||||
|
||||
/* Enqueues a MIDI event for subsequent playback.
|
||||
* The MIDI event will be processed not before the specified timestamp.
|
||||
* The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz).
|
||||
@@ -324,7 +330,6 @@ MT32EMU_EXPORT mt32emu_midi_delay_mode mt32emu_get_midi_delay_mode(mt32emu_const
|
||||
* Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume,
|
||||
* it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with mt32emu_set_reverb_output_gain()
|
||||
* it offers to the user a capability to control the gain of reverb and non-reverb output channels independently.
|
||||
* Ignored in MT32EMU_DAC_PURE mode.
|
||||
*/
|
||||
MT32EMU_EXPORT void mt32emu_set_output_gain(mt32emu_const_context context, float gain);
|
||||
/** Returns current output gain factor for synth output channels. */
|
||||
@@ -339,7 +344,6 @@ MT32EMU_EXPORT float mt32emu_get_output_gain(mt32emu_const_context context);
|
||||
* corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic,
|
||||
* there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68
|
||||
* of that for LA32 analogue output. This factor is applied to the reverb output gain.
|
||||
* Ignored in MT32EMU_DAC_PURE mode.
|
||||
*/
|
||||
MT32EMU_EXPORT void mt32emu_set_reverb_output_gain(mt32emu_const_context context, float gain);
|
||||
/** Returns current output gain factor for reverb wet output channels. */
|
||||
@@ -350,6 +354,18 @@ MT32EMU_EXPORT void mt32emu_set_reversed_stereo_enabled(mt32emu_const_context co
|
||||
/** Returns whether left and right output channels are swapped. */
|
||||
MT32EMU_EXPORT mt32emu_boolean mt32emu_is_reversed_stereo_enabled(mt32emu_const_context context);
|
||||
|
||||
/**
|
||||
* Allows to toggle the NiceAmpRamp mode.
|
||||
* In this mode, we want to ensure that amp ramp never jumps to the target
|
||||
* value and always gradually increases or decreases. It seems that real units
|
||||
* do not bother to always check if a newly started ramp leads to a jump.
|
||||
* We also prefer the quality improvement over the emulation accuracy,
|
||||
* so this mode is enabled by default.
|
||||
*/
|
||||
MT32EMU_EXPORT void mt32emu_set_nice_amp_ramp_enabled(mt32emu_const_context context, const mt32emu_boolean enabled);
|
||||
/** Returns whether NiceAmpRamp mode is enabled. */
|
||||
MT32EMU_EXPORT mt32emu_boolean mt32emu_is_nice_amp_ramp_enabled(mt32emu_const_context context);
|
||||
|
||||
/**
|
||||
* Renders samples to the specified output stream as if they were sampled at the analog stereo output at the desired sample rate.
|
||||
* If the output sample rate is not specified explicitly, the default output sample rate is used which depends on the current
|
||||
|
||||
@@ -120,7 +120,8 @@ typedef enum {
|
||||
typedef enum {
|
||||
MT32EMU_SERVICE_VERSION_0 = 0,
|
||||
MT32EMU_SERVICE_VERSION_1 = 1,
|
||||
MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_1
|
||||
MT32EMU_SERVICE_VERSION_2 = 2,
|
||||
MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_2
|
||||
} mt32emu_service_version;
|
||||
|
||||
/* === Report Handler Interface === */
|
||||
@@ -297,6 +298,11 @@ typedef union mt32emu_service_i mt32emu_service_i;
|
||||
mt32emu_bit32u (*convertOutputToSynthTimestamp)(mt32emu_const_context context, mt32emu_bit32u output_timestamp); \
|
||||
mt32emu_bit32u (*convertSynthToOutputTimestamp)(mt32emu_const_context context, mt32emu_bit32u synth_timestamp);
|
||||
|
||||
#define MT32EMU_SERVICE_I_V2 \
|
||||
mt32emu_bit32u (*getInternalRenderedSampleCount)(mt32emu_const_context context); \
|
||||
void (*setNiceAmpRampEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \
|
||||
mt32emu_boolean (*isNiceAmpRampEnabled)(mt32emu_const_context context);
|
||||
|
||||
typedef struct {
|
||||
MT32EMU_SERVICE_I_V0
|
||||
} mt32emu_service_i_v0;
|
||||
@@ -306,6 +312,12 @@ typedef struct {
|
||||
MT32EMU_SERVICE_I_V1
|
||||
} mt32emu_service_i_v1;
|
||||
|
||||
typedef struct {
|
||||
MT32EMU_SERVICE_I_V0
|
||||
MT32EMU_SERVICE_I_V1
|
||||
MT32EMU_SERVICE_I_V2
|
||||
} mt32emu_service_i_v2;
|
||||
|
||||
/**
|
||||
* Extensible interface for all the library services.
|
||||
* Union intended to view an interface of any subsequent version as any parent interface not requiring a cast.
|
||||
@@ -314,9 +326,11 @@ typedef struct {
|
||||
union mt32emu_service_i {
|
||||
const mt32emu_service_i_v0 *v0;
|
||||
const mt32emu_service_i_v1 *v1;
|
||||
const mt32emu_service_i_v2 *v2;
|
||||
};
|
||||
|
||||
#undef MT32EMU_SERVICE_I_V0
|
||||
#undef MT32EMU_SERVICE_I_V1
|
||||
#undef MT32EMU_SERVICE_I_V2
|
||||
|
||||
#endif /* #ifndef MT32EMU_C_TYPES_H */
|
||||
|
||||
@@ -61,6 +61,7 @@ mt32emu_service_i mt32emu_get_service_i();
|
||||
#define mt32emu_flush_midi_queue i.v0->flushMIDIQueue
|
||||
#define mt32emu_set_midi_event_queue_size i.v0->setMIDIEventQueueSize
|
||||
#define mt32emu_set_midi_receiver i.v0->setMIDIReceiver
|
||||
#define mt32emu_get_internal_rendered_sample_count iV2()->getInternalRenderedSampleCount
|
||||
#define mt32emu_parse_stream i.v0->parseStream
|
||||
#define mt32emu_parse_stream_at i.v0->parseStream_At
|
||||
#define mt32emu_play_short_message i.v0->playShortMessage
|
||||
@@ -90,6 +91,8 @@ mt32emu_service_i mt32emu_get_service_i();
|
||||
#define mt32emu_get_reverb_output_gain i.v0->getReverbOutputGain
|
||||
#define mt32emu_set_reversed_stereo_enabled i.v0->setReversedStereoEnabled
|
||||
#define mt32emu_is_reversed_stereo_enabled i.v0->isReversedStereoEnabled
|
||||
#define mt32emu_set_nice_amp_ramp_enabled iV2()->setNiceAmpRampEnabled
|
||||
#define mt32emu_is_nice_amp_ramp_enabled iV2()->isNiceAmpRampEnabled
|
||||
#define mt32emu_render_bit16s i.v0->renderBit16s
|
||||
#define mt32emu_render_float i.v0->renderFloat
|
||||
#define mt32emu_render_bit16s_streams i.v0->renderBit16sStreams
|
||||
@@ -213,6 +216,7 @@ public:
|
||||
void setMIDIReceiver(mt32emu_midi_receiver_i midi_receiver, void *instance_data) { mt32emu_set_midi_receiver(c, midi_receiver, instance_data); }
|
||||
void setMIDIReceiver(IMidiReceiver &midi_receiver) { setMIDIReceiver(CppInterfaceImpl::getMidiReceiverThunk(), &midi_receiver); }
|
||||
|
||||
Bit32u getInternalRenderedSampleCount() { return mt32emu_get_internal_rendered_sample_count(c); }
|
||||
void parseStream(const Bit8u *stream, Bit32u length) { mt32emu_parse_stream(c, stream, length); }
|
||||
void parseStream_At(const Bit8u *stream, Bit32u length, Bit32u timestamp) { mt32emu_parse_stream_at(c, stream, length, timestamp); }
|
||||
void playShortMessage(Bit32u message) { mt32emu_play_short_message(c, message); }
|
||||
@@ -249,6 +253,9 @@ public:
|
||||
void setReversedStereoEnabled(const bool enabled) { mt32emu_set_reversed_stereo_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); }
|
||||
bool isReversedStereoEnabled() { return mt32emu_is_reversed_stereo_enabled(c) != MT32EMU_BOOL_FALSE; }
|
||||
|
||||
void setNiceAmpRampEnabled(const bool enabled) { mt32emu_set_nice_amp_ramp_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); }
|
||||
bool isNiceAmpRampEnabled() { return mt32emu_is_nice_amp_ramp_enabled(c) != MT32EMU_BOOL_FALSE; }
|
||||
|
||||
void renderBit16s(Bit16s *stream, Bit32u len) { mt32emu_render_bit16s(c, stream, len); }
|
||||
void renderFloat(float *stream, Bit32u len) { mt32emu_render_float(c, stream, len); }
|
||||
void renderBit16sStreams(const mt32emu_dac_output_bit16s_streams *streams, Bit32u len) { mt32emu_render_bit16s_streams(c, streams, len); }
|
||||
@@ -271,6 +278,7 @@ private:
|
||||
|
||||
#if MT32EMU_API_TYPE == 2
|
||||
const mt32emu_service_i_v1 *iV1() { return (getVersionID() < MT32EMU_SERVICE_VERSION_1) ? NULL : i.v1; }
|
||||
const mt32emu_service_i_v2 *iV2() { return (getVersionID() < MT32EMU_SERVICE_VERSION_2) ? NULL : i.v2; }
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -421,6 +429,7 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() {
|
||||
#undef mt32emu_flush_midi_queue
|
||||
#undef mt32emu_set_midi_event_queue_size
|
||||
#undef mt32emu_set_midi_receiver
|
||||
#undef mt32emu_get_internal_rendered_sample_count
|
||||
#undef mt32emu_parse_stream
|
||||
#undef mt32emu_parse_stream_at
|
||||
#undef mt32emu_play_short_message
|
||||
@@ -450,6 +459,8 @@ static mt32emu_midi_receiver_i getMidiReceiverThunk() {
|
||||
#undef mt32emu_get_reverb_output_gain
|
||||
#undef mt32emu_set_reversed_stereo_enabled
|
||||
#undef mt32emu_is_reversed_stereo_enabled
|
||||
#undef mt32emu_set_nice_amp_ramp_enabled
|
||||
#undef mt32emu_is_nice_amp_ramp_enabled
|
||||
#undef mt32emu_render_bit16s
|
||||
#undef mt32emu_render_float
|
||||
#undef mt32emu_render_bit16s_streams
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
#ifndef MT32EMU_CONFIG_H
|
||||
#define MT32EMU_CONFIG_H
|
||||
|
||||
#define MT32EMU_VERSION "2.1.0"
|
||||
#define MT32EMU_VERSION "2.2.0"
|
||||
#define MT32EMU_VERSION_MAJOR 2
|
||||
#define MT32EMU_VERSION_MINOR 1
|
||||
#define MT32EMU_VERSION_MINOR 2
|
||||
#define MT32EMU_VERSION_PATCH 0
|
||||
|
||||
/* Library Exports Configuration
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
#define MT32EMU_MAX_STREAM_BUFFER_SIZE 32768
|
||||
|
||||
/* This should correspond to the MIDI buffer size used in real h/w devices.
|
||||
* CM-32L control ROM seems using 1000 bytes, old MT-32 isn't confirmed by now.
|
||||
* CM-32L control ROM is using 1000 bytes, and MT-32 GEN0 is using only 240 bytes (semi-confirmed by now).
|
||||
*/
|
||||
#define MT32EMU_SYSEX_BUFFER_SIZE 1000
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ typedef float FloatSample;
|
||||
/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */
|
||||
class FloatSampleProvider {
|
||||
public:
|
||||
virtual ~FloatSampleProvider() {};
|
||||
virtual ~FloatSampleProvider() {}
|
||||
|
||||
virtual void getOutputSamples(FloatSample *outBuffer, unsigned int size) = 0;
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace SRCTools {
|
||||
/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */
|
||||
class ResamplerStage {
|
||||
public:
|
||||
virtual ~ResamplerStage() {};
|
||||
virtual ~ResamplerStage() {}
|
||||
|
||||
/** Returns a lower estimation of required number of input samples to produce the specified number of output samples. */
|
||||
virtual unsigned int estimateInLength(const unsigned int outLength) const = 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,69 +1,300 @@
|
||||
/* All these defines are in samples, not in bytes. */
|
||||
#define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF
|
||||
#define EMU8K_RAM_MEM_START 0x200000
|
||||
#define EMU8K_ROM_MEM_1MB_END 0x80000
|
||||
#define EMU8K_FM_MEM_ADDRESS 0xFFFFE0
|
||||
#define EMU8K_RAM_POINTERS_MASK 0x3F
|
||||
|
||||
/*
|
||||
Everything in this file assumes little endian
|
||||
|
||||
used for the increment of oscillator position */
|
||||
typedef struct emu8k_mem_internal_t {
|
||||
union {
|
||||
uint64_t addr;
|
||||
struct {
|
||||
uint16_t fract_lw_address;
|
||||
uint16_t fract_address;
|
||||
uint32_t int_address;
|
||||
};
|
||||
};
|
||||
} emu8k_mem_internal_t;
|
||||
|
||||
/* used for access to ram pointers from oscillator position. */
|
||||
typedef struct emu8k_mem_pointers_t {
|
||||
union {
|
||||
uint32_t addr;
|
||||
struct {
|
||||
uint16_t lw_address;
|
||||
uint8_t hb_address;
|
||||
uint8_t unused_address;
|
||||
};
|
||||
};
|
||||
} emu8k_mem_pointers_t;
|
||||
|
||||
/*
|
||||
* From the Soundfount 2.0 fileformat Spec.:
|
||||
*
|
||||
An envelope generates a control signal in six phases.
|
||||
When key-on occurs, a delay period begins during which the envelope value is zero.
|
||||
The envelope then rises in a convex curve to a value of one during the attack phase.
|
||||
" Note that the attack is convex; the curve is nominally such that when applied to a
|
||||
decibel or semitone parameter, the result is linear in amplitude or Hz respectively"
|
||||
|
||||
When a value of one is reached, the envelope enters a hold phase during which it remains at one.
|
||||
When the hold phase ends, the envelope enters a decay phase during which its value decreases linearly to a sustain level.
|
||||
" For the Volume Envelope, the decay phase linearly ramps toward the sustain level, causing a constant dB change for each time unit. "
|
||||
When the sustain level is reached, the envelope enters sustain phase, during which the envelope stays at the sustain level.
|
||||
|
||||
Whenever a key-off occurs, the envelope immediately enters a release phase during which the value linearly ramps from the current value to zero.
|
||||
" For the Volume Envelope, the release phase linearly ramps toward zero from the current level, causing a constant dB change for each time unit"
|
||||
|
||||
When zero is reached, the envelope value remains at zero.
|
||||
|
||||
Modulation of pitch and filter cutoff are in octaves, semitones, and cents.
|
||||
These parameters can be modulated to varying degree, either positively or negatively, by the modulation envelope.
|
||||
The degree of modulation is specified in cents for the full-scale attack peak.
|
||||
|
||||
The volume envelope operates in dB, with the attack peak providing a full scale output, appropriately scaled by the initial volume.
|
||||
The zero value, however, is actually zero gain.
|
||||
The implementation in the EMU8000 provides for 96 dB of amplitude control.
|
||||
When 96 dB of attenuation is reached in the final gain amplifier, an abrupt jump to zero gain (infinite dB of attenuation) occurs. In a 16-bit system, this jump is inaudible
|
||||
*/
|
||||
/* It seems that the envelopes don't really have a decay/release stage,
|
||||
but instead they have a volume ramper that can be triggered
|
||||
automatically (after hold period), or manually (by activating release)
|
||||
and the "sustain" value is the target of any of both cases.
|
||||
Some programs like cubic player and AWEAmp use this, and it was
|
||||
described in the following way in Vince Vu/Judge Dredd's awe32p10.txt:
|
||||
If the MSB (most significant bit or bit 15) of this register is set,
|
||||
the Decay/Release will begin immediately, overriding the Delay, Attack,
|
||||
and Hold. Otherwise the Decay/Release will wait until the Delay, Attack,
|
||||
and Hold are finished. If you set the MSB of this register, you can use
|
||||
it as a volume ramper, as on the GUS. The upper byte (except the MSB),
|
||||
contains the destination volume, and the lower byte contains the ramp time. */
|
||||
|
||||
/* attack_amount is linear amplitude (added directly to value). ramp_amount_db is linear dB (added directly to value too, but needs conversion to get linear amplitude).
|
||||
value range is 21bits for both, linear amplitude being 1<<21 = 0dBFS and 0 = -96dBFS (which is shortcut to silence), and db amplutide being 0 = 0dBFS and -(1<<21) = -96dBFS (which is shortcut to silence). This allows to operate db values by simply adding them. */
|
||||
typedef struct emu8k_envelope_t {
|
||||
int state;
|
||||
int32_t delay_samples, hold_samples, attack_samples;
|
||||
int32_t value_amp_hz, value_db_oct;
|
||||
int32_t sustain_value_db_oct;
|
||||
int32_t attack_amount_amp_hz, ramp_amount_db_oct;
|
||||
} emu8k_envelope_t;
|
||||
|
||||
|
||||
|
||||
/* Chorus Params */
|
||||
typedef struct {
|
||||
uint16_t FbkLevReg; /* Feedback Level (0xE600-0xE6FF) */
|
||||
uint16_t Delay; /* Delay (0-0x0DA3) [1/44100 sec] */
|
||||
uint16_t LfoDepReg; /* LFO Depth (0xBC00-0xBCFF) */
|
||||
uint32_t DelayR; /* Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] */
|
||||
uint32_t LfoFreq; /* LFO Frequency (0-0xFFFFFFFF) */
|
||||
} emu8k_chorus_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t write;
|
||||
int32_t feedback;
|
||||
int32_t delay_samples_central;
|
||||
int32_t lfodepth_samples;
|
||||
emu8k_mem_internal_t delay_offset_samples_right;
|
||||
emu8k_mem_internal_t lfo_inc;
|
||||
emu8k_mem_internal_t lfo_pos;
|
||||
|
||||
int32_t chorus_left_buffer[SOUNDBUFLEN];
|
||||
int32_t chorus_right_buffer[SOUNDBUFLEN];
|
||||
|
||||
} emu8k_chorus_eng_t;
|
||||
|
||||
typedef struct emu8k_voice_t
|
||||
{
|
||||
union {
|
||||
uint32_t cpf;
|
||||
struct {
|
||||
uint16_t cpf_curr_frac_addr; /* fractional part of the playing cursor. */
|
||||
uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint32_t ptrx;
|
||||
struct {
|
||||
uint8_t ptrx_pan_aux;
|
||||
uint8_t ptrx_revb_send;
|
||||
uint16_t ptrx_pit_target; /* target pitch to which slide at curr_pitch speed. */
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint32_t cvcf;
|
||||
struct {
|
||||
uint16_t cvcf_curr_filt_ctoff;
|
||||
uint16_t cvcf_curr_volume;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint32_t vtft;
|
||||
struct {
|
||||
uint16_t vtft_filter_target;
|
||||
uint16_t vtft_vol_target; /* written to by the envelope engine. */
|
||||
};
|
||||
};
|
||||
/* These registers are used at least by the Windows drivers, and seem to be resetting
|
||||
something, similarly to targets and current, but... of what?
|
||||
what is curious is that if they are already zero, they are not written to, so it really
|
||||
looks like they are information about the status of the channel. (lfo position maybe?) */
|
||||
uint32_t unknown_data0_4;
|
||||
uint32_t unknown_data0_5;
|
||||
union {
|
||||
uint32_t psst;
|
||||
struct {
|
||||
uint16_t psst_lw_address;
|
||||
uint8_t psst_hw_address;
|
||||
uint8_t psst_pan;
|
||||
};
|
||||
#define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */
|
||||
};
|
||||
union {
|
||||
uint32_t csl;
|
||||
struct {
|
||||
uint16_t csl_lw_address;
|
||||
uint8_t csl_hw_address;
|
||||
uint8_t csl_chor_send;
|
||||
};
|
||||
#define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */
|
||||
};
|
||||
union {
|
||||
uint32_t ccca;
|
||||
struct {
|
||||
uint16_t ccca_lw_addr;
|
||||
uint8_t ccca_hb_addr;
|
||||
uint8_t ccca_qcontrol;
|
||||
};
|
||||
};
|
||||
#define CCCA_FILTQ_GET(ccca) (ccca>>28)
|
||||
#define CCCA_FILTQ_SET(ccca,q) ccca = (ccca&0x0FFFFFFF) | (q<<28)
|
||||
/* Bit 27 should always be zero */
|
||||
#define CCCA_DMA_ACTIVE(ccca) (ccca&0x04000000)
|
||||
#define CCCA_DMA_WRITE_MODE(ccca) (ccca&0x02000000)
|
||||
#define CCCA_DMA_WRITE_RIGHT(ccca) (ccca&0x01000000)
|
||||
|
||||
uint16_t envvol;
|
||||
#define ENVVOL_NODELAY(envol) (envvol&0x8000)
|
||||
/* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */
|
||||
#define ENVVOL_TO_EMU_SAMPLES(envvol) (envvol&0x8000) ? 0 : ((0x8000-(envvol&0x7FFF)) <<5)
|
||||
|
||||
uint16_t dcysusv;
|
||||
#define DCYSUSV_IS_RELEASE(dcysusv) (dcysusv&0x8000)
|
||||
#define DCYSUSV_GENERATOR_ENGINE_ON(dcysusv) !(dcysusv&0x0080)
|
||||
#define DCYSUSV_SUSVALUE_GET(dcysusv) ((dcysusv>>8)&0x7F)
|
||||
/* Inverting the range compared to documentation because the envelope runs from 0dBFS = 0 to -96dBFS = (1 <<21) */
|
||||
#define DCYSUSV_SUS_TO_ENV_RANGE(susvalue) (((0x7F-susvalue) << 21)/0x7F)
|
||||
#define DCYSUSV_DECAYRELEASE_GET(dcysusv) (dcysusv&0x7F)
|
||||
|
||||
uint16_t envval;
|
||||
#define ENVVAL_NODELAY(enval) (envval&0x8000)
|
||||
/* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */
|
||||
#define ENVVAL_TO_EMU_SAMPLES(envval)(envval&0x8000) ? 0 : ((0x8000-(envval&0x7FFF)) <<5)
|
||||
|
||||
uint16_t dcysus;
|
||||
#define DCYSUS_IS_RELEASE(dcysus) (dcysus&0x8000)
|
||||
#define DCYSUS_SUSVALUE_GET(dcysus) ((dcysus>>8)&0x7F)
|
||||
#define DCYSUS_SUS_TO_ENV_RANGE(susvalue) ((susvalue << 21)/0x7F)
|
||||
#define DCYSUS_DECAYRELEASE_GET(dcysus) (dcysus&0x7F)
|
||||
|
||||
uint16_t atkhldv;
|
||||
#define ATKHLDV_TRIGGER(atkhldv) !(atkhldv&0x8000)
|
||||
#define ATKHLDV_HOLD(atkhldv) ((atkhldv>>8)&0x7F)
|
||||
#define ATKHLDV_HOLD_TO_EMU_SAMPLES(atkhldv) (4096*(0x7F-((atkhldv>>8)&0x7F)))
|
||||
#define ATKHLDV_ATTACK(atkhldv) (atkhldv&0x7F)
|
||||
|
||||
uint16_t lfo1val, lfo2val;
|
||||
#define LFOxVAL_NODELAY(lfoxval) (lfoxval&0x8000)
|
||||
#define LFOxVAL_TO_EMU_SAMPLES(lfoxval) (lfoxval&0x8000) ? 0 : ((0x8000-(lfoxval&0x7FFF)) <<5)
|
||||
|
||||
uint16_t atkhld;
|
||||
#define ATKHLD_TRIGGER(atkhld) !(atkhld&0x8000)
|
||||
#define ATKHLD_HOLD(atkhld) ((atkhld>>8)&0x7F)
|
||||
#define ATKHLD_HOLD_TO_EMU_SAMPLES(atkhld) (4096*(0x7F-((atkhld>>8)&0x7F)))
|
||||
#define ATKHLD_ATTACK(atkhld) (atkhld&0x7F)
|
||||
|
||||
|
||||
uint16_t ip;
|
||||
#define INTIAL_PITCH_CENTER 0xE000
|
||||
#define INTIAL_PITCH_OCTAVE 0x1000
|
||||
|
||||
union {
|
||||
uint16_t ifatn;
|
||||
struct{
|
||||
uint8_t ifatn_attenuation;
|
||||
uint8_t ifatn_init_filter;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint16_t pefe;
|
||||
struct {
|
||||
int8_t pefe_modenv_filter_height;
|
||||
int8_t pefe_modenv_pitch_height;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint16_t fmmod;
|
||||
struct {
|
||||
int8_t fmmod_lfo1_filt_mod;
|
||||
int8_t fmmod_lfo1_vibrato;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint16_t tremfrq;
|
||||
struct {
|
||||
uint8_t tremfrq_lfo1_freq;
|
||||
int8_t tremfrq_lfo1_tremolo;
|
||||
};
|
||||
};
|
||||
union {
|
||||
uint16_t fm2frq2;
|
||||
struct {
|
||||
uint8_t fm2frq2_lfo2_freq;
|
||||
int8_t fm2frq2_lfo2_vibrato;
|
||||
};
|
||||
};
|
||||
|
||||
int env_engine_on;
|
||||
|
||||
emu8k_mem_internal_t addr, loop_start, loop_end;
|
||||
|
||||
int32_t initial_att;
|
||||
int32_t initial_filter;
|
||||
|
||||
emu8k_envelope_t vol_envelope;
|
||||
emu8k_envelope_t mod_envelope;
|
||||
|
||||
int64_t lfo1_speed, lfo2_speed;
|
||||
emu8k_mem_internal_t lfo1_count, lfo2_count;
|
||||
int32_t lfo1_delay_samples, lfo2_delay_samples;
|
||||
int vol_l, vol_r;
|
||||
|
||||
int16_t fixed_modenv_filter_height;
|
||||
int16_t fixed_modenv_pitch_height;
|
||||
int16_t fixed_lfo1_filt_mod;
|
||||
int16_t fixed_lfo1_vibrato;
|
||||
int16_t fixed_lfo1_tremolo;
|
||||
int16_t fixed_lfo2_vibrato;
|
||||
|
||||
/* filter internal data. */
|
||||
int filterq_idx;
|
||||
int32_t filt_att;
|
||||
int64_t filt_buffer[5];
|
||||
|
||||
} emu8k_voice_t;
|
||||
|
||||
typedef struct emu8k_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t cpf;
|
||||
uint32_t ptrx;
|
||||
uint32_t cvcf;
|
||||
uint32_t vtft;
|
||||
uint32_t psst;
|
||||
uint32_t csl;
|
||||
|
||||
uint32_t ccca;
|
||||
emu8k_voice_t voice[32];
|
||||
|
||||
uint16_t init1, init2, init3, init4;
|
||||
|
||||
uint16_t envvol;
|
||||
uint16_t dcysusv;
|
||||
uint16_t envval;
|
||||
uint16_t dcysus;
|
||||
uint16_t atkhldv;
|
||||
uint16_t lfo1val, lfo2val;
|
||||
uint16_t atkhld;
|
||||
uint16_t ip;
|
||||
uint16_t ifatn;
|
||||
uint16_t pefe;
|
||||
uint16_t fmmod;
|
||||
uint16_t tremfrq;
|
||||
uint16_t fm2frq2;
|
||||
|
||||
int voice_on;
|
||||
|
||||
uint64_t addr;
|
||||
uint64_t loop_start, loop_end;
|
||||
|
||||
uint16_t pitch;
|
||||
int attenuation;
|
||||
int env_state, env_vol;
|
||||
int env_attack, env_decay, env_sustain, env_release;
|
||||
uint16_t hwcf1, hwcf2, hwcf3;
|
||||
uint32_t hwcf4, hwcf5, hwcf6, hwcf7;
|
||||
|
||||
int menv_state, menv_vol;
|
||||
int menv_attack, menv_decay, menv_sustain, menv_release;
|
||||
|
||||
int lfo1_count, lfo2_count;
|
||||
int8_t lfo1_fmmod, lfo2_fmmod;
|
||||
int8_t lfo1_trem;
|
||||
int vol_l, vol_r;
|
||||
|
||||
int8_t fe_height;
|
||||
|
||||
int64_t vlp, vbp, vhp;
|
||||
int32_t q;
|
||||
|
||||
int filter_offset;
|
||||
|
||||
/* float vlp, vbp, vhp;
|
||||
float q;*/
|
||||
|
||||
int cutoff;
|
||||
} voice[32];
|
||||
|
||||
uint32_t hwcf1, hwcf2, hwcf3;
|
||||
uint32_t hwcf4, hwcf5, hwcf6;
|
||||
uint16_t init1[32], init2[32], init3[32], init4[32];
|
||||
|
||||
uint32_t smalr, smarr, smalw, smarw;
|
||||
uint16_t smld_buffer, smrd_buffer;
|
||||
@@ -72,22 +303,32 @@ typedef struct emu8k_t
|
||||
|
||||
uint16_t c02_read;
|
||||
|
||||
uint16_t id;
|
||||
|
||||
int16_t *ram, *rom;
|
||||
|
||||
uint16_t id;
|
||||
|
||||
/* The empty block is used to act as an unallocated memory returning zero. */
|
||||
int16_t *ram, *rom, *empty;
|
||||
|
||||
/* RAM pointers are a way to avoid checking ram boundaries on read */
|
||||
int16_t *ram_pointers[0x100];
|
||||
uint32_t ram_end_addr;
|
||||
|
||||
|
||||
int cur_reg, cur_voice;
|
||||
|
||||
int timer_count;
|
||||
|
||||
int16_t out_l, out_r;
|
||||
|
||||
emu8k_chorus_eng_t chorus_engine;
|
||||
int32_t chorus_in_buffer[SOUNDBUFLEN];
|
||||
int32_t reverb_in_buffer[SOUNDBUFLEN];
|
||||
int32_t reverb_out_buffer[SOUNDBUFLEN * 2];
|
||||
|
||||
int pos;
|
||||
int32_t buffer[SOUNDBUFLEN * 2];
|
||||
} emu8k_t;
|
||||
|
||||
|
||||
|
||||
void emu8k_init(emu8k_t *emu8k, int onboard_ram);
|
||||
void emu8k_close(emu8k_t *emu8k);
|
||||
|
||||
|
||||
@@ -341,13 +341,27 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
while (c<65536)
|
||||
{
|
||||
int dma_result;
|
||||
d = gus->ram[gus->dmaaddr];
|
||||
if (val & 0x80) d ^= 0x80;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
if (dma_result == DMA_NODATA)
|
||||
break;
|
||||
if (val & 0x04)
|
||||
{
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
|
||||
d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8);
|
||||
if (val & 0x80)
|
||||
d ^= 0x8080;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
if (dma_result == DMA_NODATA)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
d = gus->ram[gus->dmaaddr];
|
||||
if (val & 0x80)
|
||||
d ^= 0x80;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
if (dma_result == DMA_NODATA)
|
||||
break;
|
||||
}
|
||||
gus->dmaaddr++;
|
||||
gus->dmaaddr&=0xFFFFF;
|
||||
gus->dmaaddr &= 0xFFFFF;
|
||||
c++;
|
||||
if (dma_result & DMA_OVER)
|
||||
break;
|
||||
@@ -363,10 +377,22 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
d = dma_channel_read(gus->dma);
|
||||
if (d == DMA_NODATA)
|
||||
break;
|
||||
if (val&0x80) d^=0x80;
|
||||
gus->ram[gus->dmaaddr]=d;
|
||||
if (val & 0x04)
|
||||
{
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
|
||||
if (val & 0x80)
|
||||
d ^= 0x8080;
|
||||
gus->ram[gus_addr] = d & 0xff;
|
||||
gus->ram[gus_addr +1] = (d >> 8) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val & 0x80)
|
||||
d ^= 0x80;
|
||||
gus->ram[gus->dmaaddr] = d;
|
||||
}
|
||||
gus->dmaaddr++;
|
||||
gus->dmaaddr&=0xFFFFF;
|
||||
gus->dmaaddr &= 0xFFFFF;
|
||||
c++;
|
||||
if (d & DMA_OVER)
|
||||
break;
|
||||
|
||||
@@ -652,8 +652,8 @@ void cirrus_bitblt_start(clgd_t *clgd, svga_t *svga)
|
||||
clgd->blt.height = (svga->gdcreg[0x22] | (svga->gdcreg[0x23] << 8)) + 1;
|
||||
clgd->blt.dst_pitch = (svga->gdcreg[0x24] | (svga->gdcreg[0x25] << 8));
|
||||
clgd->blt.src_pitch = (svga->gdcreg[0x26] | (svga->gdcreg[0x27] << 8));
|
||||
clgd->blt.dst_addr = (svga->gdcreg[0x28] | (svga->gdcreg[0x29] << 8) || (svga->gdcreg[0x2a] << 16));
|
||||
clgd->blt.src_addr = (svga->gdcreg[0x2c] | (svga->gdcreg[0x2d] << 8) || (svga->gdcreg[0x2e] << 16));
|
||||
clgd->blt.dst_addr = (svga->gdcreg[0x28] | (svga->gdcreg[0x29] << 8) | (svga->gdcreg[0x2a] << 16));
|
||||
clgd->blt.src_addr = (svga->gdcreg[0x2c] | (svga->gdcreg[0x2d] << 8) | (svga->gdcreg[0x2e] << 16));
|
||||
clgd->blt.mode = svga->gdcreg[0x30];
|
||||
clgd->blt.modeext = svga->gdcreg[0x33];
|
||||
blt_rop = svga->gdcreg[0x32];
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* Emulation of the EGA, Chips & Technologies SuperEGA, and
|
||||
* AX JEGA graphics cards.
|
||||
*
|
||||
* Version: @(#)vid_ega.c 1.0.2 2017/06/05
|
||||
* Version: @(#)vid_ega.c 1.0.3 2017/07/21
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -45,6 +45,7 @@ static int old_overscan_color = 0;
|
||||
|
||||
int update_overscan = 0;
|
||||
|
||||
#ifdef JEGA
|
||||
uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */
|
||||
uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */
|
||||
|
||||
@@ -146,6 +147,7 @@ void ega_jega_read_font(ega_t *ega)
|
||||
ega->font_index++;
|
||||
ega->RSTAT |= 0x02;
|
||||
}
|
||||
#endif
|
||||
|
||||
void ega_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
@@ -259,7 +261,11 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
|
||||
return;
|
||||
case 0x3d1:
|
||||
case 0x3d5:
|
||||
#ifdef JEGA
|
||||
if ((ega->crtcreg < 0xb9) || !ega->is_jega)
|
||||
#else
|
||||
if (ega->crtcreg < 0xb9)
|
||||
#endif
|
||||
{
|
||||
crtcreg = ega->crtcreg & 0x1f;
|
||||
if (crtcreg <= 7 && ega->crtc[0x11] & 0x80) return;
|
||||
@@ -274,6 +280,7 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef JEGA
|
||||
else
|
||||
{
|
||||
switch(ega->crtcreg)
|
||||
@@ -331,6 +338,7 @@ void ega_out(uint16_t addr, uint8_t val, void *p)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -391,11 +399,16 @@ uint8_t ega_in(uint16_t addr, void *p)
|
||||
return ega->crtcreg;
|
||||
case 0x3d1:
|
||||
case 0x3d5:
|
||||
#ifdef JEGA
|
||||
if ((ega->crtcreg < 0xb9) || !ega->is_jega)
|
||||
#else
|
||||
if (ega->crtcreg < 0xb9)
|
||||
#endif
|
||||
{
|
||||
crtcreg = ega->crtcreg & 0x1f;
|
||||
return ega->crtc[crtcreg];
|
||||
}
|
||||
#ifdef JEGA
|
||||
else
|
||||
{
|
||||
switch(ega->crtcreg)
|
||||
@@ -434,6 +447,8 @@ uint8_t ega_in(uint16_t addr, void *p)
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0xff;
|
||||
case 0x3da:
|
||||
ega->attrff = 0;
|
||||
ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/
|
||||
@@ -454,7 +469,7 @@ void ega_recalctimings(ega_t *ega)
|
||||
|
||||
if (ega->crtc[7] & 1) ega->vtotal |= 0x100;
|
||||
if (ega->crtc[7] & 32) ega->vtotal |= 0x200;
|
||||
ega->vtotal++;
|
||||
ega->vtotal += 2;
|
||||
|
||||
if (ega->crtc[7] & 2) ega->dispend |= 0x100;
|
||||
if (ega->crtc[7] & 64) ega->dispend |= 0x200;
|
||||
@@ -466,7 +481,7 @@ void ega_recalctimings(ega_t *ega)
|
||||
|
||||
if (ega->crtc[7] & 0x10) ega->split |= 0x100;
|
||||
if (ega->crtc[9] & 0x40) ega->split |= 0x200;
|
||||
ega->split+=2;
|
||||
ega->split++;
|
||||
|
||||
ega->hdisp = ega->crtc[1];
|
||||
ega->hdisp++;
|
||||
@@ -532,13 +547,20 @@ void ega_poll(void *p)
|
||||
}
|
||||
else if (!(ega->gdcreg[6] & 1))
|
||||
{
|
||||
if (ega_jega_enabled(ega))
|
||||
{
|
||||
ega_render_text_jega(ega, drawcursor);
|
||||
}
|
||||
else
|
||||
if (fullchange)
|
||||
{
|
||||
#ifdef JEGA
|
||||
if (ega_jega_enabled(ega))
|
||||
{
|
||||
ega_render_text_jega(ega, drawcursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
ega_render_text_standard(ega, drawcursor);
|
||||
}
|
||||
#else
|
||||
ega_render_text_standard(ega, drawcursor);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -572,6 +594,8 @@ void ega_poll(void *p)
|
||||
}
|
||||
|
||||
ega->displine++;
|
||||
if (ega->interlace)
|
||||
ega->displine++;
|
||||
if ((ega->stat & 8) && ((ega->displine & 15) == (ega->crtc[0x11] & 15)) && ega->vslines)
|
||||
ega->stat &= ~8;
|
||||
ega->vslines++;
|
||||
@@ -595,6 +619,8 @@ void ega_poll(void *p)
|
||||
ega->con = 0;
|
||||
|
||||
ega->maback += (ega->rowoffset << 3);
|
||||
if (ega->interlace)
|
||||
ega->maback += (ega->rowoffset << 3);
|
||||
ega->maback &= ega->vrammask;
|
||||
ega->ma = ega->maback;
|
||||
}
|
||||
@@ -631,10 +657,14 @@ void ega_poll(void *p)
|
||||
ega->stat |= 8;
|
||||
if (ega->seqregs[1] & 8) x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9) * 2;
|
||||
else x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9);
|
||||
if ((x != xsize || (ega->lastline - ega->firstline) != ysize) || update_overscan)
|
||||
|
||||
if (ega->interlace && !ega->oddeven) ega->lastline++;
|
||||
if (ega->interlace && ega->oddeven) ega->firstline--;
|
||||
|
||||
if ((x != xsize || (ega->lastline - ega->firstline + 1) != ysize) || update_overscan)
|
||||
{
|
||||
xsize = x;
|
||||
ysize = ega->lastline - ega->firstline;
|
||||
ysize = ega->lastline - ega->firstline + 1;
|
||||
if (xsize < 64) xsize = 640;
|
||||
if (ysize < 32) ysize = 200;
|
||||
y_add = enable_overscan ? 14 : 0;
|
||||
@@ -714,7 +744,7 @@ void ega_poll(void *p)
|
||||
}
|
||||
}
|
||||
|
||||
video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline + y_add_ex, xsize + x_add_ex, ega->lastline - ega->firstline + y_add_ex);
|
||||
video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline + 1 + y_add_ex, xsize + x_add_ex, ega->lastline - ega->firstline + 1 + y_add_ex);
|
||||
|
||||
frames++;
|
||||
|
||||
@@ -754,7 +784,7 @@ void ega_poll(void *p)
|
||||
ega->vc = 0;
|
||||
ega->sc = 0;
|
||||
ega->dispon = 1;
|
||||
ega->displine = 0;
|
||||
ega->displine = (ega->interlace && ega->oddeven) ? 1 : 0;
|
||||
ega->scrollcache = ega->attrregs[0x13] & 7;
|
||||
}
|
||||
if (ega->sc == (ega->crtc[10] & 31))
|
||||
@@ -1005,7 +1035,9 @@ void ega_common_defaults(ega_t *ega)
|
||||
|
||||
update_overscan = 0;
|
||||
|
||||
#ifdef JEGA
|
||||
ega->is_jega = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void *ega_standalone_init()
|
||||
@@ -1127,6 +1159,7 @@ void *sega_standalone_init()
|
||||
return ega;
|
||||
}
|
||||
|
||||
#ifdef JEGA
|
||||
uint16_t chrtosht(FILE *fp)
|
||||
{
|
||||
uint16_t i, j;
|
||||
@@ -1232,6 +1265,7 @@ void *jega_standalone_init()
|
||||
|
||||
return ega;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ega_standalone_available()
|
||||
{
|
||||
@@ -1326,6 +1360,7 @@ device_t sega_device =
|
||||
ega_config
|
||||
};
|
||||
|
||||
#ifdef JEGA
|
||||
device_t jega_device =
|
||||
{
|
||||
"AX JEGA",
|
||||
@@ -1338,3 +1373,4 @@ device_t jega_device =
|
||||
NULL,
|
||||
ega_config
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -91,11 +91,13 @@ typedef struct ega_t
|
||||
|
||||
int video_res_x, video_res_y, video_bpp;
|
||||
|
||||
#ifdef JEGA
|
||||
uint8_t RMOD1, RMOD2, RDAGS, RDFFB, RDFSB, RDFAP, RPESL, RPULP, RPSSC, RPSSU, RPSSL;
|
||||
uint8_t RPPAJ;
|
||||
uint8_t RCMOD, RCCLH, RCCLL, RCCSL, RCCEL, RCSKW, ROMSL, RSTAT;
|
||||
int is_jega, font_index;
|
||||
int chr_left, chr_wide;
|
||||
#endif
|
||||
} ega_t;
|
||||
|
||||
extern int update_overscan;
|
||||
@@ -113,6 +115,7 @@ extern device_t ega_device;
|
||||
extern device_t cpqega_device;
|
||||
extern device_t sega_device;
|
||||
|
||||
#ifdef JEGA
|
||||
#define SBCS 0
|
||||
#define DBCS 1
|
||||
#define ID_LEN 6
|
||||
@@ -122,3 +125,4 @@ extern device_t sega_device;
|
||||
|
||||
extern uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */
|
||||
extern uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */
|
||||
#endif
|
||||
|
||||
@@ -146,6 +146,7 @@ void ega_render_text_standard(ega_t *ega, int drawcursor)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JEGA
|
||||
static __inline int is_kanji1(uint8_t chr)
|
||||
{
|
||||
return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc);
|
||||
@@ -374,6 +375,7 @@ void ega_render_text_jega(ega_t *ega, int drawcursor)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ega_render_2bpp_lowres(ega_t *ega)
|
||||
{
|
||||
|
||||
@@ -29,7 +29,9 @@ extern uint8_t edatlookup[4][4];
|
||||
|
||||
void ega_render_blank(ega_t *ega);
|
||||
void ega_render_text_standard(ega_t *ega, int drawcursor);
|
||||
#ifdef JEGA
|
||||
void ega_render_text_jega(ega_t *ega, int drawcursor);
|
||||
#endif
|
||||
|
||||
void ega_render_2bpp_lowres(ega_t *ega);
|
||||
void ega_render_2bpp_highres(ega_t *ega);
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
#include "../device.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
#include "vid_sc1502x_ramdac.h"
|
||||
#include "vid_et4000.h"
|
||||
|
||||
|
||||
typedef struct et4000_t
|
||||
{
|
||||
svga_t svga;
|
||||
unk_ramdac_t ramdac;
|
||||
sc1502x_ramdac_t ramdac;
|
||||
|
||||
rom_t bios_rom;
|
||||
|
||||
@@ -49,7 +49,7 @@ void et4000_out(uint16_t addr, uint8_t val, void *p)
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
unk_ramdac_out(addr, val, &et4000->ramdac, svga);
|
||||
sc1502x_ramdac_out(addr, val, &et4000->ramdac, svga);
|
||||
return;
|
||||
|
||||
case 0x3CD: /*Banking*/
|
||||
@@ -96,7 +96,7 @@ uint8_t et4000_in(uint16_t addr, void *p)
|
||||
break;
|
||||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
return unk_ramdac_in(addr, &et4000->ramdac, svga);
|
||||
return sc1502x_ramdac_in(addr, &et4000->ramdac, svga);
|
||||
|
||||
case 0x3CD: /*Banking*/
|
||||
return et4000->banking;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,6 @@
|
||||
#include "vid_paradise.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
|
||||
|
||||
typedef struct paradise_t
|
||||
|
||||
@@ -638,7 +638,7 @@ static void s3_virge_updatemapping(virge_t *virge)
|
||||
return;
|
||||
}
|
||||
|
||||
pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
|
||||
//pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc);
|
||||
switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
|
||||
{
|
||||
case 0x0: /*128k at A0000*/
|
||||
@@ -661,7 +661,7 @@ static void s3_virge_updatemapping(virge_t *virge)
|
||||
|
||||
virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24);
|
||||
|
||||
pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10);
|
||||
//pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10);
|
||||
if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/
|
||||
{
|
||||
switch (svga->crtc[0x58] & 3)
|
||||
@@ -681,7 +681,7 @@ static void s3_virge_updatemapping(virge_t *virge)
|
||||
}
|
||||
virge->linear_base &= ~(virge->linear_size - 1);
|
||||
svga->linear_base = virge->linear_base;
|
||||
pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size);
|
||||
//pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size);
|
||||
if (virge->linear_base == 0xa0000)
|
||||
{
|
||||
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
|
||||
@@ -697,7 +697,7 @@ static void s3_virge_updatemapping(virge_t *virge)
|
||||
svga->fb_only = 0;
|
||||
}
|
||||
|
||||
pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18);
|
||||
//pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x18);
|
||||
if (svga->crtc[0x53] & 0x10) /*Old MMIO*/
|
||||
{
|
||||
if (svga->crtc[0x53] & 0x20)
|
||||
@@ -1352,14 +1352,27 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
||||
|
||||
if ((addr & 0xfffc) < 0x8000)
|
||||
{
|
||||
if ((addr & 0xe000) == 0)
|
||||
{
|
||||
if (virge->s3d.cmd_set & CMD_SET_MS)
|
||||
s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
else
|
||||
s3_virge_bitblt(virge, 32, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD);
|
||||
}
|
||||
else if ((addr & 0xe000) == 0xa000)
|
||||
{
|
||||
s3_virge_queue(virge, addr, val, FIFO_WRITE_DWORD);
|
||||
}
|
||||
}
|
||||
else switch (addr & 0xfffc)
|
||||
{
|
||||
case 0:
|
||||
if (virge->s3d.cmd_set & CMD_SET_MS)
|
||||
s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
|
||||
else
|
||||
s3_virge_bitblt(virge, 32, val);
|
||||
break;
|
||||
|
||||
case 0x8180:
|
||||
virge->streams.pri_ctrl = val;
|
||||
svga_recalctimings(svga);
|
||||
@@ -1879,7 +1892,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
|
||||
uint32_t *pattern_data;
|
||||
uint32_t src_addr;
|
||||
uint32_t dest_addr;
|
||||
uint32_t source = 0, dest, pattern;
|
||||
uint32_t source = 0, dest = 0, pattern;
|
||||
uint32_t out = 0;
|
||||
int update;
|
||||
|
||||
@@ -2097,7 +2110,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
|
||||
while (count && virge->s3d.h)
|
||||
{
|
||||
uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str);
|
||||
uint32_t source = 0, dest, pattern = virge->s3d.pat_fg_clr;
|
||||
uint32_t source = 0, dest = 0, pattern = virge->s3d.pat_fg_clr;
|
||||
uint32_t out = 0;
|
||||
int update = 1;
|
||||
|
||||
@@ -2170,7 +2183,7 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat)
|
||||
do
|
||||
{
|
||||
uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str);
|
||||
uint32_t source = 0, dest, pattern;
|
||||
uint32_t source = 0, dest = 0, pattern;
|
||||
uint32_t out = 0;
|
||||
int update = 1;
|
||||
|
||||
@@ -2227,7 +2240,7 @@ skip_line:
|
||||
do
|
||||
{
|
||||
uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str);
|
||||
uint32_t source = 0, dest, pattern;
|
||||
uint32_t source = 0, dest = 0, pattern;
|
||||
uint32_t out = 0;
|
||||
int update = 1;
|
||||
|
||||
@@ -3789,7 +3802,6 @@ static void *s3_virge_init()
|
||||
virge->pci_regs[6] = 0;
|
||||
virge->pci_regs[7] = 2;
|
||||
virge->pci_regs[0x32] = 0x0c;
|
||||
virge->pci_regs[0x3c] = device_get_config_int("irq");
|
||||
virge->pci_regs[0x3d] = 1;
|
||||
virge->pci_regs[0x3e] = 4;
|
||||
virge->pci_regs[0x3f] = 0xff;
|
||||
@@ -3884,7 +3896,6 @@ static void *s3_virge_988_init()
|
||||
virge->pci_regs[6] = 0;
|
||||
virge->pci_regs[7] = 2;
|
||||
virge->pci_regs[0x32] = 0x0c;
|
||||
virge->pci_regs[0x3c] = device_get_config_int("irq");
|
||||
virge->pci_regs[0x3d] = 1;
|
||||
virge->pci_regs[0x3e] = 4;
|
||||
virge->pci_regs[0x3f] = 0xff;
|
||||
@@ -3911,7 +3922,7 @@ static void *s3_virge_988_init()
|
||||
|
||||
virge->is_375 = 0;
|
||||
|
||||
pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
|
||||
virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
|
||||
|
||||
virge->wake_render_thread = thread_create_event();
|
||||
virge->wake_main_thread = thread_create_event();
|
||||
@@ -3979,7 +3990,6 @@ static void *s3_virge_375_init(wchar_t *romfn)
|
||||
virge->pci_regs[6] = 0;
|
||||
virge->pci_regs[7] = 2;
|
||||
virge->pci_regs[0x32] = 0x0c;
|
||||
virge->pci_regs[0x3c] = device_get_config_int("irq");
|
||||
virge->pci_regs[0x3d] = 1;
|
||||
virge->pci_regs[0x3e] = 4;
|
||||
virge->pci_regs[0x3f] = 0xff;
|
||||
@@ -4007,7 +4017,7 @@ static void *s3_virge_375_init(wchar_t *romfn)
|
||||
|
||||
virge->is_375 = 1;
|
||||
|
||||
pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
|
||||
virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge);
|
||||
|
||||
virge->wake_render_thread = thread_create_event();
|
||||
virge->wake_main_thread = thread_create_event();
|
||||
@@ -4125,45 +4135,6 @@ static device_config_t s3_virge_config[] =
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"irq", "IRQ", CONFIG_SELECTION, "", 3,
|
||||
{
|
||||
{
|
||||
"IRQ 3", 3
|
||||
},
|
||||
{
|
||||
"IRQ 4", 4
|
||||
},
|
||||
{
|
||||
"IRQ 5", 5
|
||||
},
|
||||
{
|
||||
"IRQ 7", 7
|
||||
},
|
||||
{
|
||||
"IRQ 9", 9
|
||||
},
|
||||
{
|
||||
"IRQ 10", 10
|
||||
},
|
||||
{
|
||||
"IRQ 11", 11
|
||||
},
|
||||
{
|
||||
"IRQ 12", 12
|
||||
},
|
||||
{
|
||||
"IRQ 14", 14
|
||||
},
|
||||
{
|
||||
"IRQ 15", 15
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
},
|
||||
.default_int = 3
|
||||
},
|
||||
{
|
||||
"bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1
|
||||
},
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
#include "../mem.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_unk_ramdac.h"
|
||||
#include "vid_sc1502x_ramdac.h"
|
||||
|
||||
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga)
|
||||
void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
int oldbpp = 0;
|
||||
switch (addr)
|
||||
@@ -74,7 +74,7 @@ void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *sv
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga)
|
||||
uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
11
src/VIDEO/vid_sc1502x_ramdac.h
Normal file
11
src/VIDEO/vid_sc1502x_ramdac.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
typedef struct unk_ramdac_t
|
||||
{
|
||||
int state;
|
||||
uint8_t ctrl;
|
||||
} sc1502x_ramdac_t;
|
||||
|
||||
void sc1502x_ramdac_out(uint16_t addr, uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t sc1502x_ramdac_in(uint16_t addr, sc1502x_ramdac_t *ramdac, svga_t *svga);
|
||||
@@ -251,6 +251,10 @@ void svga_out(uint16_t addr, uint8_t val, void *p)
|
||||
svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b);
|
||||
else
|
||||
{
|
||||
svga->vgapal[svga->dac_write].r &= 0x3f;
|
||||
svga->vgapal[svga->dac_write].g &= 0x3f;
|
||||
svga->vgapal[svga->dac_write].b &= 0x3f;
|
||||
|
||||
if ((romset == ROM_IBMPS1_2011) || (romset == ROM_IBMPS1_2121) || (romset == ROM_IBMPS2_M30_286))
|
||||
{
|
||||
svga->pallook[svga->dac_write] = makecol32((svga->vgapal[svga->dac_write].r & 0x3f) * 4, (svga->vgapal[svga->dac_write].g & 0x3f) * 4, (svga->vgapal[svga->dac_write].b & 0x3f) * 4);
|
||||
@@ -1610,7 +1614,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((wx!=xsize || wy!=ysize) && !vid_resize)
|
||||
if (((wx!=xsize) || ((wy + 1)!=ysize)) && !vid_resize)
|
||||
{
|
||||
xsize=wx;
|
||||
ysize=wy+1;
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/* Copyright holders: Sarah Walker, Tenshi
|
||||
see COPYING for more details
|
||||
*/
|
||||
typedef struct unk_ramdac_t
|
||||
{
|
||||
int state;
|
||||
uint8_t ctrl;
|
||||
} unk_ramdac_t;
|
||||
|
||||
void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga);
|
||||
uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga);
|
||||
@@ -6116,7 +6116,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p)
|
||||
default:
|
||||
if (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)
|
||||
{
|
||||
fatal("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val);
|
||||
pclog("Unknown register write in CMDFIFO mode %08x %08x\n", addr, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -800,10 +800,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(0x47);
|
||||
addbyte(0xc3);
|
||||
|
||||
if (depth_jump_pos)
|
||||
*(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1;
|
||||
if (depth_jump_pos)
|
||||
*(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1;
|
||||
if (depth_jump_pos)
|
||||
*(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1;
|
||||
if (depth_jump_pos)
|
||||
*(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1;
|
||||
|
||||
if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE)
|
||||
{
|
||||
@@ -1047,8 +1047,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[1]);
|
||||
addbyte(0x39); /*CMP EAX, EDX*/
|
||||
addbyte(0xd0);
|
||||
addbyte(0x0f); /*CMOVA EAX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EAX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xc2);
|
||||
addbyte(0x66); /*MOVD XMM0, EAX*/
|
||||
addbyte(0x0f);
|
||||
@@ -1201,8 +1201,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[1]);
|
||||
addbyte(0x39); /*CMP EAX, EDX*/
|
||||
addbyte(0xd0);
|
||||
addbyte(0x0f); /*CMOVA EAX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EAX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xc2);
|
||||
break;
|
||||
case TCA_MSELECT_LOD_FRAC:
|
||||
@@ -1371,8 +1371,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[0]);
|
||||
addbyte(0x39); /*CMP EAX, EDX*/
|
||||
addbyte(0xd0);
|
||||
addbyte(0x0f); /*CMOVA EAX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EAX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xc2);
|
||||
addbyte(0x66); /*MOVD XMM4, EAX*/
|
||||
addbyte(0x0f);
|
||||
@@ -1569,8 +1569,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[1]);
|
||||
addbyte(0x39); /*CMP EBX, EDX*/
|
||||
addbyte(0xd3);
|
||||
addbyte(0x0f); /*CMOVA EBX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EBX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xda);
|
||||
break;
|
||||
case TCA_MSELECT_LOD_FRAC:
|
||||
|
||||
@@ -759,14 +759,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(0x47);
|
||||
addbyte(0xc3);
|
||||
|
||||
if (depth_jump_pos)
|
||||
{
|
||||
*(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1;
|
||||
}
|
||||
if (depth_jump_pos2)
|
||||
{
|
||||
*(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1;
|
||||
}
|
||||
if (depth_jump_pos)
|
||||
*(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1;
|
||||
if (depth_jump_pos)
|
||||
*(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1;
|
||||
|
||||
if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE)
|
||||
{
|
||||
@@ -1034,8 +1030,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[1]);
|
||||
addbyte(0x39); /*CMP EAX, EDX*/
|
||||
addbyte(0xd0);
|
||||
addbyte(0x0f); /*CMOVA EAX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EAX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xc2);
|
||||
addbyte(0x66); /*MOVD XMM0, EAX*/
|
||||
addbyte(0x0f);
|
||||
@@ -1186,8 +1182,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[1]);
|
||||
addbyte(0x39); /*CMP EAX, EDX*/
|
||||
addbyte(0xd0);
|
||||
addbyte(0x0f); /*CMOVA EAX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EAX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xc2);
|
||||
break;
|
||||
case TCA_MSELECT_LOD_FRAC:
|
||||
@@ -1356,8 +1352,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[0]);
|
||||
addbyte(0x39); /*CMP EAX, EDX*/
|
||||
addbyte(0xd0);
|
||||
addbyte(0x0f); /*CMOVA EAX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EAX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xc2);
|
||||
addbyte(0x66); /*MOVD XMM4, EAX*/
|
||||
addbyte(0x0f);
|
||||
@@ -1552,8 +1548,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
|
||||
addbyte(params->detail_scale[1]);
|
||||
addbyte(0x39); /*CMP EBX, EDX*/
|
||||
addbyte(0xd3);
|
||||
addbyte(0x0f); /*CMOVA EBX, EDX*/
|
||||
addbyte(0x47);
|
||||
addbyte(0x0f); /*CMOVNL EBX, EDX*/
|
||||
addbyte(0x4d);
|
||||
addbyte(0xda);
|
||||
break;
|
||||
case TCA_MSELECT_LOD_FRAC:
|
||||
|
||||
@@ -93,6 +93,10 @@ static VIDEO_CARD video_cards[] =
|
||||
{"MDA", "mda", &mda_device, GFX_MDA},
|
||||
{"MDSI Genius", "genius", &genius_device, GFX_GENIUS},
|
||||
{"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX},
|
||||
#ifdef DEV_BRANCH
|
||||
{"nVidia RIVA 128", "riva128", &riva128_device, GFX_RIVA128},
|
||||
{"nVidia RIVA TNT", "rivatnt", &rivatnt_device, GFX_RIVATNT},
|
||||
#endif
|
||||
{"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067},
|
||||
{"OAK OTI-077", "oti077", &oti077_device, GFX_OTI077},
|
||||
{"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64},
|
||||
|
||||
198
src/WIN/86Box.rc
198
src/WIN/86Box.rc
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Windows resource script.
|
||||
*
|
||||
* Version: @(#)86Box.rc 1.0.4 2017/06/17
|
||||
* Version: @(#)86Box.rc 1.0.5 2017/08/08
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
@@ -461,8 +461,10 @@ BEGIN
|
||||
COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Type:",IDT_1738,7,86,24,8
|
||||
CONTROL "Turbo timings (no accuracy)",IDC_CHECKTURBO,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,131,86,129,10
|
||||
CONTROL "Turbo timings",IDC_CHECKTURBO,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,131,86,64,10
|
||||
CONTROL "Check BPB",IDC_CHECKBPB,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,196,86,64,10
|
||||
CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT |
|
||||
LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER |
|
||||
WS_TABSTOP,7,116,253,60
|
||||
@@ -703,12 +705,12 @@ BEGIN
|
||||
IDS_2053 "Invalid number of sectors (valid values are between 1 and 63)"
|
||||
IDS_2054 "Invalid number of heads (valid values are between 1 and 16)"
|
||||
IDS_2055 "Invalid number of cylinders (valid values are between 1 and 266305)"
|
||||
IDS_2056 "Please enter a valid file name"
|
||||
IDS_2057 "Unable to open the file for write"
|
||||
IDS_2058 "Attempting to create a HDI image larger than 4 GB"
|
||||
IDS_2059 "Remember to partition and format the new drive"
|
||||
IDS_2060 "Unable to open the file for read"
|
||||
IDS_2061 "HDI or HDX image with a sector size that is not 512 are not supported"
|
||||
IDS_2056 "Specify the NVR Path"
|
||||
IDS_2057 "(empty)"
|
||||
IDS_2058 "(host drive %c:)"
|
||||
IDS_2059 "Turbo"
|
||||
IDS_2060 "On"
|
||||
IDS_2061 "Off"
|
||||
IDS_2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box."
|
||||
IDS_2063 "Configured ROM set not available.\nDefaulting to an available ROM set."
|
||||
END
|
||||
@@ -724,9 +726,9 @@ BEGIN
|
||||
IDS_2070 "Other peripherals"
|
||||
IDS_2071 "Hard disks"
|
||||
IDS_2072 "Removable devices"
|
||||
IDS_2073 "%i"" floppy drive: %s"
|
||||
IDS_2074 "Disabled CD-ROM drive"
|
||||
IDS_2075 "%s CD-ROM drive: %s"
|
||||
IDS_2073 "Unable to create bitmap file: %s"
|
||||
IDS_2074 "Use CTRL+ALT+PAGE DOWN to return to windowed mode"
|
||||
IDS_2075 "CD-ROM images (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0"
|
||||
IDS_2076 "Host CD/DVD Drive (%c:)"
|
||||
IDS_2077 "Click to capture mouse"
|
||||
IDS_2078 "Press F12-F8 to release mouse"
|
||||
@@ -743,14 +745,12 @@ BEGIN
|
||||
IDS_2085 "H"
|
||||
IDS_2086 "S"
|
||||
IDS_2087 "MB"
|
||||
IDS_2088 "%i"
|
||||
IDS_2089 "Enabled"
|
||||
IDS_2090 "Mute"
|
||||
IDS_2091 "Type"
|
||||
IDS_2092 "Bus"
|
||||
IDS_2093 "DMA"
|
||||
IDS_2094 "KB"
|
||||
IDS_2095 "MFM, RLL, or ESDI CD-ROM drives never existed"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
@@ -766,7 +766,6 @@ BEGIN
|
||||
IDS_2104 "Network Type"
|
||||
IDS_2105 "Surround Module"
|
||||
IDS_2106 "MPU-401 Base Address"
|
||||
IDS_2107 "No PCap devices found"
|
||||
IDS_2108 "On-board RAM"
|
||||
IDS_2109 "Memory Size"
|
||||
IDS_2110 "Display Type"
|
||||
@@ -806,15 +805,15 @@ BEGIN
|
||||
IDS_2136 "Slow VLB/PCI"
|
||||
IDS_2137 "Mid VLB/PCI"
|
||||
IDS_2138 "Fast VLB/PCI"
|
||||
IDS_2139 "Microsoft 2-button mouse (serial)"
|
||||
IDS_2140 "Mouse Systems mouse (serial)"
|
||||
IDS_2141 "2-button mouse (PS/2)"
|
||||
IDS_2142 "Microsoft Intellimouse (PS/2)"
|
||||
IDS_2143 "Bus mouse"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_2139 "PCap failed to set up because it may not be initialized"
|
||||
IDS_2140 "No PCap devices found"
|
||||
IDS_2141 "Invalid PCap device"
|
||||
IDS_2142 "&Notify disk change"
|
||||
IDS_2143 "Type"
|
||||
IDS_2144 "Standard 2-button joystick(s)"
|
||||
IDS_2145 "Standard 4-button joystick"
|
||||
IDS_2146 "Standard 6-button joystick"
|
||||
@@ -827,80 +826,93 @@ BEGIN
|
||||
IDS_2153 "AT Fixed Disk Adapter"
|
||||
IDS_2154 "Internal IDE"
|
||||
IDS_2155 "IRQ %i"
|
||||
IDS_2156 "MFM (%01i:%01i)"
|
||||
IDS_2157 "IDE (PIO+DMA) (%01i:%01i)"
|
||||
IDS_2158 "SCSI (%02i:%02i)"
|
||||
IDS_2159 "Invalid number of cylinders (valid values are between 1 and 1023)"
|
||||
IDS_2160 "%" PRIu64
|
||||
IDS_2161 "Genius Bus mouse"
|
||||
IDS_2162 "Amstrad mouse"
|
||||
IDS_2163 "Attempting to create a spuriously large hard disk image"
|
||||
IDS_2164 "Invalid number of sectors (valid values are between 1 and 99)"
|
||||
IDS_2165 "MFM"
|
||||
IDS_2166 "XT IDE"
|
||||
IDS_2167 "RLL"
|
||||
IDS_2168 "IDE (PIO-only)"
|
||||
IDS_2169 "%01i:%01i"
|
||||
IDS_2170 "Custom..."
|
||||
IDS_2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")"
|
||||
IDS_2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0"
|
||||
IDS_2173"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0"
|
||||
IDS_2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0"
|
||||
IDS_2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0"
|
||||
IDS_2176 "Use CTRL+ALT+PAGE DOWN to return to windowed mode"
|
||||
IDS_2177 "Olivetti M24 mouse"
|
||||
IDS_2178 "This image exists and will be overwritten.\nAre you sure you want to use it?"
|
||||
IDS_2179 "Floppy %i (%s): %ws"
|
||||
IDS_2180 "CD-ROM %i: %ws"
|
||||
IDS_2181 "MFM hard disk"
|
||||
IDS_2182 "IDE hard disk (PIO-only)"
|
||||
IDS_2183 "IDE hard disk (PIO and DMA)"
|
||||
IDS_2184 "SCSI hard disk"
|
||||
IDS_2185 "(empty)"
|
||||
IDS_2186 "(host drive %c:)"
|
||||
IDS_2187 "Custom (large)..."
|
||||
IDS_2188 "Type"
|
||||
IDS_2189 "ATAPI (PIO-only)"
|
||||
IDS_2190 "ATAPI (PIO and DMA)"
|
||||
IDS_2191 "ATAPI (PIO-only) (%01i:%01i)"
|
||||
IDS_2192 "ATAPI (PIO and DMA) (%01i:%01i)"
|
||||
IDS_2193 "Use CTRL+ALT+PAGE DOWN to return to windowed mode"
|
||||
IDS_2194 "Unable to create bitmap file: %s"
|
||||
IDS_2195 "IDE (PIO-only) (%01i:%01i)"
|
||||
IDS_2196 "Add New Hard Disk"
|
||||
IDS_2197 "Add Existing Hard Disk"
|
||||
IDS_2198 "SCSI removable disk %i: %s"
|
||||
IDS_2199 "USB is not yet supported"
|
||||
IDS_2200 "Invalid PCap device"
|
||||
IDS_2201 "&Notify disk change"
|
||||
IDS_2202 "SCSI (removable)"
|
||||
IDS_2203 "SCSI (removable) (%02i:%02i)"
|
||||
IDS_2204 "Pcap Library Not Available"
|
||||
IDS_2205 "RLL (%01i:%01i)"
|
||||
IDS_2206 "XT IDE (%01i:%01i)"
|
||||
IDS_2207 "RLL hard disk"
|
||||
IDS_2208 "XT IDE hard disk"
|
||||
IDS_2209 "IDE (PIO and DMA)"
|
||||
IDS_2210 "SCSI"
|
||||
IDS_2211 "&New image..."
|
||||
IDS_2212 "Existing image..."
|
||||
IDS_2213 "Existing image (&Write-protected)..."
|
||||
IDS_2214 "E&ject"
|
||||
IDS_2215 "&Mute"
|
||||
IDS_2216 "E&mpty"
|
||||
IDS_2217 "&Reload previous image"
|
||||
IDS_2218 "&Image..."
|
||||
IDS_2219 "PCap failed to set up because it may not be initialized"
|
||||
IDS_2220 "Image (&Write-protected)..."
|
||||
IDS_2221 "Turbo"
|
||||
IDS_2222 "On"
|
||||
IDS_2223 "Off"
|
||||
IDS_2224 "Logitech 3-button mouse (serial)"
|
||||
IDS_2225 "Specify the NVR Path"
|
||||
IDS_2226 "<Placeholder string>"
|
||||
IDS_2227 "English (United States)"
|
||||
IDS_2156 "%" PRIu64
|
||||
IDS_2157 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")"
|
||||
IDS_2158 "Floppy %i (%s): %ws"
|
||||
IDS_2159"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0"
|
||||
IDS_2160 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0"
|
||||
IDS_2161 "&New image..."
|
||||
IDS_2162 "Existing image..."
|
||||
IDS_2163 "Existing image (&Write-protected)..."
|
||||
IDS_2164 "E&ject"
|
||||
IDS_2165 "&Mute"
|
||||
IDS_2166 "E&mpty"
|
||||
IDS_2167 "&Reload previous image"
|
||||
IDS_2168 "&Image..."
|
||||
IDS_2169 "Image (&Write-protected)..."
|
||||
IDS_2170 "Check BPB"
|
||||
IDS_2171 "Unable to initialize FluidSynth, make sure you have the following libraries\nin your 86Box folder:\n\nlibfluidsynth.dll\nlibglib-2.0-0.dll\nlibiconv-2.dll\nlibintl-8.dll\nlibpcre-1.dll"
|
||||
|
||||
IDS_3072 "None"
|
||||
IDS_3073 "[Bus] Logitech Bus Mouse"
|
||||
IDS_3074 "[Bus] Microsoft Bus Mouse (InPort)"
|
||||
IDS_3075 "[Serial] Mouse Systems Mouse"
|
||||
IDS_3076 "[Serial] Microsoft 2-button Mouse"
|
||||
IDS_3077 "[Serial] Logitech 3-button Mouse"
|
||||
IDS_3078 "[Serial] Microsoft Wheel Mouse"
|
||||
IDS_3079 "[PS/2] 2-button Mouse"
|
||||
IDS_3080 "[PS/2] Microsoft Intellimouse"
|
||||
IDS_3081 "[Proprietary] Amstrad Mouse"
|
||||
IDS_3082 "[Proprietary] Olivetti M24 Mouse"
|
||||
|
||||
IDS_4096 "Hard disk (%s)"
|
||||
IDS_4097 "%01i:%01i"
|
||||
IDS_4098 "%i"
|
||||
IDS_4099 "Disabled"
|
||||
IDS_4100 "Custom..."
|
||||
IDS_4101 "Custom (large)..."
|
||||
IDS_4102 "Add New Hard Disk"
|
||||
IDS_4103 "Add Existing Hard Disk"
|
||||
IDS_4104 "Attempting to create a HDI image larger than 4 GB"
|
||||
IDS_4105 "Attempting to create a spuriously large hard disk image"
|
||||
IDS_4106 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0"
|
||||
IDS_4107 "Unable to open the file for read"
|
||||
IDS_4108 "Unable to open the file for write"
|
||||
IDS_4109 "HDI or HDX image with a sector size that is not 512 are not supported"
|
||||
IDS_4110 "USB is not yet supported"
|
||||
IDS_4111 "This image exists and will be overwritten.\nAre you sure you want to use it?"
|
||||
IDS_4112 "Please enter a valid file name"
|
||||
IDS_4113 "Remember to partition and format the new drive"
|
||||
IDS_4114 "MFM or ESDI CD-ROM drives never existed"
|
||||
IDS_4115 "Removable disk %i (SCSI): %ws"
|
||||
|
||||
IDS_4352 "MFM"
|
||||
IDS_4353 "XT IDE"
|
||||
IDS_4354 "ESDI"
|
||||
IDS_4355 "IDE (PIO-only)"
|
||||
IDS_4356 "IDE (PIO+DMA)"
|
||||
IDS_4357 "SCSI"
|
||||
IDS_4358 "SCSI (removable)"
|
||||
|
||||
IDS_4608 "MFM (%01i:%01i)"
|
||||
IDS_4609 "XT IDE (%01i:%01i)"
|
||||
IDS_4610 "ESDI (%01i:%01i)"
|
||||
IDS_4611 "IDE (PIO-only) (%01i:%01i)"
|
||||
IDS_4612 "IDE (PIO+DMA) (%01i:%01i)"
|
||||
IDS_4613 "SCSI (%02i:%02i)"
|
||||
IDS_4614 "SCSI (removable) (%02i:%02i)"
|
||||
|
||||
IDS_5120 "CD-ROM %i (%s): %s"
|
||||
|
||||
IDS_5376 "Disabled"
|
||||
IDS_5377 "<Reserved>"
|
||||
IDS_5378 "<Reserved>"
|
||||
IDS_5379 "<Reserved>"
|
||||
IDS_5380 "ATAPI (PIO-only)"
|
||||
IDS_5381 "ATAPI (PIO and DMA)"
|
||||
IDS_5382 "SCSI"
|
||||
|
||||
IDS_5632 "Disabled"
|
||||
IDS_5633 "<Reserved>"
|
||||
IDS_5634 "<Reserved>"
|
||||
IDS_5635 "<Reserved>"
|
||||
IDS_5636 "ATAPI (PIO-only) (%01i:%01i)"
|
||||
IDS_5637 "ATAPI (PIO and DMA) (%01i:%01i)"
|
||||
IDS_5638 "SCSI (%02i:%02i)"
|
||||
|
||||
IDS_6144 "English (United States)"
|
||||
END
|
||||
#define IDS_LANG_ENUS IDS_2227
|
||||
#define IDS_LANG_ENUS IDS_6144
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
extern void plat_msgbox_error(int i);
|
||||
extern wchar_t *plat_get_string_from_id(int i);
|
||||
|
||||
#ifndef IDS_2219
|
||||
#define IDS_2219 2219
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2077
|
||||
#define IDS_2077 2077
|
||||
#endif
|
||||
@@ -17,6 +13,18 @@ extern wchar_t *plat_get_string_from_id(int i);
|
||||
#ifndef IDS_2079
|
||||
#define IDS_2079 2079
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2139
|
||||
#define IDS_2139 2139
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2171
|
||||
#define IDS_2171 2171
|
||||
#endif
|
||||
|
||||
#ifndef IDS_2219
|
||||
#define IDS_2219 2219
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern void plat_msgbox_fatal(char *string);
|
||||
|
||||
@@ -163,17 +163,18 @@
|
||||
#define IDC_LIST_FLOPPY_DRIVES 1151
|
||||
#define IDC_COMBO_FD_TYPE 1152
|
||||
#define IDC_CHECKTURBO 1153
|
||||
#define IDC_BUTTON_FDD_ADD 1154 // status bar menu
|
||||
#define IDC_BUTTON_FDD_EDIT 1155 // status bar menu
|
||||
#define IDC_BUTTON_FDD_REMOVE 1156 // status bar menu
|
||||
#define IDC_LIST_CDROM_DRIVES 1157
|
||||
#define IDC_COMBO_CD_BUS 1158
|
||||
#define IDC_COMBO_CD_ID 1159
|
||||
#define IDC_COMBO_CD_LUN 1160
|
||||
#define IDC_COMBO_CD_CHANNEL_IDE 1161
|
||||
#define IDC_BUTTON_CDROM_ADD 1162 // status bar menu
|
||||
#define IDC_BUTTON_CDROM_EDIT 1163 // status bar menu
|
||||
#define IDC_BUTTON_CDROM_REMOVE 1164 // status bar menu
|
||||
#define IDC_CHECKBPB 1154
|
||||
#define IDC_BUTTON_FDD_ADD 1155 // status bar menu
|
||||
#define IDC_BUTTON_FDD_EDIT 1156 // status bar menu
|
||||
#define IDC_BUTTON_FDD_REMOVE 1157 // status bar menu
|
||||
#define IDC_LIST_CDROM_DRIVES 1158
|
||||
#define IDC_COMBO_CD_BUS 1159
|
||||
#define IDC_COMBO_CD_ID 1160
|
||||
#define IDC_COMBO_CD_LUN 1161
|
||||
#define IDC_COMBO_CD_CHANNEL_IDE 1162
|
||||
#define IDC_BUTTON_CDROM_ADD 1163 // status bar menu
|
||||
#define IDC_BUTTON_CDROM_EDIT 1164 // status bar menu
|
||||
#define IDC_BUTTON_CDROM_REMOVE 1165 // status bar menu
|
||||
|
||||
|
||||
/* For the DeviceConfig code, re-do later. */
|
||||
@@ -288,11 +289,11 @@
|
||||
#define IDS_2136 2136 // "Slow VLB/PCI"
|
||||
#define IDS_2137 2137 // "Mid VLB/PCI"
|
||||
#define IDS_2138 2138 // "Fast VLB/PCI"
|
||||
#define IDS_2139 2139 // "Microsoft 2-button mouse (serial)"
|
||||
#define IDS_2140 2140 // "Mouse Systems mouse (serial)"
|
||||
#define IDS_2141 2141 // "2-button mouse (PS/2)"
|
||||
#define IDS_2142 2142 // "Microsoft Intellimouse (PS/2)"
|
||||
#define IDS_2143 2143 // "Bus mouse"
|
||||
#define IDS_2139 2139
|
||||
#define IDS_2140 2140
|
||||
#define IDS_2141 2141
|
||||
#define IDS_2142 2142
|
||||
#define IDS_2143 2143
|
||||
#define IDS_2144 2144 // "Standard 2-button joystick(s)"
|
||||
#define IDS_2145 2145 // "Standard 4-button joystick"
|
||||
#define IDS_2146 2146 // "Standard 6-button joystick"
|
||||
@@ -310,8 +311,8 @@
|
||||
#define IDS_2158 2158 // "SCSI (%02i:%02i)"
|
||||
#define IDS_2159 2159 // "Invalid number of cylinders.."
|
||||
#define IDS_2160 2160 // "%" PRIu64
|
||||
#define IDS_2161 2161 // "Genius Bus mouse"
|
||||
#define IDS_2162 2162 // "Amstrad mouse"
|
||||
#define IDS_2161 2161
|
||||
#define IDS_2162 2162
|
||||
#define IDS_2163 2163 // "Attempting to create a spuriously.."
|
||||
#define IDS_2164 2164 // "Invalid number of sectors.."
|
||||
#define IDS_2165 2165 // "MFM"
|
||||
@@ -319,67 +320,89 @@
|
||||
#define IDS_2167 2167 // "RLL"
|
||||
#define IDS_2168 2168 // "IDE (PIO-only)"
|
||||
#define IDS_2169 2169 // "%01i:%01i"
|
||||
#define IDS_2170 2170 // "Custom..."
|
||||
#define IDS_2171 2171 // "%" PRIu64 " MB (CHS: %" ..
|
||||
#define IDS_2172 2172 // "Hard disk images .."
|
||||
#define IDS_2173 2173 // "All floppy images .."
|
||||
#define IDS_2174 2174 // "Configuration files .."
|
||||
#define IDS_2175 2175 // "CD-ROM image .."
|
||||
#define IDS_2176 2176 // "Use CTRL+ALT+PAGE DOWN .."
|
||||
#define IDS_2177 2177 // "Olivetti M24 mouse"
|
||||
#define IDS_2178 2178 // "This image exists and will.."
|
||||
#define IDS_2179 2179 // "Floppy %i (%s): %ws"
|
||||
#define IDS_2180 2180 // "CD-ROM %i: %ws"
|
||||
#define IDS_2181 2181 // "MFM hard disk"
|
||||
#define IDS_2182 2182 // "IDE hard disk (PIO-only)"
|
||||
#define IDS_2183 2183 // "IDE hard disk (PIO and DMA)"
|
||||
#define IDS_2184 2184 // "SCSI hard disk"
|
||||
#define IDS_2185 2185 // "(empty)"
|
||||
#define IDS_2186 2186 // "(host drive %c:)"
|
||||
#define IDS_2187 2187 // "Custom (large)..."
|
||||
#define IDS_2188 2188 // "Type"
|
||||
#define IDS_2189 2189 // "ATAPI (PIO-only)"
|
||||
#define IDS_2190 2190 // "ATAPI (PIO and DMA)"
|
||||
#define IDS_2191 2191 // "ATAPI (PIO-only) (%01i:%01i)"
|
||||
#define IDS_2192 2192 // "ATAPI (PIO and DMA) (%01i:%01i)"
|
||||
#define IDS_2193 2193 // "Use CTRL+ALT+PAGE DOWN to .."
|
||||
#define IDS_2194 2194 // "Unable to create bitmap file: %s"
|
||||
#define IDS_2195 2195 // "IDE (PIO-only) (%01i:%01i)"
|
||||
#define IDS_2196 2196 // "Add New Hard Disk"
|
||||
#define IDS_2197 2197 // "Add Existing Hard Disk"
|
||||
#define IDS_2198 2198 // "SCSI removable disk %i: %s"
|
||||
#define IDS_2199 2199 // "USB is not yet supported"
|
||||
#define IDS_2200 2200 // "Invalid PCap device"
|
||||
#define IDS_2201 2201 // "&Notify disk change"
|
||||
#define IDS_2202 2202 // "SCSI (removable)"
|
||||
#define IDS_2203 2203 // "SCSI (removable) (%02i:%02i)"
|
||||
#define IDS_2204 2204 // "Pcap Library Not Available"
|
||||
#define IDS_2205 2205 // "RLL (%01i:%01i)"
|
||||
#define IDS_2206 2206 // "XT IDE (%01i:%01i)"
|
||||
#define IDS_2207 2207 // "RLL hard disk"
|
||||
#define IDS_2208 2208 // "XT IDE hard disk"
|
||||
#define IDS_2209 2209 // "IDE (PIO and DMA)"
|
||||
#define IDS_2210 2210 // "SCSI"
|
||||
#define IDS_2211 2211 // "&New image..."
|
||||
#define IDS_2212 2212 // "Existing image..."
|
||||
#define IDS_2213 2213 // "Existing image (&Write-.."
|
||||
#define IDS_2214 2214 // "E&ject"
|
||||
#define IDS_2215 2215 // "&Mute"
|
||||
#define IDS_2216 2216 // "E&mpty"
|
||||
#define IDS_2217 2217 // "&Reload previous image"
|
||||
#define IDS_2218 2218 // "&Image..."
|
||||
#define IDS_2219 2219 // "PCap failed to set up .."
|
||||
#define IDS_2220 2220 // "Image (&Write-protected)..."
|
||||
#define IDS_2221 2221 // "Turbo"
|
||||
#define IDS_2222 2222 // "On"
|
||||
#define IDS_2223 2223 // "Off"
|
||||
#define IDS_2224 2224 // "Logitech 3-button mouse (serial)"
|
||||
#define IDS_2225 2225 // "Specify the NVR Path"
|
||||
#define IDS_2226 2226 // "<Placeholder string>"
|
||||
#define IDS_2227 2227 // "English (United States)"
|
||||
#define IDS_2170 2170 // "%01i:%01i"
|
||||
#define IDS_2171 2171
|
||||
|
||||
#define IDS_LANG_ENUS IDS_2227
|
||||
#define STRINGS_NUM 180
|
||||
#define IDS_3072 3072
|
||||
#define IDS_3073 3073
|
||||
#define IDS_3074 3074
|
||||
#define IDS_3075 3075
|
||||
#define IDS_3076 3076
|
||||
#define IDS_3077 3077
|
||||
#define IDS_3078 3078
|
||||
#define IDS_3079 3079
|
||||
#define IDS_3080 3080
|
||||
#define IDS_3081 3081
|
||||
#define IDS_3082 3082
|
||||
|
||||
#define IDS_4096 4096
|
||||
#define IDS_4097 4097
|
||||
#define IDS_4098 4098
|
||||
#define IDS_4099 4099
|
||||
#define IDS_4100 4100
|
||||
#define IDS_4101 4101
|
||||
#define IDS_4102 4102
|
||||
#define IDS_4103 4103
|
||||
#define IDS_4104 4104
|
||||
#define IDS_4105 4105
|
||||
#define IDS_4106 4106
|
||||
#define IDS_4107 4107
|
||||
#define IDS_4108 4108
|
||||
#define IDS_4109 4109
|
||||
#define IDS_4110 4110
|
||||
#define IDS_4111 4111
|
||||
#define IDS_4112 4112
|
||||
#define IDS_4113 4113
|
||||
#define IDS_4114 4114
|
||||
#define IDS_4115 4115
|
||||
|
||||
#define IDS_4352 4352
|
||||
#define IDS_4353 4353
|
||||
#define IDS_4354 4354
|
||||
#define IDS_4355 4355
|
||||
#define IDS_4356 4356
|
||||
#define IDS_4357 4357
|
||||
#define IDS_4358 4358
|
||||
|
||||
#define IDS_4608 4608
|
||||
#define IDS_4609 4609
|
||||
#define IDS_4610 4610
|
||||
#define IDS_4611 4611
|
||||
#define IDS_4612 4612
|
||||
#define IDS_4613 4613
|
||||
#define IDS_4614 4614
|
||||
|
||||
#define IDS_5120 5120
|
||||
|
||||
#define IDS_5376 5376
|
||||
#define IDS_5377 5377
|
||||
#define IDS_5378 5378
|
||||
#define IDS_5379 5379
|
||||
#define IDS_5380 5380
|
||||
#define IDS_5381 5381
|
||||
#define IDS_5382 5382
|
||||
|
||||
#define IDS_5632 5632
|
||||
#define IDS_5633 5633
|
||||
#define IDS_5634 5634
|
||||
#define IDS_5635 5635
|
||||
#define IDS_5636 5636
|
||||
#define IDS_5637 5637
|
||||
#define IDS_5638 5638
|
||||
|
||||
#define IDS_6144 6144
|
||||
|
||||
#define IDS_LANG_ENUS IDS_6144
|
||||
|
||||
#define STRINGS_NUM_2048 124
|
||||
#define STRINGS_NUM_3072 11
|
||||
#define STRINGS_NUM_4096 20
|
||||
#define STRINGS_NUM_4352 7
|
||||
#define STRINGS_NUM_4608 7
|
||||
#define STRINGS_NUM_5120 1
|
||||
#define STRINGS_NUM_5376 7
|
||||
#define STRINGS_NUM_5632 7
|
||||
#define STRINGS_NUM_6144 1
|
||||
|
||||
|
||||
#define IDM_ABOUT 40001
|
||||
|
||||
197
src/WIN/win.c
197
src/WIN/win.c
@@ -165,6 +165,8 @@ void updatewindowsize(int x, int y)
|
||||
int temp_overscan_x = overscan_x;
|
||||
int temp_overscan_y = overscan_y;
|
||||
|
||||
double dx, dy, dtx, dty;
|
||||
|
||||
if (vid_resize) return;
|
||||
|
||||
if (x < 160) x = 160;
|
||||
@@ -182,30 +184,37 @@ void updatewindowsize(int x, int y)
|
||||
|
||||
if (force_43)
|
||||
{
|
||||
dx = (double) x;
|
||||
dtx = (double) temp_overscan_x;
|
||||
|
||||
dy = (double) y;
|
||||
dty = (double) temp_overscan_y;
|
||||
|
||||
/* Account for possible overscan. */
|
||||
if (temp_overscan_y == 16)
|
||||
{
|
||||
/* CGA */
|
||||
unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y;
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
}
|
||||
else if (temp_overscan_y < 16)
|
||||
{
|
||||
/* MDA/Hercules */
|
||||
unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0));
|
||||
dy = (x / 4.0) * 3.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable_overscan)
|
||||
{
|
||||
/* EGA/(S)VGA with overscan */
|
||||
unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y;
|
||||
dy = (((dx - dtx) / 4.0) * 3.0) + dty;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* EGA/(S)VGA without overscan */
|
||||
unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0));
|
||||
dy = (x / 4.0) * 3.0;
|
||||
}
|
||||
}
|
||||
unscaled_size_y = (int) dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -325,7 +334,6 @@ void mainthread(LPVOID param)
|
||||
|
||||
if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0))
|
||||
{
|
||||
video_wait_for_blit();
|
||||
SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders);
|
||||
GetWindowRect(ghwnd, &r);
|
||||
MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE);
|
||||
@@ -454,12 +462,12 @@ HMENU create_popup_menu(int part)
|
||||
|
||||
void create_floppy_submenu(HMENU m, int id)
|
||||
{
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_NEW | id, win_language_get_string_from_id(2211));
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_NEW | id, win_language_get_string_from_id(IDS_2161));
|
||||
AppendMenu(m, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING | id, win_language_get_string_from_id(2212));
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING_WP | id, win_language_get_string_from_id(2213));
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING | id, win_language_get_string_from_id(IDS_2162));
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING_WP | id, win_language_get_string_from_id(IDS_2163));
|
||||
AppendMenu(m, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, win_language_get_string_from_id(2214));
|
||||
AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, win_language_get_string_from_id(IDS_2164));
|
||||
}
|
||||
|
||||
void create_cdrom_submenu(HMENU m, int id)
|
||||
@@ -467,12 +475,12 @@ void create_cdrom_submenu(HMENU m, int id)
|
||||
int i = 0;
|
||||
WCHAR s[64];
|
||||
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_MUTE | id, win_language_get_string_from_id(2215));
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_MUTE | id, win_language_get_string_from_id(IDS_2165));
|
||||
AppendMenu(m, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_EMPTY | id, win_language_get_string_from_id(2216));
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_RELOAD | id, win_language_get_string_from_id(2217));
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_EMPTY | id, win_language_get_string_from_id(IDS_2166));
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_RELOAD | id, win_language_get_string_from_id(IDS_2167));
|
||||
AppendMenu(m, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_IMAGE | id, win_language_get_string_from_id(2218));
|
||||
AppendMenu(m, MF_STRING, IDM_CDROM_IMAGE | id, win_language_get_string_from_id(IDS_2168));
|
||||
|
||||
if (host_cdrom_drive_available_num == 0)
|
||||
{
|
||||
@@ -528,13 +536,13 @@ check_menu_items:
|
||||
|
||||
void create_removable_disk_submenu(HMENU m, int id)
|
||||
{
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, win_language_get_string_from_id(2216));
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, win_language_get_string_from_id(2217));
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, win_language_get_string_from_id(IDS_2166));
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, win_language_get_string_from_id(IDS_2167));
|
||||
AppendMenu(m, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, win_language_get_string_from_id(2201));
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, win_language_get_string_from_id(IDS_2142));
|
||||
AppendMenu(m, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, win_language_get_string_from_id(2218));
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, win_language_get_string_from_id(2220));
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, win_language_get_string_from_id(IDS_2168));
|
||||
AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, win_language_get_string_from_id(IDS_2169));
|
||||
}
|
||||
|
||||
void get_executable_name(wchar_t *s, int size)
|
||||
@@ -781,11 +789,11 @@ void create_floppy_tip(int part)
|
||||
mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1);
|
||||
if (wcslen(discfns[drive]) == 0)
|
||||
{
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185));
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_2158), drive + 1, wtext, win_language_get_string_from_id(IDS_2057));
|
||||
}
|
||||
else
|
||||
{
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]);
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_2158), drive + 1, wtext, discfns[drive]);
|
||||
}
|
||||
|
||||
if (sbTips[part] != NULL)
|
||||
@@ -801,27 +809,36 @@ void create_cdrom_tip(int part)
|
||||
WCHAR wtext[512];
|
||||
WCHAR tempTip[512];
|
||||
|
||||
WCHAR *szText;
|
||||
int id;
|
||||
|
||||
int drive = sb_part_meanings[part] & 0xf;
|
||||
|
||||
int bus = cdrom_drives[drive].bus_type;
|
||||
|
||||
id = IDS_4352 + (bus - 1);
|
||||
|
||||
szText = (WCHAR *) win_language_get_string_from_id(id);
|
||||
|
||||
if (cdrom_drives[drive].host_drive == 200)
|
||||
{
|
||||
if (wcslen(cdrom_image[drive].image_path) == 0)
|
||||
{
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185));
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057));
|
||||
}
|
||||
else
|
||||
{
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path);
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, cdrom_image[drive].image_path);
|
||||
}
|
||||
}
|
||||
else if (cdrom_drives[drive].host_drive < 0x41)
|
||||
else if ((cdrom_drives[drive].host_drive >= 'A') && (cdrom_drives[drive].host_drive <= 'Z'))
|
||||
{
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185));
|
||||
_swprintf(wtext, win_language_get_string_from_id(IDS_2058), cdrom_drives[drive].host_drive & ~0x20);
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, wtext);
|
||||
}
|
||||
else
|
||||
{
|
||||
_swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20);
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, wtext);
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_5120), drive + 1, szText, win_language_get_string_from_id(IDS_2057));
|
||||
}
|
||||
|
||||
if (sbTips[part] != NULL)
|
||||
@@ -840,11 +857,11 @@ void create_removable_hd_tip(int part)
|
||||
|
||||
if (wcslen(hdc[drive].fn) == 0)
|
||||
{
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2198), drive, win_language_get_string_from_id(2185));
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, win_language_get_string_from_id(IDS_2057));
|
||||
}
|
||||
else
|
||||
{
|
||||
_swprintf(tempTip, win_language_get_string_from_id(2198), drive, hdc[drive].fn);
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_4115), drive, hdc[drive].fn);
|
||||
}
|
||||
|
||||
if (sbTips[part] != NULL)
|
||||
@@ -857,41 +874,24 @@ void create_removable_hd_tip(int part)
|
||||
|
||||
void create_hd_tip(int part)
|
||||
{
|
||||
WCHAR tempTip[512];
|
||||
WCHAR *szText;
|
||||
int id = 2181;
|
||||
int id;
|
||||
|
||||
int bus = sb_part_meanings[part] & 0xf;
|
||||
|
||||
switch(bus)
|
||||
{
|
||||
case HDD_BUS_MFM:
|
||||
id = 2181;
|
||||
break;
|
||||
case HDD_BUS_RLL:
|
||||
id = 2207;
|
||||
break;
|
||||
case HDD_BUS_XTIDE:
|
||||
id = 2208;
|
||||
break;
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
id = 2182;
|
||||
break;
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
id = 2183;
|
||||
break;
|
||||
case HDD_BUS_SCSI:
|
||||
id = 2184;
|
||||
break;
|
||||
}
|
||||
id = IDS_4352 + (bus - 1);
|
||||
|
||||
szText = (WCHAR *) win_language_get_string_from_id(id);
|
||||
|
||||
_swprintf(tempTip, win_language_get_string_from_id(IDS_4096), szText);
|
||||
|
||||
if (sbTips[part] != NULL)
|
||||
{
|
||||
free(sbTips[part]);
|
||||
}
|
||||
sbTips[part] = (WCHAR *) malloc((wcslen(szText) << 1) + 2);
|
||||
wcscpy(sbTips[part], szText);
|
||||
sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2);
|
||||
wcscpy(sbTips[part], tempTip);
|
||||
}
|
||||
|
||||
void update_tip(int meaning)
|
||||
@@ -978,9 +978,18 @@ void destroy_menu_handles(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sb_menu_handles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sb_parts; i++)
|
||||
{
|
||||
DestroyMenu(sb_menu_handles[i]);
|
||||
if (sb_menu_handles[i])
|
||||
{
|
||||
DestroyMenu(sb_menu_handles[i]);
|
||||
sb_menu_handles[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(sb_menu_handles);
|
||||
@@ -995,12 +1004,22 @@ void destroy_tips(void)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sbTips)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < sb_parts; i++)
|
||||
{
|
||||
free(sbTips[i]);
|
||||
if (sbTips[i])
|
||||
{
|
||||
free(sbTips[i]);
|
||||
sbTips[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
free(sbTips);
|
||||
sbTips = NULL;
|
||||
}
|
||||
|
||||
void update_status_bar_panes(HWND hwnds)
|
||||
@@ -1031,16 +1050,34 @@ void update_status_bar_panes(HWND hwnds)
|
||||
SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL);
|
||||
}
|
||||
|
||||
sb_parts = 0;
|
||||
SendMessage(hwnds, SB_SETPARTS, (WPARAM) 0, (LPARAM) NULL);
|
||||
|
||||
free(iStatusWidths);
|
||||
free(sb_part_meanings);
|
||||
free(sb_part_icons);
|
||||
free(sb_icon_flags);
|
||||
if (iStatusWidths)
|
||||
{
|
||||
free(iStatusWidths);
|
||||
iStatusWidths = NULL;
|
||||
}
|
||||
if (sb_part_meanings)
|
||||
{
|
||||
free(sb_part_meanings);
|
||||
sb_part_meanings = NULL;
|
||||
}
|
||||
if (sb_part_icons)
|
||||
{
|
||||
free(sb_part_icons);
|
||||
sb_part_icons = NULL;
|
||||
}
|
||||
if (sb_icon_flags)
|
||||
{
|
||||
free(sb_icon_flags);
|
||||
sb_icon_flags = NULL;
|
||||
}
|
||||
destroy_menu_handles();
|
||||
destroy_tips();
|
||||
}
|
||||
|
||||
sb_parts = 0;
|
||||
|
||||
for (i = 0; i < FDD_NUM; i++)
|
||||
{
|
||||
if (fdd_get_type(i) != 0)
|
||||
@@ -1051,6 +1088,18 @@ void update_status_bar_panes(HWND hwnds)
|
||||
}
|
||||
for (i = 0; i < CDROM_NUM; i++)
|
||||
{
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) && !(models[model].flags & MODEL_HAS_IDE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) && !(models[model].flags & MODEL_HAS_IDE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_SCSI) && (scsi_card_current == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (cdrom_drives[i].bus_type != 0)
|
||||
{
|
||||
sb_parts++;
|
||||
@@ -1058,7 +1107,7 @@ void update_status_bar_panes(HWND hwnds)
|
||||
}
|
||||
for (i = 0; i < HDC_NUM; i++)
|
||||
{
|
||||
if (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
if ((hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) && (scsi_card_current != 0))
|
||||
{
|
||||
sb_parts++;
|
||||
}
|
||||
@@ -1118,6 +1167,18 @@ void update_status_bar_panes(HWND hwnds)
|
||||
}
|
||||
for (i = 0; i < CDROM_NUM; i++)
|
||||
{
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) && !(models[model].flags & MODEL_HAS_IDE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) && !(models[model].flags & MODEL_HAS_IDE))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((cdrom_drives[i].bus_type == CDROM_BUS_SCSI) && (scsi_card_current == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (cdrom_drives[i].bus_type != 0)
|
||||
{
|
||||
edge += SB_ICON_WIDTH;
|
||||
@@ -1128,7 +1189,7 @@ void update_status_bar_panes(HWND hwnds)
|
||||
}
|
||||
for (i = 0; i < HDC_NUM; i++)
|
||||
{
|
||||
if (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE)
|
||||
if ((hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) && (scsi_card_current != 0))
|
||||
{
|
||||
edge += SB_ICON_WIDTH;
|
||||
iStatusWidths[sb_parts] = edge;
|
||||
@@ -1171,7 +1232,7 @@ void update_status_bar_panes(HWND hwnds)
|
||||
sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE_PIO_AND_DMA;
|
||||
sb_parts++;
|
||||
}
|
||||
if (c_scsi)
|
||||
if (c_scsi && (scsi_card_current != 0))
|
||||
{
|
||||
edge += SB_ICON_WIDTH;
|
||||
iStatusWidths[sb_parts] = edge;
|
||||
@@ -1912,7 +1973,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
if (video_fullscreen_first)
|
||||
{
|
||||
video_fullscreen_first = 0;
|
||||
msgbox_info(ghwnd, IDS_2193);
|
||||
msgbox_info(ghwnd, IDS_2074);
|
||||
}
|
||||
|
||||
startblit();
|
||||
@@ -2060,7 +2121,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
|
||||
case IDM_CONFIG_LOAD:
|
||||
pause = 1;
|
||||
if (!file_dlg_st(hwnd, IDS_2174, "", 0))
|
||||
if (!file_dlg_st(hwnd, IDS_2160, "", 0))
|
||||
{
|
||||
if (msgbox_reset_yn(ghwnd) == IDYES)
|
||||
{
|
||||
@@ -2125,7 +2186,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
||||
|
||||
case IDM_CONFIG_SAVE:
|
||||
pause = 1;
|
||||
if (!file_dlg_st(hwnd, IDS_2174, "", 1))
|
||||
if (!file_dlg_st(hwnd, IDS_2160, "", 1))
|
||||
{
|
||||
config_save(wopenfilestring);
|
||||
}
|
||||
@@ -2361,7 +2422,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR
|
||||
break;
|
||||
}
|
||||
|
||||
ret = file_dlg_w_st(hwnd, IDS_2173, discfns[id], 0);
|
||||
ret = file_dlg_w_st(hwnd, IDS_2159, discfns[id], 0);
|
||||
if (!ret)
|
||||
{
|
||||
disc_close(id);
|
||||
@@ -2417,7 +2478,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR
|
||||
break;
|
||||
}
|
||||
|
||||
if (!file_dlg_w_st(hwnd, IDS_2175, cdrom_image[id].image_path, 0))
|
||||
if (!file_dlg_w_st(hwnd, IDS_2075, cdrom_image[id].image_path, 0))
|
||||
{
|
||||
cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive;
|
||||
wcscpy(temp_image_path, wopenfilestring);
|
||||
@@ -2506,7 +2567,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR
|
||||
case IDM_RDISK_IMAGE:
|
||||
case IDM_RDISK_IMAGE_WP:
|
||||
id = item_params & 0x001f;
|
||||
ret = file_dlg_w_st(hwnd, IDS_2172, hdc[id].fn, id);
|
||||
ret = file_dlg_w_st(hwnd, IDS_4106, hdc[id].fn, id);
|
||||
if (!ret)
|
||||
{
|
||||
removable_disk_unload(id);
|
||||
|
||||
@@ -118,7 +118,7 @@ void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap)
|
||||
|
||||
if((fp = _wfopen(szFilename,L"wb"))==NULL)
|
||||
{
|
||||
_swprintf(szMessage, win_language_get_string_from_id(2194), szFilename);
|
||||
_swprintf(szMessage, win_language_get_string_from_id(IDS_2073), szFilename);
|
||||
msgbox_error_wstr(ghwnd, szMessage);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -35,11 +35,13 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam
|
||||
int val_int;
|
||||
int ret;
|
||||
int id;
|
||||
device_config_t *config;
|
||||
int c;
|
||||
int num;
|
||||
int num;
|
||||
int changed;
|
||||
int cid;
|
||||
device_config_t *config;
|
||||
char s[80];
|
||||
wchar_t ws[512];
|
||||
|
||||
switch (message)
|
||||
{
|
||||
@@ -94,6 +96,24 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
|
||||
sprintf(s, "%i", val_int);
|
||||
SendMessage(h, WM_SETTEXT, 0, (LPARAM)s);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
{
|
||||
char* str = config_get_string(config_device->name, config->name, 0);
|
||||
if (str)
|
||||
SendMessage(h, WM_SETTEXT, 0, (LPARAM)str);
|
||||
id += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONFIG_HEX16:
|
||||
val_int = config_get_hex16(config_device->name, config->name, config->default_int);
|
||||
|
||||
@@ -132,13 +152,14 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
{
|
||||
cid = LOWORD(wParam);
|
||||
if (cid == IDOK)
|
||||
{
|
||||
id = IDC_CONFIG_BASE;
|
||||
config = config_device->config;
|
||||
changed = 0;
|
||||
char s[512];
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
@@ -181,6 +202,33 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
{
|
||||
char* str = config_get_string(config_device->name, config->name, (char*)"");
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
|
||||
if (strcmp(str, s))
|
||||
changed = 1;
|
||||
|
||||
id += 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
val_int = config_get_int(config_device->name, config->name, config->default_int);
|
||||
if (val_int > config->spinner.max)
|
||||
val_int = config->spinner.max;
|
||||
else if (val_int < config->spinner.min)
|
||||
val_int = config->spinner.min;
|
||||
|
||||
SendMessage(h, WM_GETTEXT, 79, (LPARAM)s);
|
||||
sscanf(s, "%i", &c);
|
||||
|
||||
if (val_int != c)
|
||||
changed = 1;
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_HEX16:
|
||||
val_int = config_get_hex16(config_device->name, config->name, config->default_int);
|
||||
|
||||
@@ -218,16 +266,16 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ret = msgbox_reset(ghwnd);
|
||||
switch(ret)
|
||||
{
|
||||
case IDNO:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
return FALSE;
|
||||
default:
|
||||
break;
|
||||
ret = msgbox_reset(ghwnd);
|
||||
switch(ret)
|
||||
{
|
||||
case IDNO:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
case IDCANCEL:
|
||||
return FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
id = IDC_CONFIG_BASE;
|
||||
@@ -262,6 +310,27 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
|
||||
|
||||
config_set_string(config_device->name, config->name, s);
|
||||
|
||||
id += 3;
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
SendMessage(h, WM_GETTEXT, 79, (LPARAM)s);
|
||||
sscanf(s, "%i", &c);
|
||||
if (c > config->spinner.max)
|
||||
c = config->spinner.max;
|
||||
else if (c < config->spinner.min)
|
||||
c = config->spinner.min;
|
||||
|
||||
config_set_int(config_device->name, config->name, c);
|
||||
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_HEX16:
|
||||
c = SendMessage(h, CB_GETCURSEL, 0, 0);
|
||||
for (; c > 0; c--)
|
||||
@@ -289,12 +358,91 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam
|
||||
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
case IDCANCEL:
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (cid == IDCANCEL)
|
||||
{
|
||||
EndDialog(hdlg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int id = IDC_CONFIG_BASE;
|
||||
device_config_t *config = config_device->config;
|
||||
|
||||
while (config->type != -1)
|
||||
{
|
||||
switch (config->type)
|
||||
{
|
||||
case CONFIG_BINARY:
|
||||
id++;
|
||||
break;
|
||||
|
||||
case CONFIG_SELECTION:
|
||||
case CONFIG_MIDI:
|
||||
case CONFIG_SPINNER:
|
||||
id += 2;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
{
|
||||
if (cid == id+1)
|
||||
{
|
||||
char s[512];
|
||||
s[0] = 0;
|
||||
int c, d;
|
||||
HWND h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, WM_GETTEXT, 511, (LPARAM)s);
|
||||
char file_filter[512];
|
||||
file_filter[0] = 0;
|
||||
|
||||
c = 0;
|
||||
while (config->file_filter[c].description[0])
|
||||
{
|
||||
if (c > 0)
|
||||
strcat(file_filter, "|");
|
||||
strcat(file_filter, config->file_filter[c].description);
|
||||
strcat(file_filter, " (");
|
||||
d = 0;
|
||||
while (config->file_filter[c].extensions[d][0])
|
||||
{
|
||||
if (d > 0)
|
||||
strcat(file_filter, ";");
|
||||
strcat(file_filter, "*.");
|
||||
strcat(file_filter, config->file_filter[c].extensions[d]);
|
||||
d++;
|
||||
}
|
||||
strcat(file_filter, ")|");
|
||||
d = 0;
|
||||
while (config->file_filter[c].extensions[d][0])
|
||||
{
|
||||
if (d > 0)
|
||||
strcat(file_filter, ";");
|
||||
strcat(file_filter, "*.");
|
||||
strcat(file_filter, config->file_filter[c].extensions[d]);
|
||||
d++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
strcat(file_filter, "|All files (*.*)|*.*|");
|
||||
mbstowcs(ws, file_filter, strlen(file_filter) + 1);
|
||||
d = strlen(file_filter);
|
||||
|
||||
/* replace | with \0 */
|
||||
for (c = 0; c < d; ++c)
|
||||
if (ws[c] == L'|')
|
||||
ws[c] = 0;
|
||||
|
||||
if (!file_dlg(hdlg, ws, s, 0))
|
||||
SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
config++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -323,8 +471,8 @@ void deviceconfig_open(HWND hwnd, device_t *device)
|
||||
*data++ = 0; /*predefined dialog box class*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50);
|
||||
|
||||
*data++ = 8; /*Point*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50);
|
||||
*data++ = 9; /*Point*/
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Segoe UI", -1, data, 50);
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
data++;
|
||||
@@ -402,6 +550,122 @@ void deviceconfig_open(HWND hwnd, device_t *device)
|
||||
|
||||
y += 20;
|
||||
break;
|
||||
|
||||
case CONFIG_SPINNER:
|
||||
/*Spinner*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 140;
|
||||
item->cy = 14;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_NUMBER;
|
||||
item->dwExtendedStyle = WS_EX_CLIENTEDGE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0081; /* edit text class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/* TODO: add up down class */
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
break;
|
||||
|
||||
case CONFIG_FILE:
|
||||
/*File*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 70;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 100;
|
||||
item->cy = 14;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | ES_READONLY;
|
||||
item->dwExtendedStyle = WS_EX_CLIENTEDGE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0081; /* edit text class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/* Button */
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 175;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 35;
|
||||
item->cy = 14;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0080; /* button class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, "Browse", -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
/*Static text*/
|
||||
item = (DLGITEMTEMPLATE *)data;
|
||||
item->x = 10;
|
||||
item->y = y;
|
||||
item->id = id++;
|
||||
|
||||
item->cx = 60;
|
||||
item->cy = 15;
|
||||
|
||||
item->style = WS_CHILD | WS_VISIBLE;
|
||||
|
||||
data = (uint16_t *)(item + 1);
|
||||
*data++ = 0xFFFF;
|
||||
*data++ = 0x0082; /* static class */
|
||||
|
||||
data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256);
|
||||
*data++ = 0; /* no creation data */
|
||||
|
||||
if (((uintptr_t)data) & 2)
|
||||
data++;
|
||||
|
||||
y += 20;
|
||||
break;
|
||||
}
|
||||
|
||||
if (((unsigned long)data) & 2)
|
||||
|
||||
@@ -37,7 +37,20 @@ LCID dwLanguage;
|
||||
|
||||
uint32_t dwLangID, dwSubLangID;
|
||||
|
||||
WCHAR lpResourceString[STRINGS_NUM][512];
|
||||
typedef struct
|
||||
{
|
||||
WCHAR lpString[512];
|
||||
} resource_string_t;
|
||||
|
||||
resource_string_t *lpResourceString2048;
|
||||
resource_string_t *lpResourceString3072;
|
||||
resource_string_t *lpResourceString4096;
|
||||
resource_string_t *lpResourceString4352;
|
||||
resource_string_t *lpResourceString4608;
|
||||
resource_string_t *lpResourceString5120;
|
||||
resource_string_t *lpResourceString5376;
|
||||
resource_string_t *lpResourceString5632;
|
||||
resource_string_t *lpResourceString6144;
|
||||
|
||||
char openfilestring[260];
|
||||
WCHAR wopenfilestring[260];
|
||||
@@ -51,15 +64,65 @@ void win_language_load_common_strings()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < STRINGS_NUM; i++)
|
||||
lpResourceString2048 = (resource_string_t *) malloc(STRINGS_NUM_2048 * sizeof(resource_string_t));
|
||||
lpResourceString3072 = (resource_string_t *) malloc(STRINGS_NUM_3072 * sizeof(resource_string_t));
|
||||
lpResourceString4096 = (resource_string_t *) malloc(STRINGS_NUM_4096 * sizeof(resource_string_t));
|
||||
lpResourceString4352 = (resource_string_t *) malloc(STRINGS_NUM_4352 * sizeof(resource_string_t));
|
||||
lpResourceString4608 = (resource_string_t *) malloc(STRINGS_NUM_4608 * sizeof(resource_string_t));
|
||||
lpResourceString5120 = (resource_string_t *) malloc(STRINGS_NUM_5120 * sizeof(resource_string_t));
|
||||
lpResourceString5376 = (resource_string_t *) malloc(STRINGS_NUM_5376 * sizeof(resource_string_t));
|
||||
lpResourceString5632 = (resource_string_t *) malloc(STRINGS_NUM_5632 * sizeof(resource_string_t));
|
||||
lpResourceString6144 = (resource_string_t *) malloc(STRINGS_NUM_6144 * sizeof(resource_string_t));
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_2048; i++)
|
||||
{
|
||||
LoadString(hinstance, 2048 + i, lpResourceString[i], 512);
|
||||
LoadString(hinstance, 2048 + i, lpResourceString2048[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_3072; i++)
|
||||
{
|
||||
LoadString(hinstance, 3072 + i, lpResourceString3072[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_4096; i++)
|
||||
{
|
||||
LoadString(hinstance, 4096 + i, lpResourceString4096[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_4352; i++)
|
||||
{
|
||||
LoadString(hinstance, 4352 + i, lpResourceString4352[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_4608; i++)
|
||||
{
|
||||
LoadString(hinstance, 4608 + i, lpResourceString4608[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_5120; i++)
|
||||
{
|
||||
LoadString(hinstance, 5120 + i, lpResourceString5120[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_5376; i++)
|
||||
{
|
||||
LoadString(hinstance, 5376 + i, lpResourceString5376[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_5632; i++)
|
||||
{
|
||||
LoadString(hinstance, 5632 + i, lpResourceString5632[i].lpString, 512);
|
||||
}
|
||||
|
||||
for (i = 0; i < STRINGS_NUM_6144; i++)
|
||||
{
|
||||
LoadString(hinstance, 6144 + i, lpResourceString6144[i].lpString, 512);
|
||||
}
|
||||
}
|
||||
|
||||
LPTSTR win_language_get_settings_category(int i)
|
||||
{
|
||||
return lpResourceString[17 + i];
|
||||
return lpResourceString2048[17 + i].lpString;
|
||||
}
|
||||
|
||||
void win_language_update()
|
||||
@@ -81,7 +144,42 @@ void win_language_check()
|
||||
|
||||
LPTSTR win_language_get_string_from_id(int i)
|
||||
{
|
||||
return lpResourceString[i - 2048];
|
||||
if ((i >= 2048) && (i <= 3071))
|
||||
{
|
||||
return lpResourceString2048[i - 2048].lpString;
|
||||
}
|
||||
else if ((i >= 3072) && (i <= 4095))
|
||||
{
|
||||
return lpResourceString3072[i - 3072].lpString;
|
||||
}
|
||||
else if ((i >= 4096) && (i <= 4351))
|
||||
{
|
||||
return lpResourceString4096[i - 4096].lpString;
|
||||
}
|
||||
else if ((i >= 4352) && (i <= 4607))
|
||||
{
|
||||
return lpResourceString4352[i - 4352].lpString;
|
||||
}
|
||||
else if ((i >= 4608) && (i <= 5119))
|
||||
{
|
||||
return lpResourceString4608[i - 4608].lpString;
|
||||
}
|
||||
else if ((i >= 5120) && (i <= 5375))
|
||||
{
|
||||
return lpResourceString5120[i - 5120].lpString;
|
||||
}
|
||||
else if ((i >= 5376) && (i <= 5631))
|
||||
{
|
||||
return lpResourceString5376[i - 5376].lpString;
|
||||
}
|
||||
else if ((i >= 5632) && (i <= 6143))
|
||||
{
|
||||
return lpResourceString5632[i - 5632].lpString;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lpResourceString6144[i - 6144].lpString;
|
||||
}
|
||||
}
|
||||
|
||||
wchar_t *plat_get_string_from_id(int i)
|
||||
@@ -91,37 +189,37 @@ wchar_t *plat_get_string_from_id(int i)
|
||||
|
||||
LPTSTR win_language_get_string_from_string(char *str)
|
||||
{
|
||||
return lpResourceString[atoi(str) - 2048];
|
||||
return win_language_get_string_from_id(atoi(str));
|
||||
}
|
||||
|
||||
int msgbox_reset(HWND hwndParent)
|
||||
{
|
||||
return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNOCANCEL | MB_ICONQUESTION);
|
||||
return MessageBox(hwndParent, lpResourceString2048[3].lpString, lpResourceString2048[0].lpString, MB_YESNOCANCEL | MB_ICONQUESTION);
|
||||
}
|
||||
|
||||
int msgbox_reset_yn(HWND hwndParent)
|
||||
{
|
||||
return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNO | MB_ICONQUESTION);
|
||||
return MessageBox(hwndParent, lpResourceString2048[3].lpString, lpResourceString2048[0].lpString, MB_YESNO | MB_ICONQUESTION);
|
||||
}
|
||||
|
||||
int msgbox_question(HWND hwndParent, int i)
|
||||
{
|
||||
return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_YESNO | MB_ICONQUESTION);
|
||||
return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[0].lpString, MB_YESNO | MB_ICONQUESTION);
|
||||
}
|
||||
|
||||
void msgbox_info(HWND hwndParent, int i)
|
||||
{
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION);
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[0].lpString, MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr)
|
||||
{
|
||||
MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION);
|
||||
MessageBox(hwndParent, wstr, lpResourceString2048[0].lpString, MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
void msgbox_error(HWND hwndParent, int i)
|
||||
{
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING);
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[1].lpString, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
void plat_msgbox_error(int i)
|
||||
@@ -131,12 +229,12 @@ void plat_msgbox_error(int i)
|
||||
|
||||
void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr)
|
||||
{
|
||||
MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING);
|
||||
MessageBox(hwndParent, wstr, lpResourceString2048[1].lpString, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
void msgbox_critical(HWND hwndParent, int i)
|
||||
{
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], MB_OK | MB_ICONERROR);
|
||||
MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString2048[2].lpString, MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
void msgbox_fatal(HWND hwndParent, char *string)
|
||||
@@ -146,7 +244,7 @@ void msgbox_fatal(HWND hwndParent, char *string)
|
||||
|
||||
mbstowcs(lptsTemp, string, strlen(string) + 1);
|
||||
|
||||
MessageBox(hwndParent, lptsTemp, lpResourceString[2], MB_OK | MB_ICONERROR);
|
||||
MessageBox(hwndParent, lptsTemp, lpResourceString2048[2].lpString, MB_OK | MB_ICONERROR);
|
||||
|
||||
free(lptsTemp);
|
||||
}
|
||||
@@ -215,6 +313,15 @@ int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save)
|
||||
return file_dlg_w(hwnd, f, ufn, save);
|
||||
}
|
||||
|
||||
int file_dlg_mb(HWND hwnd, char *f, char *fn, int save)
|
||||
{
|
||||
WCHAR uf[512];
|
||||
WCHAR ufn[512];
|
||||
mbstowcs(uf, f, strlen(fn) + 1);
|
||||
mbstowcs(ufn, fn, strlen(fn) + 1);
|
||||
return file_dlg_w(hwnd, uf, ufn, save);
|
||||
}
|
||||
|
||||
int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save)
|
||||
{
|
||||
return file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save);
|
||||
|
||||
@@ -34,6 +34,7 @@ void msgbox_critical(HWND hwndParent, int i);
|
||||
|
||||
int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save);
|
||||
int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save);
|
||||
int file_dlg_mb(HWND hwnd, char *f, char *fn, int save);
|
||||
int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save);
|
||||
int file_dlg_st(HWND hwnd, int i, char *fn, int save);
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "../hdd.h"
|
||||
#include "../ide.h"
|
||||
#include "../scsi.h"
|
||||
#include "../scsi_buslogic.h"
|
||||
#include "../network/network.h"
|
||||
#include "../sound/midi.h"
|
||||
#include "../sound/sound.h"
|
||||
@@ -78,6 +77,7 @@ static hard_disk_t temp_hdc[HDC_NUM];
|
||||
/* Removable devices category */
|
||||
static int temp_fdd_types[FDD_NUM];
|
||||
static int temp_fdd_turbo[FDD_NUM];
|
||||
static int temp_fdd_check_bpb[FDD_NUM];
|
||||
static cdrom_drive_t temp_cdrom_drives[CDROM_NUM];
|
||||
|
||||
static HWND hwndParentDialog, hwndChildDialog;
|
||||
@@ -158,6 +158,7 @@ static void win_settings_init(void)
|
||||
{
|
||||
temp_fdd_types[i] = fdd_get_type(i);
|
||||
temp_fdd_turbo[i] = fdd_get_turbo(i);
|
||||
temp_fdd_check_bpb[i] = fdd_get_check_bpb(i);
|
||||
}
|
||||
memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t));
|
||||
}
|
||||
@@ -224,6 +225,7 @@ static int win_settings_changed(void)
|
||||
{
|
||||
i = i || (temp_fdd_types[j] != fdd_get_type(j));
|
||||
i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j));
|
||||
i = i || (temp_fdd_check_bpb[j] != fdd_get_check_bpb(j));
|
||||
}
|
||||
i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t));
|
||||
|
||||
@@ -327,6 +329,7 @@ static void win_settings_save(void)
|
||||
{
|
||||
fdd_set_type(i, temp_fdd_types[i]);
|
||||
fdd_set_turbo(i, temp_fdd_turbo[i]);
|
||||
fdd_set_check_bpb(i, temp_fdd_check_bpb[i]);
|
||||
}
|
||||
memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t));
|
||||
|
||||
@@ -624,7 +627,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w
|
||||
deviceconfig_open(hdlg, (void *)model_getdevice(temp_model));
|
||||
break;
|
||||
case IDC_BUTTON_NVR_PATH:
|
||||
p = BrowseFolder(temp_nvr_path, win_language_get_string_from_id(IDS_2225));
|
||||
p = BrowseFolder(temp_nvr_path, win_language_get_string_from_id(IDS_2056));
|
||||
if (wcscmp(p, L""))
|
||||
{
|
||||
memset(temp_nvr_path, 0, sizeof(temp_nvr_path));
|
||||
@@ -663,7 +666,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_MEMTEXT);
|
||||
SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, sizeof(stransi));
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
sscanf(stransi, "%i", &temp_mem_size);
|
||||
temp_mem_size &= ~(models[temp_model].ram_granularity - 1);
|
||||
if (temp_mem_size < models[temp_model].min_ram)
|
||||
@@ -765,7 +768,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_VIDEO);
|
||||
SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, sizeof(stransi));
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
gfx = video_card_getid(stransi);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIGURE_VID);
|
||||
@@ -792,7 +795,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_VIDEO);
|
||||
SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, sizeof(stransi));
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
gfx = video_card_getid(stransi);
|
||||
temp_gfxcard = video_new_to_old(gfx);
|
||||
|
||||
@@ -828,7 +831,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_VIDEO);
|
||||
SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, sizeof(stransi));
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi)));
|
||||
|
||||
free(stransi);
|
||||
@@ -843,7 +846,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_VIDEO);
|
||||
SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp);
|
||||
wcstombs(stransi, lptsTemp, sizeof(stransi));
|
||||
wcstombs(stransi, lptsTemp, 512);
|
||||
temp_gfxcard = video_new_to_old(video_card_getid(stransi));
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED);
|
||||
@@ -900,40 +903,7 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa
|
||||
|
||||
if (mouse_valid(type, temp_model))
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case MOUSE_TYPE_NONE:
|
||||
str_id = IDS_2151;
|
||||
break;
|
||||
case MOUSE_TYPE_SERIAL:
|
||||
default:
|
||||
str_id = IDS_2139;
|
||||
break;
|
||||
case MOUSE_TYPE_PS2:
|
||||
str_id = IDS_2141;
|
||||
break;
|
||||
case MOUSE_TYPE_PS2_MS:
|
||||
str_id = IDS_2142;
|
||||
break;
|
||||
case MOUSE_TYPE_BUS:
|
||||
str_id = IDS_2143;
|
||||
break;
|
||||
case MOUSE_TYPE_AMSTRAD:
|
||||
str_id = IDS_2162;
|
||||
break;
|
||||
case MOUSE_TYPE_OLIM24:
|
||||
str_id = IDS_2177;
|
||||
break;
|
||||
case MOUSE_TYPE_MSYSTEMS:
|
||||
str_id = IDS_2140;
|
||||
break;
|
||||
case MOUSE_TYPE_LOGITECH:
|
||||
str_id = IDS_2224;
|
||||
break;
|
||||
case MOUSE_TYPE_GENIUS:
|
||||
str_id = IDS_2161;
|
||||
break;
|
||||
}
|
||||
str_id = IDS_3072 + c;
|
||||
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(str_id));
|
||||
|
||||
@@ -1289,7 +1259,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa
|
||||
|
||||
c++;
|
||||
}
|
||||
SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_midi_device], 0);
|
||||
SendMessage(h, CB_SETCURSEL, settings_midi_to_list[temp_midi_device], 0);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI);
|
||||
if (midi_device_has_config(temp_midi_device))
|
||||
@@ -1498,7 +1468,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR
|
||||
recalc_hdd_list(hdlg, temp_model, 0);
|
||||
|
||||
h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_5376));
|
||||
|
||||
for (c = 0; c < 11; c++)
|
||||
{
|
||||
@@ -1516,7 +1486,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR
|
||||
}
|
||||
|
||||
h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2151));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_5376));
|
||||
|
||||
for (c = 0; c < 11; c++)
|
||||
{
|
||||
@@ -1921,41 +1891,36 @@ static void add_locations(HWND hdlg)
|
||||
lptsTemp = (LPTSTR) malloc(512);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS);
|
||||
for (i = 0; i < 4; i++)
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_4352 + i));
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2209 + i));
|
||||
}
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2202));
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1);
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4097), i >> 1, i & 1);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_ID);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(2088), i);
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(2088), i);
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1);
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4097), i >> 1, i & 1);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
|
||||
}
|
||||
|
||||
@@ -2010,16 +1975,6 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg)
|
||||
EnableWindow(h, TRUE);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0);
|
||||
break;
|
||||
case HDD_BUS_RLL: /* RLL */
|
||||
h = GetDlgItem(hdlg, IDT_1722);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.rll_channel : temp_hdc[hdlv_current_sel].rll_channel, 0);
|
||||
break;
|
||||
case HDD_BUS_XTIDE: /* XT IDE */
|
||||
h = GetDlgItem(hdlg, IDT_1722);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
@@ -2030,6 +1985,16 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg)
|
||||
EnableWindow(h, TRUE);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.xtide_channel : temp_hdc[hdlv_current_sel].xtide_channel, 0);
|
||||
break;
|
||||
case HDD_BUS_RLL: /* RLL */
|
||||
h = GetDlgItem(hdlg, IDT_1722);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL);
|
||||
ShowWindow(h, SW_SHOW);
|
||||
EnableWindow(h, TRUE);
|
||||
SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.rll_channel : temp_hdc[hdlv_current_sel].rll_channel, 0);
|
||||
break;
|
||||
case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */
|
||||
case HDD_BUS_IDE_PIO_AND_DMA: /* IDE (PIO and DMA) */
|
||||
h = GetDlgItem(hdlg, IDT_1722);
|
||||
@@ -2197,25 +2162,25 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column
|
||||
switch(temp_hdc[i].bus)
|
||||
{
|
||||
case HDD_BUS_MFM:
|
||||
wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_RLL:
|
||||
wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_XTIDE:
|
||||
wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_RLL:
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_SCSI:
|
||||
wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
break;
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
break;
|
||||
}
|
||||
lvI.pszText = szText;
|
||||
@@ -2228,25 +2193,25 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column
|
||||
}
|
||||
else if (column == 2)
|
||||
{
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].tracks);
|
||||
lvI.pszText = szText;
|
||||
lvI.iImage = 0;
|
||||
}
|
||||
else if (column == 3)
|
||||
{
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].hpc);
|
||||
lvI.pszText = szText;
|
||||
lvI.iImage = 0;
|
||||
}
|
||||
else if (column == 4)
|
||||
{
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].spt);
|
||||
lvI.pszText = szText;
|
||||
lvI.iImage = 0;
|
||||
}
|
||||
else if (column == 5)
|
||||
{
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11);
|
||||
lvI.pszText = szText;
|
||||
lvI.iImage = 0;
|
||||
}
|
||||
@@ -2281,25 +2246,25 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList)
|
||||
switch(temp_hdc[i].bus)
|
||||
{
|
||||
case HDD_BUS_MFM:
|
||||
wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_RLL:
|
||||
wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4608), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_XTIDE:
|
||||
wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4609), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_RLL:
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4610), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_IDE_PIO_ONLY:
|
||||
wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4611), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_IDE_PIO_AND_DMA:
|
||||
wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4612), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1);
|
||||
break;
|
||||
case HDD_BUS_SCSI:
|
||||
wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4613), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
break;
|
||||
case HDD_BUS_SCSI_REMOVABLE:
|
||||
wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4614), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun);
|
||||
break;
|
||||
}
|
||||
lvI.pszText = szText;
|
||||
@@ -2322,7 +2287,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList)
|
||||
}
|
||||
|
||||
lvI.iSubItem = 2;
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].tracks);
|
||||
lvI.pszText = szText;
|
||||
lvI.iItem = j;
|
||||
lvI.iImage = 0;
|
||||
@@ -2333,7 +2298,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList)
|
||||
}
|
||||
|
||||
lvI.iSubItem = 3;
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].hpc);
|
||||
lvI.pszText = szText;
|
||||
lvI.iItem = j;
|
||||
lvI.iImage = 0;
|
||||
@@ -2344,7 +2309,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList)
|
||||
}
|
||||
|
||||
lvI.iSubItem = 4;
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), temp_hdc[i].spt);
|
||||
lvI.pszText = szText;
|
||||
lvI.iItem = j;
|
||||
lvI.iImage = 0;
|
||||
@@ -2355,7 +2320,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList)
|
||||
}
|
||||
|
||||
lvI.iSubItem = 5;
|
||||
wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_4098), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11);
|
||||
lvI.pszText = szText;
|
||||
lvI.iItem = j;
|
||||
lvI.iImage = 0;
|
||||
@@ -2436,7 +2401,7 @@ static void get_edit_box_contents(HWND hdlg, int id, uint64_t *val)
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText);
|
||||
wcstombs(stransi, szText, sizeof(stransi));
|
||||
wcstombs(stransi, szText, 256);
|
||||
sscanf(stransi, "%" PRIu64, val);
|
||||
}
|
||||
|
||||
@@ -2454,7 +2419,7 @@ static void set_edit_box_contents(HWND hdlg, int id, uint64_t val)
|
||||
WCHAR szText[256];
|
||||
|
||||
h = GetDlgItem(hdlg, id);
|
||||
wsprintf(szText, win_language_get_string_from_id(2160), val);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_2156), val);
|
||||
SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText);
|
||||
}
|
||||
|
||||
@@ -2488,15 +2453,15 @@ static int hdconf_initialize_hdt_combo(HWND hdlg)
|
||||
{
|
||||
temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2];
|
||||
size_mb = temp_size >> 11;
|
||||
wsprintf(szText, win_language_get_string_from_id(2171), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]);
|
||||
wsprintf(szText, win_language_get_string_from_id(IDS_2157), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText);
|
||||
if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2]))
|
||||
{
|
||||
selection = i;
|
||||
}
|
||||
}
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2170));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2187));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_4100));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_4101));
|
||||
SendMessage(h, CB_SETCURSEL, selection, 0);
|
||||
return selection;
|
||||
}
|
||||
@@ -2538,7 +2503,6 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W
|
||||
char *big_buf;
|
||||
int b = 0;
|
||||
uint64_t r = 0;
|
||||
int j = 0;
|
||||
|
||||
switch (message)
|
||||
{
|
||||
@@ -2555,7 +2519,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W
|
||||
hdc_ptr = &(temp_hdc[next_free_id]);
|
||||
}
|
||||
|
||||
SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? 2197 : 2196));
|
||||
SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? IDS_4103 : IDS_4102));
|
||||
|
||||
no_update = 1;
|
||||
spt = (existing & 1) ? 0 : 17;
|
||||
@@ -2656,7 +2620,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W
|
||||
if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE))
|
||||
{
|
||||
hdc_ptr->bus = HDD_BUS_DISABLED;
|
||||
msgbox_error(hwndParentDialog, IDS_2056);
|
||||
msgbox_error(hwndParentDialog, IDS_4112);
|
||||
return TRUE;
|
||||
}
|
||||
else if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE))
|
||||
@@ -2728,7 +2692,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W
|
||||
if (size >= 0x100000000ll)
|
||||
{
|
||||
fclose(f);
|
||||
msgbox_error(hwndParentDialog, IDS_2058);
|
||||
msgbox_error(hwndParentDialog, IDS_4104);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2751,7 +2715,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W
|
||||
if (size > 0xffffffffffffffffll)
|
||||
{
|
||||
fclose(f);
|
||||
msgbox_error(hwndParentDialog, IDS_2163);
|
||||
msgbox_error(hwndParentDialog, IDS_4105);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2791,7 +2755,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
msgbox_info(hwndParentDialog, IDS_2059);
|
||||
msgbox_info(hwndParentDialog, IDS_4113);
|
||||
}
|
||||
|
||||
hd_add_ok_common:
|
||||
@@ -2809,7 +2773,7 @@ hd_add_ok_common:
|
||||
return TRUE;
|
||||
|
||||
case IDC_CFILE:
|
||||
if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !(existing & 1)))
|
||||
if (!file_dlg_w(hdlg, win_language_get_string_from_id(IDS_4106), L"", !(existing & 1)))
|
||||
{
|
||||
if (!(existing & 1))
|
||||
{
|
||||
@@ -2817,7 +2781,7 @@ hd_add_ok_common:
|
||||
if (f != NULL)
|
||||
{
|
||||
fclose(f);
|
||||
if (msgbox_question(ghwnd, IDS_2178) != IDYES)
|
||||
if (msgbox_question(ghwnd, IDS_4111) != IDYES)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2828,7 +2792,7 @@ hd_add_ok_common:
|
||||
if (f == NULL)
|
||||
{
|
||||
hdd_add_file_open_error:
|
||||
msgbox_error(hwndParentDialog, (existing & 1) ? 2060 : 2057);
|
||||
msgbox_error(hwndParentDialog, (existing & 1) ? IDS_4107 : IDS_4108);
|
||||
return TRUE;
|
||||
}
|
||||
if (existing & 1)
|
||||
@@ -2839,7 +2803,7 @@ hdd_add_file_open_error:
|
||||
fread(§or_size, 1, 4, f);
|
||||
if (sector_size != 512)
|
||||
{
|
||||
msgbox_error(hwndParentDialog, IDS_2061);
|
||||
msgbox_error(hwndParentDialog, IDS_4109);
|
||||
fclose(f);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2866,7 +2830,7 @@ hdd_add_file_open_error:
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = 0; j < 16; j++)
|
||||
for (i = 5; i < 16; i++)
|
||||
{
|
||||
if (((size % (i << 9)) == 0) && (size <= ((i * 17) << 19)))
|
||||
{
|
||||
@@ -3471,42 +3435,12 @@ int cdlv_current_sel;
|
||||
|
||||
static int combo_id_to_string_id(int combo_id)
|
||||
{
|
||||
switch (combo_id)
|
||||
{
|
||||
case CDROM_BUS_DISABLED: /* Disabled */
|
||||
default:
|
||||
return 2151;
|
||||
break;
|
||||
case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */
|
||||
return 2189;
|
||||
break;
|
||||
case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */
|
||||
return 2190;
|
||||
break;
|
||||
case CDROM_BUS_SCSI: /* SCSI */
|
||||
return 2210;
|
||||
break;
|
||||
}
|
||||
return IDS_5376 + combo_id;
|
||||
}
|
||||
|
||||
static int combo_id_to_format_string_id(int combo_id)
|
||||
{
|
||||
switch (combo_id)
|
||||
{
|
||||
case CDROM_BUS_DISABLED: /* Disabled */
|
||||
default:
|
||||
return 2151;
|
||||
break;
|
||||
case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */
|
||||
return 2191;
|
||||
break;
|
||||
case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */
|
||||
return 2192;
|
||||
break;
|
||||
case CDROM_BUS_SCSI: /* SCSI */
|
||||
return 2158;
|
||||
break;
|
||||
}
|
||||
return IDS_5632 + combo_id;
|
||||
}
|
||||
|
||||
static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList)
|
||||
@@ -3583,7 +3517,7 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList)
|
||||
}
|
||||
else
|
||||
{
|
||||
lvI.pszText = win_language_get_string_from_id(2151);
|
||||
lvI.pszText = win_language_get_string_from_id(IDS_5376);
|
||||
}
|
||||
lvI.iItem = i;
|
||||
lvI.iImage = temp_fdd_types[i];
|
||||
@@ -3592,7 +3526,17 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList)
|
||||
return FALSE;
|
||||
|
||||
lvI.iSubItem = 1;
|
||||
lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223);
|
||||
lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061);
|
||||
lvI.iItem = i;
|
||||
lvI.iImage = 0;
|
||||
|
||||
if (ListView_SetItem(hwndList, &lvI) == -1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lvI.iSubItem = 2;
|
||||
lvI.pszText = win_language_get_string_from_id(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061);
|
||||
lvI.iItem = i;
|
||||
lvI.iImage = 0;
|
||||
|
||||
@@ -3659,7 +3603,7 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList)
|
||||
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
|
||||
|
||||
lvc.iSubItem = 0;
|
||||
lvc.pszText = win_language_get_string_from_id(2188);
|
||||
lvc.pszText = win_language_get_string_from_id(IDS_2143);
|
||||
|
||||
lvc.cx = 292;
|
||||
lvc.fmt = LVCFMT_LEFT;
|
||||
@@ -3670,9 +3614,9 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList)
|
||||
}
|
||||
|
||||
lvc.iSubItem = 1;
|
||||
lvc.pszText = win_language_get_string_from_id(2221);
|
||||
lvc.pszText = win_language_get_string_from_id(IDS_2059);
|
||||
|
||||
lvc.cx = 100;
|
||||
lvc.cx = 50;
|
||||
lvc.fmt = LVCFMT_LEFT;
|
||||
|
||||
if (ListView_InsertColumn(hwndList, 1, &lvc) == -1)
|
||||
@@ -3680,6 +3624,16 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lvc.iSubItem = 2;
|
||||
lvc.pszText = win_language_get_string_from_id(IDS_2170);
|
||||
|
||||
lvc.cx = 75;
|
||||
lvc.fmt = LVCFMT_LEFT;
|
||||
|
||||
if (ListView_InsertColumn(hwndList, 2, &lvc) == -1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -3761,7 +3715,7 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i)
|
||||
}
|
||||
else
|
||||
{
|
||||
lvI.pszText = win_language_get_string_from_id(2151);
|
||||
lvI.pszText = win_language_get_string_from_id(IDS_5376);
|
||||
}
|
||||
lvI.iImage = temp_fdd_types[i];
|
||||
|
||||
@@ -3771,7 +3725,17 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i)
|
||||
}
|
||||
|
||||
lvI.iSubItem = 1;
|
||||
lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223);
|
||||
lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? IDS_2060 : IDS_2061);
|
||||
lvI.iItem = i;
|
||||
lvI.iImage = 0;
|
||||
|
||||
if (ListView_SetItem(hwndList, &lvI) == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lvI.iSubItem = 2;
|
||||
lvI.pszText = win_language_get_string_from_id(temp_fdd_check_bpb[i] ? IDS_2060 : IDS_2061);
|
||||
lvI.iItem = i;
|
||||
lvI.iImage = 0;
|
||||
|
||||
@@ -3845,21 +3809,21 @@ static void cdrom_add_locations(HWND hdlg)
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_CD_ID);
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(2088), i);
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(2088), i);
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4098), i);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
|
||||
}
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1);
|
||||
wsprintf(lptsTemp, win_language_get_string_from_id(IDS_4097), i >> 1, i & 1);
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp);
|
||||
}
|
||||
|
||||
@@ -3953,7 +3917,7 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151));
|
||||
SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_5376));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3966,6 +3930,9 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message
|
||||
h = GetDlgItem(hdlg, IDC_CHECKTURBO);
|
||||
SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0);
|
||||
|
||||
h = GetDlgItem(hdlg, IDC_CHECKBPB);
|
||||
SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[fdlv_current_sel], 0);
|
||||
|
||||
cdlv_current_sel = 0;
|
||||
h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES);
|
||||
win_settings_cdrom_drives_init_columns(h);
|
||||
@@ -4027,6 +3994,8 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message
|
||||
SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0);
|
||||
h = GetDlgItem(hdlg, IDC_CHECKTURBO);
|
||||
SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0);
|
||||
h = GetDlgItem(hdlg, IDC_CHECKBPB);
|
||||
SendMessage(h, BM_SETCHECK, temp_fdd_check_bpb[fdlv_current_sel], 0);
|
||||
rd_ignore_change = 0;
|
||||
}
|
||||
else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES))
|
||||
@@ -4104,6 +4073,20 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message
|
||||
rd_ignore_change = 0;
|
||||
return FALSE;
|
||||
|
||||
case IDC_CHECKBPB:
|
||||
if (rd_ignore_change)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rd_ignore_change = 1;
|
||||
h = GetDlgItem(hdlg, IDC_CHECKBPB);
|
||||
temp_fdd_check_bpb[fdlv_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0);
|
||||
h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES);
|
||||
win_settings_floppy_drives_update_item(h, fdlv_current_sel);
|
||||
rd_ignore_change = 0;
|
||||
return FALSE;
|
||||
|
||||
case IDC_COMBO_CD_BUS:
|
||||
if (rd_ignore_change)
|
||||
{
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
#include "ibm.h"
|
||||
#include "cpu/cpu.h"
|
||||
#include "io.h"
|
||||
#include "device.h"
|
||||
#include "model.h"
|
||||
|
||||
|
||||
static int acerm3a_index;
|
||||
|
||||
|
||||
static void acerm3a_write(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
if (port == 0xea)
|
||||
acerm3a_index = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t acerm3a_read(uint16_t port, void *p)
|
||||
{
|
||||
if (port == 0xeb)
|
||||
{
|
||||
switch (acerm3a_index)
|
||||
{
|
||||
case 2:
|
||||
return 0xfd;
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
void acerm3a_io_init(void)
|
||||
{
|
||||
io_sethandler(0x00ea, 0x0002, acerm3a_read, NULL, NULL, acerm3a_write, NULL, NULL, NULL);
|
||||
}
|
||||
@@ -233,6 +233,7 @@ void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks);
|
||||
void cdrom_insert(uint8_t id);
|
||||
|
||||
int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun);
|
||||
int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len);
|
||||
|
||||
#define cdrom_sense_error cdrom[id].sense[0]
|
||||
#define cdrom_sense_key cdrom[id].sense[2]
|
||||
|
||||
@@ -247,7 +247,11 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename)
|
||||
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.mode2 = true;
|
||||
} else return false;
|
||||
} else {
|
||||
/* Unknown mode: Assume regular 2048-byte sectors, this is needed so Apple Rhapsody ISO's can be mounted. */
|
||||
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||
track.mode2 = false;
|
||||
}
|
||||
|
||||
track.length = track.file->getLength() / track.sectorSize;
|
||||
tracks.push_back(track);
|
||||
|
||||
@@ -171,4 +171,6 @@ typedef std::vector<Track>::iterator track_it;
|
||||
std::string mcn;
|
||||
};
|
||||
|
||||
void cdrom_image_log(const char *format, ...);
|
||||
|
||||
#endif /* __CDROM_INTERFACE__ */
|
||||
|
||||
@@ -988,6 +988,7 @@ int image_open(uint8_t id, wchar_t *fn)
|
||||
wcstombs(afn, fn, sizeof(afn));
|
||||
if (!cdimg[id]->SetDevice(afn, false))
|
||||
{
|
||||
pclog("Image failed to load\n");
|
||||
image_close(id);
|
||||
cdrom_set_null_handler(id);
|
||||
return 1;
|
||||
|
||||
80
src/config.c
80
src/config.c
@@ -1,5 +1,23 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
* see COPYING for more details
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Configuration file handler.
|
||||
*
|
||||
* Version: @(#)config.c 1.0.0 2017/07/26
|
||||
*
|
||||
* Authors: Sarah Walker,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Overdoze,
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
* Copyright 2017-2017 Fred N. van Kempen.
|
||||
* Copyright 2017-2017 Overdoze.
|
||||
*
|
||||
* NOTE: Forcing config files to be in Unicode encoding breaks it on
|
||||
* Windows XP, and possibly also Vista. Use -DANSI_CFG for use
|
||||
@@ -81,6 +99,18 @@ typedef struct entry_t
|
||||
(new)->next = NULL; \
|
||||
}
|
||||
|
||||
#define list_delete(old, head) \
|
||||
{ \
|
||||
struct list_t *next = head; \
|
||||
\
|
||||
while ((next)->next != old) \
|
||||
{ \
|
||||
next = (next)->next; \
|
||||
} \
|
||||
\
|
||||
(next)->next = (old)->next; \
|
||||
}
|
||||
|
||||
|
||||
void config_dump(void)
|
||||
{
|
||||
@@ -471,7 +501,8 @@ void config_delete_var(char *head, char *name)
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
memset(entry->name, 0, strlen(entry->name));
|
||||
list_delete(&entry->list, §ion->entry_head);
|
||||
free(entry);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -488,7 +519,8 @@ void config_delete_section_if_empty(char *head)
|
||||
|
||||
if (entries_num(section) == 0)
|
||||
{
|
||||
memset(section->name, 0, strlen(section->name));
|
||||
list_delete(§ion->list, &config_head);
|
||||
free(section);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -742,7 +774,7 @@ void config_save(wchar_t *fn)
|
||||
|
||||
while (current_entry)
|
||||
{
|
||||
if(strlen(current_entry->name) > 0)
|
||||
if(current_entry->name[0])
|
||||
{
|
||||
mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1);
|
||||
if (current_entry->wdata[0] == L'\0')
|
||||
@@ -841,7 +873,17 @@ static void loadconfig_machine(void)
|
||||
|
||||
p = config_get_string(cat, "model", NULL);
|
||||
if (p != NULL)
|
||||
model = model_get_model_from_internal_name(p);
|
||||
{
|
||||
/* Detect the old model typo and fix it, so that old configurations don't braek. */
|
||||
if (strcmp(p, "p55r2p4") == 0)
|
||||
{
|
||||
model = model_get_model_from_internal_name("p55t2p4");
|
||||
}
|
||||
else
|
||||
{
|
||||
model = model_get_model_from_internal_name(p);
|
||||
}
|
||||
}
|
||||
else
|
||||
model = 0;
|
||||
if (model >= model_count())
|
||||
@@ -1056,11 +1098,11 @@ static void loadconfig_network(void)
|
||||
{
|
||||
if ((network_ndev == 1) && strcmp(network_pcap, "none"))
|
||||
{
|
||||
msgbox_error(ghwnd, IDS_2107);
|
||||
msgbox_error(ghwnd, IDS_2140);
|
||||
}
|
||||
else if (network_dev_to_id(p) == -1)
|
||||
{
|
||||
msgbox_error(ghwnd, IDS_2200);
|
||||
msgbox_error(ghwnd, IDS_2141);
|
||||
}
|
||||
|
||||
strcpy(network_pcap, "none");
|
||||
@@ -1218,14 +1260,14 @@ static int config_string_to_bus(char *str, int cdrom)
|
||||
|
||||
if (!strcmp(str, "usb"))
|
||||
{
|
||||
msgbox_error(ghwnd, IDS_2199);
|
||||
msgbox_error(ghwnd, IDS_4110);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
no_mfm_cdrom:
|
||||
msgbox_error(ghwnd, IDS_2095);
|
||||
msgbox_error(ghwnd, IDS_4114);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1505,6 +1547,8 @@ static void loadconfig_removable_devices(void)
|
||||
ui_writeprot[c] = !!config_get_int(cat, temps, 0);
|
||||
sprintf(temps, "fdd_%02i_turbo", c + 1);
|
||||
fdd_set_turbo(c, !!config_get_int(cat, temps, 0));
|
||||
sprintf(temps, "fdd_%02i_check_bpb", c + 1);
|
||||
fdd_set_check_bpb(c, !!config_get_int(cat, temps, 1));
|
||||
|
||||
/* Check, whether each value is default, if yes, delete it so that only non-default values will later be saved. */
|
||||
if (fdd_get_type(c) == ((c < 2) ? 2 : 0))
|
||||
@@ -1530,6 +1574,12 @@ static void loadconfig_removable_devices(void)
|
||||
sprintf(temps, "fdd_%02i_turbo", c + 1);
|
||||
config_delete_var(cat, temps);
|
||||
}
|
||||
|
||||
if (fdd_get_check_bpb(c) == 1)
|
||||
{
|
||||
sprintf(temps, "fdd_%02i_check_bpb", c + 1);
|
||||
config_delete_var(cat, temps);
|
||||
}
|
||||
}
|
||||
|
||||
memset(temps, 0, 512);
|
||||
@@ -2413,6 +2463,16 @@ static void saveconfig_removable_devices(void)
|
||||
{
|
||||
config_set_int(cat, temps, fdd_get_turbo(c));
|
||||
}
|
||||
|
||||
sprintf(temps, "fdd_%02i_check_bpb", c + 1);
|
||||
if (fdd_get_check_bpb(c) == 1)
|
||||
{
|
||||
config_delete_var(cat, temps);
|
||||
}
|
||||
else
|
||||
{
|
||||
config_set_int(cat, temps, fdd_get_check_bpb(c));
|
||||
}
|
||||
}
|
||||
|
||||
memset(temps, '\0', sizeof(temps));
|
||||
|
||||
26
src/config.h
26
src/config.h
@@ -1,8 +1,24 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Configuration file handler header.
|
||||
*
|
||||
* Version: @(#)config.h 1.0.0 2017/07/26
|
||||
*
|
||||
* Authors: Sarah Walker,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Overdoze,
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
* Copyright 2017-2017 Fred N. van Kempen.
|
||||
* Copyright 2017-2017 Overdoze.
|
||||
*/
|
||||
extern wchar_t config_file_default[256];
|
||||
|
||||
|
||||
|
||||
23
src/device.h
23
src/device.h
@@ -25,9 +25,11 @@
|
||||
#define CONFIG_BINARY 2
|
||||
#define CONFIG_SELECTION 3
|
||||
#define CONFIG_MIDI 4
|
||||
#define CONFIG_HEX16 5
|
||||
#define CONFIG_HEX20 6
|
||||
#define CONFIG_MAC 7
|
||||
#define CONFIG_FILE 5
|
||||
#define CONFIG_SPINNER 6
|
||||
#define CONFIG_HEX16 7
|
||||
#define CONFIG_HEX20 8
|
||||
#define CONFIG_MAC 9
|
||||
|
||||
|
||||
enum
|
||||
@@ -46,6 +48,19 @@ typedef struct device_config_selection_t
|
||||
int value;
|
||||
} device_config_selection_t;
|
||||
|
||||
typedef struct device_config_file_filter_t
|
||||
{
|
||||
char description[256];
|
||||
char extensions[25][25];
|
||||
} device_config_file_filter_t;
|
||||
|
||||
typedef struct device_config_spinner_t
|
||||
{
|
||||
int min;
|
||||
int max;
|
||||
int step;
|
||||
} device_config_spinner_t;
|
||||
|
||||
typedef struct device_config_t
|
||||
{
|
||||
char name[256];
|
||||
@@ -54,6 +69,8 @@ typedef struct device_config_t
|
||||
char default_string[256];
|
||||
int default_int;
|
||||
device_config_selection_t selection[16];
|
||||
device_config_file_filter_t file_filter[16];
|
||||
device_config_spinner_t spinner;
|
||||
} device_config_t;
|
||||
|
||||
typedef struct device_t
|
||||
|
||||
12
src/disc.c
12
src/disc.c
@@ -194,11 +194,6 @@ double disc_byteperiod(int drive)
|
||||
|
||||
if (drives[drive].byteperiod)
|
||||
{
|
||||
if (fdd_get_turbo(drive))
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return drives[drive].byteperiod(drive);
|
||||
}
|
||||
else
|
||||
@@ -217,7 +212,12 @@ double disc_real_period(int drive)
|
||||
dusec = (double) TIMER_USEC;
|
||||
|
||||
/* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */
|
||||
if ((romset == ROM_MRTHOR) && !fdd_get_turbo(drive))
|
||||
if (fdd_get_turbo(drive))
|
||||
{
|
||||
return (32.0 * dusec);
|
||||
}
|
||||
|
||||
if (romset == ROM_MRTHOR)
|
||||
{
|
||||
return (ddbp * dusec) / 4.0;
|
||||
}
|
||||
|
||||
@@ -231,5 +231,10 @@ typedef union
|
||||
sector_id_fields_t id;
|
||||
} sector_id_t;
|
||||
|
||||
void d86f_set_version(int drive, uint16_t version);
|
||||
|
||||
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n);
|
||||
void d86f_zero_bit_field(int drive, int side);
|
||||
|
||||
|
||||
#endif /*EMU_DISC_H*/
|
||||
|
||||
329
src/disc_86f.c
329
src/disc_86f.c
@@ -35,8 +35,6 @@
|
||||
#include "fdd.h"
|
||||
#include "ibm.h"
|
||||
|
||||
#define D86FVER 0x020B
|
||||
|
||||
#define CHUNK 16384
|
||||
|
||||
uint64_t poly = 0x42F0E1EBA9EA3693ll; /* ECMA normal */
|
||||
@@ -252,6 +250,8 @@ struct __attribute__((__packed__))
|
||||
uint8_t *filebuf;
|
||||
uint8_t *outbuf;
|
||||
uint32_t dma_over;
|
||||
int turbo_pos;
|
||||
uint16_t sector_id_bit_field[2][256][256][256];
|
||||
} d86f[FDD_NUM];
|
||||
#ifdef __MSC__
|
||||
# pragma pack(pop)
|
||||
@@ -273,6 +273,28 @@ void d86f_log(const char *format, ...)
|
||||
#endif
|
||||
}
|
||||
|
||||
void d86f_zero_bit_field(int drive, int side)
|
||||
{
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
int l = 0;
|
||||
|
||||
for (i = 0; i < side; i++)
|
||||
{
|
||||
for (j = 0; j < 256; j++)
|
||||
{
|
||||
for (k = 0; k < 256; k++)
|
||||
{
|
||||
for (l = 0; l < 256; l++)
|
||||
{
|
||||
d86f[drive].sector_id_bit_field[i][j][k][l] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void d86f_setupcrc(uint16_t poly)
|
||||
{
|
||||
int c = 256, bc;
|
||||
@@ -490,6 +512,11 @@ uint32_t common_get_raw_size(int drive, int side)
|
||||
return ((((uint32_t) size) >> 4) << 4) + d86f_handler[drive].extra_bit_cells(drive, side);
|
||||
}
|
||||
|
||||
void d86f_set_version(int drive, uint16_t version)
|
||||
{
|
||||
d86f[drive].version = version;
|
||||
}
|
||||
|
||||
void d86f_unregister(int drive)
|
||||
{
|
||||
d86f_handler[drive].disk_flags = null_disk_flags;
|
||||
@@ -1793,6 +1820,20 @@ void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_
|
||||
fdc_sector_finishread();
|
||||
}
|
||||
|
||||
void d86f_format_turbo_finish(int drive, int side, int do_write)
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
|
||||
if (do_write)
|
||||
{
|
||||
d86f_handler[drive].writeback(drive);
|
||||
}
|
||||
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].datac = 0;
|
||||
fdc_sector_finishread();
|
||||
}
|
||||
|
||||
void d86f_format_track(int drive, int side, int do_write)
|
||||
{
|
||||
int data;
|
||||
@@ -2001,6 +2042,267 @@ void d86f_format_track_nop(int drive, int side)
|
||||
d86f_format_track(drive, side, 0);
|
||||
}
|
||||
|
||||
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n)
|
||||
{
|
||||
d86f[drive].last_sector.id.c = c;
|
||||
d86f[drive].last_sector.id.h = h;
|
||||
d86f[drive].last_sector.id.r = r;
|
||||
d86f[drive].last_sector.id.n = n;
|
||||
}
|
||||
|
||||
void d86f_turbo_read(int drive, int side)
|
||||
{
|
||||
uint8_t dat = 0;
|
||||
|
||||
int recv_data = 0;
|
||||
int read_status = 0;
|
||||
|
||||
dat = d86f_handler[drive].read_data(drive, side, d86f[drive].turbo_pos);
|
||||
d86f[drive].turbo_pos++;
|
||||
|
||||
if (d86f[drive].state == STATE_11_SCAN_DATA)
|
||||
{
|
||||
/* Scan/compare command. */
|
||||
recv_data = d86f_get_data(drive, 0);
|
||||
d86f_compare_byte(drive, recv_data, dat);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (d86f[drive].data_find.bytes_obtained < (128 << d86f[drive].last_sector.id.n))
|
||||
{
|
||||
if (d86f[drive].state != STATE_16_VERIFY_DATA)
|
||||
{
|
||||
read_status = fdc_data(dat);
|
||||
if (read_status == -1)
|
||||
{
|
||||
d86f[drive].dma_over++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (d86f[drive].dma_over > 1)
|
||||
{
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_finishread();
|
||||
fdc_overrun();
|
||||
return;
|
||||
}
|
||||
|
||||
if (d86f[drive].turbo_pos >= (128 << d86f[drive].last_sector.id.n))
|
||||
{
|
||||
/* CRC is valid. */
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
if (d86f[drive].state == STATE_11_SCAN_DATA)
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishcompare((d86f[drive].satisfying_bytes == ((128 << ((uint32_t) d86f[drive].last_sector.id.n)) - 1)) ? 1 : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
fdc_sector_finishread();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_turbo_write(int drive, int side)
|
||||
{
|
||||
uint8_t dat = 0;
|
||||
|
||||
dat = d86f_get_data(drive, 1);
|
||||
d86f_handler[drive].write_data(drive, side, d86f[drive].turbo_pos, dat);
|
||||
|
||||
d86f[drive].turbo_pos++;
|
||||
|
||||
if (d86f[drive].turbo_pos >= (128 << d86f[drive].last_sector.id.n))
|
||||
{
|
||||
/* We've written the data. */
|
||||
d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0;
|
||||
d86f[drive].error_condition = 0;
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_handler[drive].writeback(drive);
|
||||
fdc_sector_finishread();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_turbo_format(int drive, int side, int nop)
|
||||
{
|
||||
int dat;
|
||||
int i = 0;
|
||||
|
||||
uint16_t sc = 0;
|
||||
uint16_t dtl = 0;
|
||||
|
||||
sc = fdc_get_format_sectors();
|
||||
dtl = 128 << fdc_get_format_n();
|
||||
|
||||
if (d86f[drive].datac <= 3)
|
||||
{
|
||||
dat = fdc_getdata(0);
|
||||
if (dat != -1)
|
||||
{
|
||||
dat &= 0xff;
|
||||
}
|
||||
if ((dat == -1) && (d86f[drive].datac < 3))
|
||||
{
|
||||
dat = 0;
|
||||
}
|
||||
d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = dat & 0xff;
|
||||
if (d86f[drive].datac == 3)
|
||||
{
|
||||
fdc_stop_id_request();
|
||||
d86f_handler[drive].set_sector(drive, side, d86f[drive].format_sector_id.id.c, d86f[drive].format_sector_id.id.h, d86f[drive].format_sector_id.id.r, d86f[drive].format_sector_id.id.n);
|
||||
}
|
||||
}
|
||||
else if (d86f[drive].datac == 4)
|
||||
{
|
||||
if (!nop)
|
||||
{
|
||||
for (i = 0; i < dtl; i++)
|
||||
{
|
||||
d86f_handler[drive].write_data(drive, side, i, d86f[drive].fill);
|
||||
}
|
||||
}
|
||||
|
||||
d86f[drive].sector_count++;
|
||||
}
|
||||
|
||||
d86f[drive].datac++;
|
||||
|
||||
if (d86f[drive].datac == 6)
|
||||
{
|
||||
d86f[drive].datac = 0;
|
||||
|
||||
if (d86f[drive].sector_count < sc)
|
||||
{
|
||||
/* Sector within allotted amount. */
|
||||
fdc_request_next_sector_id();
|
||||
}
|
||||
else
|
||||
{
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
d86f_format_turbo_finish(drive, side, nop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_turbo_poll(int drive, int side)
|
||||
{
|
||||
if ((d86f[drive].state != STATE_IDLE) && (d86f[drive].state != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state & 0xF8) != 0xE8))
|
||||
{
|
||||
if (!d86f_can_read_address(drive))
|
||||
{
|
||||
/* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) d86f_log("[%i, %i] Bitcell period mismatch (%i != %i)\n", drive, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive));
|
||||
if (!fdd_can_read_medium(real_drive(drive))) d86f_log("[%i, %i] Drive can not read medium (hole = %01X)\n", drive, side, d86f_hole(drive));
|
||||
if (fdc_is_mfm() != d86f_is_mfm(drive)) d86f_log("[%i, %i] Encoding mismatch\n", drive, side);
|
||||
if (d86f_get_encoding(drive) > 1) d86f_log("[%i, %i] Image encoding (%s) not FM or MFM\n", drive, side, (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */
|
||||
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_noidam();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(d86f[drive].state)
|
||||
{
|
||||
case STATE_0D_SPIN_TO_INDEX:
|
||||
case STATE_0D_NOP_SPIN_TO_INDEX:
|
||||
d86f[drive].sector_count = 0;
|
||||
d86f[drive].datac = 5;
|
||||
case STATE_02_SPIN_TO_INDEX:
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
case STATE_02_FIND_ID:
|
||||
if (!(d86f[drive].sector_id_bit_field[side][fdc_get_read_track_sector().id.c][fdc_get_read_track_sector().id.h][fdc_get_read_track_sector().id.r] & (1 << fdc_get_read_track_sector().id.n)))
|
||||
{
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_nosector();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
d86f[drive].last_sector.id.c = fdc_get_read_track_sector().id.c;
|
||||
d86f[drive].last_sector.id.h = fdc_get_read_track_sector().id.h;
|
||||
d86f[drive].last_sector.id.r = fdc_get_read_track_sector().id.r;
|
||||
d86f[drive].last_sector.id.n = fdc_get_read_track_sector().id.n;
|
||||
d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
|
||||
d86f[drive].turbo_pos = 0;
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
case STATE_05_FIND_ID:
|
||||
case STATE_09_FIND_ID:
|
||||
case STATE_06_FIND_ID:
|
||||
case STATE_0C_FIND_ID:
|
||||
case STATE_11_FIND_ID:
|
||||
case STATE_16_FIND_ID:
|
||||
if (!(d86f[drive].sector_id_bit_field[side][d86f[drive].req_sector.id.c][d86f[drive].req_sector.id.h][d86f[drive].req_sector.id.r] & (1 << d86f[drive].req_sector.id.n)))
|
||||
{
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_nosector();
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
return;
|
||||
}
|
||||
d86f[drive].last_sector.id.c = d86f[drive].req_sector.id.c;
|
||||
d86f[drive].last_sector.id.h = d86f[drive].req_sector.id.h;
|
||||
d86f[drive].last_sector.id.r = d86f[drive].req_sector.id.r;
|
||||
d86f[drive].last_sector.id.n = d86f[drive].req_sector.id.n;
|
||||
d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n);
|
||||
case STATE_0A_FIND_ID:
|
||||
d86f[drive].turbo_pos = 0;
|
||||
d86f[drive].state++;
|
||||
return;
|
||||
case STATE_0A_READ_ID:
|
||||
d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = d86f[drive].error_condition = 0;
|
||||
fdc_sectorid(d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n, 0, 0);
|
||||
d86f[drive].state = STATE_IDLE;
|
||||
break;
|
||||
case STATE_02_READ_ID:
|
||||
case STATE_05_READ_ID:
|
||||
case STATE_09_READ_ID:
|
||||
case STATE_06_READ_ID:
|
||||
case STATE_0C_READ_ID:
|
||||
case STATE_11_READ_ID:
|
||||
case STATE_16_READ_ID:
|
||||
d86f[drive].state++;
|
||||
break;
|
||||
case STATE_02_FIND_DATA:
|
||||
case STATE_06_FIND_DATA:
|
||||
case STATE_11_FIND_DATA:
|
||||
case STATE_16_FIND_DATA:
|
||||
case STATE_05_FIND_DATA:
|
||||
case STATE_09_FIND_DATA:
|
||||
case STATE_0C_FIND_DATA:
|
||||
d86f[drive].state++;
|
||||
break;
|
||||
case STATE_02_READ_DATA:
|
||||
case STATE_06_READ_DATA:
|
||||
case STATE_0C_READ_DATA:
|
||||
case STATE_11_SCAN_DATA:
|
||||
case STATE_16_VERIFY_DATA:
|
||||
d86f_turbo_read(drive, side);
|
||||
break;
|
||||
case STATE_05_WRITE_DATA:
|
||||
case STATE_09_WRITE_DATA:
|
||||
d86f_turbo_write(drive, side);
|
||||
break;
|
||||
case STATE_0D_FORMAT_TRACK:
|
||||
d86f_turbo_format(drive, side, 0);
|
||||
return;
|
||||
case STATE_0D_NOP_FORMAT_TRACK:
|
||||
d86f_turbo_format(drive, side, 1);
|
||||
return;
|
||||
case STATE_IDLE:
|
||||
case STATE_SECTOR_NOT_FOUND:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void d86f_poll(int drive)
|
||||
{
|
||||
int side = 0;
|
||||
@@ -2022,6 +2324,12 @@ void d86f_poll(int drive)
|
||||
}
|
||||
}
|
||||
|
||||
if (fdd_get_turbo(drive) && (d86f[drive].version == 0x0063))
|
||||
{
|
||||
d86f_turbo_poll(drive, side);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((d86f[drive].state != STATE_IDLE) && (d86f[drive].state != STATE_SECTOR_NOT_FOUND) && ((d86f[drive].state & 0xF8) != 0xE8))
|
||||
{
|
||||
if (!d86f_can_read_address(drive))
|
||||
@@ -2337,6 +2645,8 @@ uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf,
|
||||
uint16_t dataam_mfm = 0x4555;
|
||||
uint16_t datadam_mfm = 0x4A55;
|
||||
|
||||
d86f[drive].sector_id_bit_field[side][id_buf[0]][id_buf[1]][id_buf[2]] |= (1 << id_buf[3]);
|
||||
|
||||
mfm = d86f_is_mfm(drive);
|
||||
|
||||
gap_fill = mfm ? 0x4E : 0xFF;
|
||||
@@ -3080,6 +3390,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
{
|
||||
/* File is WAY too small, abort. */
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
memset(discfns[drive], 0, sizeof(discfns[drive]));
|
||||
return;
|
||||
}
|
||||
@@ -3089,6 +3400,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
/* File is not of the valid format, abort. */
|
||||
d86f_log("86F: Unrecognized magic bytes: %08X\n", magic);
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
memset(discfns[drive], 0, sizeof(discfns[drive]));
|
||||
return;
|
||||
}
|
||||
@@ -3111,6 +3423,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
d86f_log("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF);
|
||||
}
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
update_status_bar_icon_state(drive, 1);
|
||||
return;
|
||||
}
|
||||
@@ -3127,6 +3440,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
{
|
||||
/* File too small, abort. */
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
memset(discfns[drive], 0, sizeof(discfns[drive]));
|
||||
return;
|
||||
}
|
||||
@@ -3149,6 +3463,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
{
|
||||
d86f_log("86F: CRC64 error\n");
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
memset(discfns[drive], 0, sizeof(discfns[drive]));
|
||||
return;
|
||||
}
|
||||
@@ -3160,6 +3475,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
memcpy(d86f[drive].original_file_name, fn, (wcslen(fn) << 1) + 2);
|
||||
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
|
||||
d86f[drive].f = _wfopen(temp_file_name, L"wb");
|
||||
if (!d86f[drive].f)
|
||||
@@ -3190,6 +3506,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
|
||||
fclose(tf);
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
|
||||
if (!temp)
|
||||
{
|
||||
@@ -3207,6 +3524,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
/* Zoned disk. */
|
||||
d86f_log("86F: Disk is zoned (Apple or Sony)\n");
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
if (d86f[drive].is_compressed)
|
||||
{
|
||||
_wremove(temp_file_name);
|
||||
@@ -3220,6 +3538,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
/* Zone type is not 0 but the disk is fixed-RPM. */
|
||||
d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n");
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
if (d86f[drive].is_compressed)
|
||||
{
|
||||
_wremove(temp_file_name);
|
||||
@@ -3237,6 +3556,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
if (writeprot[drive])
|
||||
{
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
|
||||
if (d86f[drive].is_compressed)
|
||||
{
|
||||
@@ -3257,6 +3577,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
/* File has no track 0 side 0, abort. */
|
||||
d86f_log("86F: No Track 0 side 0\n");
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
memset(discfns[drive], 0, sizeof(discfns[drive]));
|
||||
return;
|
||||
}
|
||||
@@ -3266,6 +3587,7 @@ void d86f_load(int drive, wchar_t *fn)
|
||||
/* File is 2-sided but has no track 0 side 1, abort. */
|
||||
d86f_log("86F: No Track 0 side 1\n");
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
memset(discfns[drive], 0, sizeof(discfns[drive]));
|
||||
return;
|
||||
}
|
||||
@@ -3347,7 +3669,10 @@ void d86f_close(int drive)
|
||||
memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 26);
|
||||
|
||||
if (d86f[drive].f)
|
||||
{
|
||||
fclose(d86f[drive].f);
|
||||
d86f[drive].f = NULL;
|
||||
}
|
||||
if (d86f[drive].is_compressed)
|
||||
_wremove(temp_file_name);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ void d86f_readaddress(int drive, int side, int density);
|
||||
void d86f_format(int drive, int side, int density, uint8_t fill);
|
||||
|
||||
void d86f_prepare_track_layout(int drive, int side);
|
||||
void d86f_set_version(int drive, uint16_t version);
|
||||
|
||||
#define length_gap0 80
|
||||
#define length_gap1 50
|
||||
@@ -59,3 +60,8 @@ extern int gap2_size[2];
|
||||
extern int gap3_size[2];
|
||||
extern int gap4_size[2];
|
||||
#endif
|
||||
|
||||
#define D86FVER 0x020B
|
||||
|
||||
void d86f_initialize_last_sector_id(int drive, int c, int h, int r, int n);
|
||||
void d86f_zero_bit_field(int drive, int side);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user