Changes to logging - nothing (other than some parts of pc.c) uses the global pclog anymore (and logs will be almost empty (until the base set logging flags is agreed upon);

Fixes to various hard disk controllers;
Added the Packard Bell PB640;
Fixed the InPort mouse emulation - now it works correctly on Windows NT 3.1;
Removed the status window and the associated variables;
Completely removed the Green B 486 machine;
Fixed the MDSI Genius;
Fixed the single-sided 5.25" floppy drive;
Ported a CPU-related commit from VARCem.
This commit is contained in:
OBattler
2018-05-21 19:04:05 +02:00
parent 534ed6ea32
commit 5d8deea63b
130 changed files with 5062 additions and 3262 deletions

View File

@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
@@ -7,6 +8,7 @@
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -68,122 +70,6 @@ uint32_t *eal_r, *eal_w;
uint16_t *mod1add[2][8];
uint32_t *mod1seg[8];
#if 0
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (cpu_rm == 4)
{
uint8_t sib = rmdat >> 8;
switch (cpu_mod)
{
case 0:
cpu_state.eaaddr = cpu_state.regs[sib & 7].l;
cpu_state.pc++;
break;
case 1:
cpu_state.pc++;
cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
/* pc++; */
break;
case 2:
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
cpu_state.pc += 5;
break;
}
/*SIB byte present*/
if ((sib & 7) == 5 && !cpu_mod)
cpu_state.eaaddr = getlong();
else if ((sib & 6) == 4 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
if (((sib >> 3) & 7) != 4)
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
}
else
{
cpu_state.eaaddr = cpu_state.regs[cpu_rm].l;
if (cpu_mod)
{
if (cpu_rm == 5 && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
if (cpu_mod == 1)
{
cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8));
cpu_state.pc++;
}
else
{
cpu_state.eaaddr += getlong();
}
}
else if (cpu_rm == 5)
{
cpu_state.eaaddr = getlong();
}
}
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;
if ( readlookup2[addr >> 12] != -1)
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
}
}
static __inline void fetch_ea_16_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
ea_rseg = cpu_state.ea_seg->seg;
if (!cpu_mod && cpu_rm == 6)
{
cpu_state.eaaddr = getword();
}
else
{
switch (cpu_mod)
{
case 0:
cpu_state.eaaddr = 0;
break;
case 1:
cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++;
break;
case 2:
cpu_state.eaaddr = getword();
break;
}
cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]);
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
{
easeg = ss;
ea_rseg = SS;
cpu_state.ea_seg = &_ss;
}
cpu_state.eaaddr &= 0xFFFF;
}
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
{
uint32_t addr = easeg + cpu_state.eaaddr;
if ( readlookup2[addr >> 12] != -1)
eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr);
if (writelookup2[addr >> 12] != -1)
eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr);
}
}
#endif
#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 0; }
#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 0
@@ -222,6 +108,27 @@ extern int dontprint;
break; \
}
#ifdef ENABLE_386_LOG
int x386_do_log = ENABLE_386_LOG;
#endif
static void
x386_log(const char *fmt, ...)
{
#ifdef ENABLE_386_LOG
va_list ap;
if (x386_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
void exec386(int cycs)
{
uint8_t temp;
@@ -240,7 +147,6 @@ void exec386(int cycs)
cycdiff=0;
oldcyc=cycles;
timer_start_period(cycles << TIMER_SHIFT);
/* pclog("%i %02X\n", ins, ram[8]); */
while (cycdiff < cycle_period)
{
/* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX;
@@ -268,10 +174,6 @@ dontprint=0;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
if (output == 3)
{
pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X %02X%02X %02X\n",CS,cs,cpu_state.pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0xB270+0x3F5], ram[0xB270+0x3F4], ram[0xB270+0x3F7], ram[0xB270+0x3F6], ram[0xB270+0x3F9], ram[0xB270+0x3F8], ram[0x4430+0x0D49]);
}
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
if (x86_was_reset)
@@ -284,17 +186,6 @@ dontprint=0;
if (cpu_state.abrt)
{
flags_rebuild();
/* pclog("Abort\n"); */
/* if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,cpu_state.abrt); */
/* if (testr[0]!=EAX) pclog("EAX corrupted %08X\n",pc);
if (testr[1]!=EBX) pclog("EBX corrupted %08X\n",pc);
if (testr[2]!=ECX) pclog("ECX corrupted %08X\n",pc);
if (testr[3]!=EDX) pclog("EDX corrupted %08X\n",pc);
if (testr[4]!=ESI) pclog("ESI corrupted %08X\n",pc);
if (testr[5]!=EDI) pclog("EDI corrupted %08X\n",pc);
if (testr[6]!=EBP) pclog("EBP corrupted %08X\n",pc);
if (testr[7]!=ESP) pclog("ESP corrupted %08X\n",pc);*/
/* if (testr[8]!=flags) pclog("FLAGS corrupted %08X\n",pc);*/
tempi = cpu_state.abrt;
cpu_state.abrt = 0;
x86_doabrt(tempi);
@@ -303,14 +194,14 @@ dontprint=0;
cpu_state.abrt = 0;
CS = oldcs;
cpu_state.pc = cpu_state.oldpc;
pclog("Double fault %i\n", ins);
x386_log("Double fault %i\n", ins);
pmodeint(8, 0);
if (cpu_state.abrt)
{
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault - reset\n");
x386_log("Triple fault - reset\n");
}
}
}
@@ -342,7 +233,6 @@ dontprint=0;
{
cpu_state.oldpc = cpu_state.pc;
oldcs = CS;
/* pclog("NMI\n"); */
x86_int(2);
nmi_enable = 0;
if (nmi_auto_clear)
@@ -356,10 +246,6 @@ dontprint=0;
temp=picinterrupt();
if (temp!=0xFF)
{
/* if (temp == 0x54) pclog("Take int 54\n"); */
/* if (output) output=3; */
/* if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc); */
/* if (temp==0x54) output=3; */
flags_rebuild();
if (msw&1)
{
@@ -377,9 +263,7 @@ dontprint=0;
oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
/* if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc); */
}
/* pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); */
}
}

View File

@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
@@ -7,6 +8,7 @@
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -69,6 +71,27 @@ uint32_t *eal_r, *eal_w;
uint16_t *mod1add[2][8];
uint32_t *mod1seg[8];
#ifdef ENABLE_386_DYNAREC_LOG
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
#endif
static void
x386_dynarec_log(const char *fmt, ...)
{
#ifdef ENABLE_386_DYNAREC_LOG
va_list ap;
if (x386_dynarec_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
@@ -210,7 +233,7 @@ void x86_int(int num)
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault in real mode - reset\n");
x386_dynarec_log("Triple fault in real mode - reset\n");
}
else
x86_int(8);
@@ -303,9 +326,9 @@ int x86_int_sw_rm(int num)
if (cpu_state.abrt) return 1;
writememw(ss,((SP-2)&0xFFFF),flags); if (cpu_state.abrt) {pclog("abrt5\n"); return 1; }
writememw(ss,((SP-2)&0xFFFF),flags); if (cpu_state.abrt) {x386_dynarec_log("abrt5\n"); return 1; }
writememw(ss,((SP-4)&0xFFFF),CS);
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {pclog("abrt6\n"); return 1; }
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc); if (cpu_state.abrt) {x386_dynarec_log("abrt6\n"); return 1; }
SP-=6;
eflags &= ~VIF_FLAG;
@@ -428,13 +451,6 @@ int checkio(int port)
int xout=0;
#if 0
#define divexcp() { \
pclog("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \
x86_int(0); \
}
#endif
#define divexcp() { \
x86_int(0); \
}
@@ -842,14 +858,14 @@ inrecomp=0;
cpu_state.abrt = 0;
CS = oldcs;
cpu_state.pc = cpu_state.oldpc;
pclog("Double fault %i\n", ins);
x386_dynarec_log("Double fault %i\n", ins);
pmodeint(8, 0);
if (cpu_state.abrt)
{
cpu_state.abrt = 0;
softresetx86();
cpu_set_edx();
pclog("Triple fault - reset\n");
x386_dynarec_log("Triple fault - reset\n");
}
}
}
@@ -879,7 +895,6 @@ inrecomp=0;
{
cpu_state.oldpc = cpu_state.pc;
oldcs = CS;
pclog("NMI\n");
x86_int(2);
nmi_enable = 0;
if (nmi_auto_clear)
@@ -897,18 +912,10 @@ inrecomp=0;
flags_rebuild();
if (msw&1)
{
/* if (temp == 0x0E)
{
pclog("Servicing FDC interupt (p)!\n");
} */
pmodeint(temp,0);
}
else
{
/* if (temp == 0x0E)
{
pclog("Servicing FDC interupt (r)!\n");
} */
writememw(ss,(SP-2)&0xFFFF,flags);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -921,10 +928,6 @@ inrecomp=0;
loadcs(readmemw(0,addr+2));
}
}
/* else
{
pclog("Servicing pending interrupt 0xFF (!)!\n");
} */
}
}
timer_end_period(cycles << TIMER_SHIFT);

View File

@@ -1,23 +1,43 @@
/*
* 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.
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the 86Box distribution.
* This file is part of the VARCem Project.
*
* 286/386+ instruction handlers list.
*
* Version: @(#)386_ops.h 1.0.3 2018/04/25
* Version: @(#)386_ops.h 1.0.2 2018/05/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include "x86_ops.h"
@@ -147,20 +167,9 @@ static int ILLEGAL(uint32_t fetchdat)
return 0;
}
#if defined(DEV_BRANCH) && (defined(USE_AMD_K) || defined(USE_I686))
static int internal_illegal(char *s)
{
cpu_state.pc = cpu_state.oldpc;
x86gpf(s, 0);
return cpu_state.abrt;
}
#endif
#include "x86seg.h"
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#include "x86_ops_amd.h"
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
# include "x86_ops_amd.h"
#endif
#include "x86_ops_arith.h"
#include "x86_ops_atomic.h"
@@ -176,10 +185,8 @@ static int internal_illegal(char *s)
#include "x86_ops_jump.h"
#include "x86_ops_misc.h"
#include "x87_ops.h"
#ifdef DEV_BRANCH
#ifdef USE_I686
#include "x86_ops_i686.h"
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
# include "x86_ops_i686.h"
#endif
#include "x86_ops_mmx.h"
#include "x86_ops_mmx_arith.h"
@@ -204,6 +211,7 @@ static int internal_illegal(char *s)
#include "x86_ops_string.h"
#include "x86_ops_xchg.h"
static int op0F_w_a16(uint32_t fetchdat)
{
int opcode = fetchdat & 0xff;
@@ -245,7 +253,8 @@ static int op0F_l_a32(uint32_t fetchdat)
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
}
OpFn OP_TABLE(286_0f)[1024] =
const OpFn OP_TABLE(286_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -336,7 +345,7 @@ OpFn OP_TABLE(286_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(386_0f)[1024] =
const OpFn OP_TABLE(386_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -427,7 +436,7 @@ OpFn OP_TABLE(386_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(486_0f)[1024] =
const OpFn OP_TABLE(486_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -518,7 +527,7 @@ OpFn OP_TABLE(486_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(winchip_0f)[1024] =
const OpFn OP_TABLE(winchip_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -609,7 +618,7 @@ OpFn OP_TABLE(winchip_0f)[1024] =
/*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,
};
OpFn OP_TABLE(pentium_0f)[1024] =
const OpFn OP_TABLE(pentium_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -700,7 +709,7 @@ OpFn OP_TABLE(pentium_0f)[1024] =
/*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL,
};
OpFn OP_TABLE(pentiummmx_0f)[1024] =
const OpFn OP_TABLE(pentiummmx_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -791,9 +800,8 @@ OpFn OP_TABLE(pentiummmx_0f)[1024] =
/*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,
};
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
OpFn OP_TABLE(k6_0f)[1024] =
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
const OpFn OP_TABLE(k6_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -884,9 +892,8 @@ OpFn OP_TABLE(k6_0f)[1024] =
/*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,
};
#endif
#endif
OpFn OP_TABLE(c6x86mx_0f)[1024] =
const OpFn OP_TABLE(c6x86mx_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -979,7 +986,7 @@ OpFn OP_TABLE(c6x86mx_0f)[1024] =
#ifdef DEV_BRANCH
#ifdef USE_I686
OpFn OP_TABLE(pentiumpro_0f)[1024] =
const OpFn OP_TABLE(pentiumpro_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1071,7 +1078,7 @@ OpFn OP_TABLE(pentiumpro_0f)[1024] =
};
#if 0
OpFn OP_TABLE(pentium2_0f)[1024] =
const OpFn OP_TABLE(pentium2_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1163,7 +1170,7 @@ OpFn OP_TABLE(pentium2_0f)[1024] =
};
#endif
OpFn OP_TABLE(pentium2d_0f)[1024] =
const OpFn OP_TABLE(pentium2d_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1256,7 +1263,7 @@ OpFn OP_TABLE(pentium2d_0f)[1024] =
#endif
#endif
OpFn OP_TABLE(286)[1024] =
const OpFn OP_TABLE(286)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1347,7 +1354,7 @@ OpFn OP_TABLE(286)[1024] =
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
};
OpFn OP_TABLE(386)[1024] =
const OpFn OP_TABLE(386)[1024] =
{
/*16-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1438,7 +1445,7 @@ OpFn OP_TABLE(386)[1024] =
/*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] =
const 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*/
@@ -1529,7 +1536,7 @@ OpFn OP_TABLE(REPE)[1024] =
/*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
OpFn OP_TABLE(REPNE)[1024] =
const 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*/

View File

@@ -18,7 +18,7 @@
* 2 clocks - fetch opcode 1 2 clocks - execute
* 2 clocks - fetch opcode 2 etc
*
* Version: @(#)808x.c 1.0.4 2018/04/26
* Version: @(#)808x.c 1.0.5 2018/04/29
*
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
@@ -44,10 +44,12 @@
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -81,6 +83,27 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val);
uint32_t readmemll(uint32_t seg, uint32_t addr);
void writememll(uint32_t seg, uint32_t addr, uint32_t val);
#ifdef ENABLE_808X_LOG
int x808x_do_log = ENABLE_808X_LOG;
#endif
static void
x808x_log(const char *fmt, ...)
{
#ifdef ENABLE_808X_LOG
va_list ap;
if (x808x_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
#undef readmemb
#undef readmemw
uint8_t readmemb(uint32_t a)
@@ -106,7 +129,7 @@ uint16_t readmemw(uint32_t s, uint16_t a)
else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a);
}
void refreshread() { /*pclog("Refreshread\n"); */FETCHCOMPLETE(); memcycs+=4; }
void refreshread() { FETCHCOMPLETE(); memcycs+=4; }
#undef fetchea
#define fetchea() { rmdat=FETCH(); \
@@ -485,7 +508,7 @@ void makeznptable()
{
znptable8[c]=P_FLAG;
}
if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]);
if (c == 0xb1) x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]);
if (!c) znptable8[c]|=Z_FLAG;
if (c&0x80) znptable8[c]|=N_FLAG;
}
@@ -504,8 +527,8 @@ void makeznptable()
znptable16[c]=0;
else
znptable16[c]=P_FLAG;
if (c == 0xb1) pclog("znp16 b1 = %i %02X\n", d, znptable16[c]);
if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]);
if (c == 0xb1) x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]);
if (c == 0x65b1) x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]);
if (!c) znptable16[c]|=Z_FLAG;
if (c&0x8000) znptable16[c]|=N_FLAG;
}
@@ -538,11 +561,11 @@ void dumpregs(int force)
f=fopen("ram.dmp","wb");
fwrite(ram,mem_size*1024,1,f);
fclose(f);
pclog("Dumping rram.dmp\n");
x808x_log("Dumping rram.dmp\n");
f=fopen("rram.dmp","wb");
for (c=0;c<0x1000000;c++) putc(readmemb(c),f);
fclose(f);
pclog("Dumping rram4.dmp\n");
x808x_log("Dumping rram4.dmp\n");
f=fopen("rram4.dmp","wb");
for (c=0;c<0x0050000;c++)
{
@@ -550,44 +573,44 @@ void dumpregs(int force)
putc(readmemb386l(0,c+0x80000000),f);
}
fclose(f);
pclog("Dumping done\n");
x808x_log("Dumping done\n");
#endif
if (is386)
pclog("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP);
x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP);
else
pclog("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP);
pclog("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,flags);
pclog("%04X:%04X %04X:%04X\n",oldcs,cpu_state.oldpc, oldcs2, oldpc2);
pclog("%i ins\n",ins);
x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n",AX,BX,CX,DX,DI,SI,BP,SP);
x808x_log("PC=%04X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n",cpu_state.pc,CS,DS,ES,SS,flags);
x808x_log("%04X:%04X %04X:%04X\n",oldcs,cpu_state.oldpc, oldcs2, oldpc2);
x808x_log("%i ins\n",ins);
if (is386)
pclog("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
x808x_log("In %s mode\n",(msw&1)?((eflags&VM_FLAG)?"V86":"protected"):"real");
else
pclog("In %s mode\n",(msw&1)?"protected":"real");
pclog("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high);
pclog("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high);
pclog("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high);
x808x_log("In %s mode\n",(msw&1)?"protected":"real");
x808x_log("CS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",cs,_cs.limit,_cs.access, _cs.limit_low, _cs.limit_high);
x808x_log("DS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ds,_ds.limit,_ds.access, _ds.limit_low, _ds.limit_high);
x808x_log("ES : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",es,_es.limit,_es.access, _es.limit_low, _es.limit_high);
if (is386)
{
pclog("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",seg_fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high);
pclog("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high);
x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",seg_fs,_fs.limit,_fs.access, _fs.limit_low, _fs.limit_high);
x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",gs,_gs.limit,_gs.access, _gs.limit_low, _gs.limit_high);
}
pclog("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high);
pclog("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
pclog("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
pclog("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
pclog("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
x808x_log("SS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n",ss,_ss.limit,_ss.access, _ss.limit_low, _ss.limit_high);
x808x_log("GDT : base=%06X limit=%04X\n",gdt.base,gdt.limit);
x808x_log("LDT : base=%06X limit=%04X\n",ldt.base,ldt.limit);
x808x_log("IDT : base=%06X limit=%04X\n",idt.base,idt.limit);
x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit);
if (is386)
{
pclog("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
pclog("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4);
x808x_log("386 in %s mode stack in %s mode\n",(use32)?"32-bit":"16-bit",(stack32)?"32-bit":"16-bit");
x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n",cr0,cr2,cr3, cr4);
}
pclog("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
x808x_log("Entries in readlookup : %i writelookup : %i\n",readlnum,writelnum);
for (c=0;c<1024*1024;c++)
{
if (readlookup2[c]!=0xFFFFFFFF) d++;
if (writelookup2[c]!=0xFFFFFFFF) e++;
}
pclog("Entries in readlookup : %i writelookup : %i\n",d,e);
x808x_log("Entries in readlookup : %i writelookup : %i\n",d,e);
x87_dumpregs();
indump = 0;
}
@@ -596,7 +619,7 @@ int resets = 0;
int x86_was_reset = 0;
void resetx86()
{
pclog("x86 reset\n");
x808x_log("x86 reset\n");
resets++;
ins = 0;
use32=0;
@@ -1065,7 +1088,7 @@ void execx86(int cycs)
cpu_state.pc--;
if (output)
{
if (!skipnextprint) pclog("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i %p %02X\n",cs,cpu_state.pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ins, ram, ram[0x1a925]);
if (!skipnextprint) x808x_log("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i %p %02X\n",cs,cpu_state.pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ins, ram, ram[0x1a925]);
skipnextprint=0;
}
cpu_state.pc++;
@@ -2974,7 +2997,7 @@ void execx86(int cycs)
}
else
{
pclog("DIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("DIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -2998,7 +3021,7 @@ void execx86(int cycs)
}
else
{
pclog("IDIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("IDIVb BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -3070,7 +3093,7 @@ void execx86(int cycs)
}
else
{
pclog("DIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("DIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
@@ -3094,7 +3117,7 @@ void execx86(int cycs)
}
else
{
pclog("IDIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
x808x_log("IDIVw BY 0 %04X:%04X\n",cs>>4,cpu_state.pc);
writememw(ss,(SP-2)&0xFFFF,flags|0xF000);
writememw(ss,(SP-4)&0xFFFF,CS);
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);

View File

@@ -1,8 +1,10 @@
#ifdef __amd64__
#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "x86.h"
@@ -94,7 +96,6 @@ void codegen_init()
exit(-1);
}
#endif
// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block);
}
void codegen_reset()
@@ -111,20 +112,6 @@ void codegen_reset()
void dump_block()
{
/* codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n");
while (block)
{
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff);
uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff);
pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next);
if (!block->pc)
fatal("Dead PC=0\n");
block = block->next;
}
pclog("dump_block done\n");*/
}
static void add_to_block_list(codeblock_t *block)
@@ -204,7 +191,6 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
}
else
{
// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2);
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2;
if (block->next_2)
block->next_2->prev_2 = NULL;
@@ -270,11 +256,8 @@ void codegen_block_init(uint32_t phys_addr)
block_current = (block_current + 1) & BLOCK_MASK;
block = &codeblock[block_current];
// if (block->pc == 0xb00b4ff5)
// pclog("Init target block\n");
if (block->valid != 0)
{
// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc);
delete_block(block);
cpu_recomp_reuse++;
}
@@ -374,8 +357,6 @@ void codegen_block_start_recompile(codeblock_t *block)
addbyte(0xBD);
addquad(((uintptr_t)&cpu_state) + 128);
// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num);
last_op32 = -1;
last_ea_seg = NULL;
last_ssegs = -1;
@@ -434,14 +415,10 @@ void codegen_block_generate_end_mask()
end_pc = 0x3ff;
start_pc >>= PAGE_MASK_SHIFT;
end_pc >>= PAGE_MASK_SHIFT;
// pclog("block_end: %08x %08x\n", start_pc, end_pc);
for (; start_pc <= end_pc; start_pc++)
{
block->page_mask |= ((uint64_t)1 << start_pc);
// pclog(" %08x %llx\n", start_pc, block->page_mask);
}
pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask;
block->phys_2 = -1;
@@ -467,7 +444,6 @@ void codegen_block_generate_end_mask()
fatal("!page_mask2\n");
if (block->next_2)
{
// pclog(" next_2->pc=%08x\n", block->next_2->pc);
if (block->next_2->valid == 0)
fatal("block->next_2->valid=0 %p\n", (void *)block->next_2);
}
@@ -476,7 +452,6 @@ void codegen_block_generate_end_mask()
}
}
// pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask);
recomp_page = -1;
}
@@ -542,7 +517,6 @@ void codegen_block_end_recompile(codeblock_t *block)
block->next_2 = block->prev_2 = NULL;
codegen_block_generate_end_mask();
add_to_block_list(block);
// pclog("End block %i\n", block_num);
}
void codegen_flush()
@@ -597,10 +571,6 @@ int opcode_0f_modrm[256] =
void codegen_debug()
{
if (output)
{
pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, cs, cpu_state.pc, SS, ss, ESP, es,EAX, BX,ECX,BP, EDX,EDI);
}
}
static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
@@ -1122,17 +1092,6 @@ generate_call:
addlong(codegen_block_ins);
codegen_block_ins = 0;
}
#if 0
if (codegen_block_full_ins)
{
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)&cpu_recomp_full_ins);
addlong(codegen_block_full_ins);
codegen_block_full_ins = 0;
}
#endif
}
if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32])
@@ -1159,8 +1118,6 @@ generate_call:
}
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
// if (output)
// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]);
if (op_ssegs != last_ssegs)
{
last_ssegs = op_ssegs;
@@ -1169,7 +1126,6 @@ generate_call:
addbyte((uint8_t)cpu_state_offset(ssegs));
addbyte(op_ssegs);
}
//#if 0
if ((!test_modrm ||
(op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) ||
(op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/)
@@ -1195,10 +1151,8 @@ generate_call:
op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset);
op_pc -= pc_off;
}
//#endif
if (op_ea_seg != last_ea_seg)
{
// last_ea_seg = op_ea_seg;
addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/
addbyte(0x45);
addbyte((uint8_t)cpu_state_offset(ea_seg));
@@ -1235,8 +1189,6 @@ generate_call:
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4]));
// call(block, codegen_debug);
codegen_endpc = (cs + cpu_state.pc) + 8;
}

View File

@@ -1,3 +1,41 @@
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Dynamic Recompiler for Intel 32-bit systems.
*
* Version: @(#)codegen_x86.c 1.0.3 2018/05/05
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32
#include <stdio.h>
@@ -956,11 +994,6 @@ static uint32_t gen_MEM_CHECK_WRITE()
return addr;
}
/*static void checkdebug(uint32_t a)
{
pclog("checkdebug %08x\n", a);
}*/
static uint32_t gen_MEM_CHECK_WRITE_W()
{
uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos];
@@ -1200,10 +1233,17 @@ void codegen_init()
block_pos = (block_pos + 15) & ~15;
mem_check_write_l = (uint32_t)gen_MEM_CHECK_WRITE_L();
#ifndef _MSC_VER
asm(
"fstcw %0\n"
: "=m" (cpu_state.old_npxc)
);
#else
__asm
{
fstcw cpu_state.old_npxc
}
#endif
}
void codegen_reset()
@@ -1215,20 +1255,6 @@ void codegen_reset()
void dump_block()
{
/* codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n");
while (block)
{
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff);
uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff);
pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next);
if (!block->pc)
fatal("Dead PC=0\n");
block = block->next;
}
pclog("dump_block done\n");*/
}
static void add_to_block_list(codeblock_t *block)
@@ -1657,10 +1683,6 @@ int opcode_0f_modrm[256] =
void codegen_debug()
{
if (output)
{
pclog("At %04x(%08x):%04x %04x(%08x):%04x es=%08x EAX=%08x BX=%04x ECX=%08x BP=%04x EDX=%08x EDI=%08x\n", CS, cs, cpu_state.pc, SS, ss, ESP, es,EAX, BX,ECX,BP, EDX,EDI);
}
}
static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc)
@@ -1844,7 +1866,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
codeblock_t *block = &codeblock[block_current];
uint32_t op_32 = use32;
uint32_t op_pc = new_pc;
OpFn *op_table = x86_dynarec_opcodes;
const OpFn *op_table = x86_dynarec_opcodes;
RecompOpFn *recomp_op_table = recomp_opcodes;
int opcode_shift = 0;
int opcode_mask = 0x3ff;

View File

@@ -1,22 +1,42 @@
/*
* 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.
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the 86Box distribution.
* This file is part of the VARCem Project.
*
* CPU type handler.
*
* Version: @(#)cpu.c 1.0.15 2018/04/08
* Version: @(#)cpu.c 1.0.6 2018/05/05
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include <stdio.h>
#include <stdint.h>
@@ -31,58 +51,11 @@
#include "../mem.h"
#include "../pci.h"
#ifdef USE_DYNAREC
#include "codegen.h"
# include "codegen.h"
#endif
int isa_cycles;
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
#ifdef USE_DYNAREC
OpFn *x86_dynarec_opcodes;
OpFn *x86_dynarec_opcodes_0f;
OpFn *x86_dynarec_opcodes_d8_a16;
OpFn *x86_dynarec_opcodes_d8_a32;
OpFn *x86_dynarec_opcodes_d9_a16;
OpFn *x86_dynarec_opcodes_d9_a32;
OpFn *x86_dynarec_opcodes_da_a16;
OpFn *x86_dynarec_opcodes_da_a32;
OpFn *x86_dynarec_opcodes_db_a16;
OpFn *x86_dynarec_opcodes_db_a32;
OpFn *x86_dynarec_opcodes_dc_a16;
OpFn *x86_dynarec_opcodes_dc_a32;
OpFn *x86_dynarec_opcodes_dd_a16;
OpFn *x86_dynarec_opcodes_dd_a32;
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;
#endif
OpFn *x86_opcodes;
OpFn *x86_opcodes_0f;
OpFn *x86_opcodes_d8_a16;
OpFn *x86_opcodes_d8_a32;
OpFn *x86_opcodes_d9_a16;
OpFn *x86_opcodes_d9_a32;
OpFn *x86_opcodes_da_a16;
OpFn *x86_opcodes_da_a32;
OpFn *x86_opcodes_db_a16;
OpFn *x86_opcodes_db_a32;
OpFn *x86_opcodes_dc_a16;
OpFn *x86_opcodes_dc_a32;
OpFn *x86_opcodes_dd_a16;
OpFn *x86_opcodes_dd_a32;
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
{
enum {
CPUID_FPU = (1 << 0),
CPUID_VME = (1 << 1),
CPUID_PSE = (1 << 3),
@@ -96,93 +69,145 @@ enum
CPUID_FXSR = (1 << 24)
};
CPU *cpu_s;
int cpu_effective;
int cpu_multi;
int cpu_iscyrix;
int cpu_16bitbus;
int cpu_busspeed;
int cpu_hasrdtsc;
int cpu_hasMMX, cpu_hasMSR;
int cpu_hasCR4;
int cpu_hasVME;
int cpu_cyrix_alignment;
int hasfpu;
int cpuspeed;
uint64_t cpu_CR4_mask;
int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
int cpu_pci_speed;
int is286, is386, is486;
int israpidcad, is_pentium;
uint64_t tsc = 0;
cr0_t CR0;
uint64_t pmc[2] = {0, 0};
uint16_t temp_seg_data[4] = {0, 0, 0, 0};
#ifdef DEV_BRANCH
#ifdef USE_I686
uint16_t cs_msr = 0;
uint32_t esp_msr = 0;
uint32_t eip_msr = 0;
uint64_t apic_base_msr = 0;
uint64_t mtrr_cap_msr = 0;
uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_fix64k_8000_msr = 0;
uint64_t mtrr_fix16k_8000_msr = 0;
uint64_t mtrr_fix16k_a000_msr = 0;
uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t pat_msr = 0;
uint64_t mtrr_deftype_msr = 0;
uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t ecx17_msr = 0;
uint64_t ecx79_msr = 0;
uint64_t ecx8x_msr[4] = {0, 0, 0, 0};
uint64_t ecx116_msr = 0;
uint64_t ecx11x_msr[4] = {0, 0, 0, 0};
uint64_t ecx11e_msr = 0;
uint64_t ecx186_msr = 0;
uint64_t ecx187_msr = 0;
uint64_t ecx1e0_msr = 0;
uint64_t ecx570_msr = 0;
#endif
#ifdef USE_DYNAREC
const OpFn *x86_dynarec_opcodes;
const OpFn *x86_dynarec_opcodes_0f;
const OpFn *x86_dynarec_opcodes_d8_a16;
const OpFn *x86_dynarec_opcodes_d8_a32;
const OpFn *x86_dynarec_opcodes_d9_a16;
const OpFn *x86_dynarec_opcodes_d9_a32;
const OpFn *x86_dynarec_opcodes_da_a16;
const OpFn *x86_dynarec_opcodes_da_a32;
const OpFn *x86_dynarec_opcodes_db_a16;
const OpFn *x86_dynarec_opcodes_db_a32;
const OpFn *x86_dynarec_opcodes_dc_a16;
const OpFn *x86_dynarec_opcodes_dc_a32;
const OpFn *x86_dynarec_opcodes_dd_a16;
const OpFn *x86_dynarec_opcodes_dd_a32;
const OpFn *x86_dynarec_opcodes_de_a16;
const OpFn *x86_dynarec_opcodes_de_a32;
const OpFn *x86_dynarec_opcodes_df_a16;
const OpFn *x86_dynarec_opcodes_df_a32;
const OpFn *x86_dynarec_opcodes_REPE;
const OpFn *x86_dynarec_opcodes_REPNE;
#endif
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
/* AMD K5 and K6 MSR's. */
uint64_t ecx83_msr = 0;
/* These are K6-only. */
uint64_t star = 0;
uint64_t sfmask = 0;
#endif
const OpFn *x86_opcodes;
const OpFn *x86_opcodes_0f;
const OpFn *x86_opcodes_d8_a16;
const OpFn *x86_opcodes_d8_a32;
const OpFn *x86_opcodes_d9_a16;
const OpFn *x86_opcodes_d9_a32;
const OpFn *x86_opcodes_da_a16;
const OpFn *x86_opcodes_da_a32;
const OpFn *x86_opcodes_db_a16;
const OpFn *x86_opcodes_db_a32;
const OpFn *x86_opcodes_dc_a16;
const OpFn *x86_opcodes_dc_a32;
const OpFn *x86_opcodes_dd_a16;
const OpFn *x86_opcodes_dd_a32;
const OpFn *x86_opcodes_de_a16;
const OpFn *x86_opcodes_de_a32;
const OpFn *x86_opcodes_df_a16;
const OpFn *x86_opcodes_df_a32;
const OpFn *x86_opcodes_REPE;
const OpFn *x86_opcodes_REPNE;
CPU *cpu_s;
int cpu_effective;
int cpu_multi;
int cpu_16bitbus;
int cpu_busspeed;
int cpu_cyrix_alignment;
int cpuspeed;
int CPUID;
uint64_t cpu_CR4_mask;
int isa_cycles;
int cpu_cycles_read, cpu_cycles_read_l,
cpu_cycles_write, cpu_cycles_write_l;
int cpu_prefetch_cycles, cpu_prefetch_width,
cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
int cpu_waitstates;
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
int cpu_pci_speed;
int is286,
is386,
is486,
cpu_iscyrix,
israpidcad,
is_pentium;
int hasfpu,
cpu_hasrdtsc,
cpu_hasMMX,
cpu_hasMSR,
cpu_hasCR4,
cpu_hasVME;
uint64_t tsc = 0;
msr_t msr;
cr0_t CR0;
uint64_t pmc[2] = {0, 0};
uint16_t temp_seg_data[4] = {0, 0, 0, 0};
#if defined(DEV_BRANCH) && defined(USE_I686)
uint16_t cs_msr = 0;
uint32_t esp_msr = 0;
uint32_t eip_msr = 0;
uint64_t apic_base_msr = 0;
uint64_t mtrr_cap_msr = 0;
uint64_t mtrr_physbase_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_physmask_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t mtrr_fix64k_8000_msr = 0;
uint64_t mtrr_fix16k_8000_msr = 0;
uint64_t mtrr_fix16k_a000_msr = 0;
uint64_t mtrr_fix4k_msr[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t pat_msr = 0;
uint64_t mtrr_deftype_msr = 0;
uint64_t msr_ia32_pmc[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint64_t ecx17_msr = 0;
uint64_t ecx79_msr = 0;
uint64_t ecx8x_msr[4] = {0, 0, 0, 0};
uint64_t ecx116_msr = 0;
uint64_t ecx11x_msr[4] = {0, 0, 0, 0};
uint64_t ecx11e_msr = 0;
uint64_t ecx186_msr = 0;
uint64_t ecx187_msr = 0;
uint64_t ecx1e0_msr = 0;
uint64_t ecx570_msr = 0;
#endif
int timing_rr;
int timing_mr, timing_mrl;
int timing_rm, timing_rml;
int timing_mm, timing_mml;
int timing_bt, timing_bnt;
int timing_int, timing_int_rm, timing_int_v86, timing_int_pm, timing_int_pm_outer;
int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer;
int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner;
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;
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
uint64_t ecx83_msr = 0; /* AMD K5 and K6 MSR's. */
uint64_t star = 0; /* These are K6-only. */
uint64_t sfmask = 0;
#endif
msr_t msr;
int timing_rr;
int timing_mr, timing_mrl;
int timing_rm, timing_rml;
int timing_mm, timing_mml;
int timing_bt, timing_bnt;
int timing_int, timing_int_rm, timing_int_v86, timing_int_pm,
timing_int_pm_outer;
int timing_iret_rm, timing_iret_v86, timing_iret_pm,
timing_iret_pm_outer;
int timing_call_rm, timing_call_pm, timing_call_pm_gate,
timing_call_pm_gate_inner;
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;
void cpu_dynamic_switch(int new_cpu)
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
void
cpu_dynamic_switch(int new_cpu)
{
if (cpu_effective == new_cpu)
return;
@@ -194,16 +219,17 @@ void cpu_dynamic_switch(int new_cpu)
cpu = c;
}
void cpu_set_edx()
void
cpu_set_edx(void)
{
EDX = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].edx_reset;
}
void cpu_set()
void
cpu_set(void)
{
CPU *cpu_s;
if (!machines[machine].cpu[cpu_manufacturer].cpus)
{
/*CPU is invalid, set to default*/
@@ -250,7 +276,7 @@ void cpu_set()
cpu_rom_prefetch_cycles = cpu_mem_prefetch_cycles;
else
cpu_rom_prefetch_cycles = cpu_s->rspeed / 1000000;
if (cpu_s->pci_speed)
{
pci_nonburst_time = 4*cpu_s->rspeed / cpu_s->pci_speed;
@@ -261,16 +287,12 @@ void cpu_set()
pci_nonburst_time = 4;
pci_burst_time = 1;
}
pclog("PCI burst=%i nonburst=%i\n", pci_burst_time, pci_nonburst_time);
if (cpu_iscyrix)
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
else
io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
pclog("hasfpu - %i\n",hasfpu);
pclog("is486 - %i %i\n",is486,cpu_s->cpu_type);
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
#else
@@ -1091,8 +1113,7 @@ void cpu_set()
ccr4 = 0x80;
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
case CPU_5K86:
#ifdef USE_DYNAREC
@@ -1146,10 +1167,8 @@ void cpu_set()
#endif
break;
#endif
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
#if defined(DEV_BRANCH) && defined(USE_I686)
case CPU_PENTIUMPRO:
#ifdef USE_DYNAREC
x86_setopcodes(ops_386, ops_pentiumpro_0f, dynarec_ops_386, dynarec_ops_pentiumpro_0f);
@@ -1271,7 +1290,6 @@ void cpu_set()
codegen_timing_set(&codegen_timing_686);
#endif
break;
#endif
#endif
default:
@@ -1294,7 +1312,8 @@ cpu_current_pc(char *bufp)
}
void cpu_CPUID()
void
cpu_CPUID(void)
{
switch (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type)
{
@@ -1313,7 +1332,7 @@ void cpu_CPUID()
EDX = CPUID_FPU; /*FPU*/
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_iDX4:
@@ -1331,7 +1350,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_Am486SX:
@@ -1348,7 +1367,7 @@ void cpu_CPUID()
EBX = ECX = EDX = 0; /*No FPU*/
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_Am486DX:
@@ -1366,7 +1385,7 @@ void cpu_CPUID()
EDX = CPUID_FPU; /*FPU*/
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_WINCHIP:
@@ -1397,7 +1416,7 @@ void cpu_CPUID()
EDX |= CPUID_MMX;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_PENTIUM:
@@ -1415,11 +1434,10 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
if (!EAX)
{
@@ -1435,7 +1453,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_5K86:
@@ -1487,7 +1505,7 @@ void cpu_CPUID()
EDX = 0x10040120;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
case CPU_K6:
@@ -1549,9 +1567,8 @@ void cpu_CPUID()
EDX = 0x444D416E;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#endif
#endif
case CPU_PENTIUMMMX:
@@ -1569,7 +1586,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_VME | CPUID_PSE | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1588,7 +1605,7 @@ void cpu_CPUID()
EDX = CPUID_FPU;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1607,7 +1624,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_CMPXCHG8B;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1626,7 +1643,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
@@ -1646,7 +1663,7 @@ void cpu_CPUID()
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_CMOV | CPUID_MMX;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#ifdef DEV_BRANCH
@@ -1669,7 +1686,7 @@ void cpu_CPUID()
{
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
/* case CPU_PENTIUM2:
@@ -1693,7 +1710,7 @@ void cpu_CPUID()
EDX = 0x0C040843;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break; */
case CPU_PENTIUM2D:
@@ -1717,7 +1734,7 @@ void cpu_CPUID()
EDX = 0x0C040844;
}
else
EAX = EBX = ECX = EDX = 0;
EAX = EBX = ECX = EDX = 0;
break;
#endif
#endif
@@ -1759,8 +1776,7 @@ void cpu_RDMSR()
}
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
case CPU_5K86:
case CPU_K6:
@@ -1787,14 +1803,10 @@ void cpu_RDMSR()
EDX = sfmask >> 32;
break;
default:
#ifndef RELEASE_BUILD
pclog("Invalid MSR: %08X\n", ECX);
#endif
x86gpf(NULL, 0);
break;
}
break;
#endif
#endif
case CPU_PENTIUM:
@@ -1941,9 +1953,6 @@ void cpu_RDMSR()
break;
default:
i686_invalid_rdmsr:
#ifndef RELEASE_BUILD
pclog("Invalid MSR: %08X\n", ECX);
#endif
x86gpf(NULL, 0);
break;
}
@@ -1988,8 +1997,8 @@ void cpu_WRMSR()
break;
}
break;
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
case CPU_K5:
case CPU_5K86:
case CPU_K6:
@@ -2012,7 +2021,6 @@ void cpu_WRMSR()
break;
}
break;
#endif
#endif
case CPU_PENTIUM:
@@ -2124,9 +2132,6 @@ void cpu_WRMSR()
break;
default:
i686_invalid_wrmsr:
#ifndef RELEASE_BUILD
pclog("Invalid MSR: %08X\n", ECX);
#endif
x86gpf(NULL, 0);
break;
}
@@ -2202,8 +2207,11 @@ uint8_t cyrix_read(uint16_t addr, void *priv)
return 0xff;
}
void
#ifdef USE_DYNAREC
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f)
x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
const OpFn *dynarec_opcodes, const OpFn *dynarec_opcodes_0f)
{
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
@@ -2211,22 +2219,24 @@ void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn
x86_dynarec_opcodes_0f = dynarec_opcodes_0f;
}
#else
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f)
x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f)
{
x86_opcodes = opcodes;
x86_opcodes_0f = opcodes_0f;
}
#endif
void cpu_update_waitstates()
void
cpu_update_waitstates(void)
{
cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
if (is486)
cpu_prefetch_width = 16;
else
cpu_prefetch_width = cpu_16bitbus ? 2 : 4;
if (cpu_cache_int_enabled)
{
/* Disable prefetch emulation */

View File

@@ -1,6 +1,41 @@
/* Copyright holders: Sarah Walker, leilei
see COPYING for more details
*/
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Miscellaneous x86 CPU Instructions.
*
* Version: @(#)x86_ops.h 1.0.2 2018/05/05
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef _X86_OPS_H
#define _X86_OPS_H
@@ -11,194 +46,188 @@
typedef int (*OpFn)(uint32_t fetchdat);
#ifdef USE_DYNAREC
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f, OpFn *dynarec_opcodes, OpFn *dynarec_opcodes_0f);
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f,
const OpFn *dynarec_opcodes,
const OpFn *dynarec_opcodes_0f);
extern OpFn *x86_dynarec_opcodes;
extern OpFn *x86_dynarec_opcodes_0f;
extern OpFn *x86_dynarec_opcodes_d8_a16;
extern OpFn *x86_dynarec_opcodes_d8_a32;
extern OpFn *x86_dynarec_opcodes_d9_a16;
extern OpFn *x86_dynarec_opcodes_d9_a32;
extern OpFn *x86_dynarec_opcodes_da_a16;
extern OpFn *x86_dynarec_opcodes_da_a32;
extern OpFn *x86_dynarec_opcodes_db_a16;
extern OpFn *x86_dynarec_opcodes_db_a32;
extern OpFn *x86_dynarec_opcodes_dc_a16;
extern OpFn *x86_dynarec_opcodes_dc_a32;
extern OpFn *x86_dynarec_opcodes_dd_a16;
extern OpFn *x86_dynarec_opcodes_dd_a32;
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 const OpFn *x86_dynarec_opcodes;
extern const OpFn *x86_dynarec_opcodes_0f;
extern const OpFn *x86_dynarec_opcodes_d8_a16;
extern const OpFn *x86_dynarec_opcodes_d8_a32;
extern const OpFn *x86_dynarec_opcodes_d9_a16;
extern const OpFn *x86_dynarec_opcodes_d9_a32;
extern const OpFn *x86_dynarec_opcodes_da_a16;
extern const OpFn *x86_dynarec_opcodes_da_a32;
extern const OpFn *x86_dynarec_opcodes_db_a16;
extern const OpFn *x86_dynarec_opcodes_db_a32;
extern const OpFn *x86_dynarec_opcodes_dc_a16;
extern const OpFn *x86_dynarec_opcodes_dc_a32;
extern const OpFn *x86_dynarec_opcodes_dd_a16;
extern const OpFn *x86_dynarec_opcodes_dd_a32;
extern const OpFn *x86_dynarec_opcodes_de_a16;
extern const OpFn *x86_dynarec_opcodes_de_a32;
extern const OpFn *x86_dynarec_opcodes_df_a16;
extern const OpFn *x86_dynarec_opcodes_df_a32;
extern const OpFn *x86_dynarec_opcodes_REPE;
extern const OpFn *x86_dynarec_opcodes_REPNE;
extern OpFn dynarec_ops_286[1024];
extern OpFn dynarec_ops_286_0f[1024];
extern const OpFn dynarec_ops_286[1024];
extern const OpFn dynarec_ops_286_0f[1024];
extern OpFn dynarec_ops_386[1024];
extern OpFn dynarec_ops_386_0f[1024];
extern const OpFn dynarec_ops_386[1024];
extern const OpFn dynarec_ops_386_0f[1024];
extern OpFn dynarec_ops_486_0f[1024];
extern const OpFn dynarec_ops_486_0f[1024];
extern OpFn dynarec_ops_winchip_0f[1024];
extern const OpFn dynarec_ops_winchip_0f[1024];
extern OpFn dynarec_ops_pentium_0f[1024];
extern OpFn dynarec_ops_pentiummmx_0f[1024];
extern OpFn dynarec_ops_c6x86mx_0f[1024];
extern const OpFn dynarec_ops_pentium_0f[1024];
extern const OpFn dynarec_ops_pentiummmx_0f[1024];
extern const OpFn dynarec_ops_c6x86mx_0f[1024];
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
extern OpFn dynarec_ops_k6_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
extern const OpFn dynarec_ops_k6_0f[1024];
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
extern OpFn dynarec_ops_pentiumpro_0f[1024];
extern OpFn dynarec_ops_pentium2d_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
extern const OpFn dynarec_ops_pentiumpro_0f[1024];
extern const OpFn dynarec_ops_pentium2d_0f[1024];
#endif
extern OpFn dynarec_ops_fpu_287_d9_a16[256];
extern OpFn dynarec_ops_fpu_287_d9_a32[256];
extern OpFn dynarec_ops_fpu_287_da_a16[256];
extern OpFn dynarec_ops_fpu_287_da_a32[256];
extern OpFn dynarec_ops_fpu_287_db_a16[256];
extern OpFn dynarec_ops_fpu_287_db_a32[256];
extern OpFn dynarec_ops_fpu_287_dc_a16[32];
extern OpFn dynarec_ops_fpu_287_dc_a32[32];
extern OpFn dynarec_ops_fpu_287_dd_a16[256];
extern OpFn dynarec_ops_fpu_287_dd_a32[256];
extern OpFn dynarec_ops_fpu_287_de_a16[256];
extern OpFn dynarec_ops_fpu_287_de_a32[256];
extern OpFn dynarec_ops_fpu_287_df_a16[256];
extern OpFn dynarec_ops_fpu_287_df_a32[256];
extern const OpFn dynarec_ops_fpu_287_d9_a16[256];
extern const OpFn dynarec_ops_fpu_287_d9_a32[256];
extern const OpFn dynarec_ops_fpu_287_da_a16[256];
extern const OpFn dynarec_ops_fpu_287_da_a32[256];
extern const OpFn dynarec_ops_fpu_287_db_a16[256];
extern const OpFn dynarec_ops_fpu_287_db_a32[256];
extern const OpFn dynarec_ops_fpu_287_dc_a16[32];
extern const OpFn dynarec_ops_fpu_287_dc_a32[32];
extern const OpFn dynarec_ops_fpu_287_dd_a16[256];
extern const OpFn dynarec_ops_fpu_287_dd_a32[256];
extern const OpFn dynarec_ops_fpu_287_de_a16[256];
extern const OpFn dynarec_ops_fpu_287_de_a32[256];
extern const OpFn dynarec_ops_fpu_287_df_a16[256];
extern const OpFn dynarec_ops_fpu_287_df_a32[256];
extern OpFn dynarec_ops_fpu_d8_a16[32];
extern OpFn dynarec_ops_fpu_d8_a32[32];
extern OpFn dynarec_ops_fpu_d9_a16[256];
extern OpFn dynarec_ops_fpu_d9_a32[256];
extern OpFn dynarec_ops_fpu_da_a16[256];
extern OpFn dynarec_ops_fpu_da_a32[256];
extern OpFn dynarec_ops_fpu_db_a16[256];
extern OpFn dynarec_ops_fpu_db_a32[256];
extern OpFn dynarec_ops_fpu_dc_a16[32];
extern OpFn dynarec_ops_fpu_dc_a32[32];
extern OpFn dynarec_ops_fpu_dd_a16[256];
extern OpFn dynarec_ops_fpu_dd_a32[256];
extern OpFn dynarec_ops_fpu_de_a16[256];
extern OpFn dynarec_ops_fpu_de_a32[256];
extern OpFn dynarec_ops_fpu_df_a16[256];
extern OpFn dynarec_ops_fpu_df_a32[256];
extern OpFn dynarec_ops_nofpu_a16[256];
extern OpFn dynarec_ops_nofpu_a32[256];
extern const OpFn dynarec_ops_fpu_d8_a16[32];
extern const OpFn dynarec_ops_fpu_d8_a32[32];
extern const OpFn dynarec_ops_fpu_d9_a16[256];
extern const OpFn dynarec_ops_fpu_d9_a32[256];
extern const OpFn dynarec_ops_fpu_da_a16[256];
extern const OpFn dynarec_ops_fpu_da_a32[256];
extern const OpFn dynarec_ops_fpu_db_a16[256];
extern const OpFn dynarec_ops_fpu_db_a32[256];
extern const OpFn dynarec_ops_fpu_dc_a16[32];
extern const OpFn dynarec_ops_fpu_dc_a32[32];
extern const OpFn dynarec_ops_fpu_dd_a16[256];
extern const OpFn dynarec_ops_fpu_dd_a32[256];
extern const OpFn dynarec_ops_fpu_de_a16[256];
extern const OpFn dynarec_ops_fpu_de_a32[256];
extern const OpFn dynarec_ops_fpu_df_a16[256];
extern const OpFn dynarec_ops_fpu_df_a32[256];
extern const OpFn dynarec_ops_nofpu_a16[256];
extern const OpFn dynarec_ops_nofpu_a32[256];
extern OpFn dynarec_ops_fpu_686_da_a16[256];
extern OpFn dynarec_ops_fpu_686_da_a32[256];
extern OpFn dynarec_ops_fpu_686_db_a16[256];
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 const OpFn dynarec_ops_fpu_686_da_a16[256];
extern const OpFn dynarec_ops_fpu_686_da_a32[256];
extern const OpFn dynarec_ops_fpu_686_db_a16[256];
extern const OpFn dynarec_ops_fpu_686_db_a32[256];
extern const OpFn dynarec_ops_fpu_686_df_a16[256];
extern const OpFn dynarec_ops_fpu_686_df_a32[256];
extern OpFn dynarec_ops_REPE[1024];
extern OpFn dynarec_ops_REPNE[1024];
extern const OpFn dynarec_ops_REPE[1024];
extern const OpFn dynarec_ops_REPNE[1024];
#else
void x86_setopcodes(OpFn *opcodes, OpFn *opcodes_0f);
void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f);
#endif
extern OpFn *x86_opcodes;
extern OpFn *x86_opcodes_0f;
extern OpFn *x86_opcodes_d8_a16;
extern OpFn *x86_opcodes_d8_a32;
extern OpFn *x86_opcodes_d9_a16;
extern OpFn *x86_opcodes_d9_a32;
extern OpFn *x86_opcodes_da_a16;
extern OpFn *x86_opcodes_da_a32;
extern OpFn *x86_opcodes_db_a16;
extern OpFn *x86_opcodes_db_a32;
extern OpFn *x86_opcodes_dc_a16;
extern OpFn *x86_opcodes_dc_a32;
extern OpFn *x86_opcodes_dd_a16;
extern OpFn *x86_opcodes_dd_a32;
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 const OpFn *x86_opcodes;
extern const OpFn *x86_opcodes_0f;
extern const OpFn *x86_opcodes_d8_a16;
extern const OpFn *x86_opcodes_d8_a32;
extern const OpFn *x86_opcodes_d9_a16;
extern const OpFn *x86_opcodes_d9_a32;
extern const OpFn *x86_opcodes_da_a16;
extern const OpFn *x86_opcodes_da_a32;
extern const OpFn *x86_opcodes_db_a16;
extern const OpFn *x86_opcodes_db_a32;
extern const OpFn *x86_opcodes_dc_a16;
extern const OpFn *x86_opcodes_dc_a32;
extern const OpFn *x86_opcodes_dd_a16;
extern const OpFn *x86_opcodes_dd_a32;
extern const OpFn *x86_opcodes_de_a16;
extern const OpFn *x86_opcodes_de_a32;
extern const OpFn *x86_opcodes_df_a16;
extern const OpFn *x86_opcodes_df_a32;
extern const OpFn *x86_opcodes_REPE;
extern const OpFn *x86_opcodes_REPNE;
extern OpFn ops_286[1024];
extern OpFn ops_286_0f[1024];
extern const OpFn ops_286[1024];
extern const OpFn ops_286_0f[1024];
extern OpFn ops_386[1024];
extern OpFn ops_386_0f[1024];
extern const OpFn ops_386[1024];
extern const OpFn ops_386_0f[1024];
extern OpFn ops_486_0f[1024];
extern const OpFn ops_486_0f[1024];
extern OpFn ops_winchip_0f[1024];
extern const OpFn ops_winchip_0f[1024];
extern OpFn ops_pentium_0f[1024];
extern OpFn ops_pentiummmx_0f[1024];
extern const OpFn ops_pentium_0f[1024];
extern const OpFn ops_pentiummmx_0f[1024];
extern OpFn ops_c6x86mx_0f[1024];
extern const OpFn ops_c6x86mx_0f[1024];
#ifdef DEV_BRANCH
#ifdef USE_AMD_K
extern OpFn ops_k6_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
extern const OpFn ops_k6_0f[1024];
#endif
#ifdef DEV_BRANCH
#ifdef USE_I686
extern OpFn ops_pentiumpro_0f[1024];
extern OpFn ops_pentium2d_0f[1024];
#endif
#if defined(DEV_BRANCH) && defined(USE_I686)
extern const OpFn ops_pentiumpro_0f[1024];
extern const OpFn ops_pentium2d_0f[1024];
#endif
extern OpFn ops_fpu_287_d9_a16[256];
extern OpFn ops_fpu_287_d9_a32[256];
extern OpFn ops_fpu_287_da_a16[256];
extern OpFn ops_fpu_287_da_a32[256];
extern OpFn ops_fpu_287_db_a16[256];
extern OpFn ops_fpu_287_db_a32[256];
extern OpFn ops_fpu_287_dc_a16[32];
extern OpFn ops_fpu_287_dc_a32[32];
extern OpFn ops_fpu_287_dd_a16[256];
extern OpFn ops_fpu_287_dd_a32[256];
extern OpFn ops_fpu_287_de_a16[256];
extern OpFn ops_fpu_287_de_a32[256];
extern OpFn ops_fpu_287_df_a16[256];
extern OpFn ops_fpu_287_df_a32[256];
extern const OpFn ops_fpu_287_d9_a16[256];
extern const OpFn ops_fpu_287_d9_a32[256];
extern const OpFn ops_fpu_287_da_a16[256];
extern const OpFn ops_fpu_287_da_a32[256];
extern const OpFn ops_fpu_287_db_a16[256];
extern const OpFn ops_fpu_287_db_a32[256];
extern const OpFn ops_fpu_287_dc_a16[32];
extern const OpFn ops_fpu_287_dc_a32[32];
extern const OpFn ops_fpu_287_dd_a16[256];
extern const OpFn ops_fpu_287_dd_a32[256];
extern const OpFn ops_fpu_287_de_a16[256];
extern const OpFn ops_fpu_287_de_a32[256];
extern const OpFn ops_fpu_287_df_a16[256];
extern const OpFn ops_fpu_287_df_a32[256];
extern OpFn ops_fpu_d8_a16[32];
extern OpFn ops_fpu_d8_a32[32];
extern OpFn ops_fpu_d9_a16[256];
extern OpFn ops_fpu_d9_a32[256];
extern OpFn ops_fpu_da_a16[256];
extern OpFn ops_fpu_da_a32[256];
extern OpFn ops_fpu_db_a16[256];
extern OpFn ops_fpu_db_a32[256];
extern OpFn ops_fpu_dc_a16[32];
extern OpFn ops_fpu_dc_a32[32];
extern OpFn ops_fpu_dd_a16[256];
extern OpFn ops_fpu_dd_a32[256];
extern OpFn ops_fpu_de_a16[256];
extern OpFn ops_fpu_de_a32[256];
extern OpFn ops_fpu_df_a16[256];
extern OpFn ops_fpu_df_a32[256];
extern OpFn ops_nofpu_a16[256];
extern OpFn ops_nofpu_a32[256];
extern const OpFn ops_fpu_d8_a16[32];
extern const OpFn ops_fpu_d8_a32[32];
extern const OpFn ops_fpu_d9_a16[256];
extern const OpFn ops_fpu_d9_a32[256];
extern const OpFn ops_fpu_da_a16[256];
extern const OpFn ops_fpu_da_a32[256];
extern const OpFn ops_fpu_db_a16[256];
extern const OpFn ops_fpu_db_a32[256];
extern const OpFn ops_fpu_dc_a16[32];
extern const OpFn ops_fpu_dc_a32[32];
extern const OpFn ops_fpu_dd_a16[256];
extern const OpFn ops_fpu_dd_a32[256];
extern const OpFn ops_fpu_de_a16[256];
extern const OpFn ops_fpu_de_a32[256];
extern const OpFn ops_fpu_df_a16[256];
extern const OpFn ops_fpu_df_a32[256];
extern const OpFn ops_nofpu_a16[256];
extern const OpFn ops_nofpu_a32[256];
extern OpFn ops_fpu_686_da_a16[256];
extern OpFn ops_fpu_686_da_a32[256];
extern OpFn ops_fpu_686_db_a16[256];
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 const OpFn ops_fpu_686_da_a16[256];
extern const OpFn ops_fpu_686_da_a32[256];
extern const OpFn ops_fpu_686_db_a16[256];
extern const OpFn ops_fpu_686_db_a32[256];
extern const OpFn ops_fpu_686_df_a16[256];
extern const OpFn ops_fpu_686_df_a32[256];
extern OpFn ops_REPE[1024];
extern OpFn ops_REPNE[1024];
extern const OpFn ops_REPE[1024];
extern const OpFn ops_REPNE[1024];
#endif /*_X86_OPS_H*/

View File

@@ -8,20 +8,22 @@
*
* x86 CPU segment emulation.
*
* Version: @(#)x86seg.c 1.0.6 2017/11/24
* Version: @(#)x86seg.c 1.0.7 2018/04/29
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016,2017 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 Miran Grca.
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include "../86box.h"
#include "cpu.h"
#include "../device.h"
@@ -58,7 +60,27 @@ void pmodeint(int num, int soft);
/*NOT PRESENT is INT 0B
GPF is INT 0D*/
FILE *pclogf;
#ifdef ENABLE_X86SEG_LOG
int x86seg_do_log = ENABLE_X86SEG_LOG;
#endif
static void
x86seg_log(const char *fmt, ...)
{
#ifdef ENABLE_X86SEG_LOG
va_list ap;
if (x86seg_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
#endif
}
void x86abort(const char *format, ...)
{
va_list ap;
@@ -378,8 +400,8 @@ void loadseg(uint16_t seg, x86seg *s)
}
else if (s!=&_cs)
{
if (output) pclog("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]);
if (output) pclog("Seg type %03X\n",segdat[2]&0x1F00);
x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]);
x86seg_log("Seg type %03X\n",segdat[2]&0x1F00);
switch ((segdat[2]>>8)&0x1F)
{
case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/
@@ -467,7 +489,7 @@ void loadcs(uint16_t seg)
{
uint16_t segdat[4];
uint32_t addr;
if (output) pclog("Load CS %04X\n",seg);
x86seg_log("Load CS %04X\n",seg);
if (msw&1 && !(eflags&VM_FLAG))
{
if (!(seg&~3))
@@ -601,7 +623,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
segdat[1]=readmemw(0,addr+2);
segdat[2]=readmemw(0,addr+4);
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
if (output) pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]);
x86seg_log("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]);
if (segdat[2]&0x1000) /*Normal code segment*/
{
if (!(segdat[2]&0x400)) /*Not conforming*/
@@ -864,7 +886,7 @@ void loadcscall(uint16_t seg)
if (msw&1 && !(eflags&VM_FLAG))
{
if (csout) pclog("Protected mode CS load! %04X\n",seg);
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
if (!(seg&~3))
{
x86gpf(NULL,0);
@@ -898,7 +920,7 @@ void loadcscall(uint16_t seg)
newpc=segdat[0];
if (type&0x800) newpc|=segdat[3]<<16;
if (csout) pclog("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
if (csout) x86seg_log("Code seg call - %04X - %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2]);
if (segdat[2]&0x1000)
{
if (!(segdat[2]&0x400)) /*Not conforming*/
@@ -943,18 +965,18 @@ void loadcscall(uint16_t seg)
CS=seg;
do_seg_load(&_cs, segdat);
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
if (csout) pclog("Complete\n");
if (csout) x86seg_log("Complete\n");
cycles -= timing_call_pm;
}
else
{
type=segdat[2]&0xF00;
if (csout) pclog("Type %03X\n",type);
if (csout) x86seg_log("Type %03X\n",type);
switch (type)
{
case 0x400: /*Call gate*/
case 0xC00: /*386 Call gate*/
if (output) pclog("Callgate %08X\n", cpu_state.pc);
x86seg_log("Callgate %08X\n", cpu_state.pc);
cgate32=(type&0x800);
cgate16=!cgate32;
oldcs=CS;
@@ -971,13 +993,13 @@ void loadcscall(uint16_t seg)
}
if (!(segdat[2]&0x8000))
{
if (output) pclog("Call gate not present %04X\n",seg);
x86seg_log("Call gate not present %04X\n",seg);
x86np("Call gate not present\n", seg & 0xfffc);
return;
}
seg2=segdat[1];
if (output) pclog("New address : %04X:%08X\n", seg2, newpc);
x86seg_log("New address : %04X:%08X\n", seg2, newpc);
if (!(seg2&~3))
{
@@ -1009,7 +1031,7 @@ void loadcscall(uint16_t seg)
segdat[2]=readmemw(0,addr+4);
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
if (output) pclog("Code seg2 call - %04X - %04X %04X %04X\n",seg2,segdat[0],segdat[1],segdat[2]);
x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n",seg2,segdat[0],segdat[1],segdat[2]);
if (DPL > CPL)
{
@@ -1018,7 +1040,7 @@ void loadcscall(uint16_t seg)
}
if (!(segdat[2]&0x8000))
{
if (output) pclog("Call gate CS not present %04X\n",seg2);
x86seg_log("Call gate CS not present %04X\n",seg2);
x86np("Call gate CS not present", seg2 & 0xfffc);
return;
}
@@ -1048,7 +1070,7 @@ void loadcscall(uint16_t seg)
}
cpl_override=0;
if (cpu_state.abrt) return;
if (output) pclog("New stack %04X:%08X\n",newss,newsp);
x86seg_log("New stack %04X:%08X\n",newss,newsp);
if (!(newss&~3))
{
x86ts(NULL,newss&~3);
@@ -1076,12 +1098,12 @@ void loadcscall(uint16_t seg)
addr+=gdt.base;
}
cpl_override=1;
if (output) pclog("Read stack seg\n");
x86seg_log("Read stack seg\n");
segdat2[0]=readmemw(0,addr);
segdat2[1]=readmemw(0,addr+2);
segdat2[2]=readmemw(0,addr+4);
segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
if (output) pclog("Read stack seg done!\n");
x86seg_log("Read stack seg done!\n");
if (((newss & 3) != DPL) || (DPL2 != DPL))
{
x86ts(NULL,newss&~3);
@@ -1105,7 +1127,7 @@ void loadcscall(uint16_t seg)
do_seg_load(&_ss, segdat2);
if (output) pclog("Set access 1\n");
x86seg_log("Set access 1\n");
#ifdef SEL_ACCESSED
cpl_override = 1;
@@ -1119,7 +1141,7 @@ void loadcscall(uint16_t seg)
set_use32(segdat[3]&0x40);
cpu_state.pc=newpc;
if (output) pclog("Set access 2\n");
x86seg_log("Set access 2\n");
#ifdef CS_ACCESSED
cpl_override = 1;
@@ -1127,7 +1149,7 @@ void loadcscall(uint16_t seg)
cpl_override = 0;
#endif
if (output) pclog("Type %04X\n",type);
x86seg_log("Type %04X\n",type);
if (type==0xC00)
{
PUSHL(oldss);
@@ -1155,9 +1177,9 @@ void loadcscall(uint16_t seg)
}
else
{
if (output) pclog("Stack %04X\n",SP);
x86seg_log("Stack %04X\n",SP);
PUSHW(oldss);
if (output) pclog("Write SS to %04X:%04X\n",SS,SP);
x86seg_log("Write SS to %04X:%04X\n",SS,SP);
PUSHW(oldsp2);
if (cpu_state.abrt)
{
@@ -1165,14 +1187,14 @@ void loadcscall(uint16_t seg)
ESP = oldsp2;
return;
}
if (output) pclog("Write SP to %04X:%04X\n",SS,SP);
x86seg_log("Write SP to %04X:%04X\n",SS,SP);
if (count)
{
while (count)
{
count--;
tempw=readmemw(oldssbase,(oldsp&0xFFFF)+(count*2));
if (output) pclog("PUSH %04X\n",tempw);
x86seg_log("PUSH %04X\n",tempw);
PUSHW(tempw);
if (cpu_state.abrt)
{
@@ -1246,7 +1268,7 @@ void pmoderetf(int is32, uint16_t off)
uint32_t addr, oaddr;
uint16_t segdat[4],segdat2[4],seg,newss;
uint32_t oldsp=ESP;
if (output) pclog("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,eflags);
x86seg_log("RETF %i %04X:%04X %08X %04X\n",is32,CS,cpu_state.pc,cr0,eflags);
if (is32)
{
newpc=POPL();
@@ -1254,12 +1276,12 @@ void pmoderetf(int is32, uint16_t off)
}
else
{
if (output) pclog("PC read from %04X:%04X\n",SS,SP);
x86seg_log("PC read from %04X:%04X\n",SS,SP);
newpc=POPW();
if (output) pclog("CS read from %04X:%04X\n",SS,SP);
x86seg_log("CS read from %04X:%04X\n",SS,SP);
seg=POPW(); if (cpu_state.abrt) return;
}
if (output) pclog("Return to %04X:%08X\n",seg,newpc);
x86seg_log("Return to %04X:%08X\n",seg,newpc);
if ((seg&3)<CPL)
{
ESP=oldsp;
@@ -1297,14 +1319,14 @@ void pmoderetf(int is32, uint16_t off)
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; }
oaddr = addr;
if (output) pclog("CPL %i RPL %i %i\n",CPL,seg&3,is32);
x86seg_log("CPL %i RPL %i %i\n",CPL,seg&3,is32);
if (stack32) ESP+=off;
else SP+=off;
if (CPL==(seg&3))
{
if (output) pclog("RETF CPL = RPL %04X\n", segdat[2]);
x86seg_log("RETF CPL = RPL %04X\n", segdat[2]);
switch (segdat[2]&0x1F00)
{
case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/
@@ -1362,7 +1384,7 @@ void pmoderetf(int is32, uint16_t off)
x86gpf(NULL,seg&~3);
return;
}
if (output) pclog("RETF non-conforming, %i %i\n",seg&3, DPL);
x86seg_log("RETF non-conforming, %i %i\n",seg&3, DPL);
break;
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
if ((seg&3) < DPL)
@@ -1371,7 +1393,7 @@ void pmoderetf(int is32, uint16_t off)
x86gpf(NULL,seg&~3);
return;
}
if (output) pclog("RETF conforming, %i %i\n",seg&3, DPL);
x86seg_log("RETF conforming, %i %i\n",seg&3, DPL);
break;
default:
ESP=oldsp;
@@ -1391,12 +1413,12 @@ void pmoderetf(int is32, uint16_t off)
}
else
{
if (output) pclog("SP read from %04X:%04X\n",SS,SP);
x86seg_log("SP read from %04X:%04X\n",SS,SP);
newsp=POPW();
if (output) pclog("SS read from %04X:%04X\n",SS,SP);
x86seg_log("SS read from %04X:%04X\n",SS,SP);
newss=POPW(); if (cpu_state.abrt) return;
}
if (output) pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base);
x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base);
if (!(newss&~3))
{
ESP=oldsp;
@@ -1429,7 +1451,7 @@ void pmoderetf(int is32, uint16_t off)
segdat2[1]=readmemw(0,addr+2);
segdat2[2]=readmemw(0,addr+4);
segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; }
if (output) pclog("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]);
x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]);
if ((newss & 3) != (seg & 3))
{
ESP=oldsp;
@@ -1508,7 +1530,7 @@ void pmodeint(int num, int soft)
if (eflags&VM_FLAG && IOPL!=3 && soft)
{
if (output) pclog("V86 banned int\n");
x86seg_log("V86 banned int\n");
x86gpf(NULL,0);
return;
}
@@ -1529,7 +1551,7 @@ void pmodeint(int num, int soft)
{
x86gpf(NULL,(num*8)+2+((soft)?0:1));
}
if (output) pclog("addr >= IDT.limit\n");
x86seg_log("addr >= IDT.limit\n");
return;
}
addr+=idt.base;
@@ -1537,10 +1559,10 @@ void pmodeint(int num, int soft)
segdat[0]=readmemw(0,addr);
segdat[1]=readmemw(2,addr);
segdat[2]=readmemw(4,addr);
segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* pclog("Abrt reading from %08X\n",addr); */ return; }
segdat[3]=readmemw(6,addr); cpl_override=0; if (cpu_state.abrt) { /* x86seg_log("Abrt reading from %08X\n",addr); */ return; }
oaddr = addr;
if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
x86seg_log("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]);
if (!(segdat[2]&0x1F00))
{
x86gpf(NULL,(num*8)+2);
@@ -1683,7 +1705,7 @@ void pmodeint(int num, int soft)
cpl_override = 0;
#endif
if (output) pclog("New stack %04X:%08X\n",SS,ESP);
x86seg_log("New stack %04X:%08X\n",SS,ESP);
cpl_override=1;
if (type>=0x800)
{
@@ -1868,7 +1890,7 @@ void pmodeiret(int is32)
addr=seg&~7;
if (seg&4)
{
pclog("TS LDT %04X %04X IRET\n",seg,gdt.limit);
x86seg_log("TS LDT %04X %04X IRET\n",seg,gdt.limit);
x86ts(NULL,seg&~3);
return;
}
@@ -2032,7 +2054,7 @@ void pmodeiret(int is32)
else /*Return to outer level*/
{
oaddr = addr;
if (output) pclog("Outer level\n");
x86seg_log("Outer level\n");
if (is32)
{
newsp=POPL();
@@ -2044,7 +2066,7 @@ void pmodeiret(int is32)
newss=POPW(); if (cpu_state.abrt) { ESP = oldsp; return; }
}
if (output) pclog("IRET load stack %04X:%04X\n",newss,newsp);
x86seg_log("IRET load stack %04X:%04X\n",newss,newsp);
if (!(newss&~3))
{

View File

@@ -1,25 +1,48 @@
/*
* 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.
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the 86Box distribution.
* This file is part of the VARCem Project.
*
* x87 FPU instructions core.
*
* Version: @(#)x87_ops.h 1.0.2 2018/04/05
* Version: @(#)x87_ops.h 1.0.5 2018/05/05
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2016-2018 leilei.
* Copyright 2016-2018 Miran Grca.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#include <math.h>
#include <fenv.h>
#ifdef _MSC_VER
# include <intrin.h>
#endif
#define fplog 0
@@ -208,7 +231,7 @@ static __inline void x87_st80(double d)
test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final;
test.eind.ll = mant80final;
writememl(easeg,cpu_state.eaaddr,test.eind.ll);
writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff);
writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32);
writememw(easeg,cpu_state.eaaddr+8,test.begin);
}
@@ -260,14 +283,14 @@ static __inline void x87_stmmx(MMX_REG r)
static __inline uint16_t x87_compare(double a, double b)
{
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32
uint32_t out;
uint32_t result;
if (!is386)
{
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
{
/* pclog("Comparing infinity\n"); */
#ifndef _MSC_VER
__asm volatile ("" : : : "memory");
__asm(
@@ -276,14 +299,26 @@ static __inline uint16_t x87_compare(double a, double b)
"fclex\n"
"fcompp\n"
"fnstsw %0\n"
: "=m" (out)
: "=m" (result)
: "m" (a), "m" (a)
);
#else
_ReadWriteBarrier();
__asm
{
fld a
fld a
fclex
fcompp
fnstsw result
}
#endif
return out & (C0|C2|C3);
return result & (C0|C2|C3);
}
}
#ifndef _MSC_VER
/* Memory barrier, to force GCC to write to the input parameters
* before the compare rather than after */
__asm volatile ("" : : : "memory");
@@ -294,11 +329,22 @@ static __inline uint16_t x87_compare(double a, double b)
"fclex\n"
"fcompp\n"
"fnstsw %0\n"
: "=m" (out)
: "=m" (result)
: "m" (a), "m" (b)
);
#else
_ReadWriteBarrier();
_asm
{
fld b
fld a
fclex
fcompp
fnstsw result
}
#endif
return out & (C0|C2|C3);
return result & (C0|C2|C3);
#else
/* Generic C version is known to give incorrect results in some
* situations, eg comparison of infinity (Unreal) */
@@ -308,32 +354,33 @@ static __inline uint16_t x87_compare(double a, double b)
{
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
{
out |= C3;
return out;
result |= C3;
return result;
}
if (a == b)
out |= C3;
result |= C3;
else if (a < b)
out |= C0;
result |= C0;
}
else
{
if (a == b)
out |= C3;
result |= C3;
else if (a < b)
out |= C0;
result |= C0;
}
return out;
return result;
#endif
}
static __inline uint16_t x87_ucompare(double a, double b)
{
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _WIN32
uint32_t out;
uint32_t result;
#ifndef _MSC_VER
/* Memory barrier, to force GCC to write to the input parameters
* before the compare rather than after */
__asm volatile ("" : : : "memory");
@@ -344,22 +391,33 @@ static __inline uint16_t x87_ucompare(double a, double b)
"fclex\n"
"fucompp\n"
"fnstsw %0\n"
: "=m" (out)
: "=m" (result)
: "m" (a), "m" (b)
);
#else
_ReadWriteBarrier();
_asm
{
fld b
fld a
fclex
fcompp
fnstsw result
}
#endif
return out & (C0|C2|C3);
return result & (C0|C2|C3);
#else
/* Generic C version is known to give incorrect results in some
* situations, eg comparison of infinity (Unreal) */
uint32_t out = 0;
uint32_t result = 0;
if (a == b)
out |= C3;
result |= C3;
else if (a < b)
out |= C0;
result |= C0;
return out;
return result;
#endif
}
@@ -435,14 +493,14 @@ static int FPU_ILLEGAL_a32(uint32_t fetchdat)
#define ILLEGAL_a16 FPU_ILLEGAL_a16
#define ILLEGAL_a32 FPU_ILLEGAL_a32
OpFn OP_TABLE(fpu_d8_a16)[32] =
const OpFn OP_TABLE(fpu_d8_a16)[32] =
{
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16,
opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR
};
OpFn OP_TABLE(fpu_d8_a32)[32] =
const OpFn OP_TABLE(fpu_d8_a32)[32] =
{
opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32,
opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32,
@@ -450,7 +508,7 @@ OpFn OP_TABLE(fpu_d8_a32)[32] =
opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR
};
OpFn OP_TABLE(fpu_287_d9_a16)[256] =
const OpFn OP_TABLE(fpu_287_d9_a16)[256] =
{
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -489,7 +547,7 @@ OpFn OP_TABLE(fpu_287_d9_a16)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_287_d9_a32)[256] =
const OpFn OP_TABLE(fpu_287_d9_a32)[256] =
{
opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -528,7 +586,7 @@ OpFn OP_TABLE(fpu_287_d9_a32)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_d9_a16)[256] =
const OpFn OP_TABLE(fpu_d9_a16)[256] =
{
opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -567,7 +625,7 @@ OpFn OP_TABLE(fpu_d9_a16)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_d9_a32)[256] =
const OpFn OP_TABLE(fpu_d9_a32)[256] =
{
opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -606,7 +664,7 @@ OpFn OP_TABLE(fpu_d9_a32)[256] =
opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS
};
OpFn OP_TABLE(fpu_287_da_a16)[256] =
const OpFn OP_TABLE(fpu_287_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
@@ -644,7 +702,7 @@ OpFn OP_TABLE(fpu_287_da_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_da_a32)[256] =
const OpFn OP_TABLE(fpu_287_da_a32)[256] =
{
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
@@ -683,7 +741,7 @@ OpFn OP_TABLE(fpu_287_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_da_a16)[256] =
const OpFn OP_TABLE(fpu_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
@@ -721,7 +779,7 @@ OpFn OP_TABLE(fpu_da_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_da_a32)[256] =
const OpFn OP_TABLE(fpu_da_a32)[256] =
{
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
@@ -760,7 +818,7 @@ OpFn OP_TABLE(fpu_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_686_da_a16)[256] =
const OpFn OP_TABLE(fpu_686_da_a16)[256] =
{
opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16,
opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16,
@@ -798,7 +856,7 @@ OpFn OP_TABLE(fpu_686_da_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_686_da_a32)[256] =
const OpFn OP_TABLE(fpu_686_da_a32)[256] =
{
opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32,
opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32,
@@ -837,7 +895,7 @@ OpFn OP_TABLE(fpu_686_da_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_287_db_a16)[256] =
const OpFn OP_TABLE(fpu_287_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -875,7 +933,7 @@ OpFn OP_TABLE(fpu_287_db_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_db_a32)[256] =
const OpFn OP_TABLE(fpu_287_db_a32)[256] =
{
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -914,7 +972,7 @@ OpFn OP_TABLE(fpu_287_db_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_db_a16)[256] =
const OpFn OP_TABLE(fpu_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -952,7 +1010,7 @@ OpFn OP_TABLE(fpu_db_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_db_a32)[256] =
const OpFn OP_TABLE(fpu_db_a32)[256] =
{
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -991,7 +1049,7 @@ OpFn OP_TABLE(fpu_db_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_686_db_a16)[256] =
const OpFn OP_TABLE(fpu_686_db_a16)[256] =
{
opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1029,7 +1087,7 @@ OpFn OP_TABLE(fpu_686_db_a16)[256] =
opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_686_db_a32)[256] =
const OpFn OP_TABLE(fpu_686_db_a32)[256] =
{
opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1068,14 +1126,14 @@ OpFn OP_TABLE(fpu_686_db_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_287_dc_a16)[32] =
const OpFn OP_TABLE(fpu_287_dc_a16)[32] =
{
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_287_dc_a32)[32] =
const OpFn OP_TABLE(fpu_287_dc_a32)[32] =
{
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
@@ -1083,14 +1141,14 @@ OpFn OP_TABLE(fpu_287_dc_a32)[32] =
opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_dc_a16)[32] =
const OpFn OP_TABLE(fpu_dc_a16)[32] =
{
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16,
opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_dc_a32)[32] =
const OpFn OP_TABLE(fpu_dc_a32)[32] =
{
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32,
@@ -1098,7 +1156,7 @@ OpFn OP_TABLE(fpu_dc_a32)[32] =
opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr
};
OpFn OP_TABLE(fpu_287_dd_a16)[256] =
const OpFn OP_TABLE(fpu_287_dd_a16)[256] =
{
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1136,7 +1194,7 @@ OpFn OP_TABLE(fpu_287_dd_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_dd_a32)[256] =
const OpFn OP_TABLE(fpu_287_dd_a32)[256] =
{
opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1175,7 +1233,7 @@ OpFn OP_TABLE(fpu_287_dd_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_dd_a16)[256] =
const OpFn OP_TABLE(fpu_dd_a16)[256] =
{
opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1213,7 +1271,7 @@ OpFn OP_TABLE(fpu_dd_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_dd_a32)[256] =
const OpFn OP_TABLE(fpu_dd_a32)[256] =
{
opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1252,7 +1310,7 @@ OpFn OP_TABLE(fpu_dd_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_287_de_a16)[256] =
const OpFn OP_TABLE(fpu_287_de_a16)[256] =
{
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
@@ -1291,7 +1349,7 @@ OpFn OP_TABLE(fpu_287_de_a16)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_287_de_a32)[256] =
const OpFn OP_TABLE(fpu_287_de_a32)[256] =
{
opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32,
opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32,
@@ -1330,7 +1388,7 @@ OpFn OP_TABLE(fpu_287_de_a32)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_de_a16)[256] =
const OpFn OP_TABLE(fpu_de_a16)[256] =
{
opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16,
opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16,
@@ -1369,7 +1427,7 @@ OpFn OP_TABLE(fpu_de_a16)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_de_a32)[256] =
const OpFn OP_TABLE(fpu_de_a32)[256] =
{
opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32,
opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32,
@@ -1408,7 +1466,7 @@ OpFn OP_TABLE(fpu_de_a32)[256] =
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
};
OpFn OP_TABLE(fpu_287_df_a16)[256] =
const OpFn OP_TABLE(fpu_287_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1446,7 +1504,7 @@ OpFn OP_TABLE(fpu_287_df_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_287_df_a32)[256] =
const OpFn OP_TABLE(fpu_287_df_a32)[256] =
{
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1485,7 +1543,7 @@ OpFn OP_TABLE(fpu_287_df_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_df_a16)[256] =
const OpFn OP_TABLE(fpu_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1523,7 +1581,7 @@ OpFn OP_TABLE(fpu_df_a16)[256] =
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_df_a32)[256] =
const OpFn OP_TABLE(fpu_df_a32)[256] =
{
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1562,7 +1620,7 @@ OpFn OP_TABLE(fpu_df_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(fpu_686_df_a16)[256] =
const OpFn OP_TABLE(fpu_686_df_a16)[256] =
{
opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
@@ -1600,7 +1658,7 @@ OpFn OP_TABLE(fpu_686_df_a16)[256] =
opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP,
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
};
OpFn OP_TABLE(fpu_686_df_a32)[256] =
const OpFn OP_TABLE(fpu_686_df_a32)[256] =
{
opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32,
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
@@ -1639,7 +1697,7 @@ OpFn OP_TABLE(fpu_686_df_a32)[256] =
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
};
OpFn OP_TABLE(nofpu_a16)[256] =
const OpFn OP_TABLE(nofpu_a16)[256] =
{
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
@@ -1677,7 +1735,7 @@ OpFn OP_TABLE(nofpu_a16)[256] =
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16,
};
OpFn OP_TABLE(nofpu_a32)[256] =
const OpFn OP_TABLE(nofpu_a32)[256] =
{
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,
op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32,