mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 17:15:32 -07:00
Added the IBM 5161 ISA expansion for PC and XT;
Cleaned up the parallel port emulation, added IRQ support, and made enabling/disabling per port; Added the Award 430NX and the Intel Classic/PCI (Alfredo, 420TX); Finished the 586MC1; Added 8087 emulation; Moved Cyrix 6x86'es to the Dev branch; Sanitized/cleaned up memregs.c/h and intel.c/h; Split the chipsets from machines and sanitized Port 92 emulation; Added support for the 15bpp mode to the Compaq ATI 28800; Moved the MR 386DX and 486 machines to the Dev branch; Ported the new dynamic recompiler from PCem, but it remains in Dev branch until after v2.00; Ported the new timer code from PCem; Cleaned up the CPU table of unused stuff and better optimized its structure; Ported the Open-XT and Open-AT from VARCem, the Open-AT is in the Dev branch; Ported the XT MFM controller rewrite and adding of more controllers (incl. two RLL ones), from VARCem; Added the AHA-1540A and the BusTek BT-542B; Moved the Sumo SCSI-AT to the Dev branch; Minor IDE, FDC, and floppy drive code clean-ups; Made NCR 5380/53C400-based cards' BIOS address configurable; Got rid of the legacy romset variable; Unified (video) buffer and buffer32 into one and make the unified buffer 32-bit; Added the Amstead PPC512 per PCem patch by John Elliott; Switched memory mapping granularity from 16k to 4k (less than 1k not possible due to internal pages); Rewrote the CL-GD 54xx blitter, fixes Win-OS/2 on the 54x6 among other thing; Added the Image Manager 1024 and Professional Graphics Controller per PCem patch by John Elliott and work done on VARCem; Added Headland HT-216, GC-205 and Video 7 VGA 1024i emulation based on PCem commit; Implemented the fuction keys for the Toshiba T1000/T1200/T3100 enhancement; Amstrad MegaPC does now works correctly with non-internal graphics card; The SLiRP code no longer casts a packed struct type to a non-packed struct type; The Xi8088 and PB410a no longer hang on 86Box when PS/2 mouse is not present; The S3 Virge on BeOS is no longer broken (was broken by build #1591); OS/2 2.0 build 6.167 now sees key presses again; Xi8088 now work on CGA again; 86F images converted from either the old or new variants of the HxC MFM format now work correctly; Hardware interrupts with a vector of 0xFF are now handled correctly; OPTi 495SX boards no longer incorrectly have 64 MB maximum RAM when 32 MB is correct; Fixed VNC keyboard input bugs; Fixed AT RTC periodic interrupt - Chicago 58s / 73f / 73g / 81 MIDI play no longer hangs with the build's own VTD driver; Fixed mouse polling with internal mice - Amstrad and Olivetti mice now work correctly; Triones ATAPI DMA driver now correctly reads a file at the end of a CD image with a sectors number not divisible by 4; Compaq Portable now works with all graphics cards; Fixed various MDSI Genius bugs; Added segment limit checks and improved page fault checks for several CPU instructions - Memphis 15xx WINSETUP and Chicago 58s WINDISK.CPL no longer issue a GPF, and some S3 drivers that used to have glitches, now work correctly; Further improved the 808x emulation, also fixes the noticably choppy sound when using 808x CPU's, also fixes #355; OS/2 installer no logner locks up on splash screen on PS/2 Model 70 and 80, fixes #400. Fixed several Amstead bugs, GEM no longer crashes on the Amstrad 1640, fixes #391. Ported John Elliott's Amstrad fixes and improvement from PCem, and fixed the default language so it's correctly Engliish, fixes #278, fixes #389. Fixed a minor IDE timing bug, fixes #388. Fixed Toshiba T1000 RAM issues, fixes #379. Fixed EGA/(S)VGA overscan border handling, fixes #378; Got rid of the now long useless IDE channel 2 auto-removal, fixes #370; Fixed the BIOS files used by the AMSTRAD PC1512, fixes #366; Ported the Unicode CD image file name fix from VARCem, fixes #365; Fixed high density floppy disks on the Xi8088, fixes #359; Fixed some bugs in the Hercules emulation, fixes #346, fixes #358; Fixed the SCSI hard disk mode sense pages, fixes #356; Removed the AMI Unknown 386SX because of impossibility to identify the chipset, closes #349; Fixed bugs in the serial mouse emulation, fixes #344; Compiled 86Box binaries now include all the required .DLL's, fixes #341; Made some combo boxes in the Settings dialog slightly wider, fixes #276.
This commit is contained in:
13
src/86box.h
13
src/86box.h
@@ -92,7 +92,6 @@ extern int vid_cga_contrast, /* (C) video */
|
||||
force_43, /* (C) video */
|
||||
gfxcard; /* (C) graphics/video card */
|
||||
extern int serial_enabled[], /* (C) enable serial ports */
|
||||
lpt_enabled, /* (C) enable LPT ports */
|
||||
bugger_enabled, /* (C) enable ISAbugger */
|
||||
isamem_type[], /* (C) enable ISA mem cards */
|
||||
isartc_type; /* (C) enable ISA RTC card */
|
||||
@@ -129,7 +128,9 @@ extern int nic_do_log;
|
||||
extern wchar_t exe_path[1024]; /* path (dir) of executable */
|
||||
extern wchar_t usr_path[1024]; /* path (dir) of user data */
|
||||
extern wchar_t cfg_path[1024]; /* full path of config file */
|
||||
#ifndef USE_NEW_DYNAREC
|
||||
extern FILE *stdlog; /* file to log output to */
|
||||
#endif
|
||||
extern int scrnsz_x, /* current screen size, X */
|
||||
scrnsz_y; /* current screen size, Y */
|
||||
extern int efscrnsz_y;
|
||||
@@ -164,6 +165,16 @@ extern void pc_thread(void *param);
|
||||
extern void pc_start(void);
|
||||
extern void pc_onesec(void);
|
||||
|
||||
extern uint16_t get_last_addr(void);
|
||||
|
||||
/* This is for external subtraction of cycles;
|
||||
should be in cpu.c but I put it here to avoid
|
||||
having to include cpu.c everywhere. */
|
||||
extern void sub_cycles(int c);
|
||||
|
||||
extern double isa_timing;
|
||||
extern int io_delay;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
# settings, so we can avoid changing the main one for all of
|
||||
# our local setups.
|
||||
#
|
||||
# Version: @(#)Makefile.local 1.0.20 2018/11/18
|
||||
# Version: @(#)Makefile.local 1.0.21 2019/03/03
|
||||
#
|
||||
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
#
|
||||
@@ -70,8 +70,8 @@ STUFF :=
|
||||
# -DENABLE_HDC_LOG=N sets logging level at N.
|
||||
# -DENABLE_HDD_IMAGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_IDE_LOG=N sets logging level at N.
|
||||
# -DENABLE_MFM_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_MFM_XT_LOG=N sets logging level at N.
|
||||
# -DENABLE_ST506_AT_LOG=N sets logging level at N.
|
||||
# -DENABLE_ST506_XT_LOG=N sets logging level at N.
|
||||
# -DENABLE_XTA_LOG=N sets logging level at N.
|
||||
# -DENABLE_ZIP_LOG=N sets logging level at N.
|
||||
# floppy/ logging:
|
||||
@@ -123,6 +123,10 @@ STUFF :=
|
||||
# -DENABLE_ATI28800_LOG=N sets logging level at N.
|
||||
# -DENABLE_MACH64_LOG=N sets logging level at N.
|
||||
# -DENABLE_ET4000W32_LOG=N sets logging level at N.
|
||||
# -DENABLE_HT216_LOG=N sets logging level at N.
|
||||
# -DENABLE_ICD2061_LOG=N sets logging level at N.
|
||||
# -DENABLE_IM1024_LOG=N sets logging level at N.
|
||||
# -DENABLE_PGC_LOG=N sets logging level at N.
|
||||
# -DENABLE_S3_VIRGE_LOG=N sets logging level at N.
|
||||
# -DENABLE_VID_TABLE_LOG=N sets logging level at N.
|
||||
# -DENABLE_VOODOO_LOG=N sets logging level at N.
|
||||
|
||||
149
src/apm.c
Normal file
149
src/apm.c
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Advanced Power Management emulation.
|
||||
*
|
||||
* Version: @(#)apm.c 1.0.0 2019/05/12
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "86box.h"
|
||||
#include "cpu/cpu.h"
|
||||
#include "device.h"
|
||||
#include "io.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cmd,
|
||||
stat;
|
||||
} apm_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_APM_LOG
|
||||
int apm_do_log = ENABLE_APM_LOG;
|
||||
|
||||
|
||||
static void
|
||||
apm_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (apm_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define apm_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
apm_out(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
apm_t *apm = (apm_t *) p;
|
||||
|
||||
apm_log("[%04X:%08X] APM write: %04X = %02X (BX = %04X, CX = %04X)\n", CS, cpu_state.pc, port, val, BX, CX);
|
||||
|
||||
port &= 0x0001;
|
||||
|
||||
if (port == 0x0000) {
|
||||
apm->cmd = val;
|
||||
|
||||
switch (apm->cmd) {
|
||||
case 0x07: /* Set Power State */
|
||||
if (CH == 0x00) switch (CX) {
|
||||
case 0x0000:
|
||||
#ifdef ENABLE_APM_LOG
|
||||
apm_log("APM Set Power State: APM Enabled\n");
|
||||
#endif
|
||||
break;
|
||||
case 0x0001:
|
||||
#ifdef ENABLE_APM_LOG
|
||||
apm_log("APM Set Power State: Standby\n");
|
||||
#endif
|
||||
break;
|
||||
case 0x0002:
|
||||
#ifdef ENABLE_APM_LOG
|
||||
apm_log("APM Set Power State: Suspend\n");
|
||||
#endif
|
||||
break;
|
||||
case 0x0003: /* Off */
|
||||
#ifdef ENABLE_APM_LOG
|
||||
apm_log("APM Set Power State: Off\n");
|
||||
#endif
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
apm->stat = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
apm_in(uint16_t port, void *p)
|
||||
{
|
||||
apm_t *apm = (apm_t *) p;
|
||||
|
||||
apm_log("[%04X:%08X] APM read: %04X = FF\n", CS, cpu_state.pc, port);
|
||||
|
||||
port &= 0x0001;
|
||||
|
||||
if (port == 0x0000)
|
||||
return apm->cmd;
|
||||
else
|
||||
return apm->stat;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
apm_close(void *p)
|
||||
{
|
||||
apm_t *dev = (apm_t *)p;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*apm_init(const device_t *info)
|
||||
{
|
||||
apm_t *apm = (apm_t *) malloc(sizeof(apm_t));
|
||||
memset(apm, 0, sizeof(apm_t));
|
||||
|
||||
io_sethandler(0x00b2, 0x0002, apm_in, NULL, NULL, apm_out, NULL, NULL, apm);
|
||||
|
||||
return apm;
|
||||
}
|
||||
|
||||
|
||||
const device_t apm_device =
|
||||
{
|
||||
"Advanced Power Management",
|
||||
0,
|
||||
0,
|
||||
apm_init,
|
||||
apm_close,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
43
src/apm.h
Normal file
43
src/apm.h
Normal file
@@ -0,0 +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.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ISA Bus (de)Bugger expansion card
|
||||
* sold as a DIY kit in the late 1980's in The Netherlands.
|
||||
* This card was a assemble-yourself 8bit ISA addon card for
|
||||
* PC and AT systems that had several tools to aid in low-
|
||||
* level debugging (mostly for faulty BIOSes, bootloaders
|
||||
* and system kernels...)
|
||||
*
|
||||
* Definitions for the Advanced Power Management emulation.
|
||||
*
|
||||
* Version: @(#)apm.h 1.0.0 2019/05/12
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#ifndef APM_H
|
||||
# define APM_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Global variables. */
|
||||
extern const device_t apm_device;
|
||||
|
||||
|
||||
/* Functions. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*APM_H*/
|
||||
203
src/cassette/cassette.c
Normal file
203
src/cassette/cassette.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/************************************************************************
|
||||
|
||||
PCEM: IBM 5150 Cassette support
|
||||
|
||||
Copyright (C) 2019 John Elliott <seasip.webmaster@gmail.com>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../ppi.h"
|
||||
#include "../ui.h"
|
||||
#include "../plat.h"
|
||||
#include "pzx.h"
|
||||
#include "cassette.h"
|
||||
|
||||
typedef struct cassette_t
|
||||
{
|
||||
uint8_t motor; /* Motor status */
|
||||
pzxfile_t pzx;
|
||||
int cycles_last; /* Cycle count at last cassette poll */
|
||||
|
||||
} cassette_t;
|
||||
|
||||
wchar_t cassettefn[256];
|
||||
|
||||
static cassette_t *st_cas;
|
||||
|
||||
|
||||
#ifdef ENABLE_CASSETTE_LOG
|
||||
int cassette_do_log = ENABLE_CASSETTE_LOG;
|
||||
|
||||
|
||||
static void
|
||||
cassette_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (cassette_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define cassette_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* The PCEM CPU uses IBM cycles (4.77MHz). PZX uses Spectrum cycles (3.5MHz)
|
||||
* so scale accordingly. */
|
||||
static int32_t
|
||||
pzx_cycles(int32_t pc)
|
||||
{
|
||||
double d = pc;
|
||||
|
||||
return (int32_t)(((d * 3.5) / 4.772728) + 0.5);
|
||||
}
|
||||
|
||||
void
|
||||
cassette_eject(void)
|
||||
{
|
||||
if (st_cas->pzx.input) {
|
||||
pzx_close(&st_cas->pzx);
|
||||
}
|
||||
cassettefn[0] = 0;
|
||||
}
|
||||
|
||||
void
|
||||
cassette_load(wchar_t *fn)
|
||||
{
|
||||
FILE *fp;
|
||||
unsigned char magic[8];
|
||||
|
||||
if (!fn)
|
||||
return;
|
||||
|
||||
fp = plat_fopen(fn, L"rb");
|
||||
if (!fp) {
|
||||
/* Warn user? */
|
||||
cassette_log("Failed to open cassette input %s\n", fn);
|
||||
return;
|
||||
}
|
||||
memset(magic, 0, sizeof(magic));
|
||||
fread(magic, 1, sizeof(magic), fp);
|
||||
|
||||
/* Check for PZX signature. In due course support could be added for
|
||||
* other formats like TZX */
|
||||
if (!memcmp(magic, "PZXT", 4)) {
|
||||
wchar_t *result;
|
||||
|
||||
result = pzx_open(&st_cas->pzx, fp);
|
||||
|
||||
if (result) {
|
||||
cassette_log("Failed to open %s as PZX: %s\n",
|
||||
fn, result);
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
wcscpy(cassettefn, fn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
cassette_input(void)
|
||||
{
|
||||
int ticks;
|
||||
|
||||
/* While motor is off, result is loopback */
|
||||
if (!st_cas->motor)
|
||||
return ppispeakon;
|
||||
/* If there is no tapefile open don't try to extract data */
|
||||
if (st_cas->pzx.input == NULL)
|
||||
return 0;
|
||||
/* Otherwise see how many ticks there have been since the last input */
|
||||
if (st_cas->cycles_last == -1)
|
||||
st_cas->cycles_last = cycles;
|
||||
if (cycles <= st_cas->cycles_last)
|
||||
ticks = (st_cas->cycles_last - cycles);
|
||||
else
|
||||
ticks = (st_cas->cycles_last + (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed / 100) - cycles);
|
||||
st_cas->cycles_last = cycles;
|
||||
|
||||
return pzx_advance(&st_cas->pzx, pzx_cycles(ticks));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
cassette_set_motor(uint8_t on)
|
||||
{
|
||||
if (on && !st_cas->motor) {
|
||||
cassette_log("Start cassette motor\n");
|
||||
st_cas->cycles_last = -1;
|
||||
}
|
||||
if (st_cas->motor && !on) {
|
||||
cassette_log("Stop cassette motor\n");
|
||||
st_cas->cycles_last = -1;
|
||||
}
|
||||
st_cas->motor = on;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*cassette_init(const device_t *info)
|
||||
{
|
||||
cassette_t *cas = (cassette_t *)malloc(sizeof(cassette_t));
|
||||
memset(cas, 0, sizeof(cassette_t));
|
||||
pzx_init(&cas->pzx);
|
||||
|
||||
st_cas = cas;
|
||||
return cas;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cassette_close(void *p)
|
||||
{
|
||||
cassette_t *cas = (cassette_t *)p;
|
||||
|
||||
pzx_close(&cas->pzx);
|
||||
|
||||
free(cas);
|
||||
}
|
||||
|
||||
|
||||
const device_t cassette_device = {
|
||||
"IBM PC 5150 Cassette",
|
||||
0,
|
||||
0,
|
||||
cassette_init,
|
||||
cassette_close,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
30
src/cassette/cassette.h
Normal file
30
src/cassette/cassette.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/************************************************************************
|
||||
|
||||
PCEM: IBM 5150 cassette support
|
||||
|
||||
Copyright (C) 2019 John Elliott <seasip.webmaster@gmail.com>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
extern wchar_t cassettefn[256];
|
||||
|
||||
extern const device_t cassette_device;
|
||||
|
||||
uint8_t cassette_input(void);
|
||||
void cassette_set_motor(uint8_t on);
|
||||
void cassette_eject(void);
|
||||
void cassette_load(wchar_t *filename);
|
||||
414
src/cassette/pzx.c
Normal file
414
src/cassette/pzx.c
Normal file
@@ -0,0 +1,414 @@
|
||||
/************************************************************************
|
||||
|
||||
PCEM: IBM 5150 Cassette support
|
||||
|
||||
Copyright (C) 2019 John Elliott <seasip.webmaster@gmail.com>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../ui.h"
|
||||
#include "pzx.h"
|
||||
|
||||
/* This module is intended to abstract all the details of a PZX file and
|
||||
* emit its contents as a bitstream in a form suitable for PCEM. Similar
|
||||
* modules could be written to add support for other tape formats such as TZX,
|
||||
* TAP or CSW. */
|
||||
|
||||
|
||||
#ifdef ENABLE_PZX_LOG
|
||||
int pzx_do_log = ENABLE_PZX_LOG;
|
||||
|
||||
|
||||
static void
|
||||
pzx_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (pzx_do_log)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define pzx_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
static uint32_t
|
||||
peek2(uint8_t *data)
|
||||
{
|
||||
return (((uint32_t)data[1]) << 8) | data[0];
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
peek4(uint8_t *data)
|
||||
{
|
||||
return (((uint32_t)data[3]) << 24) |
|
||||
(((uint32_t)data[2]) << 16) |
|
||||
(((uint32_t)data[1]) << 8) | data[0];
|
||||
}
|
||||
|
||||
/* Cue up the next pulse definition from the current PULS block. */
|
||||
static void
|
||||
pzx_parse_pulse(pzxfile_t *pzx)
|
||||
{
|
||||
pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr);
|
||||
pzx->puls_ptr += 2;
|
||||
if (pzx->puls_duration > 0x8000) {
|
||||
pzx->puls_count = pzx->puls_duration & 0x7FFF;
|
||||
pzx->puls_duration = peek2(pzx->curblock + pzx->puls_ptr);
|
||||
pzx->puls_ptr += 2;
|
||||
}
|
||||
if (pzx->puls_duration >= 0x8000) {
|
||||
pzx->puls_duration &= 0x7FFF;
|
||||
pzx->puls_duration <<= 16;
|
||||
pzx->puls_duration |= peek2(pzx->curblock + pzx->puls_ptr);
|
||||
pzx->puls_ptr += 2;
|
||||
}
|
||||
if (!pzx->puls_count) pzx->puls_count = 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pzx_init(pzxfile_t *pzx)
|
||||
{
|
||||
memset(pzx, 0, sizeof(pzxfile_t));
|
||||
pzx->state = PZX_CLOSED;
|
||||
}
|
||||
|
||||
/* Load the next block from a PZX-format file.
|
||||
*
|
||||
* Returns block if successful, NULL if end of file or error
|
||||
* Caller must free the block with free(). */
|
||||
uint8_t
|
||||
*pzx_load_block(FILE *fp)
|
||||
{
|
||||
uint8_t block_header[8];
|
||||
uint8_t *block_data;
|
||||
uint32_t block_len;
|
||||
|
||||
/* The first 8 bytes of a PZX block are fixed: the first 4 give
|
||||
* the ID, the second 4 the length (excluding the header itself) */
|
||||
if (fread(block_header, 1, 8, fp) < 8)
|
||||
return NULL; /* EoF */
|
||||
|
||||
block_len = peek4(block_header + 4);
|
||||
block_data = malloc(8 + block_len);
|
||||
if (!block_data) return NULL;
|
||||
memcpy(block_data, block_header, 8);
|
||||
if (!block_len) { /* Block is only the header */
|
||||
/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */
|
||||
return block_data;
|
||||
}
|
||||
if (fread(block_data + 8, 1, block_len, fp) < block_len) {
|
||||
free(block_data); /* Unexpected EoF */
|
||||
return NULL;
|
||||
}
|
||||
/* CAS_LOG(("Loaded PZX block: %-4.4s\n", block_data)); */
|
||||
return block_data;
|
||||
}
|
||||
|
||||
|
||||
/* Search the current file for PZX version headers and check they're all 1.x */
|
||||
static wchar_t
|
||||
*pzx_check_version(FILE *fp)
|
||||
{
|
||||
uint8_t *block;
|
||||
static wchar_t message[80];
|
||||
|
||||
rewind(fp);
|
||||
while ((block = pzx_load_block(fp))) {
|
||||
if (!memcmp(block, "PZXT", 4)) {
|
||||
pzx_log("PZX version %d.%d\n", block[8], block[9]);
|
||||
if (block[8] != 1) {
|
||||
swprintf(message, 80, L"Unsupported PZX version %d.%d\n", block[8], block[9]);
|
||||
free(block);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
free(block);
|
||||
}
|
||||
rewind(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
wchar_t
|
||||
*pzx_open(pzxfile_t *pzx, FILE *fp)
|
||||
{
|
||||
wchar_t *result;
|
||||
|
||||
rewind(fp);
|
||||
/* Check that this file is compatible */
|
||||
result = pzx_check_version(fp);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
pzx->level = 0;
|
||||
pzx->state = PZX_IDLE;
|
||||
pzx->input = fp;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
pzx_close(pzxfile_t *pzx)
|
||||
{
|
||||
if (pzx->input) {
|
||||
fclose(pzx->input);
|
||||
pzx->input = NULL;
|
||||
}
|
||||
if (pzx->curblock) {
|
||||
free(pzx->curblock);
|
||||
pzx->curblock = NULL;
|
||||
}
|
||||
pzx->state = PZX_CLOSED;
|
||||
}
|
||||
|
||||
/* Read the next block of type DATA, PAUS or PULS */
|
||||
int
|
||||
pzx_next_block(pzxfile_t *pzx)
|
||||
{
|
||||
long pos;
|
||||
|
||||
pos = ftell(pzx->input);
|
||||
while (pzx->state == PZX_IDLE) {
|
||||
uint8_t *blk;
|
||||
|
||||
/* In idle state there should be no current block. But
|
||||
* make sure of that */
|
||||
if (pzx->curblock) {
|
||||
free(pzx->curblock);
|
||||
pzx->curblock = NULL;
|
||||
}
|
||||
|
||||
/* Load the next block */
|
||||
blk = pzx_load_block(pzx->input);
|
||||
|
||||
/* If that didn't load we've reached the end of file; wrap to
|
||||
* beginning. */
|
||||
if (!blk) {
|
||||
rewind(pzx->input);
|
||||
blk = pzx_load_block(pzx->input);
|
||||
if (!blk) { /* Couldn't even load first block */
|
||||
pzx_close(pzx);
|
||||
return 0;
|
||||
}
|
||||
/* Have we read the whole file and come back to where
|
||||
* we were? */
|
||||
if (ftell(pzx->input) == pos) {
|
||||
free(blk);
|
||||
pzx_close(pzx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* We have loaded the next block. What is it? */
|
||||
if (!memcmp(blk, "PULS", 4)) {
|
||||
pzx->state = PZX_IN_PULS;
|
||||
pzx->curblock = blk;
|
||||
pzx->puls_len = 8 + peek4(blk + 4);
|
||||
pzx->puls_ptr = 8;
|
||||
pzx->puls_count = 0;
|
||||
pzx->puls_remain = 0;
|
||||
pzx->puls_duration = 0;
|
||||
pzx->level = 0;
|
||||
pzx_log("Beginning PULS block\n");
|
||||
}
|
||||
else if (!memcmp(blk, "PAUS", 4)) {
|
||||
pzx->state = PZX_IN_PAUS;
|
||||
pzx->curblock = blk;
|
||||
pzx->paus_remain = peek4(blk + 8);
|
||||
pzx->level = (pzx->paus_remain >> 31);
|
||||
pzx->paus_remain &= 0x7FFFFFFF;
|
||||
pzx_log("Beginning PAUS block, duration=%d\n",
|
||||
pzx->paus_remain);
|
||||
}
|
||||
else if (!memcmp(blk, "DATA", 4)) {
|
||||
pzx->state = PZX_IN_DATA;
|
||||
pzx->curblock = blk;
|
||||
pzx->data_bits = peek4(blk + 8);
|
||||
pzx->level = (pzx->data_bits >> 31);
|
||||
pzx->data_bits &= 0x7FFFFFFF;
|
||||
pzx->data_tail = peek2(blk + 12);
|
||||
pzx->data_p0 = blk[14];
|
||||
pzx->data_p1 = blk[15];
|
||||
pzx->data_p = 0;
|
||||
pzx->data_w = 16;
|
||||
pzx->data_remain = 0;
|
||||
pzx->data_ptr = 16 + 2 * (pzx->data_p0 + pzx->data_p1);
|
||||
pzx->data_mask = 0x80;
|
||||
pzx_log("Beginning DATA block, length=%d p0=%d p1=%d"
|
||||
" data_ptr=%d\n",
|
||||
pzx->data_bits,
|
||||
pzx->data_p0, pzx->data_p1,
|
||||
pzx->data_ptr);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pzx_endblock(pzxfile_t *pzx)
|
||||
{
|
||||
if (pzx->curblock)
|
||||
free(pzx->curblock);
|
||||
pzx->curblock = NULL;
|
||||
pzx->state = PZX_IDLE;
|
||||
}
|
||||
|
||||
/* PAUS is easy - just run the timer down */
|
||||
static int
|
||||
pzx_advance_paus(pzxfile_t *pzx, int time)
|
||||
{
|
||||
if (pzx->paus_remain > time) {
|
||||
pzx->paus_remain -= time;
|
||||
return 0;
|
||||
}
|
||||
time -= pzx->paus_remain;
|
||||
pzx_endblock(pzx);
|
||||
return time;
|
||||
}
|
||||
|
||||
static int
|
||||
pzx_advance_puls(pzxfile_t *pzx, int time)
|
||||
{
|
||||
/* At the start of a pulse sequence? */
|
||||
if (pzx->puls_count == 0) {
|
||||
pzx_parse_pulse(pzx);
|
||||
pzx->puls_remain = pzx->puls_duration;
|
||||
}
|
||||
/* Does sample trigger a pulse change? If not, that's easy. */
|
||||
if (time < pzx->puls_remain) {
|
||||
pzx->puls_remain -= time;
|
||||
return 0;
|
||||
}
|
||||
/* Sample does trigger a pulse change */
|
||||
time -= pzx->puls_remain;
|
||||
/* If there's another pulse in the current sequence, that's
|
||||
* straightforward; just flip the level and continue */
|
||||
--pzx->puls_count;
|
||||
pzx->level = !pzx->level;
|
||||
if (pzx->puls_count) {
|
||||
pzx->puls_remain = pzx->puls_duration;
|
||||
return time;
|
||||
}
|
||||
/* If we've reached the end of the pulse sequence, there may be
|
||||
* another one */
|
||||
if (pzx->puls_ptr < pzx->puls_len) {
|
||||
return time;
|
||||
}
|
||||
/* If there isn't another one, it's the end of the block */
|
||||
pzx_endblock(pzx);
|
||||
return time;
|
||||
}
|
||||
|
||||
/* Decode a DATA block */
|
||||
static int
|
||||
pzx_advance_data(pzxfile_t *pzx, int time)
|
||||
{
|
||||
uint8_t bit;
|
||||
|
||||
/* Reached end of data? */
|
||||
if (pzx->data_bits == 0) {
|
||||
/* Time interval is covered by the tail bit */
|
||||
if (pzx->data_tail > time) {
|
||||
pzx->data_tail -= time;
|
||||
return 0;
|
||||
}
|
||||
/* Have run out of block */
|
||||
time -= pzx->data_tail;
|
||||
pzx_endblock(pzx);
|
||||
return time;
|
||||
}
|
||||
/* No more time remaining on the current bit? */
|
||||
if (pzx->data_p < 1 && !pzx->data_remain) {
|
||||
bit = pzx->curblock[pzx->data_ptr] & pzx->data_mask;
|
||||
pzx->data_mask >>= 1;
|
||||
if (!pzx->data_mask) {
|
||||
pzx->data_mask = 0x80;
|
||||
++pzx->data_ptr;
|
||||
}
|
||||
--pzx->data_bits;
|
||||
|
||||
if (bit) {
|
||||
pzx->data_p = pzx->data_p1;
|
||||
pzx->data_w = 16 + 2 * pzx->data_p0;
|
||||
pzx->data_remain = 0;
|
||||
} else {
|
||||
pzx->data_p = pzx->data_p0;
|
||||
pzx->data_w = 16;
|
||||
pzx->data_remain = 0;
|
||||
}
|
||||
}
|
||||
/* See if we've started processing the current waveform. If not,
|
||||
* load its first element (assuming that there is one) */
|
||||
if (!pzx->data_remain) {
|
||||
if (pzx->data_p) {
|
||||
pzx->data_remain = peek2(pzx->curblock + pzx->data_w);
|
||||
pzx->data_w += 2;
|
||||
pzx->data_p--;
|
||||
}
|
||||
}
|
||||
if (pzx->data_remain > time) {
|
||||
/* Time advance is contained within current wave */
|
||||
pzx->data_remain -= time;
|
||||
return 0;
|
||||
} else { /* Move on to next element of wave / next bit / next block */
|
||||
time -= pzx->data_remain;
|
||||
pzx->data_remain = 0;
|
||||
pzx->level = !pzx->level;
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
int
|
||||
pzx_advance(pzxfile_t *pzx, int time)
|
||||
{
|
||||
if (pzx->state == PZX_CLOSED)
|
||||
return 0; /* No tape loaded */
|
||||
|
||||
while (time) {
|
||||
switch (pzx->state)
|
||||
{
|
||||
case PZX_IDLE:
|
||||
if (!pzx_next_block(pzx)) return 0;
|
||||
break;
|
||||
case PZX_IN_PULS:
|
||||
time = pzx_advance_puls(pzx, time);
|
||||
break;
|
||||
case PZX_IN_PAUS:
|
||||
time = pzx_advance_paus(pzx, time);
|
||||
break;
|
||||
case PZX_IN_DATA:
|
||||
time = pzx_advance_data(pzx, time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pzx->level;
|
||||
}
|
||||
|
||||
|
||||
|
||||
71
src/cassette/pzx.h
Normal file
71
src/cassette/pzx.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/************************************************************************
|
||||
|
||||
PCEM: IBM 5150 cassette support
|
||||
|
||||
Copyright (C) 2019 John Elliott <seasip.webmaster@gmail.com>
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*************************************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PZX_CLOSED, /* File is not open */
|
||||
PZX_IDLE, /* File is open, no block loaded */
|
||||
PZX_IN_PULS, /* File is open, current block is a PULS block */
|
||||
PZX_IN_DATA, /* File is open, current block is a DATA block */
|
||||
PZX_IN_PAUS, /* File is open, current block is a PAUS block */
|
||||
} PZX_STATE;
|
||||
|
||||
|
||||
typedef struct pzxfile_t
|
||||
{
|
||||
FILE *input; /* Input PZX file */
|
||||
uint8_t *curblock; /* Currently-loaded block, if any */
|
||||
int level; /* Current signal level */
|
||||
PZX_STATE state; /* State machine current status */
|
||||
/* State variables for PULS */
|
||||
uint32_t puls_ptr; /* Pointer within PULS block */
|
||||
uint32_t puls_len; /* Length of PULS block */
|
||||
uint32_t puls_count; /* Count of pulses */
|
||||
uint32_t puls_duration; /* Duration of each pulse */
|
||||
uint32_t puls_remain; /* Time remaining in this pulse */
|
||||
/* State variables for PAUS */
|
||||
uint32_t paus_remain; /* Time remaining in this pause */
|
||||
/* State variables for DATA */
|
||||
uint32_t data_ptr; /* Pointer within DATA block */
|
||||
uint32_t data_bits; /* Count of bits */
|
||||
uint16_t data_tail; /* Length of pulse after last bit */
|
||||
uint8_t data_mask; /* Mask for current bit */
|
||||
uint8_t data_p0; /* Length of 0 encoding */
|
||||
uint8_t data_p1; /* Length of 1 encoding */
|
||||
int data_p; /* Current sequence being emitted */
|
||||
uint32_t data_w; /* Current waveform */
|
||||
uint32_t data_remain; /* Current data pulse time remaining */
|
||||
} pzxfile_t;
|
||||
|
||||
uint8_t *pzx_load_block(FILE *fp);
|
||||
|
||||
/* Initialise structure */
|
||||
void pzx_init(pzxfile_t *pzx);
|
||||
|
||||
/* Open file for input */
|
||||
wchar_t *pzx_open(pzxfile_t *pzx, FILE *fp);
|
||||
|
||||
/* Close file */
|
||||
void pzx_close(pzxfile_t *pzx);
|
||||
|
||||
/* Advance by 'time' samples (3.5MHz sample rate) and return current state */
|
||||
int pzx_advance(pzxfile_t *pzx, int time);
|
||||
@@ -359,7 +359,7 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
{
|
||||
uint8_t ret;
|
||||
subchannel_t subc;
|
||||
int pos = 0;
|
||||
int pos = 1;
|
||||
|
||||
dev->ops->get_subchannel(dev, dev->seek_pos, &subc);
|
||||
cdrom_log("CD-ROM %i: Returned subchannel at %02i:%02i.%02i\n", subc.abs_m, subc.abs_s, subc.abs_f);
|
||||
@@ -375,6 +375,9 @@ cdrom_get_current_subchannel(cdrom_t *dev, uint8_t *b, int msf)
|
||||
ret = 0x13;
|
||||
}
|
||||
|
||||
if (b[pos] > 1)
|
||||
return ret;
|
||||
|
||||
b[pos++] = subc.attr;
|
||||
b[pos++] = subc.track;
|
||||
b[pos++] = subc.index;
|
||||
@@ -1003,6 +1006,7 @@ cdrom_hard_reset(void)
|
||||
switch(dev->bus_type) {
|
||||
case CDROM_BUS_ATAPI:
|
||||
case CDROM_BUS_SCSI:
|
||||
case CDROM_BUS_SCSI_CHINON:
|
||||
scsi_cdrom_drive_reset(i);
|
||||
break;
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ enum {
|
||||
CDROM_BUS_DISABLED = 0,
|
||||
CDROM_BUS_ATAPI = 4,
|
||||
CDROM_BUS_SCSI,
|
||||
CDROM_BUS_SCSI_CHINON,
|
||||
CDROM_BUS_USB
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
664
src/cdrom/cdrom_dosbox.cpp.ok
Normal file
664
src/cdrom/cdrom_dosbox.cpp.ok
Normal file
@@ -0,0 +1,664 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2015 The DOSBox Team
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Modified for use with PCem by bit */
|
||||
|
||||
#define _LARGEFILE_SOURCE
|
||||
#define _LARGEFILE64_SOURCE
|
||||
#ifdef _WIN32
|
||||
//FIXME: should not be needed. */
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <limits.h> //GCC 2.95
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <sys/stat.h>
|
||||
#include "../plat.h"
|
||||
#include "cdrom_dosbox.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <libgen.h>
|
||||
#else
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define MAX_LINE_LENGTH 512
|
||||
#define MAX_FILENAME_LENGTH 256
|
||||
#define CROSS_LEN 512
|
||||
|
||||
#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0)
|
||||
|
||||
CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error)
|
||||
{
|
||||
memset(fn, 0, sizeof(fn));
|
||||
strcpy(fn, filename);
|
||||
file = fopen64(fn, "rb");
|
||||
if (file == NULL)
|
||||
error = true;
|
||||
else
|
||||
error = false;
|
||||
}
|
||||
|
||||
CDROM_Interface_Image::BinaryFile::~BinaryFile()
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
memset(fn, 0, sizeof(fn));
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count)
|
||||
{
|
||||
fseeko64(file, seek, SEEK_SET);
|
||||
fread(buffer, 1, count, file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t CDROM_Interface_Image::BinaryFile::getLength()
|
||||
{
|
||||
fseeko64(file, 0, SEEK_END);
|
||||
return ftello64(file);
|
||||
}
|
||||
|
||||
CDROM_Interface_Image::CDROM_Interface_Image()
|
||||
{
|
||||
// printf("CDROM_Interface_Image constructor\n");
|
||||
}
|
||||
|
||||
CDROM_Interface_Image::~CDROM_Interface_Image()
|
||||
{
|
||||
// printf("CDROM_Interface_Image destructor\n");
|
||||
ClearTracks();
|
||||
}
|
||||
|
||||
void CDROM_Interface_Image::InitNewMedia()
|
||||
{
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::SetDevice(char* path, int forceCD)
|
||||
{
|
||||
(void)forceCD;
|
||||
if (LoadCueSheet(path)) return true;
|
||||
if (LoadIsoFile(path)) return true;
|
||||
|
||||
// print error message on dosbox console
|
||||
//printf("Could not load image file: %s\n", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc)
|
||||
{
|
||||
attr = 0;
|
||||
strcpy(upc, this->mcn.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut)
|
||||
{
|
||||
stTrack = 1;
|
||||
end = (int)(tracks.size() - 1);
|
||||
FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr)
|
||||
{
|
||||
if (track < 1 || track > (int)tracks.size()) return false;
|
||||
FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr);
|
||||
track_number = tracks[track - 1].track_number;
|
||||
attr = tracks[track - 1].attr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetAudioTrackEndInfo(int track, int& track_number, TMSF& start, unsigned char& attr)
|
||||
{
|
||||
if (track < 1 || track > (int)tracks.size()) return false;
|
||||
FRAMES_TO_MSF(tracks[track - 1].start + tracks[track - 1].length + 150, &start.min, &start.sec, &start.fr);
|
||||
track_number = tracks[track - 1].track_number;
|
||||
attr = tracks[track - 1].attr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||
{
|
||||
int cur_track = GetTrack(sector);
|
||||
if (cur_track < 1) return false;
|
||||
track = (unsigned char)cur_track;
|
||||
attr = tracks[track - 1].attr;
|
||||
index = 1;
|
||||
FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr);
|
||||
/* FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); */
|
||||
/* Note by Kotori: Yes, the absolute position should be adjusted by 150, but not the relative position. */
|
||||
FRAMES_TO_MSF(sector - tracks[track - 1].start, &relPos.min, &relPos.sec, &relPos.fr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
|
||||
{
|
||||
mediaPresent = true;
|
||||
mediaChanged = false;
|
||||
trayOpen = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
||||
{
|
||||
int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
Bitu buflen = num * sectorSize;
|
||||
Bit8u* buf = new Bit8u[buflen];
|
||||
|
||||
bool success = true; //Gobliiins reads 0 sectors
|
||||
for(unsigned long i = 0; i < num; i++) {
|
||||
success = ReadSector(&buf[i * sectorSize], raw, sector + i);
|
||||
if (!success) break;
|
||||
}
|
||||
|
||||
memcpy((void*)buffer, buf, buflen);
|
||||
delete[] buf;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::LoadUnloadMedia(bool unload)
|
||||
{
|
||||
(void)unload;
|
||||
return true;
|
||||
}
|
||||
|
||||
int CDROM_Interface_Image::GetTrack(unsigned int sector)
|
||||
{
|
||||
vector<Track>::iterator i = tracks.begin();
|
||||
vector<Track>::iterator end = tracks.end() - 1;
|
||||
|
||||
while(i != end) {
|
||||
Track &curr = *i;
|
||||
Track &next = *(i + 1);
|
||||
if (curr.start <= sector && sector < next.start) return curr.number;
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector)
|
||||
{
|
||||
uint64_t length;
|
||||
|
||||
int track = GetTrack(sector) - 1;
|
||||
if (track < 0) return false;
|
||||
|
||||
uint64_t s = (uint64_t) sector;
|
||||
uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize);
|
||||
if (tracks[track].mode2)
|
||||
length = (raw ? RAW_SECTOR_SIZE : 2336);
|
||||
else
|
||||
length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE);
|
||||
if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false;
|
||||
if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16;
|
||||
if (tracks[track].mode2 && !raw) seek += 24;
|
||||
|
||||
return tracks[track].file->read(buffer, seek, length);
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::ReadSectorSub(Bit8u *buffer, unsigned long sector)
|
||||
{
|
||||
int track = GetTrack(sector) - 1;
|
||||
if (track < 0) return false;
|
||||
|
||||
uint64_t s = (uint64_t) sector;
|
||||
uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize);
|
||||
if (tracks[track].sectorSize != 2448) return false;
|
||||
|
||||
return tracks[track].file->read(buffer, seek, 2448);
|
||||
}
|
||||
|
||||
int CDROM_Interface_Image::GetSectorSize(unsigned long sector)
|
||||
{
|
||||
int track = GetTrack(sector) - 1;
|
||||
if (track < 0) return 0;
|
||||
|
||||
return tracks[track].sectorSize;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::IsMode2(unsigned long sector)
|
||||
{
|
||||
int track = GetTrack(sector) - 1;
|
||||
if (track < 0) return false;
|
||||
|
||||
if (tracks[track].mode2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int CDROM_Interface_Image::GetMode2Form(unsigned long sector)
|
||||
{
|
||||
int track = GetTrack(sector) - 1;
|
||||
if (track < 0) return false;
|
||||
|
||||
return tracks[track].form;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::LoadIsoFile(char* filename)
|
||||
{
|
||||
tracks.clear();
|
||||
|
||||
// data track
|
||||
Track track = {0, 0, 0, 0, 0, 0, 0, 0, false, NULL};
|
||||
bool error;
|
||||
track.file = new BinaryFile(filename, error);
|
||||
if (error) {
|
||||
delete track.file;
|
||||
return false;
|
||||
}
|
||||
track.number = 1;
|
||||
track.track_number = 1;//IMPORTANT: This is needed.
|
||||
track.attr = DATA_TRACK;//data
|
||||
track.form = 0;
|
||||
|
||||
// try to detect iso type
|
||||
if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) {
|
||||
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||
track.mode2 = false;
|
||||
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.mode2 = false;
|
||||
} else if (CanReadPVD(track.file, 2324, true)) {
|
||||
track.sectorSize = 2324;
|
||||
track.form = 2;
|
||||
track.mode2 = true;
|
||||
} else if (CanReadPVD(track.file, 2336, true)) {
|
||||
track.sectorSize = 2336;
|
||||
track.mode2 = true;
|
||||
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.mode2 = true;
|
||||
} else {
|
||||
/* Unknown mode: Assume regular 2048-byte sectors, this is needed so Apple Rhapsody ISO's can be mounted. */
|
||||
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||
track.mode2 = false;
|
||||
}
|
||||
|
||||
track.length = track.file->getLength() / track.sectorSize;
|
||||
tracks.push_back(track);
|
||||
|
||||
// leadout track
|
||||
track.number = 2;
|
||||
track.track_number = 0xAA;
|
||||
track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */
|
||||
track.start = track.length;
|
||||
track.length = 0;
|
||||
track.file = NULL;
|
||||
tracks.push_back(track);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2)
|
||||
{
|
||||
Bit8u pvd[COOKED_SECTOR_SIZE];
|
||||
uint64_t seek = 16 * sectorSize; // first vd is located at sector 16
|
||||
if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16;
|
||||
if (mode2) seek += 24;
|
||||
file->read(pvd, seek, COOKED_SECTOR_SIZE);
|
||||
// pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra)
|
||||
return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) ||
|
||||
(pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static string dirname(char * file) {
|
||||
char * sep = strrchr(file, '\\');
|
||||
if (sep == NULL)
|
||||
sep = strrchr(file, '/');
|
||||
if (sep == NULL)
|
||||
return "";
|
||||
else {
|
||||
int len = (int)(sep - file);
|
||||
char tmp[MAX_FILENAME_LENGTH];
|
||||
safe_strncpy(tmp, file, len+1);
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
|
||||
{
|
||||
Track track = {0, 0, 0, 0, 0, 0, 0, 0, false, NULL};
|
||||
tracks.clear();
|
||||
uint64_t shift = 0;
|
||||
uint64_t currPregap = 0;
|
||||
uint64_t totalPregap = 0;
|
||||
uint64_t prestart = 0;
|
||||
bool success;
|
||||
bool canAddTrack = false;
|
||||
char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument
|
||||
safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH);
|
||||
string pathname(dirname(tmp));
|
||||
ifstream in;
|
||||
in.open(cuefile, ios::in);
|
||||
if (in.fail()) return false;
|
||||
|
||||
while(!in.eof()) {
|
||||
// get next line
|
||||
char buf[MAX_LINE_LENGTH];
|
||||
in.getline(buf, MAX_LINE_LENGTH);
|
||||
if (in.fail() && !in.eof()) return false; // probably a binary file
|
||||
istringstream line(buf);
|
||||
|
||||
string command;
|
||||
GetCueKeyword(command, line);
|
||||
|
||||
if (command == "TRACK") {
|
||||
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
|
||||
else success = true;
|
||||
|
||||
track.start = 0;
|
||||
track.skip = 0;
|
||||
currPregap = 0;
|
||||
prestart = 0;
|
||||
|
||||
line >> track.number;
|
||||
track.track_number = track.number;
|
||||
string type;
|
||||
GetCueKeyword(type, line);
|
||||
|
||||
track.form = 0;
|
||||
|
||||
if (type == "AUDIO") {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.attr = AUDIO_TRACK;
|
||||
track.mode2 = false;
|
||||
} else if (type == "MODE1/2048") {
|
||||
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = false;
|
||||
} else if (type == "MODE1/2352") {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = false;
|
||||
} else if (type == "MODE2/2048") {
|
||||
track.form = 1;
|
||||
track.sectorSize = 2048;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else if (type == "MODE2/2324") {
|
||||
track.form = 2;
|
||||
track.sectorSize = 2324;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else if (type == "MODE2/2336") {
|
||||
track.sectorSize = 2336;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else if (type == "MODE2/2352") {
|
||||
track.form = 1; /* Assume this is XA Mode 2 Form 1. */
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else if (type == "CDG/2448") {
|
||||
track.sectorSize = 2448;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else if (type == "CDI/2336") {
|
||||
track.sectorSize = 2336;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else if (type == "CDI/2352") {
|
||||
track.sectorSize = RAW_SECTOR_SIZE;
|
||||
track.attr = DATA_TRACK;
|
||||
track.mode2 = true;
|
||||
} else success = false;
|
||||
|
||||
canAddTrack = true;
|
||||
}
|
||||
else if (command == "INDEX") {
|
||||
uint64_t index;
|
||||
line >> index;
|
||||
uint64_t frame;
|
||||
success = GetCueFrame(frame, line);
|
||||
|
||||
if (index == 1) track.start = frame;
|
||||
else if (index == 0) prestart = frame;
|
||||
// ignore other indices
|
||||
}
|
||||
else if (command == "FILE") {
|
||||
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
|
||||
else success = true;
|
||||
canAddTrack = false;
|
||||
|
||||
string filename;
|
||||
GetCueString(filename, line);
|
||||
GetRealFileName(filename, pathname);
|
||||
string type;
|
||||
GetCueKeyword(type, line);
|
||||
|
||||
track.file = NULL;
|
||||
bool error = true;
|
||||
if (type == "BINARY") {
|
||||
track.file = new BinaryFile(filename.c_str(), error);
|
||||
}
|
||||
if (error) {
|
||||
delete track.file;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
else if (command == "PREGAP") success = GetCueFrame(currPregap, line);
|
||||
else if (command == "CATALOG") success = GetCueString(mcn, line);
|
||||
// ignored commands
|
||||
else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC"
|
||||
|| command == "PERFORMER" || command == "POSTGAP" || command == "REM"
|
||||
|| command == "SONGWRITER" || command == "TITLE" || command == "") success = true;
|
||||
// failure
|
||||
else success = false;
|
||||
|
||||
if (!success) return false;
|
||||
}
|
||||
// add last track
|
||||
if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false;
|
||||
|
||||
// add leadout track
|
||||
track.number++;
|
||||
track.track_number = 0xAA;
|
||||
// track.attr = 0;//sync with load iso
|
||||
track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */
|
||||
// track.attr = last_attr | 0x02;
|
||||
track.start = 0;
|
||||
track.length = 0;
|
||||
track.file = NULL;
|
||||
if(!AddTrack(track, shift, 0, totalPregap, 0)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap)
|
||||
{
|
||||
// frames between index 0(prestart) and 1(curr.start) must be skipped
|
||||
uint64_t skip;
|
||||
if (prestart > 0) {
|
||||
if (prestart > curr.start) return false;
|
||||
skip = curr.start - prestart;
|
||||
} else skip = 0;
|
||||
|
||||
// first track (track number must be 1)
|
||||
if (tracks.empty()) {
|
||||
if (curr.number != 1) return false;
|
||||
curr.skip = skip * curr.sectorSize;
|
||||
curr.start += currPregap;
|
||||
totalPregap = currPregap;
|
||||
tracks.push_back(curr);
|
||||
return true;
|
||||
}
|
||||
|
||||
Track &prev = *(tracks.end() - 1);
|
||||
|
||||
// current track consumes data from the same file as the previous
|
||||
if (prev.file == curr.file) {
|
||||
curr.start += shift;
|
||||
prev.length = curr.start + totalPregap - prev.start - skip;
|
||||
curr.skip += prev.skip + (prev.length * prev.sectorSize) + (skip * curr.sectorSize);
|
||||
totalPregap += currPregap;
|
||||
curr.start += totalPregap;
|
||||
// current track uses a different file as the previous track
|
||||
} else {
|
||||
uint64_t tmp = prev.file->getLength() - ((uint64_t) prev.skip);
|
||||
prev.length = tmp / ((uint64_t) prev.sectorSize);
|
||||
if (tmp % prev.sectorSize != 0) prev.length++; // padding
|
||||
|
||||
curr.start += prev.start + prev.length + currPregap;
|
||||
curr.skip = skip * curr.sectorSize;
|
||||
shift += prev.start + prev.length;
|
||||
totalPregap = currPregap;
|
||||
}
|
||||
|
||||
// error checks
|
||||
if (curr.number <= 1) return false;
|
||||
if (prev.number + 1 != curr.number) return false;
|
||||
if (curr.start < prev.start + prev.length) return false;
|
||||
#if 0
|
||||
/* curr.length is unsigned, so... --FvK */
|
||||
if (curr.length < 0) return false;
|
||||
#endif
|
||||
|
||||
tracks.push_back(curr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::HasDataTrack(void)
|
||||
{
|
||||
//Data track has attribute 0x14
|
||||
for(track_it it = tracks.begin(); it != tracks.end(); it++) {
|
||||
if ((*it).attr == DATA_TRACK) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::HasAudioTracks(void)
|
||||
{
|
||||
for(track_it it = tracks.begin(); it != tracks.end(); it++) {
|
||||
if ((*it).attr == AUDIO_TRACK) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname)
|
||||
{
|
||||
// check if file exists
|
||||
struct stat test;
|
||||
if (stat(filename.c_str(), &test) == 0) return true;
|
||||
|
||||
// check if file with path relative to cue file exists
|
||||
string tmpstr(pathname + "/" + filename);
|
||||
if (stat(tmpstr.c_str(), &test) == 0) {
|
||||
filename = tmpstr;
|
||||
return true;
|
||||
}
|
||||
#if defined (_WIN32) || defined(OS2)
|
||||
//Nothing
|
||||
#else
|
||||
//Consider the possibility that the filename has a windows directory seperator (inside the CUE file)
|
||||
//which is common for some commercial rereleases of DOS games using DOSBox
|
||||
|
||||
string copy = filename;
|
||||
size_t l = copy.size();
|
||||
for (size_t i = 0; i < l;i++) {
|
||||
if(copy[i] == '\\') copy[i] = '/';
|
||||
}
|
||||
|
||||
if (stat(copy.c_str(), &test) == 0) {
|
||||
filename = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
tmpstr = pathname + "/" + copy;
|
||||
if (stat(tmpstr.c_str(), &test) == 0) {
|
||||
filename = tmpstr;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in)
|
||||
{
|
||||
in >> keyword;
|
||||
for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetCueFrame(uint64_t &frames, istream &in)
|
||||
{
|
||||
string msf;
|
||||
in >> msf;
|
||||
int min, sec, fr;
|
||||
bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3;
|
||||
frames = MSF_TO_FRAMES(min, sec, fr);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::GetCueString(string &str, istream &in)
|
||||
{
|
||||
int pos = (int)in.tellg();
|
||||
in >> str;
|
||||
if (str[0] == '\"') {
|
||||
if (str[str.size() - 1] == '\"') {
|
||||
str.assign(str, 1, str.size() - 2);
|
||||
} else {
|
||||
in.seekg(pos, ios::beg);
|
||||
char buffer[MAX_FILENAME_LENGTH];
|
||||
in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip
|
||||
in.getline(buffer, MAX_FILENAME_LENGTH, '\"');
|
||||
str = buffer;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDROM_Interface_Image::ClearTracks()
|
||||
{
|
||||
vector<Track>::iterator i = tracks.begin();
|
||||
vector<Track>::iterator end = tracks.end();
|
||||
|
||||
TrackFile* last = NULL;
|
||||
while(i != end) {
|
||||
Track &curr = *i;
|
||||
if (curr.file != last) {
|
||||
delete curr.file;
|
||||
last = curr.file;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
tracks.clear();
|
||||
}
|
||||
@@ -1,26 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2015 The DOSBox Team
|
||||
* 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 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 file is part of the VARCem Project.
|
||||
*
|
||||
* 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.
|
||||
* Definitions for the CD-ROM image file handling module.
|
||||
*
|
||||
* 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.
|
||||
* Version: @(#)cdrom_dosbox.h 1.0.3 2019/03/05
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* The DOSBox Team, <unknown>
|
||||
*
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2002-2015 The DOSBox Team.
|
||||
*
|
||||
* 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 CDROM_INTERFACE
|
||||
# define CDROM_INTERFACE
|
||||
|
||||
/* Modified for use with PCem by bit */
|
||||
|
||||
#ifndef __CDROM_INTERFACE__
|
||||
#define __CDROM_INTERFACE__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@@ -28,18 +47,17 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <stdint.h>
|
||||
typedef signed int Bits;
|
||||
typedef unsigned int Bitu;
|
||||
typedef int8_t Bit8s;
|
||||
typedef uint8_t Bit8u;
|
||||
typedef int16_t Bit16s;
|
||||
typedef uint16_t Bit16u;
|
||||
typedef int32_t Bit32s;
|
||||
typedef uint32_t Bit32u;
|
||||
//typedef signed int Bits;
|
||||
//typedef unsigned int Bitu;
|
||||
//typedef int8_t Bit8s;
|
||||
//typedef int16_t Bit16s;
|
||||
//typedef uint16_t Bit16u;
|
||||
//typedef int32_t Bit32s;
|
||||
//typedef uint32_t Bit32u;
|
||||
|
||||
typedef size_t PhysPt;
|
||||
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
@@ -48,130 +66,135 @@ typedef size_t PhysPt;
|
||||
|
||||
#define CD_FPS 75
|
||||
#define FRAMES_TO_MSF(f, M,S,F) { \
|
||||
int value = f; \
|
||||
*(F) = value%CD_FPS; \
|
||||
uint64_t value = f; \
|
||||
*(F) = (value%CD_FPS) & 0xff; \
|
||||
value /= CD_FPS; \
|
||||
*(S) = value%60; \
|
||||
*(S) = (value%60) & 0xff; \
|
||||
value /= 60; \
|
||||
*(M) = value; \
|
||||
*(M) = value & 0xff; \
|
||||
}
|
||||
#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F))
|
||||
|
||||
|
||||
typedef struct SMSF {
|
||||
unsigned char min;
|
||||
unsigned char sec;
|
||||
unsigned char fr;
|
||||
uint8_t min;
|
||||
uint8_t sec;
|
||||
uint8_t fr;
|
||||
} TMSF;
|
||||
|
||||
typedef struct SCtrl {
|
||||
Bit8u out[4]; // output channel
|
||||
Bit8u vol[4]; // channel volume
|
||||
uint8_t out[4]; // output channel
|
||||
uint8_t vol[4]; // channel volume
|
||||
} TCtrl;
|
||||
|
||||
extern int CDROM_GetMountType(char* path, int force);
|
||||
|
||||
class CDROM_Interface
|
||||
{
|
||||
class CDROM_Interface {
|
||||
public:
|
||||
// CDROM_Interface (void);
|
||||
virtual ~CDROM_Interface (void) {};
|
||||
// CDROM_Interface(void);
|
||||
|
||||
virtual bool SetDevice (char* path, int forceCD) = 0;
|
||||
virtual ~CDROM_Interface(void) {};
|
||||
|
||||
virtual bool GetUPC (unsigned char& attr, char* upc) = 0;
|
||||
virtual bool SetDevice(const wchar_t *path, int forceCD) = 0;
|
||||
|
||||
virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0;
|
||||
virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0;
|
||||
virtual bool GetAudioTrackEndInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0;
|
||||
virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0;
|
||||
virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0;
|
||||
virtual bool GetUPC(uint8_t& attr, char* upc) = 0;
|
||||
|
||||
virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0;
|
||||
virtual bool GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) = 0;
|
||||
virtual bool GetAudioTrackInfo(int track, int& number, TMSF& start, uint8_t& attr) = 0;
|
||||
virtual bool GetAudioTrackEndInfo(int track, int& number, TMSF& start, unsigned char& attr) = 0;
|
||||
virtual bool GetAudioSub(int sector, uint8_t& attr, uint8_t& track, uint8_t& index, TMSF& relPos, TMSF& absPos) = 0;
|
||||
virtual bool GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0;
|
||||
|
||||
virtual bool LoadUnloadMedia (bool unload) = 0;
|
||||
virtual bool ReadSectors(PhysPt buffer, bool raw, uint32_t sector, uint32_t num) = 0;
|
||||
|
||||
virtual void InitNewMedia (void) {};
|
||||
virtual bool LoadUnloadMedia(bool unload) = 0;
|
||||
|
||||
virtual void InitNewMedia(void) {};
|
||||
};
|
||||
|
||||
class CDROM_Interface_Image : public CDROM_Interface
|
||||
{
|
||||
|
||||
class CDROM_Interface_Image : public CDROM_Interface {
|
||||
private:
|
||||
class TrackFile {
|
||||
class TrackFile {
|
||||
public:
|
||||
virtual bool read(Bit8u *buffer, uint64_t seek, uint64_t count) = 0;
|
||||
virtual bool read(uint8_t *buffer, uint64_t seek, size_t count) = 0;
|
||||
virtual uint64_t getLength() = 0;
|
||||
virtual ~TrackFile() { };
|
||||
};
|
||||
};
|
||||
|
||||
class BinaryFile : public TrackFile {
|
||||
class BinaryFile : public TrackFile {
|
||||
public:
|
||||
BinaryFile(const char *filename, bool &error);
|
||||
BinaryFile(const wchar_t *filename, bool &error);
|
||||
~BinaryFile();
|
||||
bool read(Bit8u *buffer, uint64_t seek, uint64_t count);
|
||||
bool read(uint8_t *buffer, uint64_t seek, size_t count);
|
||||
uint64_t getLength();
|
||||
private:
|
||||
BinaryFile();
|
||||
char fn[260];
|
||||
wchar_t fn[260];
|
||||
FILE *file;
|
||||
};
|
||||
};
|
||||
|
||||
struct Track {
|
||||
int number;
|
||||
int track_number;
|
||||
int attr;
|
||||
int form;
|
||||
uint64_t start;
|
||||
uint64_t length;
|
||||
uint64_t skip;
|
||||
uint64_t sectorSize;
|
||||
bool mode2;
|
||||
TrackFile *file;
|
||||
};
|
||||
struct Track {
|
||||
int number;
|
||||
int track_number;
|
||||
int attr;
|
||||
int form;
|
||||
uint64_t start;
|
||||
uint64_t length;
|
||||
uint64_t skip;
|
||||
int sectorSize;
|
||||
bool mode2;
|
||||
TrackFile *file;
|
||||
};
|
||||
|
||||
public:
|
||||
CDROM_Interface_Image ();
|
||||
virtual ~CDROM_Interface_Image (void);
|
||||
void InitNewMedia (void);
|
||||
bool SetDevice (char* path, int forceCD);
|
||||
bool GetUPC (unsigned char& attr, char* upc);
|
||||
bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut);
|
||||
bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr);
|
||||
bool GetAudioTrackEndInfo (int track, int& number, TMSF& start, unsigned char& attr);
|
||||
bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos);
|
||||
bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
|
||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
bool LoadUnloadMedia (bool unload);
|
||||
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||
bool ReadSectorSub (Bit8u *buffer, unsigned long sector);
|
||||
int GetSectorSize (unsigned long sector);
|
||||
bool IsMode2 (unsigned long sector);
|
||||
int GetMode2Form (unsigned long sector);
|
||||
bool HasDataTrack (void);
|
||||
bool HasAudioTracks (void);
|
||||
CDROM_Interface_Image();
|
||||
virtual ~CDROM_Interface_Image(void);
|
||||
void InitNewMedia(void);
|
||||
bool SetDevice(const wchar_t* path, int forceCD);
|
||||
bool GetUPC(uint8_t& attr, char* upc);
|
||||
bool GetAudioTracks(int& stTrack, int& end, TMSF& leadOut);
|
||||
bool GetAudioTrackInfo(int track, int& number, TMSF& start, uint8_t& attr);
|
||||
bool GetAudioTrackEndInfo(int track, int& number, TMSF& start, unsigned char& attr);
|
||||
bool GetAudioSub(int sector, uint8_t& attr, uint8_t& track, uint8_t& index, TMSF& relPos, TMSF& absPos);
|
||||
bool GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
|
||||
bool ReadSectors(PhysPt buffer, bool raw, uint32_t sector, uint32_t num);
|
||||
bool LoadUnloadMedia(bool unload);
|
||||
bool ReadSector(uint8_t *buffer, bool raw, uint32_t sector);
|
||||
bool ReadSectorSub(uint8_t *buffer, uint32_t sector);
|
||||
int GetSectorSize(uint32_t sector);
|
||||
bool IsMode2(uint32_t sector);
|
||||
int GetMode2Form(uint32_t sector);
|
||||
bool HasDataTrack(void);
|
||||
bool HasAudioTracks(void);
|
||||
|
||||
int GetTrack (unsigned int sector);
|
||||
int GetTrack(unsigned int sector);
|
||||
|
||||
private:
|
||||
// player
|
||||
static void CDAudioCallBack(Bitu len);
|
||||
// player
|
||||
static void CDAudioCallBack(unsigned int len);
|
||||
|
||||
void ClearTracks();
|
||||
bool LoadIsoFile(char *filename);
|
||||
bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2);
|
||||
// cue sheet processing
|
||||
bool LoadCueSheet(char *cuefile);
|
||||
bool GetRealFileName(std::string& filename, std::string& pathname);
|
||||
bool GetCueKeyword(std::string &keyword, std::istream &in);
|
||||
bool GetCueFrame(uint64_t &frames, std::istream &in);
|
||||
bool GetCueString(std::string &str, std::istream &in);
|
||||
bool AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap);
|
||||
void ClearTracks();
|
||||
bool IsoLoadFile(const wchar_t *filename);
|
||||
bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2);
|
||||
|
||||
std::vector<Track> tracks;
|
||||
// cue sheet processing
|
||||
bool CueGetBuffer(char *str, char **line, bool up);
|
||||
bool CueGetString(std::string &str, char **line);
|
||||
bool CueGetKeyword(std::string &keyword, char **line);
|
||||
uint64_t CueGetNumber(char **line);
|
||||
bool CueGetFrame(uint64_t &frames, char **line);
|
||||
bool CueLoadSheet(const wchar_t *cuefile);
|
||||
bool AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap);
|
||||
|
||||
std::vector<Track> tracks;
|
||||
typedef std::vector<Track>::iterator track_it;
|
||||
std::string mcn;
|
||||
std::string mcn;
|
||||
};
|
||||
|
||||
void cdrom_image_log(const char *format, ...);
|
||||
|
||||
extern int CDROM_GetMountType(char* path, int force);
|
||||
|
||||
extern void cdrom_image_log(const char *format, ...);
|
||||
|
||||
|
||||
#endif /* __CDROM_INTERFACE__ */
|
||||
|
||||
177
src/cdrom/cdrom_dosbox.h.ok
Normal file
177
src/cdrom/cdrom_dosbox.h.ok
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2015 The DOSBox Team
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Modified for use with PCem by bit */
|
||||
|
||||
#ifndef __CDROM_INTERFACE__
|
||||
#define __CDROM_INTERFACE__
|
||||
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <stdint.h>
|
||||
typedef signed int Bits;
|
||||
typedef unsigned int Bitu;
|
||||
typedef int8_t Bit8s;
|
||||
typedef uint8_t Bit8u;
|
||||
typedef int16_t Bit16s;
|
||||
typedef uint16_t Bit16u;
|
||||
typedef int32_t Bit32s;
|
||||
typedef uint32_t Bit32u;
|
||||
|
||||
typedef size_t PhysPt;
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
#define DATA_TRACK 0x14
|
||||
#define AUDIO_TRACK 0x10
|
||||
|
||||
#define CD_FPS 75
|
||||
#define FRAMES_TO_MSF(f, M,S,F) { \
|
||||
int value = f; \
|
||||
*(F) = value%CD_FPS; \
|
||||
value /= CD_FPS; \
|
||||
*(S) = value%60; \
|
||||
value /= 60; \
|
||||
*(M) = value; \
|
||||
}
|
||||
#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F))
|
||||
|
||||
|
||||
typedef struct SMSF {
|
||||
unsigned char min;
|
||||
unsigned char sec;
|
||||
unsigned char fr;
|
||||
} TMSF;
|
||||
|
||||
typedef struct SCtrl {
|
||||
Bit8u out[4]; // output channel
|
||||
Bit8u vol[4]; // channel volume
|
||||
} TCtrl;
|
||||
|
||||
extern int CDROM_GetMountType(char* path, int force);
|
||||
|
||||
class CDROM_Interface
|
||||
{
|
||||
public:
|
||||
// CDROM_Interface (void);
|
||||
virtual ~CDROM_Interface (void) {};
|
||||
|
||||
virtual bool SetDevice (char* path, int forceCD) = 0;
|
||||
|
||||
virtual bool GetUPC (unsigned char& attr, char* upc) = 0;
|
||||
|
||||
virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0;
|
||||
virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0;
|
||||
virtual bool GetAudioTrackEndInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0;
|
||||
virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0;
|
||||
virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0;
|
||||
|
||||
virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0;
|
||||
|
||||
virtual bool LoadUnloadMedia (bool unload) = 0;
|
||||
|
||||
virtual void InitNewMedia (void) {};
|
||||
};
|
||||
|
||||
class CDROM_Interface_Image : public CDROM_Interface
|
||||
{
|
||||
private:
|
||||
class TrackFile {
|
||||
public:
|
||||
virtual bool read(Bit8u *buffer, uint64_t seek, uint64_t count) = 0;
|
||||
virtual uint64_t getLength() = 0;
|
||||
virtual ~TrackFile() { };
|
||||
};
|
||||
|
||||
class BinaryFile : public TrackFile {
|
||||
public:
|
||||
BinaryFile(const char *filename, bool &error);
|
||||
~BinaryFile();
|
||||
bool read(Bit8u *buffer, uint64_t seek, uint64_t count);
|
||||
uint64_t getLength();
|
||||
private:
|
||||
BinaryFile();
|
||||
char fn[260];
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
struct Track {
|
||||
int number;
|
||||
int track_number;
|
||||
int attr;
|
||||
int form;
|
||||
uint64_t start;
|
||||
uint64_t length;
|
||||
uint64_t skip;
|
||||
uint64_t sectorSize;
|
||||
bool mode2;
|
||||
TrackFile *file;
|
||||
};
|
||||
|
||||
public:
|
||||
CDROM_Interface_Image ();
|
||||
virtual ~CDROM_Interface_Image (void);
|
||||
void InitNewMedia (void);
|
||||
bool SetDevice (char* path, int forceCD);
|
||||
bool GetUPC (unsigned char& attr, char* upc);
|
||||
bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut);
|
||||
bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr);
|
||||
bool GetAudioTrackEndInfo (int track, int& number, TMSF& start, unsigned char& attr);
|
||||
bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos);
|
||||
bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
|
||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
bool LoadUnloadMedia (bool unload);
|
||||
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||
bool ReadSectorSub (Bit8u *buffer, unsigned long sector);
|
||||
int GetSectorSize (unsigned long sector);
|
||||
bool IsMode2 (unsigned long sector);
|
||||
int GetMode2Form (unsigned long sector);
|
||||
bool HasDataTrack (void);
|
||||
bool HasAudioTracks (void);
|
||||
|
||||
int GetTrack (unsigned int sector);
|
||||
|
||||
private:
|
||||
// player
|
||||
static void CDAudioCallBack(Bitu len);
|
||||
|
||||
void ClearTracks();
|
||||
bool LoadIsoFile(char *filename);
|
||||
bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2);
|
||||
// cue sheet processing
|
||||
bool LoadCueSheet(char *cuefile);
|
||||
bool GetRealFileName(std::string& filename, std::string& pathname);
|
||||
bool GetCueKeyword(std::string &keyword, std::istream &in);
|
||||
bool GetCueFrame(uint64_t &frames, std::istream &in);
|
||||
bool GetCueString(std::string &str, std::istream &in);
|
||||
bool AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap);
|
||||
|
||||
std::vector<Track> tracks;
|
||||
typedef std::vector<Track>::iterator track_it;
|
||||
std::string mcn;
|
||||
};
|
||||
|
||||
void cdrom_image_log(const char *format, ...);
|
||||
|
||||
#endif /* __CDROM_INTERFACE__ */
|
||||
@@ -8,15 +8,15 @@
|
||||
*
|
||||
* CD-ROM image support.
|
||||
*
|
||||
* Version: @(#)cdrom_image.cc 1.0.9 2019/02/01
|
||||
* Version: @(#)cdrom_image.cc 1.0.10 2019/03/06
|
||||
*
|
||||
* Author: RichardG867,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* bit,
|
||||
*
|
||||
* Copyright 2015-2018 Richardg867.
|
||||
* Copyright 2015-2018 Miran Grca.
|
||||
* Copyright 2017,2018 bit.
|
||||
* Copyright 2015-2019 Richardg867.
|
||||
* Copyright 2015-2019 Miran Grca.
|
||||
* Copyright 2017-2019 bit.
|
||||
*/
|
||||
#define __USE_LARGEFILE64
|
||||
#define _LARGEFILE_SOURCE
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../config.h"
|
||||
#include "../plat.h"
|
||||
#include "../scsi/scsi_device.h"
|
||||
@@ -108,7 +110,7 @@ image_get_subchannel(cdrom_t *dev, uint32_t lba, subchannel_t *subc)
|
||||
|
||||
|
||||
static int
|
||||
image_get_last_block(cdrom_t *dev)
|
||||
image_get_capacity(cdrom_t *dev)
|
||||
{
|
||||
CDROM_Interface_Image *img = (CDROM_Interface_Image *)dev->image;
|
||||
int first_track, last_track;
|
||||
@@ -250,7 +252,6 @@ image_open_abort(cdrom_t *dev)
|
||||
int
|
||||
cdrom_image_open(cdrom_t *dev, const wchar_t *fn)
|
||||
{
|
||||
char temp[1024];
|
||||
CDROM_Interface_Image *img;
|
||||
|
||||
wcscpy(dev->image_path, fn);
|
||||
@@ -265,10 +266,8 @@ cdrom_image_open(cdrom_t *dev, const wchar_t *fn)
|
||||
|
||||
dev->image = img;
|
||||
|
||||
/* Convert filename and open the image. */
|
||||
memset(temp, '\0', sizeof(temp));
|
||||
wcstombs(temp, fn, sizeof(temp));
|
||||
if (!img->SetDevice(temp, false))
|
||||
/* Open the image. */
|
||||
if (! img->SetDevice(fn, false))
|
||||
return image_open_abort(dev);
|
||||
|
||||
/* All good, reset state. */
|
||||
@@ -278,7 +277,8 @@ cdrom_image_open(cdrom_t *dev, const wchar_t *fn)
|
||||
dev->cd_status = CD_STATUS_STOPPED;
|
||||
dev->seek_pos = 0;
|
||||
dev->cd_buflen = 0;
|
||||
dev->cdrom_capacity = image_get_last_block(dev) + 1;
|
||||
dev->cdrom_capacity = image_get_capacity(dev);
|
||||
cdrom_image_log("CD-ROM capacity: %i sectors (%i bytes)\n", dev->cdrom_capacity, dev->cdrom_capacity << 11);
|
||||
|
||||
/* Attach this handler to the drive. */
|
||||
dev->ops = &cdrom_image_ops;
|
||||
|
||||
171
src/chipset/acc2168.c
Normal file
171
src/chipset/acc2168.c
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ACC 2168 chipset
|
||||
* used by the Packard Bell Legend 760 Supreme (PB410A or PB430).
|
||||
*
|
||||
* Version: @(#)acc2168.c 1.0.0 2019/05/13
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
*
|
||||
* Copyright 2019 Sarah Walker.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../mouse.h"
|
||||
#include "../port_92.h"
|
||||
#include "../sio.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../video/video.h"
|
||||
#include "../video/vid_ht216.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct acc2168_t
|
||||
{
|
||||
int reg_idx;
|
||||
uint8_t regs[256];
|
||||
uint8_t port_78;
|
||||
} acc2168_t;
|
||||
|
||||
|
||||
static void
|
||||
acc2168_shadow_recalc(acc2168_t *dev)
|
||||
{
|
||||
if (dev->regs[0x02] & 8) {
|
||||
switch (dev->regs[0x02] & 0x30) {
|
||||
case 0x00:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x10:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x20:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 0x30:
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
|
||||
if (dev->regs[0x02] & 4) {
|
||||
switch (dev->regs[0x02] & 0x30) {
|
||||
case 0x00:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x10:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x20:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 0x30:
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
mem_set_mem_state(0xe0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
acc2168_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)p;
|
||||
|
||||
if (!(addr & 1))
|
||||
dev->reg_idx = val;
|
||||
else {
|
||||
dev->regs[dev->reg_idx] = val;
|
||||
|
||||
switch (dev->reg_idx) {
|
||||
case 0x02:
|
||||
acc2168_shadow_recalc(dev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
acc2168_read(uint16_t addr, void *p)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)p;
|
||||
|
||||
if (!(addr & 1))
|
||||
return dev->reg_idx;
|
||||
|
||||
return dev->regs[dev->reg_idx];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Bit 7 = Super I/O chip: 1 = enabled, 0 = disabled;
|
||||
Bit 6 = Graphics card: 1 = standalone, 0 = on-board;
|
||||
Bit 5 = ???? (if 1, siren and hangs).
|
||||
*/
|
||||
static uint8_t
|
||||
acc2168_port_78_read(uint16_t addr, void *p)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)p;
|
||||
|
||||
return dev->port_78;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
acc2168_close(void *priv)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
acc2168_init(const device_t *info)
|
||||
{
|
||||
acc2168_t *dev = (acc2168_t *)malloc(sizeof(acc2168_t));
|
||||
memset(dev, 0, sizeof(acc2168_t));
|
||||
|
||||
io_sethandler(0x00f2, 0x0002,
|
||||
acc2168_read, NULL, NULL, acc2168_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0078, 0x0001,
|
||||
acc2168_port_78_read, NULL, NULL, NULL, NULL, NULL, dev);
|
||||
|
||||
device_add(&port_92_inv_device);
|
||||
|
||||
if (gfxcard != VID_INTERNAL)
|
||||
dev->port_78 = 0x40;
|
||||
else
|
||||
dev->port_78 = 0;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t acc2168_device = {
|
||||
"ACC 2168",
|
||||
0,
|
||||
0,
|
||||
acc2168_init, acc2168_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
97
src/chipset/acer_m3a.c
Normal file
97
src/chipset/acer_m3a.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Acer M3A and V35N ports EAh and EBh.
|
||||
*
|
||||
* Version: @(#)acer_m3a.c 1.0.0 2019/05/13
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "../io.h"
|
||||
#include "../rom.h"
|
||||
#include "../pci.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int index;
|
||||
} acerm3a_t;
|
||||
|
||||
|
||||
static void
|
||||
acerm3a_out(uint16_t port, uint8_t val, void *p)
|
||||
{
|
||||
acerm3a_t *dev = (acerm3a_t *) p;
|
||||
|
||||
if (port == 0xea)
|
||||
dev->index = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
acerm3a_in(uint16_t port, void *p)
|
||||
{
|
||||
acerm3a_t *dev = (acerm3a_t *) p;
|
||||
|
||||
if (port == 0xeb) {
|
||||
switch (dev->index) {
|
||||
case 2:
|
||||
return 0xfd;
|
||||
}
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
acerm3a_close(void *p)
|
||||
{
|
||||
acerm3a_t *dev = (acerm3a_t *)p;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*acerm3a_init(const device_t *info)
|
||||
{
|
||||
acerm3a_t *acerm3a = (acerm3a_t *) malloc(sizeof(acerm3a_t));
|
||||
memset(acerm3a, 0, sizeof(acerm3a_t));
|
||||
|
||||
io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, acerm3a);
|
||||
|
||||
return acerm3a;
|
||||
}
|
||||
|
||||
|
||||
const device_t acerm3a_device =
|
||||
{
|
||||
"Acer M3A Register",
|
||||
0,
|
||||
0,
|
||||
acerm3a_init,
|
||||
acerm3a_close,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
146
src/chipset/ali1429.c
Normal file
146
src/chipset/ali1429.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the ALi M-1429/1431 chipset.
|
||||
*
|
||||
* Version: @(#)ali1429.c 1.0.8 2019/04/08
|
||||
*
|
||||
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../timer.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../disk/hdc_ide.h"
|
||||
#include "../timer.h"
|
||||
#include "../port_92.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cur_reg,
|
||||
regs[256];
|
||||
} ali1429_t;
|
||||
|
||||
|
||||
static void
|
||||
ali1429_recalc(ali1429_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
|
||||
if (dev->regs[0x13] & (1 << i)) {
|
||||
shadowbios |= (base >= 0xe8000) && !!(dev->regs[0x14] & 0x01);
|
||||
shadowbios_write |= (base >= 0xe8000) && !!(dev->regs[0x14] & 0x02);
|
||||
shflags = (dev->regs[0x14] & 0x01) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL;
|
||||
shflags |= !(dev->regs[0x14] & 0x02) ? MEM_WRITE_EXTERNAL : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *) priv;
|
||||
|
||||
if (port & 1) {
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
|
||||
switch (dev->cur_reg) {
|
||||
case 0x13:
|
||||
ali1429_recalc(dev);
|
||||
break;
|
||||
case 0x14:
|
||||
ali1429_recalc(dev);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
dev->cur_reg = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
ali1429_read(uint16_t port, void *priv)
|
||||
{
|
||||
uint8_t ret = 0xff;
|
||||
ali1429_t *dev = (ali1429_t *) priv;
|
||||
|
||||
if (!(port & 1))
|
||||
ret = dev->cur_reg;
|
||||
else if (((dev->cur_reg >= 0xc0) || (dev->cur_reg == 0x20)) && cpu_iscyrix)
|
||||
ret = 0xff; /*Don't conflict with Cyrix config registers*/
|
||||
else
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ali1429_close(void *priv)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ali1429_init(const device_t *info)
|
||||
{
|
||||
ali1429_t *dev = (ali1429_t *) malloc(sizeof(ali1429_t));
|
||||
memset(dev, 0, sizeof(ali1429_t));
|
||||
|
||||
memset(dev->regs, 0xff, 256);
|
||||
dev->regs[0x13] = dev->regs[0x14] = 0x00;
|
||||
|
||||
io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, dev);
|
||||
|
||||
ali1429_recalc(dev);
|
||||
|
||||
device_add(&port_92_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t ali1429_device = {
|
||||
"ALi-M1429",
|
||||
0,
|
||||
0,
|
||||
ali1429_init, ali1429_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
68
src/chipset/chipset.h
Normal file
68
src/chipset/chipset.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Handling of the emulated chipsets.
|
||||
*
|
||||
* Version: @(#)machine.h 1.0.0 2019/05/13
|
||||
*
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#ifndef EMU_CHIPSET_H
|
||||
# define EMU_CHIPSET_H
|
||||
|
||||
|
||||
/* ACC */
|
||||
extern const device_t acc2168_device;
|
||||
|
||||
/* Acer M3A and V35N */
|
||||
extern const device_t acerm3a_device;
|
||||
|
||||
/* ALi */
|
||||
extern const device_t ali1429_device;
|
||||
|
||||
/* Headland */
|
||||
extern const device_t headland_device;
|
||||
extern const device_t headland_386_device;
|
||||
|
||||
/* Intel 4x0xX */
|
||||
extern const device_t i420tx_device;
|
||||
extern const device_t i430lx_device;
|
||||
extern const device_t i430nx_device;
|
||||
extern const device_t i430fx_device;
|
||||
extern const device_t i430fx_pb640_device;
|
||||
extern const device_t i430hx_device;
|
||||
extern const device_t i430vx_device;
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
extern const device_t i440fx_device;
|
||||
#endif
|
||||
|
||||
/* NEAT */
|
||||
extern const device_t neat_device;
|
||||
|
||||
/* OPTi */
|
||||
extern const device_t opti495_device;
|
||||
|
||||
/* SCAT */
|
||||
extern const device_t scat_device;
|
||||
extern const device_t scat_4_device;
|
||||
extern const device_t scat_sx_device;
|
||||
|
||||
/* SiS */
|
||||
extern const device_t sis_85c471_device;
|
||||
extern const device_t sis_85c496_device;
|
||||
#if defined(DEV_BRANCH) && defined(USE_SIS_85C50X)
|
||||
extern const device_t sis_85c50x_device;
|
||||
#endif
|
||||
|
||||
/* WD */
|
||||
extern const device_t wd76c10_device;
|
||||
|
||||
|
||||
#endif /*EMU_CHIPSET_H*/
|
||||
635
src/chipset/headland.c
Normal file
635
src/chipset/headland.c
Normal file
@@ -0,0 +1,635 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the HEADLAND AT286 chipset.
|
||||
*
|
||||
* Version: @(#)headland.c 1.0.0 2019/05/14
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Original by GreatPsycho for PCem.
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2010-2019 Sarah Walker.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2017,2018 Miran Grca.
|
||||
* Copyright 2017,2018 GreatPsycho.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../cpu/x86.h"
|
||||
#include "../timer.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../port_92.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t valid, pad;
|
||||
uint16_t mr;
|
||||
|
||||
struct headland_t * headland;
|
||||
} headland_mr_t;
|
||||
|
||||
|
||||
typedef struct headland_t {
|
||||
uint8_t type;
|
||||
|
||||
uint8_t cri;
|
||||
uint8_t cr[8];
|
||||
|
||||
uint8_t indx;
|
||||
uint8_t regs[256];
|
||||
|
||||
uint8_t ems_mar;
|
||||
|
||||
headland_mr_t null_mr,
|
||||
ems_mr[64];
|
||||
|
||||
rom_t vid_bios;
|
||||
|
||||
mem_mapping_t low_mapping;
|
||||
mem_mapping_t ems_mapping[64];
|
||||
mem_mapping_t mid_mapping;
|
||||
mem_mapping_t high_mapping;
|
||||
mem_mapping_t upper_mapping[24];
|
||||
} headland_t;
|
||||
|
||||
|
||||
/* TODO - Headland chipset's memory address mapping emulation isn't fully implemented yet,
|
||||
so memory configuration is hardcoded now. */
|
||||
static const int mem_conf_cr0[41] = {
|
||||
0x00, 0x00, 0x20, 0x40, 0x60, 0xA0, 0x40, 0xE0,
|
||||
0xA0, 0xC0, 0xE0, 0xE0, 0xC0, 0xE0, 0xE0, 0xE0,
|
||||
0xE0, 0x20, 0x40, 0x40, 0xA0, 0xC0, 0xE0, 0xE0,
|
||||
0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
|
||||
0x20, 0x40, 0x60, 0x60, 0xC0, 0xE0, 0xE0, 0xE0,
|
||||
0xE0
|
||||
};
|
||||
static const int mem_conf_cr1[41] = {
|
||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40,
|
||||
0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
|
||||
0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40
|
||||
};
|
||||
|
||||
|
||||
static uint32_t
|
||||
get_addr(headland_t *dev, uint32_t addr, headland_mr_t *mr)
|
||||
{
|
||||
if (mr && mr->valid && (dev->cr[0] & 2) && (mr->mr & 0x200)) {
|
||||
addr = (addr & 0x3fff) | ((mr->mr & 0x1F) << 14);
|
||||
if (dev->cr[1] & 0x40) {
|
||||
if ((dev->cr[4] & 0x80) && (dev->cr[6] & 1)) {
|
||||
if (dev->cr[0] & 0x80) {
|
||||
addr |= (mr->mr & 0x60) << 14;
|
||||
if (mr->mr & 0x100)
|
||||
addr += ((mr->mr & 0xC00) << 13) + (((mr->mr & 0x80) + 0x80) << 15);
|
||||
else
|
||||
addr += (mr->mr & 0x80) << 14;
|
||||
} else if (mr->mr & 0x100)
|
||||
addr += ((mr->mr & 0xC00) << 13) + (((mr->mr & 0x80) + 0x20) << 15);
|
||||
else
|
||||
addr += (mr->mr & 0x80) << 12;
|
||||
} else if (dev->cr[0] & 0x80)
|
||||
addr |= (mr->mr & 0x100) ? ((mr->mr & 0x80) + 0x400) << 12 : (mr->mr & 0xE0) << 14;
|
||||
else
|
||||
addr |= (mr->mr & 0x100) ? ((mr->mr & 0xE0) + 0x40) << 14 : (mr->mr & 0x80) << 12;
|
||||
} else {
|
||||
if ((dev->cr[4] & 0x80) && (dev->cr[6] & 1)) {
|
||||
if (dev->cr[0] & 0x80) {
|
||||
addr |= ((mr->mr & 0x60) << 14);
|
||||
if (mr->mr & 0x180)
|
||||
addr += ((mr->mr & 0xC00) << 13) + (((mr->mr & 0x180) - 0x60) << 16);
|
||||
} else
|
||||
addr |= ((mr->mr & 0x60) << 14) | ((mr->mr & 0x180) << 16) | ((mr->mr & 0xC00) << 13);
|
||||
} else if (dev->cr[0] & 0x80)
|
||||
addr |= (mr->mr & 0x1E0) << 14;
|
||||
else
|
||||
addr |= (mr->mr & 0x180) << 12;
|
||||
}
|
||||
} else if ((mr == NULL) && ((dev->cr[0] & 4) == 0) && (mem_size >= 1024) && (addr >= 0x100000))
|
||||
addr -= 0x60000;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_global_EMS_state(headland_t *dev, int state)
|
||||
{
|
||||
uint32_t base_addr, virt_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
base_addr = (i + 16) << 14;
|
||||
if (i >= 24)
|
||||
base_addr += 0x20000;
|
||||
if ((state & 2) && (dev->ems_mr[((state & 1) << 5) | i].mr & 0x200)) {
|
||||
virt_addr = get_addr(dev, base_addr, &dev->ems_mr[((state & 1) << 5) | i]);
|
||||
if (i < 24)
|
||||
mem_mapping_disable(&dev->upper_mapping[i]);
|
||||
mem_mapping_disable(&dev->ems_mapping[(((state ^ 1) & 1) << 5) | i]);
|
||||
mem_mapping_enable(&dev->ems_mapping[((state & 1) << 5) | i]);
|
||||
if (virt_addr < ((uint32_t)mem_size << 10))
|
||||
mem_mapping_set_exec(&dev->ems_mapping[((state & 1) << 5) | i], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[((state & 1) << 5) | i], NULL);
|
||||
} else {
|
||||
mem_mapping_set_exec(&dev->ems_mapping[((state & 1) << 5) | i], ram + base_addr);
|
||||
mem_mapping_disable(&dev->ems_mapping[(((state ^ 1) & 1) << 5) | i]);
|
||||
mem_mapping_disable(&dev->ems_mapping[((state & 1) << 5) | i]);
|
||||
if (i < 24)
|
||||
mem_mapping_enable(&dev->upper_mapping[i]);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
memmap_state_update(headland_t *dev)
|
||||
{
|
||||
uint32_t addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
addr = get_addr(dev, 0x40000 + (i << 14), NULL);
|
||||
mem_mapping_set_exec(&dev->upper_mapping[i], addr < ((uint32_t)mem_size << 10) ? ram + addr : NULL);
|
||||
}
|
||||
mem_set_mem_state(0xA0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
if (mem_size > 640) {
|
||||
if ((dev->cr[0] & 4) == 0) {
|
||||
mem_mapping_set_addr(&dev->mid_mapping, 0x100000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
mem_mapping_set_exec(&dev->mid_mapping, ram + 0xA0000);
|
||||
if (mem_size > 1024) {
|
||||
mem_mapping_set_addr(&dev->high_mapping, 0x160000, (mem_size - 1024) << 10);
|
||||
mem_mapping_set_exec(&dev->high_mapping, ram + 0x100000);
|
||||
}
|
||||
} else {
|
||||
mem_mapping_set_addr(&dev->mid_mapping, 0xA0000, mem_size > 1024 ? 0x60000 : (mem_size - 640) << 10);
|
||||
mem_mapping_set_exec(&dev->mid_mapping, ram + 0xA0000);
|
||||
if (mem_size > 1024) {
|
||||
mem_mapping_set_addr(&dev->high_mapping, 0x100000, (mem_size - 1024) << 10);
|
||||
mem_mapping_set_exec(&dev->high_mapping, ram + 0x100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_global_EMS_state(dev, dev->cr[0] & 3);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hl_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
headland_t *dev = (headland_t *)priv;
|
||||
uint32_t base_addr, virt_addr;
|
||||
uint8_t old_val, indx;
|
||||
|
||||
switch(addr) {
|
||||
case 0x0022:
|
||||
dev->indx = val;
|
||||
break;
|
||||
|
||||
case 0x0023:
|
||||
old_val = dev->regs[dev->indx];
|
||||
if ((dev->indx == 0xc1) && !is486)
|
||||
val = 0;
|
||||
dev->regs[dev->indx] = val;
|
||||
if (dev->indx == 0x82) {
|
||||
shadowbios = val & 0x10;
|
||||
shadowbios_write = !(val & 0x10);
|
||||
if (shadowbios)
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
} else if (dev->indx == 0x87) {
|
||||
if ((val & 1) && !(old_val & 1))
|
||||
softresetx86();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x01ec:
|
||||
dev->ems_mr[dev->ems_mar & 0x3f].mr = val | 0xff00;
|
||||
indx = dev->ems_mar & 0x1f;
|
||||
base_addr = (indx + 16) << 14;
|
||||
if (indx >= 24)
|
||||
base_addr += 0x20000;
|
||||
if ((dev->cr[0] & 2) && ((dev->cr[0] & 1) == ((dev->ems_mar & 0x20) >> 5))) {
|
||||
virt_addr = get_addr(dev, base_addr, &dev->ems_mr[dev->ems_mar & 0x3F]);
|
||||
if (indx < 24)
|
||||
mem_mapping_disable(&dev->upper_mapping[indx]);
|
||||
if (virt_addr < ((uint32_t)mem_size << 10))
|
||||
mem_mapping_set_exec(&dev->ems_mapping[dev->ems_mar & 0x3f], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[dev->ems_mar & 0x3f], NULL);
|
||||
mem_mapping_enable(&dev->ems_mapping[dev->ems_mar & 0x3f]);
|
||||
flushmmucache();
|
||||
}
|
||||
if (dev->ems_mar & 0x80)
|
||||
dev->ems_mar++;
|
||||
break;
|
||||
|
||||
case 0x01ed:
|
||||
dev->cri = val;
|
||||
break;
|
||||
|
||||
case 0x01ee:
|
||||
dev->ems_mar = val;
|
||||
break;
|
||||
|
||||
case 0x01ef:
|
||||
old_val = dev->cr[dev->cri];
|
||||
switch(dev->cri) {
|
||||
case 0:
|
||||
dev->cr[0] = (val & 0x1f) | mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
mem_set_mem_state(0xe0000, 0x10000, (val & 8 ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED);
|
||||
mem_set_mem_state(0xf0000, 0x10000, (val & 0x10 ? MEM_READ_INTERNAL: MEM_READ_EXTERNAL) | MEM_WRITE_DISABLED);
|
||||
memmap_state_update(dev);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
dev->cr[1] = (val & 0xbf) | mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
memmap_state_update(dev);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
case 5:
|
||||
dev->cr[dev->cri] = val;
|
||||
memmap_state_update(dev);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
dev->cr[4] = (dev->cr[4] & 0xf0) | (val & 0x0f);
|
||||
if (val & 1) {
|
||||
mem_mapping_set_addr(&bios_mapping, 0x000f0000, 0x10000);
|
||||
mem_mapping_set_exec(&bios_mapping, &(rom[0x10000]));
|
||||
} else {
|
||||
mem_mapping_set_addr(&bios_mapping, 0x000e0000, 0x20000);
|
||||
mem_mapping_set_exec(&bios_mapping, rom);
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (dev->cr[4] & 0x80) {
|
||||
dev->cr[dev->cri] = (val & 0xfe) | (mem_size > 8192 ? 1 : 0);
|
||||
memmap_state_update(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hl_writew(uint16_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
headland_t *dev = (headland_t *)priv;
|
||||
uint32_t base_addr, virt_addr;
|
||||
uint8_t indx;
|
||||
|
||||
switch(addr) {
|
||||
case 0x01ec:
|
||||
dev->ems_mr[dev->ems_mar & 0x3f].mr = val;
|
||||
indx = dev->ems_mar & 0x1f;
|
||||
base_addr = (indx + 16) << 14;
|
||||
if (indx >= 24)
|
||||
base_addr += 0x20000;
|
||||
if ((dev->cr[0] & 2) && (dev->cr[0] & 1) == ((dev->ems_mar & 0x20) >> 5)) {
|
||||
if (val & 0x200) {
|
||||
virt_addr = get_addr(dev, base_addr, &dev->ems_mr[dev->ems_mar & 0x3f]);
|
||||
if (indx < 24)
|
||||
mem_mapping_disable(&dev->upper_mapping[indx]);
|
||||
if (virt_addr < ((uint32_t)mem_size << 10))
|
||||
mem_mapping_set_exec(&dev->ems_mapping[dev->ems_mar & 0x3f], ram + virt_addr);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->ems_mapping[dev->ems_mar & 0x3f], NULL);
|
||||
mem_mapping_enable(&dev->ems_mapping[dev->ems_mar & 0x3f]);
|
||||
} else {
|
||||
mem_mapping_set_exec(&dev->ems_mapping[dev->ems_mar & 0x3f], ram + base_addr);
|
||||
mem_mapping_disable(&dev->ems_mapping[dev->ems_mar & 0x3f]);
|
||||
if (indx < 24)
|
||||
mem_mapping_enable(&dev->upper_mapping[indx]);
|
||||
}
|
||||
flushmmucache();
|
||||
}
|
||||
if (dev->ems_mar & 0x80)
|
||||
dev->ems_mar++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
hl_read(uint16_t addr, void *priv)
|
||||
{
|
||||
headland_t *dev = (headland_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x0022:
|
||||
ret = dev->indx;
|
||||
break;
|
||||
|
||||
case 0x0023:
|
||||
if ((dev->indx >= 0xc0 || dev->indx == 0x20) && cpu_iscyrix)
|
||||
ret = 0xff; /*Don't conflict with Cyrix config registers*/
|
||||
else
|
||||
ret = dev->regs[dev->indx];
|
||||
break;
|
||||
|
||||
case 0x01ec:
|
||||
ret = (uint8_t)dev->ems_mr[dev->ems_mar & 0x3f].mr;
|
||||
if (dev->ems_mar & 0x80)
|
||||
dev->ems_mar++;
|
||||
break;
|
||||
|
||||
case 0x01ed:
|
||||
ret = dev->cri;
|
||||
break;
|
||||
|
||||
case 0x01ee:
|
||||
ret = dev->ems_mar;
|
||||
break;
|
||||
|
||||
case 0x01ef:
|
||||
switch(dev->cri) {
|
||||
case 0:
|
||||
ret = (dev->cr[0] & 0x1f) | mem_conf_cr0[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ret = (dev->cr[1] & 0xbf) | mem_conf_cr1[(mem_size > 640 ? mem_size : mem_size - 128) >> 9];
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (dev->cr[4] & 0x80)
|
||||
ret = (dev->cr[6] & 0xfe) | (mem_size > 8192 ? 1 : 0);
|
||||
else
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = dev->cr[dev->cri];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
hl_readw(uint16_t addr, void *priv)
|
||||
{
|
||||
headland_t *dev = (headland_t *)priv;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x01ec:
|
||||
ret = dev->ems_mr[dev->ems_mar & 0x3f].mr | ((dev->cr[4] & 0x80) ? 0xf000 : 0xfc00);
|
||||
if (dev->ems_mar & 0x80)
|
||||
dev->ems_mar++;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
mem_read_b(uint32_t addr, void *priv)
|
||||
{
|
||||
headland_mr_t *mr = (headland_mr_t *) priv;
|
||||
headland_t *dev = mr->headland;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
addr = get_addr(dev, addr, mr);
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
ret = ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
mem_read_w(uint32_t addr, void *priv)
|
||||
{
|
||||
headland_mr_t *mr = (headland_mr_t *) priv;
|
||||
headland_t *dev = mr->headland;
|
||||
uint16_t ret = 0xffff;
|
||||
|
||||
addr = get_addr(dev, addr, mr);
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
ret = *(uint16_t *)&ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
mem_read_l(uint32_t addr, void *priv)
|
||||
{
|
||||
headland_mr_t *mr = (headland_mr_t *) priv;
|
||||
headland_t *dev = mr->headland;
|
||||
uint32_t ret = 0xffffffff;
|
||||
|
||||
addr = get_addr(dev, addr, mr);
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
ret = *(uint32_t *)&ram[addr];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_b(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
headland_mr_t *mr = (headland_mr_t *) priv;
|
||||
headland_t *dev = mr->headland;
|
||||
|
||||
addr = get_addr(dev, addr, mr);
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_w(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
headland_mr_t *mr = (headland_mr_t *) priv;
|
||||
headland_t *dev = mr->headland;
|
||||
|
||||
addr = get_addr(dev, addr, mr);
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
*(uint16_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mem_write_l(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
headland_mr_t *mr = (headland_mr_t *) priv;
|
||||
headland_t *dev = mr->headland;
|
||||
|
||||
addr = get_addr(dev, addr, mr);
|
||||
if (addr < ((uint32_t)mem_size << 10))
|
||||
*(uint32_t *)&ram[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
headland_close(void *priv)
|
||||
{
|
||||
headland_t *dev = (headland_t *)priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
headland_init(const device_t *info)
|
||||
{
|
||||
headland_t *dev;
|
||||
int ht386;
|
||||
uint32_t i;
|
||||
|
||||
dev = (headland_t *) malloc(sizeof(headland_t));
|
||||
memset(dev, 0x00, sizeof(headland_t));
|
||||
dev->type = info->local;
|
||||
|
||||
ht386 = (dev->type == 32) ? 1 : 0;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
dev->cr[i] = 0x00;
|
||||
dev->cr[0] = 0x04;
|
||||
|
||||
if (ht386) {
|
||||
dev->cr[4] = 0x20;
|
||||
|
||||
device_add(&port_92_inv_device);
|
||||
} else
|
||||
dev->cr[4] = 0x00;
|
||||
|
||||
io_sethandler(0x01ec, 1,
|
||||
hl_read,hl_readw,NULL, hl_write,hl_writew,NULL, dev);
|
||||
|
||||
io_sethandler(0x01ed, 3, hl_read,NULL,NULL, hl_write,NULL,NULL, dev);
|
||||
|
||||
dev->ems_mr[i].valid = 0;
|
||||
dev->ems_mr[i].mr = 0xff;
|
||||
dev->ems_mr[i].headland = dev;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
dev->ems_mr[i].valid = 1;
|
||||
dev->ems_mr[i].mr = 0x00;
|
||||
dev->ems_mr[i].headland = dev;
|
||||
}
|
||||
|
||||
/* Turn off mem.c mappings. */
|
||||
mem_mapping_disable(&ram_low_mapping);
|
||||
mem_mapping_disable(&ram_mid_mapping);
|
||||
mem_mapping_disable(&ram_high_mapping);
|
||||
|
||||
mem_mapping_add(&dev->low_mapping, 0, 0x40000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
ram, MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
|
||||
if (mem_size > 640) {
|
||||
mem_mapping_add(&dev->mid_mapping, 0xa0000, 0x60000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
ram + 0xa0000, MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
mem_mapping_enable(&dev->mid_mapping);
|
||||
}
|
||||
|
||||
if (mem_size > 1024) {
|
||||
mem_mapping_add(&dev->high_mapping, 0x100000, ((mem_size-1024)*1024),
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
ram + 0x100000, MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
mem_mapping_enable(&dev->high_mapping);
|
||||
}
|
||||
|
||||
for (i = 0; i < 24; i++) {
|
||||
mem_mapping_add(&dev->upper_mapping[i],
|
||||
0x40000 + (i << 14), 0x4000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
mem_size > 256 + (i << 4) ? ram + 0x40000 + (i << 14) : NULL,
|
||||
MEM_MAPPING_INTERNAL, &dev->null_mr);
|
||||
mem_mapping_enable(&dev->upper_mapping[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
dev->ems_mr[i].mr = 0x00;
|
||||
mem_mapping_add(&dev->ems_mapping[i],
|
||||
((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14, 0x04000,
|
||||
mem_read_b, mem_read_w, mem_read_l,
|
||||
mem_write_b, mem_write_w, mem_write_l,
|
||||
ram + (((i & 31) + ((i & 31) >= 24 ? 24 : 16)) << 14),
|
||||
0, &dev->ems_mr[i]);
|
||||
}
|
||||
|
||||
memmap_state_update(dev);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t headland_device = {
|
||||
"Headland 286",
|
||||
0,
|
||||
0,
|
||||
headland_init, headland_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const device_t headland_386_device = {
|
||||
"Headland 386",
|
||||
0,
|
||||
32,
|
||||
headland_init, headland_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
433
src/chipset/intel_4x0.c
Normal file
433
src/chipset/intel_4x0.c
Normal file
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the Intel PCISet chips from 420TX to 440FX.
|
||||
*
|
||||
* Version: @(#)intel_4x0.c 1.0.0 2019/05/13
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "../io.h"
|
||||
#include "../rom.h"
|
||||
#include "../pci.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
INTEL_420TX,
|
||||
INTEL_430LX,
|
||||
INTEL_430NX,
|
||||
INTEL_430FX,
|
||||
INTEL_430FX_PB640,
|
||||
INTEL_430HX,
|
||||
INTEL_430VX
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
,INTEL_440FX
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t regs[256];
|
||||
int type;
|
||||
} i4x0_t;
|
||||
static void
|
||||
i4x0_map(uint32_t addr, uint32_t size, int state)
|
||||
{
|
||||
switch (state & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(addr, size, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(addr, size, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i4x0_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
i4x0_t *dev = (i4x0_t *) priv;
|
||||
|
||||
if (func)
|
||||
return;
|
||||
|
||||
if ((addr >= 0x10) && (addr < 0x4f))
|
||||
return;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
case 0x0c: case 0x0e:
|
||||
return;
|
||||
|
||||
case 0x04: /*Command register*/
|
||||
if (dev->type >= INTEL_430FX) {
|
||||
if (dev->type == INTEL_430FX_PB640)
|
||||
val &= 0x06;
|
||||
else
|
||||
val &= 0x02;
|
||||
} else
|
||||
val &= 0x42;
|
||||
val |= 0x04;
|
||||
break;
|
||||
case 0x05:
|
||||
if (dev->type >= INTEL_430FX)
|
||||
val = 0;
|
||||
else
|
||||
val &= 0x01;
|
||||
break;
|
||||
|
||||
case 0x06: /*Status*/
|
||||
val = 0;
|
||||
break;
|
||||
case 0x07:
|
||||
if (dev->type >= INTEL_430HX) {
|
||||
val &= 0x80;
|
||||
val |= 0x02;
|
||||
} else {
|
||||
val = 0x02;
|
||||
if (dev->type == INTEL_430FX_PB640)
|
||||
val |= 0x20;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x59: /*PAM0*/
|
||||
if ((dev->regs[0x59] ^ val) & 0xf0) {
|
||||
i4x0_map(0xf0000, 0x10000, val >> 4);
|
||||
shadowbios = (val & 0x10);
|
||||
}
|
||||
break;
|
||||
case 0x5a: /*PAM1*/
|
||||
if ((dev->regs[0x5a] ^ val) & 0x0f)
|
||||
i4x0_map(0xc0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5a] ^ val) & 0xf0)
|
||||
i4x0_map(0xc4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5b: /*PAM2*/
|
||||
if ((dev->regs[0x5b] ^ val) & 0x0f)
|
||||
i4x0_map(0xc8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5b] ^ val) & 0xf0)
|
||||
i4x0_map(0xcc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5c: /*PAM3*/
|
||||
if ((dev->regs[0x5c] ^ val) & 0x0f)
|
||||
i4x0_map(0xd0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5c] ^ val) & 0xf0)
|
||||
i4x0_map(0xd4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5d: /*PAM4*/
|
||||
if ((dev->regs[0x5d] ^ val) & 0x0f)
|
||||
i4x0_map(0xd8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5d] ^ val) & 0xf0)
|
||||
i4x0_map(0xdc000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5e: /*PAM5*/
|
||||
if ((dev->regs[0x5e] ^ val) & 0x0f)
|
||||
i4x0_map(0xe0000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5e] ^ val) & 0xf0)
|
||||
i4x0_map(0xe4000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x5f: /*PAM6*/
|
||||
if ((dev->regs[0x5f] ^ val) & 0x0f)
|
||||
i4x0_map(0xe8000, 0x04000, val & 0xf);
|
||||
if ((dev->regs[0x5f] ^ val) & 0xf0)
|
||||
i4x0_map(0xec000, 0x04000, val >> 4);
|
||||
break;
|
||||
case 0x72: /*SMRAM*/
|
||||
if ((dev->type >= INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x48))
|
||||
i4x0_map(0xa0000, 0x20000, ((val & 0x48) == 0x48) ? 3 : 0);
|
||||
else if ((dev->type < INTEL_430FX) && ((dev->regs[0x72] ^ val) & 0x20))
|
||||
i4x0_map(0xa0000, 0x20000, ((val & 0x20) == 0x20) ? 3 : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
i4x0_read(int func, int addr, void *priv)
|
||||
{
|
||||
i4x0_t *dev = (i4x0_t *) priv;
|
||||
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return dev->regs[addr];
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i4x0_reset(void *priv)
|
||||
{
|
||||
i4x0_t *i4x0 = (i4x0_t *)priv;
|
||||
|
||||
i4x0_write(0, 0x59, 0x00, priv);
|
||||
if (i4x0->type >= INTEL_430FX)
|
||||
i4x0_write(0, 0x72, 0x02, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
i4x0_close(void *p)
|
||||
{
|
||||
i4x0_t *i4x0 = (i4x0_t *)p;
|
||||
|
||||
free(i4x0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
*i4x0_init(const device_t *info)
|
||||
{
|
||||
i4x0_t *i4x0 = (i4x0_t *) malloc(sizeof(i4x0_t));
|
||||
memset(i4x0, 0, sizeof(i4x0_t));
|
||||
|
||||
i4x0->type = info->local;
|
||||
|
||||
i4x0->regs[0x00] = 0x86; i4x0->regs[0x01] = 0x80; /*Intel*/
|
||||
switch(i4x0->type) {
|
||||
case INTEL_420TX:
|
||||
i4x0->regs[0x02] = 0x83; i4x0->regs[0x03] = 0x04; /*82424TX/ZX*/
|
||||
i4x0->regs[0x08] = 0x03; /*A3 stepping*/
|
||||
i4x0->regs[0x50] = 0x80;
|
||||
i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/
|
||||
break;
|
||||
case INTEL_430LX:
|
||||
i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/
|
||||
i4x0->regs[0x08] = 0x03; /*A3 stepping*/
|
||||
i4x0->regs[0x50] = 0x80;
|
||||
i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/
|
||||
break;
|
||||
case INTEL_430NX:
|
||||
i4x0->regs[0x02] = 0xa3; i4x0->regs[0x03] = 0x04; /*82434LX/NX*/
|
||||
i4x0->regs[0x08] = 0x10; /*A0 stepping*/
|
||||
i4x0->regs[0x50] = 0xA0;
|
||||
i4x0->regs[0x52] = 0x44; /*256kb PLB cache*/
|
||||
i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02;
|
||||
break;
|
||||
case INTEL_430FX:
|
||||
case INTEL_430FX_PB640:
|
||||
i4x0->regs[0x02] = 0x2d; i4x0->regs[0x03] = 0x12; /*SB82437FX-66*/
|
||||
if (i4x0->type == INTEL_430FX_PB640)
|
||||
i4x0->regs[0x08] = 0x02; /*???? stepping*/
|
||||
else
|
||||
i4x0->regs[0x08] = 0x00; /*A0 stepping*/
|
||||
i4x0->regs[0x52] = 0x40; /*256kb PLB cache*/
|
||||
break;
|
||||
case INTEL_430HX:
|
||||
i4x0->regs[0x02] = 0x50; i4x0->regs[0x03] = 0x12; /*82439HX*/
|
||||
i4x0->regs[0x08] = 0x00; /*A0 stepping*/
|
||||
i4x0->regs[0x51] = 0x20;
|
||||
i4x0->regs[0x52] = 0xB5; /*512kb cache*/
|
||||
i4x0->regs[0x56] = 0x52; /*DRAM control*/
|
||||
i4x0->regs[0x59] = 0x40;
|
||||
i4x0->regs[0x5A] = i4x0->regs[0x5B] = i4x0->regs[0x5C] = i4x0->regs[0x5D] = 0x44;
|
||||
i4x0->regs[0x5E] = i4x0->regs[0x5F] = 0x44;
|
||||
i4x0->regs[0x65] = i4x0->regs[0x66] = i4x0->regs[0x67] = 0x02;
|
||||
i4x0->regs[0x68] = 0x11;
|
||||
break;
|
||||
case INTEL_430VX:
|
||||
i4x0->regs[0x02] = 0x30; i4x0->regs[0x03] = 0x70; /*82437VX*/
|
||||
i4x0->regs[0x08] = 0x00; /*A0 stepping*/
|
||||
i4x0->regs[0x52] = 0x42; /*256kb PLB cache*/
|
||||
i4x0->regs[0x53] = 0x14;
|
||||
i4x0->regs[0x56] = 0x52; /*DRAM control*/
|
||||
i4x0->regs[0x67] = 0x11;
|
||||
i4x0->regs[0x69] = 0x03;
|
||||
i4x0->regs[0x70] = 0x20;
|
||||
i4x0->regs[0x74] = 0x0e;
|
||||
i4x0->regs[0x78] = 0x23;
|
||||
break;
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
case INTEL_440FX:
|
||||
i4x0->regs[0x02] = 0x37; i4x0->regs[0x03] = 0x12; /*82441FX*/
|
||||
i4x0->regs[0x08] = 0x02; /*A0 stepping*/
|
||||
i4x0->regs[0x2c] = 0xf4;
|
||||
i4x0->regs[0x2d] = 0x1a;
|
||||
i4x0->regs[0x2f] = 0x11;
|
||||
i4x0->regs[0x51] = 0x01;
|
||||
i4x0->regs[0x53] = 0x80;
|
||||
i4x0->regs[0x58] = 0x10;
|
||||
i4x0->regs[0x5a] = i4x0->regs[0x5b] = i4x0->regs[0x5c] = i4x0->regs[0x5d] = 0x11;
|
||||
i4x0->regs[0x5e] = 0x11;
|
||||
i4x0->regs[0x5f] = 0x31;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
i4x0->regs[0x04] = 0x06; i4x0->regs[0x05] = 0x00;
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
if (i4x0->type == INTEL_440FX)
|
||||
i4x0->regs[0x06] = 0x80;
|
||||
#endif
|
||||
if (i4x0->type == INTEL_430FX)
|
||||
i4x0->regs[0x07] = 0x82;
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
else if (i4x0->type != INTEL_440FX)
|
||||
#else
|
||||
else
|
||||
#endif
|
||||
i4x0->regs[0x07] = 0x02;
|
||||
i4x0->regs[0x0b] = 0x06;
|
||||
if (i4x0->type >= INTEL_430FX)
|
||||
i4x0->regs[0x57] = 0x01;
|
||||
else
|
||||
i4x0->regs[0x57] = 0x31;
|
||||
i4x0->regs[0x60] = i4x0->regs[0x61] = i4x0->regs[0x62] = i4x0->regs[0x63] = 0x02;
|
||||
i4x0->regs[0x64] = 0x02;
|
||||
if (i4x0->type >= INTEL_430FX)
|
||||
i4x0->regs[0x72] = 0x02;
|
||||
|
||||
pci_add_card(0, i4x0_read, i4x0_write, i4x0);
|
||||
|
||||
return i4x0;
|
||||
}
|
||||
|
||||
|
||||
const device_t i420tx_device =
|
||||
{
|
||||
"Intel 82424TX",
|
||||
DEVICE_PCI,
|
||||
INTEL_420TX,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t i430lx_device =
|
||||
{
|
||||
"Intel 82434LX",
|
||||
DEVICE_PCI,
|
||||
INTEL_430LX,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t i430nx_device =
|
||||
{
|
||||
"Intel 82434NX",
|
||||
DEVICE_PCI,
|
||||
INTEL_430NX,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t i430fx_device =
|
||||
{
|
||||
"Intel SB82437FX-66",
|
||||
DEVICE_PCI,
|
||||
INTEL_430FX,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t i430fx_pb640_device =
|
||||
{
|
||||
"Intel SB82437FX-66 (PB640)",
|
||||
DEVICE_PCI,
|
||||
INTEL_430FX_PB640,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t i430hx_device =
|
||||
{
|
||||
"Intel 82439HX",
|
||||
DEVICE_PCI,
|
||||
INTEL_430HX,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
const device_t i430vx_device =
|
||||
{
|
||||
"Intel 82437VX",
|
||||
DEVICE_PCI,
|
||||
INTEL_430VX,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_I686)
|
||||
const device_t i440fx_device =
|
||||
{
|
||||
"Intel 82441FX",
|
||||
DEVICE_PCI,
|
||||
INTEL_440FX,
|
||||
i4x0_init,
|
||||
i4x0_close,
|
||||
i4x0_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* 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.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the VARCem Project.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of C&T CS8121 ("NEAT") 82C206/211/212/215 chipset.
|
||||
*
|
||||
@@ -18,38 +18,7 @@
|
||||
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2018 Fred N. van Kempen.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
* following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the entire
|
||||
* above notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names
|
||||
* of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -57,13 +26,14 @@
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../timer.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../nmi.h"
|
||||
#include "machine.h"
|
||||
#include "chipset.h"
|
||||
|
||||
#define NEAT_DEBUG 0
|
||||
|
||||
@@ -259,6 +229,7 @@ typedef struct {
|
||||
emspage_t ems[EMS_MAXPAGE]; /* EMS page registers */
|
||||
} neat_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
int neat_do_log = ENABLE_NEAT_LOG;
|
||||
|
||||
@@ -279,6 +250,7 @@ neat_log(const char *fmt, ...)
|
||||
#define neat_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
/* Read one byte from paged RAM. */
|
||||
static uint8_t
|
||||
ems_readb(uint32_t addr, void *priv)
|
||||
@@ -442,7 +414,9 @@ ems_init(neat_t *dev, int en)
|
||||
ems_read,NULL,NULL, ems_write,NULL,NULL, dev);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_NEAT_LOG
|
||||
neat_log("NEAT: EMS disabled\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -666,9 +640,10 @@ neat_write(uint16_t port, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
dev->ems_pages = (dev->ems_size << 10) / EMS_PGSIZE;
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN)
|
||||
if (dev->regs[REG_RB7] & RB7_EMSEN) {
|
||||
neat_log("NEAT: EMS %iKB (%i pages)\n",
|
||||
dev->ems_size, dev->ems_pages);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -708,10 +683,17 @@ neat_read(uint16_t port, void *priv)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
neat_init(void)
|
||||
neat_close(void *priv)
|
||||
{
|
||||
neat_t *dev = (neat_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
neat_init(const device_t *info)
|
||||
{
|
||||
neat_t *dev;
|
||||
int i;
|
||||
@@ -857,34 +839,23 @@ neat_init(void)
|
||||
default:
|
||||
neat_log("NEAT: **INVALID DRAM SIZE %iKB !**\n", mem_size);
|
||||
}
|
||||
if (i > 0)
|
||||
if (i > 0) {
|
||||
neat_log("NEAT: using DRAM mode #%i (mem=%iKB)\n", i, mem_size);
|
||||
}
|
||||
|
||||
/* Set up an I/O handler for the chipset. */
|
||||
io_sethandler(0x0022, 2,
|
||||
neat_read,NULL,NULL, neat_write,NULL,NULL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_neat_init(const machine_t *model)
|
||||
{
|
||||
machine_at_init(model);
|
||||
|
||||
neat_init();
|
||||
|
||||
device_add(&fdc_at_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_neat_ami_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
|
||||
neat_init();
|
||||
|
||||
device_add(&keyboard_at_ami_device);
|
||||
|
||||
device_add(&fdc_at_device);
|
||||
}
|
||||
const device_t neat_device = {
|
||||
"C&T CS8121 (NEAT)",
|
||||
0,
|
||||
0,
|
||||
neat_init, neat_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
@@ -254,94 +254,116 @@ SeeAlso: #P0178,#P0187
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../timer.h"
|
||||
#include "../io.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../mem.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "machine.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
static uint8_t optiregs[0x10];
|
||||
static int optireg;
|
||||
|
||||
|
||||
static void opti495_write(uint16_t addr, uint8_t val, void *p)
|
||||
typedef struct
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x22:
|
||||
optireg=val;
|
||||
break;
|
||||
case 0x24:
|
||||
if (optireg>=0x20 && optireg<=0x2C)
|
||||
{
|
||||
optiregs[optireg-0x20]=val;
|
||||
if (optireg == 0x21)
|
||||
{
|
||||
cpu_cache_ext_enabled = val & 0x10;
|
||||
cpu_update_waitstates();
|
||||
}
|
||||
if (optireg == 0x22)
|
||||
{
|
||||
shadowbios = !(val & 0x80);
|
||||
shadowbios_write = val & 0x80;
|
||||
if (shadowbios)
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
uint8_t cur_reg,
|
||||
regs[16],
|
||||
scratch[2];
|
||||
} opti495_t;
|
||||
|
||||
|
||||
static void
|
||||
opti495_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
opti495_t *dev = (opti495_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x22:
|
||||
dev->cur_reg = val;
|
||||
break;
|
||||
case 0x24:
|
||||
if ((dev->cur_reg >= 0x20) && (dev->cur_reg <= 0x2C)) {
|
||||
dev->regs[dev->cur_reg - 0x20] = val;
|
||||
if (dev->cur_reg == 0x21) {
|
||||
cpu_cache_ext_enabled = val & 0x10;
|
||||
cpu_update_waitstates();
|
||||
}
|
||||
if (dev->cur_reg == 0x22) {
|
||||
if (!(val & 0x80))
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED);
|
||||
else
|
||||
mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
dev->scratch[addr - 0xe1] = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t opti495_read(uint16_t addr, void *p)
|
||||
static uint8_t
|
||||
opti495_read(uint16_t addr, void *priv)
|
||||
{
|
||||
switch (addr)
|
||||
{
|
||||
case 0x24:
|
||||
if (optireg>=0x20 && optireg<=0x2C) return optiregs[optireg-0x20];
|
||||
break;
|
||||
}
|
||||
return 0xFF;
|
||||
uint8_t ret = 0xff;
|
||||
opti495_t *dev = (opti495_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x24:
|
||||
if ((dev->cur_reg >= 0x20) && (dev->cur_reg <= 0x2C))
|
||||
ret = dev->regs[dev->cur_reg - 0x20];
|
||||
break;
|
||||
case 0xe1:
|
||||
case 0xe2:
|
||||
ret = dev->scratch[addr - 0xe1];
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void opti495_init(void)
|
||||
static void
|
||||
opti495_close(void *priv)
|
||||
{
|
||||
io_sethandler(0x0022, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0024, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL);
|
||||
optiregs[0x22-0x20] = 0x80;
|
||||
opti495_t *dev = (opti495_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_opti495_init(const machine_t *model)
|
||||
static void *
|
||||
opti495_init(const device_t *info)
|
||||
{
|
||||
machine_at_common_ide_init(model);
|
||||
opti495_t *dev = (opti495_t *) malloc(sizeof(opti495_t));
|
||||
memset(dev, 0, sizeof(opti495_t));
|
||||
|
||||
device_add(&keyboard_at_device);
|
||||
device_add(&fdc_at_device);
|
||||
io_sethandler(0x0022, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev);
|
||||
io_sethandler(0x0024, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev);
|
||||
|
||||
opti495_init();
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
io_sethandler(0x00e1, 0x0002, opti495_read, NULL, NULL, opti495_write, NULL, NULL, dev);
|
||||
|
||||
dev->regs[0x22 - 0x20] = 0x80;
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_opti495_ami_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_ide_init(model);
|
||||
|
||||
device_add(&keyboard_at_ami_device);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
opti495_init();
|
||||
}
|
||||
const device_t opti495_device = {
|
||||
"OPTi 82C495",
|
||||
0,
|
||||
0,
|
||||
opti495_init, opti495_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
1630
src/chipset/scat.c
Normal file
1630
src/chipset/scat.c
Normal file
File diff suppressed because it is too large
Load Diff
1642
src/chipset/scat_varcem.c
Normal file
1642
src/chipset/scat_varcem.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,16 +4,20 @@
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Emulation of the SiS 85c471 chip.
|
||||
*
|
||||
* SiS sis85c471 Super I/O Chip
|
||||
* Used by DTK PKM-0038S E-2
|
||||
*
|
||||
* Version: @(#)m_at_sis85c471.c 1.0.13 2018/11/12
|
||||
* Version: @(#)sis_85c471.c 1.0.0 2019/05/13
|
||||
*
|
||||
* Author: Miran Grca, <mgrca8@gmail.com>
|
||||
* Authors: Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
*
|
||||
* Copyright 2015-2018 Miran Grca.
|
||||
* Copyright 2019 Miran Grca.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -21,64 +25,115 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "../io.h"
|
||||
#include "../memregs.h"
|
||||
#include "../device.h"
|
||||
#include "../lpt.h"
|
||||
#include "../serial.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "../rom.h"
|
||||
#include "../pci.h"
|
||||
#include "../device.h"
|
||||
#include "../disk/hdc_ide.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "machine.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../timer.h"
|
||||
#include "../port_92.h"
|
||||
#include "../serial.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t cur_reg,
|
||||
regs[39];
|
||||
serial_t *uart[2];
|
||||
uint8_t cur_reg,
|
||||
regs[39],
|
||||
scratch[2];
|
||||
port_92_t * port_92;
|
||||
} sis_85c471_t;
|
||||
|
||||
|
||||
static void
|
||||
sis_85c471_recalcmapping(sis_85c471_t *dev)
|
||||
{
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
|
||||
if ((i > 5) || (dev->regs[0x02] & (1 << i))) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->regs[0x02] & 0x80);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->regs[0x02] & 0x40);
|
||||
shflags = (dev->regs[0x02] & 0x80) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL;
|
||||
shflags |= (dev->regs[0x02] & 0x40) ? MEM_WRITE_EXTERNAL : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c471_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c471_t *dev = (sis_85c471_t *) priv;
|
||||
uint8_t index = (port & 1) ? 0 : 1;
|
||||
uint8_t valxor;
|
||||
uint8_t valxor = 0x00;
|
||||
|
||||
if (index) {
|
||||
if (port == 0x22) {
|
||||
if ((val >= 0x50) && (val <= 0x76))
|
||||
dev->cur_reg = val;
|
||||
return;
|
||||
} else {
|
||||
} else if (port == 0x23) {
|
||||
if ((dev->cur_reg < 0x50) || (dev->cur_reg > 0x76))
|
||||
return;
|
||||
valxor = val ^ dev->regs[dev->cur_reg - 0x50];
|
||||
/* Writes to 0x52 are blocked as otherwise, large hard disks don't read correctly. */
|
||||
if (dev->cur_reg != 0x52)
|
||||
dev->regs[dev->cur_reg - 0x50] = val;
|
||||
dev->regs[dev->cur_reg - 0x50] = val;
|
||||
} else if ((port == 0xe1) || (port == 0xe2)) {
|
||||
dev->scratch[port - 0xe1] = val;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(dev->cur_reg) {
|
||||
case 0x73:
|
||||
if (valxor & 0x40) {
|
||||
ide_pri_disable();
|
||||
if (val & 0x40)
|
||||
ide_pri_enable();
|
||||
case 0x52:
|
||||
sis_85c471_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x57:
|
||||
if (valxor & 0x12)
|
||||
port_92_set_features(dev->port_92, !!(val & 0x10), !!(val & 0x02));
|
||||
|
||||
if (valxor & 0x08) {
|
||||
if (val & 0x08)
|
||||
port_92_set_period(dev->port_92, 6ULL * TIMER_USEC);
|
||||
else
|
||||
port_92_set_period(dev->port_92, 2ULL * TIMER_USEC);
|
||||
}
|
||||
if (valxor & 0x20) {
|
||||
serial_remove(dev->uart[0]);
|
||||
serial_remove(dev->uart[1]);
|
||||
if (val & 0x20) {
|
||||
serial_setup(dev->uart[0], SERIAL1_ADDR, SERIAL1_IRQ);
|
||||
serial_setup(dev->uart[0], SERIAL2_ADDR, SERIAL2_IRQ);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5b:
|
||||
if (valxor & 0x02) {
|
||||
if (val & 0x02)
|
||||
mem_remap_top(0);
|
||||
else
|
||||
mem_remap_top(256);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x63:
|
||||
if (valxor & 0x10) {
|
||||
lpt1_remove();
|
||||
if (val & 0x10)
|
||||
lpt1_init(0x378);
|
||||
if (dev->regs[0x13] & 0x10)
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x72:
|
||||
if (valxor & 0x01) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x01)
|
||||
port_92_add(dev->port_92);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -91,17 +146,19 @@ static uint8_t
|
||||
sis_85c471_read(uint16_t port, void *priv)
|
||||
{
|
||||
sis_85c471_t *dev = (sis_85c471_t *) priv;
|
||||
uint8_t index = (port & 1) ? 0 : 1;
|
||||
uint8_t ret = 0xff;;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (index)
|
||||
if (port == 0x22)
|
||||
ret = dev->cur_reg;
|
||||
else {
|
||||
else if (port == 0x23) {
|
||||
if ((dev->cur_reg >= 0x50) && (dev->cur_reg <= 0x76)) {
|
||||
ret = dev->regs[dev->cur_reg - 0x50];
|
||||
if (dev->cur_reg == 0x58)
|
||||
ret &= 0xf7;
|
||||
dev->cur_reg = 0;
|
||||
}
|
||||
}
|
||||
} else if ((port == 0xe1) || (port == 0xe2))
|
||||
ret = dev->scratch[port - 0xe1];
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -124,8 +181,6 @@ sis_85c471_init(const device_t *info)
|
||||
sis_85c471_t *dev = (sis_85c471_t *) malloc(sizeof(sis_85c471_t));
|
||||
memset(dev, 0, sizeof(sis_85c471_t));
|
||||
|
||||
lpt2_remove();
|
||||
|
||||
dev->cur_reg = 0;
|
||||
for (i = 0; i < 0x27; i++)
|
||||
dev->regs[i] = 0x00;
|
||||
@@ -199,15 +254,27 @@ sis_85c471_init(const device_t *info)
|
||||
|
||||
dev->regs[0x11] = 9;
|
||||
dev->regs[0x12] = 0xFF;
|
||||
dev->regs[0x1f] = 0x20; /* Video access enabled. */
|
||||
dev->regs[0x23] = 0xF0;
|
||||
dev->regs[0x26] = 1;
|
||||
|
||||
dev->uart[0] = device_add_inst(&i8250_device, 1);
|
||||
dev->uart[1] = device_add_inst(&i8250_device, 2);
|
||||
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].rspeed < 25000000)
|
||||
dev->regs[0x08] |= 0x80;
|
||||
|
||||
io_sethandler(0x0022, 0x0002,
|
||||
sis_85c471_read, NULL, NULL, sis_85c471_write, NULL, NULL, dev);
|
||||
|
||||
dev->scratch[0] = dev->scratch[1] = 0xff;
|
||||
|
||||
io_sethandler(0x00e1, 0x0002,
|
||||
sis_85c471_read, NULL, NULL, sis_85c471_write, NULL, NULL, dev);
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
port_92_set_period(dev->port_92, 2ULL * TIMER_USEC);
|
||||
port_92_set_features(dev->port_92, 0, 0);
|
||||
|
||||
sis_85c471_recalcmapping(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -220,14 +287,3 @@ const device_t sis_85c471_device = {
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
machine_at_dtk486_init(const machine_t *model)
|
||||
{
|
||||
machine_at_ide_init(model);
|
||||
device_add(&fdc_at_device);
|
||||
|
||||
memregs_init();
|
||||
device_add(&sis_85c471_device);
|
||||
}
|
||||
@@ -8,13 +8,12 @@
|
||||
*
|
||||
* Implementation of the SiS 85c496/85c497 chip.
|
||||
*
|
||||
* Version: @(#)m_at_sis_85c496.c 1.0.3 2018/11/05
|
||||
* Version: @(#)sis_85c496.c 1.0.0 2019/05/13
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
@@ -22,22 +21,25 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "../io.h"
|
||||
#include "../rom.h"
|
||||
#include "../pci.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../io.h"
|
||||
#include "../pci.h"
|
||||
#include "../mem.h"
|
||||
#include "../memregs.h"
|
||||
#include "../sio.h"
|
||||
#include "../disk/hdc.h"
|
||||
#include "machine.h"
|
||||
#include "../timer.h"
|
||||
#include "../port_92.h"
|
||||
#include "../disk/hdc_ide.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct sis_85c496_t
|
||||
{
|
||||
uint8_t cur_reg,
|
||||
regs[39],
|
||||
pci_conf[256];
|
||||
uint8_t cur_reg,
|
||||
regs[127],
|
||||
pci_conf[256];
|
||||
port_92_t * port_92;
|
||||
} sis_85c496_t;
|
||||
|
||||
|
||||
@@ -48,18 +50,14 @@ sis_85c497_write(uint16_t port, uint8_t val, void *priv)
|
||||
uint8_t index = (port & 1) ? 0 : 1;
|
||||
|
||||
if (index) {
|
||||
if ((val >= 0x50) && (val <= 0x76))
|
||||
if ((val != 0x01) || ((val >= 0x70) && (val <= 0x76)))
|
||||
dev->cur_reg = val;
|
||||
return;
|
||||
} else {
|
||||
if ((dev->cur_reg < 0x50) || (dev->cur_reg > 0x76))
|
||||
if (((dev->cur_reg < 0x70) && (dev->cur_reg != 0x01)) || (dev->cur_reg > 0x76))
|
||||
return;
|
||||
/* Writes to 0x52 are blocked as otherwise, large hard disks don't read correctly. */
|
||||
if (dev->cur_reg != 0x52)
|
||||
dev->regs[dev->cur_reg - 0x50] = val;
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
dev->cur_reg = 0;
|
||||
}
|
||||
|
||||
dev->cur_reg = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +71,8 @@ sis_85c497_read(uint16_t port, void *priv)
|
||||
if (index)
|
||||
ret = dev->cur_reg;
|
||||
else {
|
||||
if ((dev->cur_reg >= 0x50) && (dev->cur_reg <= 0x76)) {
|
||||
ret = dev->regs[dev->cur_reg - 0x50];
|
||||
if ((dev->cur_reg != 0x01) || ((dev->cur_reg >= 0x70) && (dev->cur_reg <= 0x76))) {
|
||||
ret = dev->regs[dev->cur_reg];
|
||||
dev->cur_reg = 0;
|
||||
}
|
||||
}
|
||||
@@ -86,51 +84,115 @@ sis_85c497_read(uint16_t port, void *priv)
|
||||
static void
|
||||
sis_85c496_recalcmapping(sis_85c496_t *dev)
|
||||
{
|
||||
int c;
|
||||
uint32_t base;
|
||||
uint32_t i, shflags = 0;
|
||||
|
||||
for (c = 0; c < 8; c++) {
|
||||
base = 0xc0000 + (c << 15);
|
||||
if (dev->pci_conf[0x44] & (1 << c)) {
|
||||
switch (dev->pci_conf[0x45] & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
shadowbios = 0;
|
||||
shadowbios_write = 0;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
base = 0xc0000 + (i << 15);
|
||||
|
||||
if (dev->pci_conf[0x44] & (1 << i)) {
|
||||
shadowbios |= (base >= 0xe0000) && (dev->pci_conf[0x45] & 0x02);
|
||||
shadowbios_write |= (base >= 0xe0000) && !(dev->pci_conf[0x45] & 0x01);
|
||||
shflags = (dev->pci_conf[0x45] & 0x02) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL;
|
||||
shflags |= (dev->pci_conf[0x45] & 0x01) ? MEM_WRITE_EXTERNAL : MEM_WRITE_INTERNAL;
|
||||
mem_set_mem_state(base, 0x8000, shflags);
|
||||
} else
|
||||
mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
shadowbios = (dev->pci_conf[0x44] & 0xf0);
|
||||
}
|
||||
|
||||
|
||||
/* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */
|
||||
static void
|
||||
sis_85c496_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
uint8_t old = dev->pci_conf[addr];
|
||||
uint8_t valxor;
|
||||
|
||||
if ((addr >= 4 && addr < 8) || addr >= 0x40)
|
||||
dev->pci_conf[addr] = val;
|
||||
|
||||
valxor = old ^ val;
|
||||
|
||||
switch (addr) {
|
||||
case 0x44: /*Shadow configure*/
|
||||
if ((dev->pci_conf[0x44] & val) ^ 0xf0) {
|
||||
dev->pci_conf[0x44] = val;
|
||||
if (valxor & 0xff)
|
||||
sis_85c496_recalcmapping(dev);
|
||||
}
|
||||
break;
|
||||
case 0x45: /*Shadow configure*/
|
||||
if ((dev->pci_conf[0x45] & val) ^ 0x01) {
|
||||
dev->pci_conf[0x45] = val;
|
||||
if (valxor & 0x03)
|
||||
sis_85c496_recalcmapping(dev);
|
||||
break;
|
||||
|
||||
case 0x56:
|
||||
if (valxor & 0x02) {
|
||||
port_92_remove(dev->port_92);
|
||||
if (val & 0x02)
|
||||
port_92_add(dev->port_92);
|
||||
pclog("Port 92: %sabled\n", (val & 0x02) ? "En" : "Dis");
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x59:
|
||||
if (valxor & 0x02) {
|
||||
if (val & 0x02) {
|
||||
ide_set_base(0, 0x0170);
|
||||
ide_set_side(0, 0x0376);
|
||||
ide_set_base(1, 0x01f0);
|
||||
ide_set_side(1, 0x03f6);
|
||||
} else {
|
||||
ide_set_base(0, 0x01f0);
|
||||
ide_set_side(0, 0x03f6);
|
||||
ide_set_base(1, 0x0170);
|
||||
ide_set_side(1, 0x0376);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x58:
|
||||
if (valxor & 0x80) {
|
||||
if (dev->pci_conf[0x59] & 0x02) {
|
||||
ide_sec_disable();
|
||||
if (val & 0x80)
|
||||
ide_sec_enable();
|
||||
} else {
|
||||
ide_pri_disable();
|
||||
if (val & 0x80)
|
||||
ide_pri_enable();
|
||||
}
|
||||
}
|
||||
if (valxor & 0x40) {
|
||||
if (dev->pci_conf[0x59] & 0x02) {
|
||||
ide_pri_disable();
|
||||
if (val & 0x40)
|
||||
ide_pri_enable();
|
||||
} else {
|
||||
ide_sec_disable();
|
||||
if (val & 0x40)
|
||||
ide_sec_enable();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5a:
|
||||
if (valxor & 0x04) {
|
||||
if (val & 0x04)
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
else
|
||||
mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x67:
|
||||
if (valxor & 0x60) {
|
||||
port_92_set_features(dev->port_92, !!(val & 0x20), !!(val & 0x40));
|
||||
pclog("[Port 92] Set features: %sreset, %sA20\n", !!(val & 0x20) ? "" : "no ", !!(val & 0x40) ? "" : "no ");
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -163,9 +225,6 @@ sis_85c496_write(int func, int addr, uint8_t val, void *priv)
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((addr >= 4 && addr < 8) || addr >= 0x40)
|
||||
dev->pci_conf[addr] = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -174,6 +233,13 @@ sis_85c496_read(int func, int addr, void *priv)
|
||||
{
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
|
||||
switch (addr) {
|
||||
case 0x82: /*Port 22h Mirror*/
|
||||
return inb(0x22);
|
||||
case 0x70: /*Port 70h Mirror*/
|
||||
return inb(0x70);
|
||||
}
|
||||
|
||||
return dev->pci_conf[addr];
|
||||
}
|
||||
|
||||
@@ -181,85 +247,11 @@ sis_85c496_read(int func, int addr, void *priv)
|
||||
static void
|
||||
sis_85c497_reset(sis_85c496_t *dev)
|
||||
{
|
||||
int mem_size_mb, i = 0;
|
||||
|
||||
memset(dev->regs, 0, sizeof(dev->regs));
|
||||
|
||||
dev->cur_reg = 0;
|
||||
for (i = 0; i < 0x27; i++)
|
||||
dev->regs[i] = 0x00;
|
||||
|
||||
dev->regs[9] = 0x40;
|
||||
|
||||
mem_size_mb = mem_size >> 10;
|
||||
switch (mem_size_mb) {
|
||||
case 0: case 1:
|
||||
dev->regs[9] |= 0;
|
||||
break;
|
||||
case 2: case 3:
|
||||
dev->regs[9] |= 1;
|
||||
break;
|
||||
case 4:
|
||||
dev->regs[9] |= 2;
|
||||
break;
|
||||
case 5:
|
||||
dev->regs[9] |= 0x20;
|
||||
break;
|
||||
case 6: case 7:
|
||||
dev->regs[9] |= 9;
|
||||
break;
|
||||
case 8: case 9:
|
||||
dev->regs[9] |= 4;
|
||||
break;
|
||||
case 10: case 11:
|
||||
dev->regs[9] |= 5;
|
||||
break;
|
||||
case 12: case 13: case 14: case 15:
|
||||
dev->regs[9] |= 0xB;
|
||||
break;
|
||||
case 16:
|
||||
dev->regs[9] |= 0x13;
|
||||
break;
|
||||
case 17:
|
||||
dev->regs[9] |= 0x21;
|
||||
break;
|
||||
case 18: case 19:
|
||||
dev->regs[9] |= 6;
|
||||
break;
|
||||
case 20: case 21: case 22: case 23:
|
||||
dev->regs[9] |= 0xD;
|
||||
break;
|
||||
case 24: case 25: case 26: case 27:
|
||||
case 28: case 29: case 30: case 31:
|
||||
dev->regs[9] |= 0xE;
|
||||
break;
|
||||
case 32: case 33: case 34: case 35:
|
||||
dev->regs[9] |= 0x1B;
|
||||
break;
|
||||
case 36: case 37: case 38: case 39:
|
||||
dev->regs[9] |= 0xF;
|
||||
break;
|
||||
case 40: case 41: case 42: case 43:
|
||||
case 44: case 45: case 46: case 47:
|
||||
dev->regs[9] |= 0x17;
|
||||
break;
|
||||
case 48:
|
||||
dev->regs[9] |= 0x1E;
|
||||
break;
|
||||
default:
|
||||
if (mem_size_mb < 64)
|
||||
dev->regs[9] |= 0x1E;
|
||||
else if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[9] |= 0x22;
|
||||
else
|
||||
dev->regs[9] |= 0x24;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[0x11] = 9;
|
||||
dev->regs[0x12] = 0xFF;
|
||||
dev->regs[0x23] = 0xF0;
|
||||
dev->regs[0x26] = 1;
|
||||
dev->regs[0x01] = 0xc0;
|
||||
dev->regs[0x71] = 0x01;
|
||||
dev->regs[0x72] = 0xff;
|
||||
|
||||
io_removehandler(0x0022, 0x0002,
|
||||
sis_85c497_read, NULL, NULL, sis_85c497_write, NULL, NULL, dev);
|
||||
@@ -271,12 +263,9 @@ sis_85c497_reset(sis_85c496_t *dev)
|
||||
static void
|
||||
sis_85c496_reset(void *priv)
|
||||
{
|
||||
uint8_t val = 0;
|
||||
sis_85c496_t *dev = (sis_85c496_t *) priv;
|
||||
|
||||
val = sis_85c496_read(0, 0x44, priv); /* Read current value of 0x44. */
|
||||
sis_85c496_write(0, 0x44, val & 0xf, priv); /* Turn off shadow BIOS but keep the lower 4 bits. */
|
||||
|
||||
sis_85c497_reset((sis_85c496_t *) priv);
|
||||
sis_85c497_reset(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -314,10 +303,19 @@ static void
|
||||
|
||||
dev->pci_conf[0x0e] = 0x00; /*Single function device*/
|
||||
|
||||
dev->pci_conf[0xd0] = 0x78; /* ROM at E0000-FFFFF, Flash enable. */
|
||||
dev->pci_conf[0xd1] = 0xff;
|
||||
|
||||
pci_add_card(5, sis_85c496_read, sis_85c496_write, dev);
|
||||
|
||||
sis_85c497_reset(dev);
|
||||
|
||||
dev->port_92 = device_add(&port_92_device);
|
||||
port_92_set_period(dev->port_92, 2ULL * TIMER_USEC);
|
||||
port_92_set_features(dev->port_92, 0, 0);
|
||||
|
||||
sis_85c496_recalcmapping(dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
@@ -335,37 +333,3 @@ const device_t sis_85c496_device =
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
machine_at_sis_85c496_common_init(const machine_t *model)
|
||||
{
|
||||
machine_at_common_init(model);
|
||||
device_add(&keyboard_ps2_pci_device);
|
||||
|
||||
device_add(&ide_pci_device);
|
||||
|
||||
memregs_init();
|
||||
pci_init(PCI_CONFIG_TYPE_1);
|
||||
pci_register_slot(0x05, PCI_CARD_SPECIAL, 0, 0, 0, 0);
|
||||
pci_register_slot(0x0B, PCI_CARD_NORMAL, 1, 2, 3, 4);
|
||||
pci_register_slot(0x0D, PCI_CARD_NORMAL, 2, 3, 4, 1);
|
||||
pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2);
|
||||
pci_register_slot(0x07, PCI_CARD_NORMAL, 4, 1, 2, 3);
|
||||
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
|
||||
device_add(&sis_85c496_device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
machine_at_r418_init(const machine_t *model)
|
||||
{
|
||||
machine_at_sis_85c496_common_init(model);
|
||||
|
||||
device_add(&fdc37c665_device);
|
||||
}
|
||||
441
src/chipset/sis_85c50x.c
Normal file
441
src/chipset/sis_85c50x.c
Normal file
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the SiS 85c501/85c503 chip.
|
||||
*
|
||||
* Version: @(#)sis_85c50x.c 1.0.0 2019/05/13
|
||||
*
|
||||
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
*
|
||||
* Copyright 2019 Miran Grca.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../mem.h"
|
||||
#include "../io.h"
|
||||
#include "../rom.h"
|
||||
#include "../pci.h"
|
||||
#include "../device.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../port_92.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct sis_85c501_t
|
||||
{
|
||||
/* 85c501 */
|
||||
uint8_t turbo_reg;
|
||||
|
||||
/* 85c503 */
|
||||
|
||||
/* Registers */
|
||||
uint8_t pci_conf[2][256];
|
||||
|
||||
/* 85c50x ISA */
|
||||
uint8_t cur_reg,
|
||||
regs[39];
|
||||
} sis_85c50x_t;
|
||||
|
||||
|
||||
static void
|
||||
sis_85c501_recalcmapping(sis_85c50x_t *dev)
|
||||
{
|
||||
int c, d;
|
||||
uint32_t base;
|
||||
|
||||
for (c = 0; c < 1; c++) {
|
||||
for (d = 0; d < 4; d++) {
|
||||
base = 0xe0000 + (d << 14);
|
||||
if (dev->pci_conf[0][0x54 + c] & (1 << (d + 4))) {
|
||||
switch (dev->pci_conf[0][0x53] & 0x60) {
|
||||
case 0x00:
|
||||
mem_set_mem_state(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x20:
|
||||
mem_set_mem_state(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 0x40:
|
||||
mem_set_mem_state(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 0x60:
|
||||
mem_set_mem_state(base, 0x4000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
mem_set_mem_state(base, 0x4000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
flushmmucache();
|
||||
shadowbios = 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c501_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
if (func)
|
||||
return;
|
||||
|
||||
if ((addr >= 0x10) && (addr < 0x4f))
|
||||
return;
|
||||
|
||||
switch (addr) {
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
case 0x0c: case 0x0e:
|
||||
return;
|
||||
|
||||
case 0x04: /*Command register*/
|
||||
val &= 0x42;
|
||||
val |= 0x04;
|
||||
break;
|
||||
case 0x05:
|
||||
val &= 0x01;
|
||||
break;
|
||||
|
||||
case 0x06: /*Status*/
|
||||
val = 0;
|
||||
break;
|
||||
case 0x07:
|
||||
val = 0x02;
|
||||
break;
|
||||
|
||||
case 0x54: /*Shadow configure*/
|
||||
if ((dev->pci_conf[0][0x54] & val) ^ 0xf0) {
|
||||
dev->pci_conf[0][0x54] = val;
|
||||
sis_85c501_recalcmapping(dev);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
dev->pci_conf[0][addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c503_write(int func, int addr, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
if (func > 0)
|
||||
return;
|
||||
|
||||
if (addr >= 0x0f && addr < 0x41)
|
||||
return;
|
||||
|
||||
switch(addr) {
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
case 0x0e:
|
||||
return;
|
||||
|
||||
case 0x04: /*Command register*/
|
||||
val &= 0x08;
|
||||
val |= 0x07;
|
||||
break;
|
||||
case 0x05:
|
||||
val = 0;
|
||||
break;
|
||||
|
||||
case 0x06: /*Status*/
|
||||
val = 0;
|
||||
break;
|
||||
case 0x07:
|
||||
val = 0x02;
|
||||
break;
|
||||
|
||||
case 0x41:
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTA, val & 0xf);
|
||||
break;
|
||||
case 0x42:
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTC, val & 0xf);
|
||||
break;
|
||||
case 0x43:
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTB, val & 0xf);
|
||||
break;
|
||||
case 0x44:
|
||||
if (val & 0x80)
|
||||
pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED);
|
||||
else
|
||||
pci_set_irq_routing(PCI_INTD, val & 0xf);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->pci_conf[1][addr] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_isa_write(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
if (port & 1) {
|
||||
if (dev->cur_reg <= 0x1a)
|
||||
dev->regs[dev->cur_reg] = val;
|
||||
} else
|
||||
dev->cur_reg = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c501_read(int func, int addr, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
if (func)
|
||||
return 0xff;
|
||||
|
||||
return dev->pci_conf[0][addr];
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c503_read(int func, int addr, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
if (func > 0)
|
||||
return 0xff;
|
||||
|
||||
return dev->pci_conf[1][addr];
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sis_85c50x_isa_read(uint16_t port, void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
if (port & 1) {
|
||||
if (dev->cur_reg <= 0x1a)
|
||||
return dev->regs[dev->cur_reg];
|
||||
else
|
||||
return 0xff;
|
||||
} else
|
||||
return dev->cur_reg;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_isa_reset(sis_85c50x_t *dev)
|
||||
{
|
||||
int mem_size_mb, i = 0;
|
||||
|
||||
memset(dev->regs, 0, sizeof(dev->regs));
|
||||
|
||||
dev->cur_reg = 0;
|
||||
for (i = 0; i < 0x27; i++)
|
||||
dev->regs[i] = 0x00;
|
||||
|
||||
dev->regs[9] = 0x40;
|
||||
|
||||
mem_size_mb = mem_size >> 10;
|
||||
switch (mem_size_mb) {
|
||||
case 0: case 1:
|
||||
dev->regs[9] |= 0;
|
||||
break;
|
||||
case 2: case 3:
|
||||
dev->regs[9] |= 1;
|
||||
break;
|
||||
case 4:
|
||||
dev->regs[9] |= 2;
|
||||
break;
|
||||
case 5:
|
||||
dev->regs[9] |= 0x20;
|
||||
break;
|
||||
case 6: case 7:
|
||||
dev->regs[9] |= 9;
|
||||
break;
|
||||
case 8: case 9:
|
||||
dev->regs[9] |= 4;
|
||||
break;
|
||||
case 10: case 11:
|
||||
dev->regs[9] |= 5;
|
||||
break;
|
||||
case 12: case 13: case 14: case 15:
|
||||
dev->regs[9] |= 0xB;
|
||||
break;
|
||||
case 16:
|
||||
dev->regs[9] |= 0x13;
|
||||
break;
|
||||
case 17:
|
||||
dev->regs[9] |= 0x21;
|
||||
break;
|
||||
case 18: case 19:
|
||||
dev->regs[9] |= 6;
|
||||
break;
|
||||
case 20: case 21: case 22: case 23:
|
||||
dev->regs[9] |= 0xD;
|
||||
break;
|
||||
case 24: case 25: case 26: case 27:
|
||||
case 28: case 29: case 30: case 31:
|
||||
dev->regs[9] |= 0xE;
|
||||
break;
|
||||
case 32: case 33: case 34: case 35:
|
||||
dev->regs[9] |= 0x1B;
|
||||
break;
|
||||
case 36: case 37: case 38: case 39:
|
||||
dev->regs[9] |= 0xF;
|
||||
break;
|
||||
case 40: case 41: case 42: case 43:
|
||||
case 44: case 45: case 46: case 47:
|
||||
dev->regs[9] |= 0x17;
|
||||
break;
|
||||
case 48:
|
||||
dev->regs[9] |= 0x1E;
|
||||
break;
|
||||
default:
|
||||
if (mem_size_mb < 64)
|
||||
dev->regs[9] |= 0x1E;
|
||||
else if ((mem_size_mb >= 65) && (mem_size_mb < 68))
|
||||
dev->regs[9] |= 0x22;
|
||||
else
|
||||
dev->regs[9] |= 0x24;
|
||||
break;
|
||||
}
|
||||
|
||||
dev->regs[0x11] = 9;
|
||||
dev->regs[0x12] = 0xFF;
|
||||
dev->regs[0x23] = 0xF0;
|
||||
dev->regs[0x26] = 1;
|
||||
|
||||
io_removehandler(0x22, 0x0002,
|
||||
sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev);
|
||||
io_sethandler(0x22, 0x0002,
|
||||
sis_85c50x_isa_read, NULL, NULL, sis_85c50x_isa_write, NULL, NULL, dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_reset(void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
uint8_t val = 0;
|
||||
|
||||
val = sis_85c501_read(0, 0x54, priv); /* Read current value of 0x44. */
|
||||
sis_85c501_write(0, 0x54, val & 0xf, priv); /* Turn off shadow BIOS but keep the lower 4 bits. */
|
||||
|
||||
sis_85c50x_isa_reset(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_setup(sis_85c50x_t *dev)
|
||||
{
|
||||
memset(dev, 0, sizeof(sis_85c50x_t));
|
||||
|
||||
/* 85c501 */
|
||||
dev->pci_conf[0][0x00] = 0x39; /*SiS*/
|
||||
dev->pci_conf[0][0x01] = 0x10;
|
||||
dev->pci_conf[0][0x02] = 0x06; /*501/502*/
|
||||
dev->pci_conf[0][0x03] = 0x04;
|
||||
|
||||
dev->pci_conf[0][0x04] = 7;
|
||||
dev->pci_conf[0][0x05] = 0;
|
||||
|
||||
dev->pci_conf[0][0x06] = 0x80;
|
||||
dev->pci_conf[0][0x07] = 0x02;
|
||||
|
||||
dev->pci_conf[0][0x08] = 0; /*Device revision*/
|
||||
|
||||
dev->pci_conf[0][0x09] = 0x00; /*Device class (PCI bridge)*/
|
||||
dev->pci_conf[0][0x0a] = 0x00;
|
||||
dev->pci_conf[0][0x0b] = 0x06;
|
||||
|
||||
dev->pci_conf[0][0x0e] = 0x00; /*Single function device*/
|
||||
|
||||
dev->pci_conf[0][0x50] = 0xbc;
|
||||
dev->pci_conf[0][0x51] = 0xfb;
|
||||
dev->pci_conf[0][0x52] = 0xad;
|
||||
dev->pci_conf[0][0x53] = 0xfe;
|
||||
|
||||
shadowbios = 1;
|
||||
|
||||
/* 85c503 */
|
||||
dev->pci_conf[1][0x00] = 0x39; /*SiS*/
|
||||
dev->pci_conf[1][0x01] = 0x10;
|
||||
dev->pci_conf[1][0x02] = 0x08; /*503*/
|
||||
dev->pci_conf[1][0x03] = 0x00;
|
||||
|
||||
dev->pci_conf[1][0x04] = 7;
|
||||
dev->pci_conf[1][0x05] = 0;
|
||||
|
||||
dev->pci_conf[1][0x06] = 0x80;
|
||||
dev->pci_conf[1][0x07] = 0x02;
|
||||
|
||||
dev->pci_conf[1][0x08] = 0; /*Device revision*/
|
||||
|
||||
dev->pci_conf[1][0x09] = 0x00; /*Device class (PCI bridge)*/
|
||||
dev->pci_conf[1][0x0a] = 0x01;
|
||||
dev->pci_conf[1][0x0b] = 0x06;
|
||||
|
||||
dev->pci_conf[1][0x0e] = 0x00; /*Single function device*/
|
||||
|
||||
dev->pci_conf[1][0x41] = dev->pci_conf[1][0x42] =
|
||||
dev->pci_conf[1][0x43] = dev->pci_conf[1][0x44] = 0x80;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sis_85c50x_close(void *priv)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sis_85c50x_init(const device_t *info)
|
||||
{
|
||||
sis_85c50x_t *dev = (sis_85c50x_t *) malloc(sizeof(sis_85c50x_t));
|
||||
|
||||
pci_add_card(0, sis_85c501_read, sis_85c501_write, dev);
|
||||
pci_add_card(5, sis_85c503_read, sis_85c503_write, dev);
|
||||
|
||||
sis_85c50x_setup(dev);
|
||||
sis_85c50x_isa_reset(dev);
|
||||
|
||||
device_add(&port_92_pci_device);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
const device_t sis_85c50x_device =
|
||||
{
|
||||
"SiS 85c501/85c503",
|
||||
DEVICE_PCI,
|
||||
0,
|
||||
sis_85c50x_init,
|
||||
sis_85c50x_close,
|
||||
sis_85c50x_reset,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
196
src/chipset/wd76c10 - Cópia.c
Normal file
196
src/chipset/wd76c10 - Cópia.c
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the WD76C10 System Controller chip.
|
||||
*
|
||||
* Version: @(#)wd76c10.c 1.0.0 2019/05/14
|
||||
*
|
||||
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../timer.h"
|
||||
#include "../io.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../mem.h"
|
||||
#include "../port_92.h"
|
||||
#include "../serial.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../video/vid_paradise.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
|
||||
uint16_t reg_0092;
|
||||
uint16_t reg_2072;
|
||||
uint16_t reg_2872;
|
||||
uint16_t reg_5872;
|
||||
|
||||
serial_t *uart[2];
|
||||
|
||||
fdc_t *fdc;
|
||||
} wd76c10_t;
|
||||
|
||||
|
||||
static uint16_t
|
||||
wd76c10_read(uint16_t port, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
int16_t ret = 0xffff;
|
||||
|
||||
switch (port) {
|
||||
case 0x2072:
|
||||
ret = dev->reg_2072;
|
||||
break;
|
||||
|
||||
case 0x2872:
|
||||
ret = dev->reg_2872;
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
ret = dev->reg_5872;
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_write(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x2072:
|
||||
dev->reg_2072 = val;
|
||||
|
||||
serial_remove(dev->uart[0]);
|
||||
if (!(val & 0x10))
|
||||
{
|
||||
switch ((val >> 5) & 7)
|
||||
{
|
||||
case 1: serial_setup(dev->uart[0], 0x3f8, 4); break;
|
||||
case 2: serial_setup(dev->uart[0], 0x2f8, 4); break;
|
||||
case 3: serial_setup(dev->uart[0], 0x3e8, 4); break;
|
||||
case 4: serial_setup(dev->uart[0], 0x2e8, 4); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
serial_remove(dev->uart[1]);
|
||||
if (!(val & 0x01))
|
||||
{
|
||||
switch ((val >> 1) & 7)
|
||||
{
|
||||
case 1: serial_setup(dev->uart[1], 0x3f8, 3); break;
|
||||
case 2: serial_setup(dev->uart[1], 0x2f8, 3); break;
|
||||
case 3: serial_setup(dev->uart[1], 0x3e8, 3); break;
|
||||
case 4: serial_setup(dev->uart[1], 0x2e8, 3); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2872:
|
||||
dev->reg_2872 = val;
|
||||
|
||||
fdc_remove(dev->fdc);
|
||||
if (! (val & 1))
|
||||
fdc_set_base(dev->fdc, 0x03f0);
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
dev->reg_5872 = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
wd76c10_readb(uint16_t port, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
return(wd76c10_read(port & ~1, priv) >> 8);
|
||||
|
||||
return(wd76c10_read(port, priv) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_writeb(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
uint16_t temp = wd76c10_read(port, priv);
|
||||
|
||||
if (port & 1)
|
||||
wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv);
|
||||
else
|
||||
wd76c10_write(port , (temp & 0xff00) | val, priv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_close(void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
wd76c10_init(const device_t *info)
|
||||
{
|
||||
wd76c10_t *dev;
|
||||
|
||||
dev = (wd76c10_t *) malloc(sizeof(wd76c10_t));
|
||||
memset(dev, 0x00, sizeof(wd76c10_t));
|
||||
dev->type = info->local;
|
||||
|
||||
dev->fdc = (fdc_t *)device_add(&fdc_at_device);
|
||||
|
||||
dev->uart[0] = device_add_inst(&i8250_device, 1);
|
||||
dev->uart[1] = device_add_inst(&i8250_device, 2);
|
||||
|
||||
device_add(&port_92_word_device);
|
||||
|
||||
io_sethandler(0x2072, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
io_sethandler(0x2872, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
io_sethandler(0x5872, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t wd76c10_device = {
|
||||
"WD 76C10",
|
||||
0,
|
||||
0,
|
||||
wd76c10_init, wd76c10_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
292
src/chipset/wd76c10.c
Normal file
292
src/chipset/wd76c10.c
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Implementation of the WD76C10 System Controller chip.
|
||||
*
|
||||
* Version: @(#)wd76c10.c 1.0.0 2019/05/14
|
||||
*
|
||||
* Authors: Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
*
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "../86box.h"
|
||||
#include "../device.h"
|
||||
#include "../timer.h"
|
||||
#include "../io.h"
|
||||
#include "../keyboard.h"
|
||||
#include "../mem.h"
|
||||
#include "../port_92.h"
|
||||
#include "../serial.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "../video/vid_paradise.h"
|
||||
#include "chipset.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
|
||||
uint16_t reg_0092;
|
||||
uint16_t reg_2072;
|
||||
uint16_t reg_2872;
|
||||
uint16_t reg_5872;
|
||||
|
||||
uint16_t reg_f872;
|
||||
|
||||
serial_t *uart[2];
|
||||
|
||||
fdc_t *fdc;
|
||||
|
||||
mem_mapping_t extram_mapping;
|
||||
uint8_t extram[65536];
|
||||
} wd76c10_t;
|
||||
|
||||
|
||||
static uint16_t
|
||||
wd76c10_read(uint16_t port, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
int16_t ret = 0xffff;
|
||||
|
||||
switch (port) {
|
||||
case 0x2072:
|
||||
ret = dev->reg_2072;
|
||||
break;
|
||||
|
||||
case 0x2872:
|
||||
ret = dev->reg_2872;
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
ret = dev->reg_5872;
|
||||
break;
|
||||
|
||||
case 0xf872:
|
||||
ret = dev->reg_f872;
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_write(uint16_t port, uint16_t val, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
switch (port) {
|
||||
case 0x2072:
|
||||
dev->reg_2072 = val;
|
||||
|
||||
serial_remove(dev->uart[0]);
|
||||
if (!(val & 0x10))
|
||||
{
|
||||
switch ((val >> 5) & 7)
|
||||
{
|
||||
case 1: serial_setup(dev->uart[0], 0x3f8, 4); break;
|
||||
case 2: serial_setup(dev->uart[0], 0x2f8, 4); break;
|
||||
case 3: serial_setup(dev->uart[0], 0x3e8, 4); break;
|
||||
case 4: serial_setup(dev->uart[0], 0x2e8, 4); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
serial_remove(dev->uart[1]);
|
||||
if (!(val & 0x01))
|
||||
{
|
||||
switch ((val >> 1) & 7)
|
||||
{
|
||||
case 1: serial_setup(dev->uart[1], 0x3f8, 3); break;
|
||||
case 2: serial_setup(dev->uart[1], 0x2f8, 3); break;
|
||||
case 3: serial_setup(dev->uart[1], 0x3e8, 3); break;
|
||||
case 4: serial_setup(dev->uart[1], 0x2e8, 3); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2872:
|
||||
dev->reg_2872 = val;
|
||||
|
||||
fdc_remove(dev->fdc);
|
||||
if (! (val & 1))
|
||||
fdc_set_base(dev->fdc, 0x03f0);
|
||||
break;
|
||||
|
||||
case 0x5872:
|
||||
dev->reg_5872 = val;
|
||||
break;
|
||||
|
||||
case 0xf872:
|
||||
dev->reg_f872 = val;
|
||||
switch (val & 3) {
|
||||
case 0:
|
||||
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 1:
|
||||
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_EXTERNAL);
|
||||
break;
|
||||
case 2:
|
||||
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
case 3:
|
||||
mem_set_mem_state(0xd0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
|
||||
break;
|
||||
}
|
||||
flushmmucache_nopc();
|
||||
if (val & 4)
|
||||
mem_mapping_enable(&dev->extram_mapping);
|
||||
else
|
||||
mem_mapping_disable(&dev->extram_mapping);
|
||||
flushmmucache_nopc();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
wd76c10_readb(uint16_t port, void *priv)
|
||||
{
|
||||
if (port & 1)
|
||||
return(wd76c10_read(port & ~1, priv) >> 8);
|
||||
|
||||
return(wd76c10_read(port, priv) & 0xff);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_writeb(uint16_t port, uint8_t val, void *priv)
|
||||
{
|
||||
uint16_t temp = wd76c10_read(port, priv);
|
||||
|
||||
if (port & 1)
|
||||
wd76c10_write(port & ~1, (temp & 0x00ff) | (val << 8), priv);
|
||||
else
|
||||
wd76c10_write(port , (temp & 0xff00) | val, priv);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
wd76c10_read_extram(uint32_t addr, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
return dev->extram[addr & 0xffff];
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
wd76c10_read_extramw(uint32_t addr, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
return *(uint16_t *)&dev->extram[addr & 0xffff];
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
wd76c10_read_extraml(uint32_t addr, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
return *(uint32_t *)&dev->extram[addr & 0xffff];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wd76c10_write_extram(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
dev->extram[addr & 0xffff] = val;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wd76c10_write_extramw(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
*(uint16_t *)&dev->extram[addr & 0xffff] = val;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wd76c10_write_extraml(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
*(uint32_t *)&dev->extram[addr & 0xffff] = val;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
wd76c10_close(void *priv)
|
||||
{
|
||||
wd76c10_t *dev = (wd76c10_t *)priv;
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
wd76c10_init(const device_t *info)
|
||||
{
|
||||
wd76c10_t *dev;
|
||||
|
||||
dev = (wd76c10_t *) malloc(sizeof(wd76c10_t));
|
||||
memset(dev, 0x00, sizeof(wd76c10_t));
|
||||
dev->type = info->local;
|
||||
|
||||
dev->fdc = (fdc_t *)device_add(&fdc_at_device);
|
||||
|
||||
dev->uart[0] = device_add_inst(&i8250_device, 1);
|
||||
dev->uart[1] = device_add_inst(&i8250_device, 2);
|
||||
|
||||
device_add(&port_92_word_device);
|
||||
|
||||
io_sethandler(0x2072, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
io_sethandler(0x2872, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
io_sethandler(0x5872, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
io_sethandler(0xf872, 2,
|
||||
wd76c10_readb,wd76c10_read,NULL,
|
||||
wd76c10_writeb,wd76c10_write,NULL, dev);
|
||||
|
||||
mem_mapping_add(&dev->extram_mapping, 0xd0000, 0x10000,
|
||||
wd76c10_read_extram,wd76c10_read_extramw,wd76c10_read_extraml,
|
||||
wd76c10_write_extram,wd76c10_write_extramw,wd76c10_write_extraml,
|
||||
dev->extram, MEM_MAPPING_EXTERNAL, dev);
|
||||
mem_mapping_disable(&dev->extram_mapping);
|
||||
|
||||
return(dev);
|
||||
}
|
||||
|
||||
|
||||
const device_t wd76c10_device = {
|
||||
"WD 76C10",
|
||||
0,
|
||||
0,
|
||||
wd76c10_init, wd76c10_close, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL
|
||||
};
|
||||
147
src/config.c
147
src/config.c
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Configuration file handler.
|
||||
*
|
||||
* Version: @(#)config.c 1.0.60 2019/01/13
|
||||
* Version: @(#)config.c 1.0.61 2019/03/03
|
||||
*
|
||||
* Authors: Sarah Walker,
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -16,10 +16,10 @@
|
||||
* Overdoze,
|
||||
* David Hrdlička, <hrdlickadavid@outlook.com>
|
||||
*
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2018 David Hrdlička.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2018,2019 David Hrdlička.
|
||||
*
|
||||
* NOTE: Forcing config files to be in Unicode encoding breaks
|
||||
* it on Windows XP, and possibly also Vista. Use the
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "86box.h"
|
||||
#include "cpu/cpu.h"
|
||||
#include "device.h"
|
||||
#include "timer.h"
|
||||
#include "nvr.h"
|
||||
#include "config.h"
|
||||
#include "isamem.h"
|
||||
@@ -517,7 +518,6 @@ load_machine(void)
|
||||
if (machine >= machine_count())
|
||||
machine = machine_count() - 1;
|
||||
|
||||
romset = machine_getromset();
|
||||
cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0);
|
||||
cpu = config_get_int(cat, "cpu", 0);
|
||||
cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0);
|
||||
@@ -565,7 +565,7 @@ load_video(void)
|
||||
char *cat = "Video";
|
||||
char *p;
|
||||
|
||||
if (machines[machine].fixed_gfxcard) {
|
||||
if (machines[machine].flags & MACHINE_VIDEO_FIXED) {
|
||||
config_delete_var(cat, "gfxcard");
|
||||
gfxcard = VID_INTERNAL;
|
||||
} else {
|
||||
@@ -726,28 +726,30 @@ load_ports(void)
|
||||
{
|
||||
char *cat = "Ports (COM & LPT)";
|
||||
char *p;
|
||||
char temp[512];
|
||||
int c, d;
|
||||
|
||||
serial_enabled[0] = !!config_get_int(cat, "serial1_enabled", 1);
|
||||
serial_enabled[1] = !!config_get_int(cat, "serial2_enabled", 1);
|
||||
lpt_enabled = !!config_get_int(cat, "lpt_enabled", 1);
|
||||
for (c = 0; c < 2; c++) {
|
||||
sprintf(temp, "serial%d_enabled", c + 1);
|
||||
serial_enabled[c] = !!config_get_int(cat, temp, 1);
|
||||
}
|
||||
|
||||
p = (char *)config_get_string(cat, "lpt1_device", NULL);
|
||||
if (p != NULL)
|
||||
strcpy(lpt_device_names[0], p);
|
||||
else
|
||||
strcpy(lpt_device_names[0], "none");
|
||||
for (c = 0; c < 3; c++) {
|
||||
sprintf(temp, "lpt%d_enabled", c + 1);
|
||||
lpt_ports[c].enabled = !!config_get_int(cat, temp, (c == 0) ? 1 : 0);
|
||||
|
||||
p = (char *)config_get_string(cat, "lpt2_device", NULL);
|
||||
if (p != NULL)
|
||||
strcpy(lpt_device_names[1], p);
|
||||
else
|
||||
strcpy(lpt_device_names[1], "none");
|
||||
sprintf(temp, "lpt%d_device", c + 1);
|
||||
p = (char *) config_get_string(cat, temp, "none");
|
||||
lpt_ports[c].device = lpt_device_get_from_internal_name(p);
|
||||
}
|
||||
|
||||
p = (char *)config_get_string(cat, "lpt3_device", NULL);
|
||||
if (p != NULL)
|
||||
strcpy(lpt_device_names[2], p);
|
||||
else
|
||||
strcpy(lpt_device_names[2], "none");
|
||||
/* Legacy config compatibility. */
|
||||
d = config_get_int(cat, "lpt_enabled", 2);
|
||||
if (d < 2) {
|
||||
for (c = 0; c < 3; c++)
|
||||
lpt_ports[c].enabled = d;
|
||||
}
|
||||
config_delete_var(cat, "lpt_enabled");
|
||||
}
|
||||
|
||||
|
||||
@@ -757,8 +759,8 @@ load_other_peripherals(void)
|
||||
{
|
||||
char *cat = "Other peripherals";
|
||||
char *p;
|
||||
char temp[512];
|
||||
int c;
|
||||
char temp[512];
|
||||
int c;
|
||||
|
||||
p = config_get_string(cat, "scsicard", NULL);
|
||||
if (p != NULL)
|
||||
@@ -776,7 +778,14 @@ load_other_peripherals(void)
|
||||
strcpy(p, "none");
|
||||
}
|
||||
}
|
||||
hdc_current = hdc_get_from_internal_name(p);
|
||||
if (!strcmp(p, "mfm_xt"))
|
||||
hdc_current = hdc_get_from_internal_name("st506_xt");
|
||||
else if (!strcmp(p, "mfm_xt_dtc5150x"))
|
||||
hdc_current = hdc_get_from_internal_name("st506_xt_dtc5150x");
|
||||
else if (!strcmp(p, "mfm_at"))
|
||||
hdc_current = hdc_get_from_internal_name("st506_at");
|
||||
else
|
||||
hdc_current = hdc_get_from_internal_name(p);
|
||||
|
||||
ide_ter_enabled = !!config_get_int(cat, "ide_ter", 0);
|
||||
ide_qua_enabled = !!config_get_int(cat, "ide_qua", 0);
|
||||
@@ -789,7 +798,7 @@ load_other_peripherals(void)
|
||||
p = config_get_string(cat, temp, "none");
|
||||
isamem_type[c] = isamem_get_from_internal_name(p);
|
||||
}
|
||||
|
||||
|
||||
p = config_get_string(cat, "isartc_type", "none");
|
||||
isartc_type = isartc_get_from_internal_name(p);
|
||||
}
|
||||
@@ -823,7 +832,7 @@ load_hard_disks(void)
|
||||
break;
|
||||
|
||||
case HDD_BUS_MFM:
|
||||
max_spt = 17; /* 26 for RLL */
|
||||
max_spt = 26; /* 26 for RLL */
|
||||
max_hpc = 15;
|
||||
max_tracks = 1023;
|
||||
break;
|
||||
@@ -1069,8 +1078,11 @@ load_other_removable_devices(void)
|
||||
if (cdrom[c].ide_channel > 7)
|
||||
cdrom[c].ide_channel = 7;
|
||||
} else {
|
||||
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
|
||||
if (cdrom[c].bus_type == CDROM_BUS_SCSI) {
|
||||
if (cdrom[c].bus_type == CDROM_BUS_SCSI_CHINON)
|
||||
sprintf(temp, "cdrom_%02i_scsi_id_chinon", c+1);
|
||||
else
|
||||
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
|
||||
if (cdrom[c].bus_type == CDROM_BUS_SCSI || cdrom[c].bus_type == CDROM_BUS_SCSI_CHINON) {
|
||||
cdrom[c].scsi_device_id = config_get_int(cat, temp, c+2);
|
||||
|
||||
if (cdrom[c].scsi_device_id > 15)
|
||||
@@ -1121,6 +1133,9 @@ load_other_removable_devices(void)
|
||||
|
||||
sprintf(temp, "cdrom_%02i_scsi_id", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "cdrom_%02i_scsi_id_chinon", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
|
||||
sprintf(temp, "cdrom_%02i_image_path", c+1);
|
||||
config_delete_var(cat, temp);
|
||||
@@ -1240,7 +1255,9 @@ config_load(void)
|
||||
hdc_current = hdc_get_from_internal_name("none");
|
||||
serial_enabled[0] = 1;
|
||||
serial_enabled[1] = 1;
|
||||
lpt_enabled = 1;
|
||||
lpt_ports[0].enabled = 1;
|
||||
lpt_ports[1].enabled = 0;
|
||||
lpt_ports[2].enabled = 0;
|
||||
for (i = 0; i < FDD_NUM; i++) {
|
||||
if (i < 2)
|
||||
fdd_set_type(i, 2);
|
||||
@@ -1586,36 +1603,32 @@ static void
|
||||
save_ports(void)
|
||||
{
|
||||
char *cat = "Ports (COM & LPT)";
|
||||
char temp[512];
|
||||
int c, d;
|
||||
|
||||
if (serial_enabled[0])
|
||||
config_delete_var(cat, "serial1_enabled");
|
||||
else
|
||||
config_set_int(cat, "serial1_enabled", serial_enabled[0]);
|
||||
for (c = 0; c < 2; c++) {
|
||||
sprintf(temp, "serial%d_enabled", c + 1);
|
||||
if (serial_enabled[c])
|
||||
config_delete_var(cat, temp);
|
||||
else
|
||||
config_set_int(cat, temp, serial_enabled[c]);
|
||||
}
|
||||
|
||||
if (serial_enabled[1])
|
||||
config_delete_var(cat, "serial2_enabled");
|
||||
else
|
||||
config_set_int(cat, "serial2_enabled", serial_enabled[1]);
|
||||
for (c = 0; c < 3; c++) {
|
||||
sprintf(temp, "lpt%d_enabled", c + 1);
|
||||
d = (c == 0) ? 1 : 0;
|
||||
if (lpt_ports[c].enabled == d)
|
||||
config_delete_var(cat, temp);
|
||||
else
|
||||
config_set_int(cat, temp, lpt_ports[c].enabled);
|
||||
|
||||
if (lpt_enabled)
|
||||
config_delete_var(cat, "lpt_enabled");
|
||||
else
|
||||
config_set_int(cat, "lpt_enabled", lpt_enabled);
|
||||
|
||||
if (!strcmp(lpt_device_names[0], "none"))
|
||||
config_delete_var(cat, "lpt1_device");
|
||||
else
|
||||
config_set_string(cat, "lpt1_device", lpt_device_names[0]);
|
||||
|
||||
if (!strcmp(lpt_device_names[1], "none"))
|
||||
config_delete_var(cat, "lpt2_device");
|
||||
else
|
||||
config_set_string(cat, "lpt2_device", lpt_device_names[1]);
|
||||
|
||||
if (!strcmp(lpt_device_names[2], "none"))
|
||||
config_delete_var(cat, "lpt3_device");
|
||||
else
|
||||
config_set_string(cat, "lpt3_device", lpt_device_names[2]);
|
||||
sprintf(temp, "lpt%d_device", c + 1);
|
||||
if (lpt_ports[c].device == 0)
|
||||
config_delete_var(cat, temp);
|
||||
else
|
||||
config_set_string(cat, temp,
|
||||
(char *) lpt_device_get_internal_name(lpt_ports[c].device));
|
||||
}
|
||||
|
||||
delete_section_if_empty(cat);
|
||||
}
|
||||
@@ -1626,8 +1639,8 @@ static void
|
||||
save_other_peripherals(void)
|
||||
{
|
||||
char *cat = "Other peripherals";
|
||||
char temp[512];
|
||||
int c;
|
||||
char temp[512];
|
||||
int c;
|
||||
|
||||
if (scsi_card_current == 0)
|
||||
config_delete_var(cat, "scsicard");
|
||||
@@ -1827,9 +1840,13 @@ save_other_removable_devices(void)
|
||||
cdrom[c].ide_channel & 1);
|
||||
config_set_string(cat, temp, tmp2);
|
||||
}
|
||||
|
||||
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
|
||||
if (cdrom[c].bus_type != CDROM_BUS_SCSI) {
|
||||
|
||||
if (cdrom[c].bus_type == CDROM_BUS_SCSI_CHINON)
|
||||
sprintf(temp, "cdrom_%02i_scsi_id_chinon", c + 1);
|
||||
else
|
||||
sprintf(temp, "cdrom_%02i_scsi_id", c + 1);
|
||||
|
||||
if (cdrom[c].bus_type != CDROM_BUS_SCSI && cdrom[c].bus_type != CDROM_BUS_SCSI_CHINON) {
|
||||
config_delete_var(cat, temp);
|
||||
} else {
|
||||
config_set_int(cat, temp, cdrom[c].scsi_device_id);
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "cpu.h"
|
||||
#include "../timer.h"
|
||||
#include "x86.h"
|
||||
#include "x87.h"
|
||||
#include "../nmi.h"
|
||||
#include "../mem.h"
|
||||
#include "../pic.h"
|
||||
#include "../pit.h"
|
||||
#include "../timer.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "386_common.h"
|
||||
@@ -29,12 +29,11 @@ extern int codegen_flags_changed;
|
||||
|
||||
int cpl_override = 0, fpucount = 0;
|
||||
int tempc, oldcpl, optype, inttype, oddeven = 0;
|
||||
int use32, stack32;
|
||||
int stack32, timetolive;
|
||||
|
||||
uint16_t flags, eflags;
|
||||
uint16_t rds, ea_rseg;
|
||||
uint16_t oldcs;
|
||||
|
||||
uint32_t use32;
|
||||
uint32_t oldds, oldss, olddslimit, oldsslimit,
|
||||
olddslimitw, oldsslimitw;
|
||||
uint32_t *eal_r, *eal_w;
|
||||
@@ -44,11 +43,9 @@ uint32_t rmdat32;
|
||||
uint32_t backupregs[16];
|
||||
|
||||
x86seg gdt,ldt,idt,tr;
|
||||
x86seg _cs,_ds,_es,_ss,_fs,_gs;
|
||||
x86seg _oldds;
|
||||
|
||||
#define rmdat rmdat32
|
||||
#define fetchdat rmdat32
|
||||
uint32_t rmdat;
|
||||
|
||||
#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
|
||||
@@ -68,7 +65,7 @@ uint32_t testr[9];
|
||||
extern int dontprint;
|
||||
|
||||
#undef NOTRM
|
||||
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
|
||||
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
|
||||
{ \
|
||||
x86_int(6); \
|
||||
return 0; \
|
||||
@@ -82,7 +79,7 @@ extern int dontprint;
|
||||
#include "x86_ops.h"
|
||||
|
||||
#undef NOTRM
|
||||
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
|
||||
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
|
||||
{ \
|
||||
x86_int(6); \
|
||||
break; \
|
||||
@@ -111,49 +108,46 @@ x386_log(const char *fmt, ...)
|
||||
|
||||
void exec386(int cycs)
|
||||
{
|
||||
uint8_t temp;
|
||||
int vector, tempi, cycdiff, oldcyc;
|
||||
int ins_cycles;
|
||||
uint32_t addr;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
int oldcyc;
|
||||
|
||||
cycles+=cycs;
|
||||
/* output=3; */
|
||||
while (cycles>0)
|
||||
{
|
||||
int cycle_period = (timer_count >> TIMER_SHIFT) + 1;
|
||||
int cycle_period = (timer_target - (uint32_t)tsc) + 1;
|
||||
|
||||
x86_was_reset = 0;
|
||||
cycdiff=0;
|
||||
oldcyc=cycles;
|
||||
timer_start_period(cycles << TIMER_SHIFT);
|
||||
while (cycdiff < cycle_period)
|
||||
{
|
||||
ins_cycles = cycles;
|
||||
|
||||
oldcs=CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl=CPL;
|
||||
oldcpl=CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
x86_was_reset = 0;
|
||||
|
||||
dontprint=0;
|
||||
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
trap = flags & T_FLAG;
|
||||
{
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
if(x86_was_reset) break;
|
||||
if(x86_was_reset)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!use32) cpu_state.pc &= 0xffff;
|
||||
@@ -180,6 +174,10 @@ dontprint=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ins_cycles -= cycles;
|
||||
tsc += ins_cycles;
|
||||
|
||||
cycdiff=oldcyc-cycles;
|
||||
|
||||
if (trap)
|
||||
@@ -193,13 +191,13 @@ dontprint=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,(SP-2)&0xFFFF,flags);
|
||||
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
|
||||
writememw(ss,(SP-4)&0xFFFF,CS);
|
||||
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
|
||||
SP-=6;
|
||||
addr = (1 << 2) + idt.base;
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
@@ -216,26 +214,26 @@ dontprint=0;
|
||||
nmi = 0;
|
||||
}
|
||||
}
|
||||
else if ((flags&I_FLAG) && pic_intpending)
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
{
|
||||
temp=picinterrupt();
|
||||
if (temp!=0xFF)
|
||||
vector = picinterrupt();
|
||||
if (vector != -1)
|
||||
{
|
||||
flags_rebuild();
|
||||
if (msw&1)
|
||||
{
|
||||
pmodeint(temp,0);
|
||||
pmodeint(vector,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,(SP-2)&0xFFFF,flags);
|
||||
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
|
||||
writememw(ss,(SP-4)&0xFFFF,CS);
|
||||
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
|
||||
SP-=6;
|
||||
addr = (temp << 2) + idt.base;
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
addr = (vector << 2) + idt.base;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
oxpc = cpu_state.pc;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
@@ -252,8 +250,7 @@ dontprint=0;
|
||||
}
|
||||
}
|
||||
|
||||
tsc += cycdiff;
|
||||
|
||||
timer_end_period(cycles << TIMER_SHIFT);
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
extern void cpu_386_flags_extract();
|
||||
extern void cpu_386_flags_rebuild();
|
||||
@@ -8,16 +8,14 @@
|
||||
*
|
||||
* Common 386 CPU code.
|
||||
*
|
||||
* Version: @(#)386_common.h 1.0.0 2017/05/30
|
||||
* Version: @(#)386_common.h 1.0.1 2019/02/19
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
|
||||
extern uint16_t ea_rseg;
|
||||
|
||||
#undef readmemb
|
||||
#undef writememb
|
||||
|
||||
@@ -32,7 +30,7 @@ extern uint16_t ea_rseg;
|
||||
#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
|
||||
|
||||
|
||||
#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \
|
||||
#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \
|
||||
{ \
|
||||
int tempi = checkio(port); \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
@@ -43,46 +41,88 @@ extern uint16_t ea_rseg;
|
||||
} \
|
||||
}
|
||||
|
||||
#define checkio_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \
|
||||
{ \
|
||||
tempi = checkio(port); \
|
||||
if (cpu_state.abrt) break; \
|
||||
if (tempi) \
|
||||
{ \
|
||||
x86gpf("checkio_perm(): no permission",0); \
|
||||
break; \
|
||||
} \
|
||||
}
|
||||
#define SEG_CHECK_READ(seg) \
|
||||
do \
|
||||
{ \
|
||||
if ((seg)->base == 0xffffffff) \
|
||||
{ \
|
||||
x86gpf("Segment can't read", 0);\
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEG_CHECK_WRITE(seg) \
|
||||
do \
|
||||
{ \
|
||||
if ((seg)->base == 0xffffffff) \
|
||||
{ \
|
||||
x86gpf("Segment can't write", 0);\
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_READ(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \
|
||||
{ \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &_ss) \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
}
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 0); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 0); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CHECK_READ_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 0); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 0); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(eflags & VM_FLAG) && ((chseg)->access & 8))) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \
|
||||
{ \
|
||||
x86gpf("Limit check (WRITE)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &_ss) \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
}
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 1); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 1); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
|
||||
@@ -90,17 +130,23 @@ extern uint16_t ea_rseg;
|
||||
x86gpf("Limit check (WRITE REP)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw&1 && !(eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &_ss) \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
}
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 1); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 1); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
#define NOTRM if (!(msw & 1) || (eflags & VM_FLAG))\
|
||||
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
|
||||
{ \
|
||||
x86_int(6); \
|
||||
return 1; \
|
||||
@@ -165,6 +211,17 @@ static __inline uint32_t fastreadl(uint32_t a)
|
||||
return val;
|
||||
}
|
||||
|
||||
static __inline void *get_ram_ptr(uint32_t a)
|
||||
{
|
||||
if ((a >> 12) == pccache)
|
||||
return &pccache2[a];
|
||||
else
|
||||
{
|
||||
uint8_t *t = getpccache(a);
|
||||
return &t[a];
|
||||
}
|
||||
}
|
||||
|
||||
static __inline uint8_t getbyte()
|
||||
{
|
||||
cpu_state.pc++;
|
||||
@@ -204,7 +261,6 @@ static __inline uint16_t geteaw()
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].w;
|
||||
/* cycles-=3; */
|
||||
if (eal_r)
|
||||
return *(uint16_t *)eal_r;
|
||||
return readmemw(easeg, cpu_state.eaaddr);
|
||||
@@ -214,7 +270,6 @@ static __inline uint32_t geteal()
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].l;
|
||||
/* cycles-=3; */
|
||||
if (eal_r)
|
||||
return *eal_r;
|
||||
return readmeml(easeg, cpu_state.eaaddr);
|
||||
@@ -246,10 +301,11 @@ static __inline void seteaq(uint64_t v)
|
||||
writememql(easeg, cpu_state.eaaddr, v);
|
||||
}
|
||||
|
||||
#define seteab(v) if (cpu_mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
|
||||
#define seteaw(v) if (cpu_mod!=3) { if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v
|
||||
#define seteal(v) if (cpu_mod!=3) { if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v
|
||||
|
||||
#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else { writememb386l(easeg,cpu_state.eaaddr,v); } } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
|
||||
#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else { writememwl(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].w=v
|
||||
#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else { writememll(easeg,cpu_state.eaaddr,v); } } else cpu_state.regs[cpu_rm].l=v
|
||||
|
||||
|
||||
#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,cpu_state.eaaddr,v);
|
||||
#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg,cpu_state.eaaddr,v);
|
||||
#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg,cpu_state.eaaddr,v);
|
||||
@@ -258,9 +314,3 @@ static __inline void seteaq(uint64_t v)
|
||||
#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2
|
||||
#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++
|
||||
#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2
|
||||
|
||||
|
||||
#define rmdat rmdat32
|
||||
#define fetchdat rmdat32
|
||||
|
||||
void x86_int(int num);
|
||||
|
||||
@@ -40,7 +40,7 @@ int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latch
|
||||
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;#endif
|
||||
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
|
||||
|
||||
|
||||
void
|
||||
@@ -63,7 +63,6 @@ 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;
|
||||
@@ -89,8 +88,7 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
else if ((sib & 6) == 4 && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
cpu_state.ea_seg = &_ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6);
|
||||
@@ -103,8 +101,7 @@ static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
if (cpu_rm == 5 && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
cpu_state.ea_seg = &_ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
if (cpu_mod == 1)
|
||||
{
|
||||
@@ -136,7 +133,6 @@ 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();
|
||||
@@ -159,8 +155,7 @@ static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs)
|
||||
{
|
||||
easeg = ss;
|
||||
ea_rseg = SS;
|
||||
cpu_state.ea_seg = &_ss;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
cpu_state.eaaddr &= 0xFFFF;
|
||||
}
|
||||
@@ -211,22 +206,22 @@ void x86_int(int num)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,flags);
|
||||
writememw(ss,ESP-2,cpu_state.flags);
|
||||
writememw(ss,ESP-4,CS);
|
||||
writememw(ss,ESP-6,cpu_state.pc);
|
||||
ESP-=6;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,((SP-2)&0xFFFF),flags);
|
||||
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
|
||||
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
|
||||
SP-=6;
|
||||
}
|
||||
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
@@ -256,22 +251,22 @@ void x86_int_sw(int num)
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,flags);
|
||||
writememw(ss,ESP-2,cpu_state.flags);
|
||||
writememw(ss,ESP-4,CS);
|
||||
writememw(ss,ESP-6,cpu_state.pc);
|
||||
ESP-=6;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,((SP-2)&0xFFFF),flags);
|
||||
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
|
||||
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
|
||||
SP-=6;
|
||||
}
|
||||
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
cycles -= timing_int_rm;
|
||||
@@ -295,7 +290,7 @@ int x86_int_sw_rm(int num)
|
||||
|
||||
if (cpu_state.abrt) return 1;
|
||||
|
||||
writememw(ss,((SP-2)&0xFFFF),flags);
|
||||
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
|
||||
if (cpu_state.abrt) {
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
x386_dynarec_log("abrt5\n");
|
||||
@@ -312,11 +307,11 @@ int x86_int_sw_rm(int num)
|
||||
}
|
||||
SP-=6;
|
||||
|
||||
eflags &= ~VIF_FLAG;
|
||||
flags &= ~T_FLAG;
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = new_pc;
|
||||
loadcs(new_cs);
|
||||
oxpc=cpu_state.pc;
|
||||
oxpc=cpu_state.pc;
|
||||
|
||||
cycles -= timing_int_rm;
|
||||
trap = 0;
|
||||
@@ -400,6 +395,8 @@ static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int
|
||||
}
|
||||
|
||||
prefetch_prefixes = 0;
|
||||
if (prefetch_bytes > 16)
|
||||
prefetch_bytes = 16;
|
||||
}
|
||||
|
||||
static void prefetch_flush()
|
||||
@@ -509,14 +506,14 @@ int dontprint=0;
|
||||
#include "386_ops.h"
|
||||
|
||||
|
||||
#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG))
|
||||
#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(cpu_state.flags & T_FLAG))
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
static int cycles_main = 0;
|
||||
|
||||
void exec386_dynarec(int cycs)
|
||||
{
|
||||
uint8_t temp;
|
||||
int vector;
|
||||
uint32_t addr;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
@@ -533,7 +530,6 @@ void exec386_dynarec(int cycs)
|
||||
cycles += cyc_period;
|
||||
cycles_start = cycles;
|
||||
|
||||
timer_start_period(cycles << TIMER_SHIFT);
|
||||
while (cycles>0)
|
||||
{
|
||||
oldcs = CS;
|
||||
@@ -552,18 +548,18 @@ void exec386_dynarec(int cycs)
|
||||
{
|
||||
oldcs=CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl=CPL;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
trap = flags & T_FLAG;
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
@@ -602,7 +598,7 @@ void exec386_dynarec(int cycs)
|
||||
int hash = HASH(phys_addr);
|
||||
codeblock_t *block = codeblock_hash[hash];
|
||||
int valid_block = 0;
|
||||
trap = 0;
|
||||
trap = 0;
|
||||
|
||||
if (block && !cpu_state.abrt)
|
||||
{
|
||||
@@ -699,18 +695,18 @@ inrecomp=0;
|
||||
{
|
||||
oldcs=CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl=CPL;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
trap = flags & T_FLAG;
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
{
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
|
||||
@@ -769,20 +765,20 @@ inrecomp=0;
|
||||
{
|
||||
oldcs=CS;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
oldcpl=CPL;
|
||||
oldcpl = CPL;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
trap = flags & T_FLAG;
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
{
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
|
||||
@@ -857,7 +853,6 @@ inrecomp=0;
|
||||
|
||||
if (trap)
|
||||
{
|
||||
|
||||
flags_rebuild();
|
||||
if (msw&1)
|
||||
{
|
||||
@@ -865,13 +860,13 @@ inrecomp=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,(SP-2)&0xFFFF,flags);
|
||||
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
|
||||
writememw(ss,(SP-4)&0xFFFF,CS);
|
||||
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
|
||||
SP-=6;
|
||||
addr = (1 << 2) + idt.base;
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
@@ -888,35 +883,37 @@ inrecomp=0;
|
||||
nmi = 0;
|
||||
}
|
||||
}
|
||||
else if ((flags&I_FLAG) && pic_intpending)
|
||||
else if ((cpu_state.flags&I_FLAG) && pic_intpending)
|
||||
{
|
||||
temp=picinterrupt();
|
||||
if (temp!=0xFF)
|
||||
vector=picinterrupt();
|
||||
if (vector!=-1)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
flags_rebuild();
|
||||
if (msw&1)
|
||||
{
|
||||
pmodeint(temp,0);
|
||||
pmodeint(vector,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,(SP-2)&0xFFFF,flags);
|
||||
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
|
||||
writememw(ss,(SP-4)&0xFFFF,CS);
|
||||
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
|
||||
SP-=6;
|
||||
addr=temp<<2;
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
addr=vector<<2;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
timer_end_period(cycles << TIMER_SHIFT);
|
||||
cycles_main -= (cycles_start - cycles);
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
|
||||
cycles_main -= (cycles_start - cycles);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -24,14 +24,10 @@
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
extern uint16_t *mod1add[2][8];
|
||||
extern uint32_t *mod1seg[8];
|
||||
|
||||
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 (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
@@ -47,7 +43,6 @@ 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 (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC)
|
||||
{
|
||||
uint32_t addr = easeg + cpu_state.eaaddr;
|
||||
|
||||
@@ -910,6 +910,7 @@ const OpFn OP_TABLE(k6_0f)[1024] =
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
const OpFn OP_TABLE(c6x86mx_0f)[1024] =
|
||||
{
|
||||
/*16-bit data, 16-bit addr*/
|
||||
@@ -1000,6 +1001,7 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] =
|
||||
/*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32,
|
||||
/*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL,
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DEV_BRANCH
|
||||
#ifdef USE_I686
|
||||
|
||||
1431
src/cpu/808x.c
1431
src/cpu/808x.c
File diff suppressed because it is too large
Load Diff
@@ -5,12 +5,12 @@ static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
|
||||
|
||||
static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
CLEAR_BITS((uintptr_t)&flags, D_FLAG);
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
SET_BITS((uintptr_t)&flags, D_FLAG);
|
||||
SET_BITS((uintptr_t)&cpu_state.flags, D_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
@@ -18,14 +18,14 @@ static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
|
||||
{
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
CLEAR_BITS((uintptr_t)&flags, I_FLAG);
|
||||
CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
|
||||
{
|
||||
if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI)))
|
||||
return 0;
|
||||
SET_BITS((uintptr_t)&flags, I_FLAG);
|
||||
SET_BITS((uintptr_t)&cpu_state.flags, I_FLAG);
|
||||
return op_pc;
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp);
|
||||
@@ -168,7 +168,7 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
return op_pc + 1;
|
||||
}
|
||||
@@ -245,7 +245,7 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc + 1);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp);
|
||||
@@ -261,7 +261,7 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
|
||||
host_reg = LOAD_HOST_REG(host_reg);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
return op_pc + 1;
|
||||
}
|
||||
|
||||
@@ -588,16 +588,16 @@ static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
||||
switch (fetchdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
LOAD_SEG(host_reg, &_es);
|
||||
LOAD_SEG(host_reg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
LOAD_SEG(host_reg, &_ds);
|
||||
LOAD_SEG(host_reg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x20: /*FS*/
|
||||
LOAD_SEG(host_reg, &_fs);
|
||||
LOAD_SEG(host_reg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
LOAD_SEG(host_reg, &_gs);
|
||||
LOAD_SEG(host_reg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -644,13 +644,13 @@ static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \
|
||||
} \
|
||||
\
|
||||
if (&rseg == &_ss) \
|
||||
if (&rseg == &cpu_state.seg_ss) \
|
||||
CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \
|
||||
return op_pc + 1; \
|
||||
}
|
||||
|
||||
ropLseg(DS, _ds)
|
||||
ropLseg(ES, _es)
|
||||
ropLseg(FS, _fs)
|
||||
ropLseg(GS, _gs)
|
||||
ropLseg(SS, _ss)
|
||||
ropLseg(DS, cpu_state.seg_ds)
|
||||
ropLseg(ES, cpu_state.seg_es)
|
||||
ropLseg(FS, cpu_state.seg_fs)
|
||||
ropLseg(GS, cpu_state.seg_gs)
|
||||
ropLseg(SS, cpu_state.seg_ss)
|
||||
|
||||
@@ -5,7 +5,7 @@ static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, ui
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_W(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc;
|
||||
@@ -17,7 +17,7 @@ static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, ui
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_L(opcode & 7);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc;
|
||||
@@ -31,7 +31,7 @@ static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+2;
|
||||
@@ -44,7 +44,7 @@ static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+4;
|
||||
@@ -61,7 +61,7 @@ static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_3
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
|
||||
return op_pc+1;
|
||||
@@ -77,7 +77,7 @@ static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_3
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(imm);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
|
||||
return op_pc+1;
|
||||
@@ -87,7 +87,7 @@ static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
SP_MODIFY(2);
|
||||
STORE_REG_TARGET_W_RELEASE(0, opcode & 7);
|
||||
|
||||
@@ -97,7 +97,7 @@ static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
SP_MODIFY(4);
|
||||
STORE_REG_TARGET_L_RELEASE(0, opcode & 7);
|
||||
|
||||
@@ -108,7 +108,7 @@ static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(2);
|
||||
|
||||
@@ -118,7 +118,7 @@ static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
|
||||
{
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(4);
|
||||
|
||||
@@ -131,7 +131,7 @@ static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(2+offset);
|
||||
|
||||
@@ -143,7 +143,7 @@ static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0);
|
||||
SP_MODIFY(4+offset);
|
||||
|
||||
@@ -158,7 +158,7 @@ static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-2);
|
||||
host_reg = LOAD_REG_IMM(op_pc+2);
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-2);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff);
|
||||
|
||||
@@ -172,7 +172,7 @@ static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_STACK_TO_EA(-4);
|
||||
host_reg = LOAD_REG_IMM(op_pc+4);
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg);
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg);
|
||||
SP_MODIFY(-4);
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset);
|
||||
|
||||
@@ -185,7 +185,7 @@ static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_W(&_ss);
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/
|
||||
ADD_HOST_REG_IMM_W(host_reg, 2);
|
||||
STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP);
|
||||
@@ -199,7 +199,7 @@ static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
|
||||
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
|
||||
LOAD_EBP_TO_EA(0);
|
||||
MEM_LOAD_ADDR_EA_L(&_ss);
|
||||
MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss);
|
||||
host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/
|
||||
ADD_HOST_REG_IMM(host_reg, 4);
|
||||
STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP);
|
||||
@@ -216,7 +216,7 @@ static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-2); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
|
||||
MEM_STORE_ADDR_EA_W(&_ss, host_reg); \
|
||||
MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-2); \
|
||||
\
|
||||
return op_pc; \
|
||||
@@ -228,7 +228,7 @@ static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(-4); \
|
||||
host_reg = LOAD_VAR_W((uintptr_t)&seg); \
|
||||
MEM_STORE_ADDR_EA_L(&_ss, host_reg); \
|
||||
MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \
|
||||
SP_MODIFY(-4); \
|
||||
\
|
||||
return op_pc; \
|
||||
@@ -246,7 +246,7 @@ static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&_ss); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(2); \
|
||||
\
|
||||
@@ -256,14 +256,14 @@ static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_
|
||||
{ \
|
||||
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
|
||||
LOAD_STACK_TO_EA(0); \
|
||||
MEM_LOAD_ADDR_EA_W(&_ss); \
|
||||
MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \
|
||||
LOAD_SEG(0, &rseg); \
|
||||
SP_MODIFY(4); \
|
||||
\
|
||||
return op_pc; \
|
||||
}
|
||||
|
||||
ROP_POP_SEG(DS, _ds)
|
||||
ROP_POP_SEG(ES, _es)
|
||||
ROP_POP_SEG(FS, _fs)
|
||||
ROP_POP_SEG(GS, _gs)
|
||||
ROP_POP_SEG(DS, cpu_state.seg_ds)
|
||||
ROP_POP_SEG(ES, cpu_state.seg_es)
|
||||
ROP_POP_SEG(FS, cpu_state.seg_fs)
|
||||
ROP_POP_SEG(GS, cpu_state.seg_gs)
|
||||
|
||||
@@ -647,7 +647,7 @@ static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u
|
||||
}
|
||||
|
||||
if (mod1seg[rm] == &ss && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
@@ -796,7 +796,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u
|
||||
addlong(stack_offset);
|
||||
}
|
||||
if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -814,7 +814,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u
|
||||
if (mod)
|
||||
{
|
||||
if (rm == 5 && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
if (mod == 1)
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+imm8*/
|
||||
@@ -857,14 +857,14 @@ static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_sseg
|
||||
static inline void CHECK_SEG_READ(x86seg *seg)
|
||||
{
|
||||
/*Segments always valid in real/V86 mode*/
|
||||
if (!(cr0 & 1) || (eflags & VM_FLAG))
|
||||
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
|
||||
return;
|
||||
/*CS and SS must always be valid*/
|
||||
if (seg == &_cs || seg == &_ss)
|
||||
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
return;
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
@@ -893,14 +893,14 @@ static inline void CHECK_SEG_READ(x86seg *seg)
|
||||
static inline void CHECK_SEG_WRITE(x86seg *seg)
|
||||
{
|
||||
/*Segments always valid in real/V86 mode*/
|
||||
if (!(cr0 & 1) || (eflags & VM_FLAG))
|
||||
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
|
||||
return;
|
||||
/*CS and SS must always be valid*/
|
||||
if (seg == &_cs || seg == &_ss)
|
||||
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
return;
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
@@ -928,7 +928,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
|
||||
}
|
||||
static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
return;
|
||||
|
||||
if (IS_32_ADDR(&seg->base))
|
||||
@@ -967,7 +967,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
|
||||
static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -1040,7 +1040,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
}
|
||||
static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -1126,7 +1126,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
}
|
||||
static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -1204,7 +1204,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
}
|
||||
static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -1325,7 +1325,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
addbyte(8);
|
||||
host_reg = 8;
|
||||
}
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -1409,7 +1409,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -1500,7 +1500,7 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -1589,7 +1589,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -5270,7 +5270,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
|
||||
|
||||
CHECK_SEG_WRITE(seg);
|
||||
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -5321,7 +5321,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
|
||||
addbyte(0xc1); /*SHR EDI, 12*/
|
||||
addbyte(0xef);
|
||||
addbyte(12);
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xfe);
|
||||
@@ -5352,7 +5352,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
|
||||
jump2 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
*jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1;
|
||||
/*slowpath:*/
|
||||
addbyte(0x67); /*LEA EDI, [EAX+ESI]*/
|
||||
@@ -5385,7 +5385,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
|
||||
CHECK_SEG_WRITE(seg);
|
||||
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -5433,7 +5433,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
addbyte(0x79); /*JNS +*/
|
||||
jump1 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xfe);
|
||||
@@ -5442,7 +5442,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
addbyte(0x8d); /*LEA ESI, 1[EDI]*/
|
||||
addbyte(0x77);
|
||||
addbyte(0x01);
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
jump4 = &codeblock[block_current].data[block_pos];
|
||||
@@ -5498,7 +5498,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
|
||||
/*slowpath:*/
|
||||
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
|
||||
jump_pos = block_pos;
|
||||
load_param_1_reg_32(REG_EBX);
|
||||
@@ -5534,7 +5534,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
|
||||
CHECK_SEG_WRITE(seg);
|
||||
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -5582,7 +5582,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
addbyte(0x79); /*JNS +*/
|
||||
jump1 = &codeblock[block_current].data[block_pos];
|
||||
addbyte(0);
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x83); /*CMP ESI, -1*/
|
||||
addbyte(0xfe);
|
||||
@@ -5591,7 +5591,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
addbyte(0x8d); /*LEA ESI, 3[EDI]*/
|
||||
addbyte(0x77);
|
||||
addbyte(0x03);
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x74); /*JE slowpath*/
|
||||
jump4 = &codeblock[block_current].data[block_pos];
|
||||
@@ -5647,7 +5647,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
|
||||
/*slowpath:*/
|
||||
*jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1;
|
||||
if (!(seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
*jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1;
|
||||
jump_pos = block_pos;
|
||||
load_param_1_reg_32(REG_EBX);
|
||||
@@ -5678,7 +5678,7 @@ static inline void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
|
||||
static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -5750,7 +5750,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -5828,7 +5828,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ECX, ECX*/
|
||||
addbyte(0xc9);
|
||||
@@ -5928,7 +5928,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
addbyte(8);
|
||||
host_reg = 8;
|
||||
}
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EBX, EBX*/
|
||||
addbyte(0xdb);
|
||||
@@ -6005,7 +6005,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EBX, EBX*/
|
||||
addbyte(0xdb);
|
||||
@@ -6089,7 +6089,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EBX, EBX*/
|
||||
addbyte(0xdb);
|
||||
|
||||
@@ -611,14 +611,14 @@ static inline void SAR_L_IMM(int reg, int count)
|
||||
static inline void CHECK_SEG_READ(x86seg *seg)
|
||||
{
|
||||
/*Segments always valid in real/V86 mode*/
|
||||
if (!(cr0 & 1) || (eflags & VM_FLAG))
|
||||
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
|
||||
return;
|
||||
/*CS and SS must always be valid*/
|
||||
if (seg == &_cs || seg == &_ss)
|
||||
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
return;
|
||||
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
@@ -634,14 +634,14 @@ static inline void CHECK_SEG_READ(x86seg *seg)
|
||||
static inline void CHECK_SEG_WRITE(x86seg *seg)
|
||||
{
|
||||
/*Segments always valid in real/V86 mode*/
|
||||
if (!(cr0 & 1) || (eflags & VM_FLAG))
|
||||
if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG))
|
||||
return;
|
||||
/*CS and SS must always be valid*/
|
||||
if (seg == &_cs || seg == &_ss)
|
||||
if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss)
|
||||
return;
|
||||
if (seg->checked)
|
||||
return;
|
||||
if (seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS))
|
||||
return;
|
||||
|
||||
addbyte(0x83); /*CMP seg->base, -1*/
|
||||
@@ -656,7 +656,7 @@ static inline void CHECK_SEG_WRITE(x86seg *seg)
|
||||
}
|
||||
static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
return;
|
||||
|
||||
addbyte(0x3b); /*CMP EAX, seg->limit_low*/
|
||||
@@ -684,7 +684,7 @@ static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset)
|
||||
|
||||
static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -702,7 +702,7 @@ static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg)
|
||||
}
|
||||
static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -722,7 +722,7 @@ static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -740,7 +740,7 @@ static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg)
|
||||
}
|
||||
static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -761,7 +761,7 @@ static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset)
|
||||
}
|
||||
static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -781,7 +781,7 @@ static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg)
|
||||
}
|
||||
static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -800,7 +800,7 @@ static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg)
|
||||
}
|
||||
static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -821,7 +821,7 @@ static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg)
|
||||
|
||||
static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR EDX, EDX*/
|
||||
addbyte(0xd2);
|
||||
@@ -859,7 +859,7 @@ static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr)
|
||||
|
||||
static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -880,7 +880,7 @@ static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -901,7 +901,7 @@ static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -922,7 +922,7 @@ static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -943,7 +943,7 @@ static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -964,7 +964,7 @@ static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg)
|
||||
}
|
||||
static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg)
|
||||
{
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -995,7 +995,7 @@ static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2)
|
||||
addbyte(0x89); /*MOV ECX, host_reg2*/
|
||||
addbyte(0xc0 | REG_ECX | (host_reg2 << 3));
|
||||
}
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -1087,7 +1087,7 @@ static inline x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_s
|
||||
addlong(0xffff);
|
||||
|
||||
if (mod1seg[rm] == &ss && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
@@ -1154,7 +1154,7 @@ static inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_s
|
||||
}
|
||||
}
|
||||
if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
{
|
||||
switch (sib >> 6)
|
||||
@@ -1199,7 +1199,7 @@ static inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_s
|
||||
if (mod)
|
||||
{
|
||||
if (rm == 5 && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
if (mod == 1)
|
||||
{
|
||||
addbyte(0x83); /*ADD EAX, imm8*/
|
||||
@@ -3919,7 +3919,7 @@ static inline void LOAD_EA()
|
||||
static inline void MEM_CHECK_WRITE(x86seg *seg)
|
||||
{
|
||||
CHECK_SEG_WRITE(seg);
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -3937,7 +3937,7 @@ static inline void MEM_CHECK_WRITE(x86seg *seg)
|
||||
static inline void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
{
|
||||
CHECK_SEG_WRITE(seg);
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
@@ -3955,7 +3955,7 @@ static inline void MEM_CHECK_WRITE_W(x86seg *seg)
|
||||
static inline void MEM_CHECK_WRITE_L(x86seg *seg)
|
||||
{
|
||||
CHECK_SEG_WRITE(seg);
|
||||
if ((seg == &_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS)))
|
||||
{
|
||||
addbyte(0x31); /*XOR ESI, ESI*/
|
||||
addbyte(0xf6);
|
||||
|
||||
@@ -817,7 +817,7 @@ static inline int COUNT(uint64_t timings, uint64_t deps, int op_32)
|
||||
case CYCLES_RMW:
|
||||
return 3;
|
||||
case CYCLES_BRANCH:
|
||||
return cpu_hasMMX ? 1 : 2;
|
||||
return cpu_has_feature(CPU_FEATURE_MMX) ? 1 : 2;
|
||||
}
|
||||
|
||||
fatal("Illegal COUNT %016llx\n", timings);
|
||||
@@ -950,13 +950,13 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat)
|
||||
last_prefix = prefix;
|
||||
return;
|
||||
}
|
||||
if (cpu_hasMMX && prefix == 0x0f)
|
||||
if (cpu_has_feature(CPU_FEATURE_MMX) && prefix == 0x0f)
|
||||
{
|
||||
/*On Pentium MMX 0fh prefix is 'free'*/
|
||||
last_prefix = prefix;
|
||||
return;
|
||||
}
|
||||
if (cpu_hasMMX && (prefix == 0x66 || prefix == 0x67))
|
||||
if (cpu_has_feature(CPU_FEATURE_MMX) && (prefix == 0x66 || prefix == 0x67))
|
||||
{
|
||||
/*On Pentium MMX 66h and 67h prefixes take 2 clocks*/
|
||||
decode_delay_offset += 2;
|
||||
@@ -1223,7 +1223,7 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
|
||||
else
|
||||
has_displacement = 0;
|
||||
|
||||
if (!has_displacement && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
|
||||
if (!has_displacement && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
|
||||
{
|
||||
int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK;
|
||||
int t2 = timings[opcode] & CYCLES_MASK;
|
||||
@@ -1276,7 +1276,7 @@ nopair:
|
||||
else
|
||||
has_displacement = 0;
|
||||
|
||||
if ((!has_displacement || cpu_hasMMX) && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
|
||||
if ((!has_displacement || cpu_has_feature(CPU_FEATURE_MMX)) && (!cpu_has_feature(CPU_FEATURE_MMX) || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7))
|
||||
{
|
||||
/*Instruction might pair with next*/
|
||||
u_pipe_full = 1;
|
||||
|
||||
@@ -376,7 +376,7 @@ void codegen_block_start_recompile(codeblock_t *block)
|
||||
codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] =
|
||||
codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0;
|
||||
|
||||
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
|
||||
cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1;
|
||||
|
||||
codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] =
|
||||
codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0;
|
||||
@@ -692,7 +692,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
||||
addbyte((uint8_t)cpu_state_offset(eaaddr));
|
||||
|
||||
if (mod1seg[cpu_rm] == &ss && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
@@ -840,7 +840,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
||||
addlong(stack_offset);
|
||||
}
|
||||
if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
|
||||
addbyte(0x89); /*MOV eaaddr, EAX*/
|
||||
addbyte(0x45);
|
||||
@@ -864,7 +864,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
||||
if (cpu_mod)
|
||||
{
|
||||
if (cpu_rm == 5 && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
if (cpu_mod == 1)
|
||||
{
|
||||
addbyte(0x67); /*LEA EAX, base_reg+imm8*/
|
||||
@@ -913,7 +913,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
int test_modrm = 1;
|
||||
int c;
|
||||
|
||||
op_ea_seg = &_ds;
|
||||
op_ea_seg = &cpu_state.seg_ds;
|
||||
op_ssegs = 0;
|
||||
op_old_pc = old_pc;
|
||||
|
||||
@@ -935,27 +935,27 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
break;
|
||||
|
||||
case 0x26: /*ES:*/
|
||||
op_ea_seg = &_es;
|
||||
op_ea_seg = &cpu_state.seg_es;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x2e: /*CS:*/
|
||||
op_ea_seg = &_cs;
|
||||
op_ea_seg = &cpu_state.seg_cs;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x36: /*SS:*/
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x3e: /*DS:*/
|
||||
op_ea_seg = &_ds;
|
||||
op_ea_seg = &cpu_state.seg_ds;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x64: /*FS:*/
|
||||
op_ea_seg = &_fs;
|
||||
op_ea_seg = &cpu_state.seg_fs;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x65: /*GS:*/
|
||||
op_ea_seg = &_gs;
|
||||
op_ea_seg = &cpu_state.seg_gs;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
|
||||
|
||||
@@ -1495,7 +1495,7 @@ void codegen_block_start_recompile(codeblock_t *block)
|
||||
codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] =
|
||||
codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0;
|
||||
|
||||
_ds.checked = _es.checked = _fs.checked = _gs.checked = (cr0 & 1) ? 0 : 1;
|
||||
cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1;
|
||||
|
||||
block->TOP = cpu_state.TOP;
|
||||
block->was_recompiled = 1;
|
||||
@@ -1735,7 +1735,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
||||
addlong((uint32_t)&cpu_state.eaaddr);
|
||||
|
||||
if (mod1seg[cpu_rm] == &ss && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
return op_ea_seg;
|
||||
}
|
||||
@@ -1791,7 +1791,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
||||
addlong(stack_offset);
|
||||
}
|
||||
if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
if (((sib >> 3) & 7) != 4)
|
||||
{
|
||||
switch (sib >> 6)
|
||||
@@ -1840,7 +1840,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
|
||||
if (cpu_mod)
|
||||
{
|
||||
if (cpu_rm == 5 && !op_ssegs)
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
if (cpu_mod == 1)
|
||||
{
|
||||
addbyte(0x05);
|
||||
@@ -1875,7 +1875,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
int test_modrm = 1;
|
||||
int c;
|
||||
|
||||
op_ea_seg = &_ds;
|
||||
op_ea_seg = &cpu_state.seg_ds;
|
||||
op_ssegs = 0;
|
||||
op_old_pc = old_pc;
|
||||
|
||||
@@ -1898,27 +1898,27 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t
|
||||
break;
|
||||
|
||||
case 0x26: /*ES:*/
|
||||
op_ea_seg = &_es;
|
||||
op_ea_seg = &cpu_state.seg_es;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x2e: /*CS:*/
|
||||
op_ea_seg = &_cs;
|
||||
op_ea_seg = &cpu_state.seg_cs;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x36: /*SS:*/
|
||||
op_ea_seg = &_ss;
|
||||
op_ea_seg = &cpu_state.seg_ss;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x3e: /*DS:*/
|
||||
op_ea_seg = &_ds;
|
||||
op_ea_seg = &cpu_state.seg_ds;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x64: /*FS:*/
|
||||
op_ea_seg = &_fs;
|
||||
op_ea_seg = &cpu_state.seg_fs;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
case 0x65: /*GS:*/
|
||||
op_ea_seg = &_gs;
|
||||
op_ea_seg = &cpu_state.seg_gs;
|
||||
op_ssegs = 1;
|
||||
break;
|
||||
|
||||
@@ -2131,7 +2131,7 @@ generate_call:
|
||||
if (op_ea_seg != last_ea_seg)
|
||||
{
|
||||
last_ea_seg = op_ea_seg;
|
||||
addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/
|
||||
addbyte(0xC7); /*MOVL $&cpu_state.seg_ds,(ea_seg)*/
|
||||
addbyte(0x45);
|
||||
addbyte((uint8_t)cpu_state_offset(ea_seg));
|
||||
addlong((uint32_t)op_ea_seg);
|
||||
|
||||
184
src/cpu/cpu.c
184
src/cpu/cpu.c
@@ -49,12 +49,20 @@
|
||||
#include "../io.h"
|
||||
#include "x86_ops.h"
|
||||
#include "../mem.h"
|
||||
#include "../nmi.h"
|
||||
#include "../pic.h"
|
||||
#include "../pci.h"
|
||||
#ifdef USE_DYNAREC
|
||||
# include "codegen.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
static void cpu_write(uint16_t addr, uint8_t val, void *priv);
|
||||
static uint8_t cpu_read(uint16_t addr, void *priv);
|
||||
#endif
|
||||
|
||||
|
||||
enum {
|
||||
CPUID_FPU = (1 << 0),
|
||||
CPUID_VME = (1 << 1),
|
||||
@@ -120,7 +128,6 @@ 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;
|
||||
@@ -130,7 +137,9 @@ 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 cpu_pci_speed, cpu_alt_reset;
|
||||
|
||||
uint32_t cpu_features;
|
||||
|
||||
int is286,
|
||||
is386,
|
||||
@@ -139,12 +148,7 @@ int is286,
|
||||
israpidcad,
|
||||
is_pentium;
|
||||
|
||||
int hasfpu,
|
||||
cpu_hasrdtsc,
|
||||
cpu_hasMMX,
|
||||
cpu_hasMSR,
|
||||
cpu_hasCR4,
|
||||
cpu_hasVME;
|
||||
int hasfpu;
|
||||
|
||||
|
||||
uint64_t tsc = 0;
|
||||
@@ -205,6 +209,11 @@ int timing_misaligned;
|
||||
|
||||
static uint8_t ccr0, ccr1, ccr2, ccr3, ccr4, ccr5, ccr6;
|
||||
|
||||
int cpu_has_feature(int feature)
|
||||
{
|
||||
return cpu_features & feature;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cpu_dynamic_switch(int new_cpu)
|
||||
@@ -236,36 +245,40 @@ cpu_set(void)
|
||||
cpu_manufacturer = 0;
|
||||
cpu = 0;
|
||||
}
|
||||
|
||||
|
||||
cpu_effective = cpu;
|
||||
cpu_s = &machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective];
|
||||
|
||||
cpu_alt_reset = 0;
|
||||
|
||||
CPUID = cpu_s->cpuid_model;
|
||||
cpuspeed = cpu_s->speed;
|
||||
is8086 = (cpu_s->cpu_type > CPU_8088);
|
||||
is286 = (cpu_s->cpu_type >= CPU_286);
|
||||
is386 = (cpu_s->cpu_type >= CPU_386SX);
|
||||
israpidcad = (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
is_pentium= (cpu_s->cpu_type >= CPU_WINCHIP);
|
||||
is_pentium = (cpu_s->cpu_type >= CPU_WINCHIP);
|
||||
hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD);
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1);
|
||||
#else
|
||||
cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86);
|
||||
#endif
|
||||
|
||||
cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC);
|
||||
if (cpu_s->multi)
|
||||
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
|
||||
if (cpu_s->multi) {
|
||||
if (cpu_s->pci_speed)
|
||||
cpu_busspeed = cpu_s->pci_speed;
|
||||
else
|
||||
cpu_busspeed = cpu_s->rspeed / cpu_s->multi;
|
||||
}
|
||||
cpu_multi = cpu_s->multi;
|
||||
cpu_hasrdtsc = 0;
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 0;
|
||||
cpu_hasCR4 = 0;
|
||||
ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0;
|
||||
|
||||
if ((cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || (cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX))
|
||||
{
|
||||
if (enable_external_fpu)
|
||||
{
|
||||
hasfpu = 1;
|
||||
}
|
||||
if ((cpu_s->cpu_type == CPU_8088) || (cpu_s->cpu_type == CPU_8086) ||
|
||||
(cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) ||
|
||||
(cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX)) {
|
||||
hasfpu = !!enable_external_fpu;
|
||||
}
|
||||
|
||||
cpu_update_waitstates();
|
||||
@@ -289,10 +302,15 @@ cpu_set(void)
|
||||
}
|
||||
|
||||
if (cpu_iscyrix)
|
||||
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
|
||||
io_sethandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
|
||||
else
|
||||
io_removehandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
|
||||
|
||||
io_removehandler(0x0022, 0x0002, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
|
||||
|
||||
if (hasfpu)
|
||||
io_sethandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
|
||||
else
|
||||
io_removehandler(0x00f0, 0x000f, cpu_read, NULL, NULL, cpu_write, NULL, NULL, NULL);
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
x86_setopcodes(ops_386, ops_386_0f, dynarec_ops_386, dynarec_ops_386_0f);
|
||||
#else
|
||||
@@ -636,8 +654,7 @@ cpu_set(void)
|
||||
break;
|
||||
|
||||
case CPU_iDX4:
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_hasVME = 1;
|
||||
cpu_features = CPU_FEATURE_CR4 | CPU_FEATURE_VME;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_VME;
|
||||
case CPU_i486SX:
|
||||
case CPU_i486DX:
|
||||
@@ -807,10 +824,8 @@ cpu_set(void)
|
||||
timing_mml = 3;
|
||||
timing_bt = 3-1; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MMX | CPU_FEATURE_MSR | CPU_FEATURE_CR4;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
||||
/*unknown*/
|
||||
timing_int_rm = 26;
|
||||
@@ -873,12 +888,8 @@ cpu_set(void)
|
||||
timing_jmp_pm = 3;
|
||||
timing_jmp_pm_gate = 18;
|
||||
timing_misaligned = 3;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_hasVME = 1;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_pentium);
|
||||
@@ -920,18 +931,15 @@ cpu_set(void)
|
||||
timing_jmp_pm = 3;
|
||||
timing_jmp_pm_gate = 18;
|
||||
timing_misaligned = 3;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 1;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_hasVME = 1;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_pentium);
|
||||
#endif
|
||||
break;
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
case CPU_Cx6x86:
|
||||
#ifdef USE_DYNAREC
|
||||
x86_setopcodes(ops_386, ops_pentium_0f, dynarec_ops_386, dynarec_ops_pentium_0f);
|
||||
@@ -967,11 +975,8 @@ cpu_set(void)
|
||||
timing_jmp_pm_gate = 14;
|
||||
timing_misaligned = 2;
|
||||
cpu_cyrix_alignment = 1;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 0;
|
||||
cpu_hasCR4 = 0;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_686);
|
||||
#endif
|
||||
@@ -1013,11 +1018,8 @@ cpu_set(void)
|
||||
timing_jmp_pm_gate = 14;
|
||||
timing_misaligned = 2;
|
||||
cpu_cyrix_alignment = 1;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 0;
|
||||
cpu_hasCR4 = 0;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_686);
|
||||
#endif
|
||||
@@ -1042,11 +1044,8 @@ cpu_set(void)
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
timing_misaligned = 2;
|
||||
cpu_cyrix_alignment = 1;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_686);
|
||||
@@ -1101,17 +1100,15 @@ cpu_set(void)
|
||||
timing_jmp_pm_gate = 14;
|
||||
timing_misaligned = 2;
|
||||
cpu_cyrix_alignment = 1;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_MMX;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 1;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_PCE;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_686);
|
||||
#endif
|
||||
ccr4 = 0x80;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
|
||||
case CPU_K5:
|
||||
@@ -1131,11 +1128,8 @@ cpu_set(void)
|
||||
timing_bt = 0; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
timing_misaligned = 3;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 1;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
|
||||
break;
|
||||
|
||||
@@ -1155,12 +1149,8 @@ cpu_set(void)
|
||||
timing_bt = 0; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
timing_misaligned = 3;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 1;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_hasVME = 1;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_pentium);
|
||||
@@ -1197,12 +1187,8 @@ cpu_set(void)
|
||||
timing_bt = 0; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
timing_misaligned = 3;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 0;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_hasVME = 1;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_686);
|
||||
@@ -1238,12 +1224,8 @@ cpu_set(void)
|
||||
timing_bt = 0; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
timing_misaligned = 3;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 1;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_hasVME = 1;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_686);
|
||||
@@ -1279,12 +1261,8 @@ cpu_set(void)
|
||||
timing_bt = 0; /*branch taken*/
|
||||
timing_bnt = 1; /*branch not taken*/
|
||||
timing_misaligned = 3;
|
||||
cpu_hasrdtsc = 1;
|
||||
cpu_features = CPU_FEATURE_RDTSC | CPU_FEATURE_MSR | CPU_FEATURE_CR4 | CPU_FEATURE_VME | CPU_FEATURE_MMX;
|
||||
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
|
||||
cpu_hasMMX = 1;
|
||||
cpu_hasMSR = 1;
|
||||
cpu_hasCR4 = 1;
|
||||
cpu_hasVME = 1;
|
||||
cpu_CR4_mask = CR4_VME | CR4_PVI | CR4_TSD | CR4_DE | CR4_PSE | CR4_MCE | CR4_PCE | CR4_OSFXSR;
|
||||
#ifdef USE_DYNAREC
|
||||
codegen_timing_set(&codegen_timing_686);
|
||||
@@ -1410,7 +1388,7 @@ cpu_CPUID(void)
|
||||
EAX = 0x540;
|
||||
EBX = ECX = 0;
|
||||
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR;
|
||||
if (msr.fcr & (1 << 1))
|
||||
if (cpu_has_feature(CPU_FEATURE_CX8))
|
||||
EDX |= CPUID_CMPXCHG8B;
|
||||
if (msr.fcr & (1 << 9))
|
||||
EDX |= CPUID_MMX;
|
||||
@@ -1590,6 +1568,7 @@ cpu_CPUID(void)
|
||||
break;
|
||||
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
case CPU_Cx6x86:
|
||||
if (!EAX)
|
||||
{
|
||||
@@ -1665,6 +1644,7 @@ cpu_CPUID(void)
|
||||
else
|
||||
EAX = EBX = ECX = EDX = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DEV_BRANCH
|
||||
#ifdef USE_I686
|
||||
@@ -1820,6 +1800,7 @@ void cpu_RDMSR()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
case CPU_Cx6x86:
|
||||
case CPU_Cx6x86L:
|
||||
case CPU_CxGX1:
|
||||
@@ -1832,6 +1813,7 @@ void cpu_RDMSR()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DEV_BRANCH
|
||||
#ifdef USE_I686
|
||||
@@ -1953,6 +1935,7 @@ void cpu_RDMSR()
|
||||
break;
|
||||
default:
|
||||
i686_invalid_rdmsr:
|
||||
pclog("Invalid MSR read %08X\n", ECX);
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
@@ -1983,11 +1966,18 @@ void cpu_WRMSR()
|
||||
break;
|
||||
case 0x107:
|
||||
msr.fcr = EAX;
|
||||
cpu_hasMMX = EAX & (1 << 9);
|
||||
if (EAX & (1 << 29))
|
||||
CPUID = 0;
|
||||
if (EAX & (1 << 9))
|
||||
cpu_features |= CPU_FEATURE_MMX;
|
||||
else
|
||||
CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpuid_model;
|
||||
cpu_features &= ~CPU_FEATURE_MMX;
|
||||
if (EAX & (1 << 1))
|
||||
cpu_features |= CPU_FEATURE_CX8;
|
||||
else
|
||||
cpu_features &= ~CPU_FEATURE_CX8;
|
||||
if (EAX & (1 << 29))
|
||||
CPUID = 0;
|
||||
else
|
||||
CPUID = machines[machine].cpu[cpu_manufacturer].cpus[cpu].cpuid_model;
|
||||
break;
|
||||
case 0x108:
|
||||
msr.fcr2 = EAX | ((uint64_t)EDX << 32);
|
||||
@@ -2032,6 +2022,7 @@ void cpu_WRMSR()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
case CPU_Cx6x86:
|
||||
case CPU_Cx6x86L:
|
||||
case CPU_CxGX1:
|
||||
@@ -2043,6 +2034,7 @@ void cpu_WRMSR()
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef DEV_BRANCH
|
||||
#ifdef USE_I686
|
||||
@@ -2132,6 +2124,7 @@ void cpu_WRMSR()
|
||||
break;
|
||||
default:
|
||||
i686_invalid_wrmsr:
|
||||
pclog("Invalid MSR write %08X: %08X%08X\n", ECX, EDX, EAX);
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
@@ -2143,8 +2136,18 @@ i686_invalid_wrmsr:
|
||||
|
||||
static int cyrix_addr;
|
||||
|
||||
void cyrix_write(uint16_t addr, uint8_t val, void *priv)
|
||||
static void cpu_write(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
if (addr == 0xf0) {
|
||||
/* Writes to F0 clear FPU error and deassert the interrupt. */
|
||||
if (is286)
|
||||
picintc(1 << 13);
|
||||
else
|
||||
nmi = 0;
|
||||
return;
|
||||
} else if (addr >= 0xf1)
|
||||
return; /* FPU stuff */
|
||||
|
||||
if (!(addr & 1))
|
||||
cyrix_addr = val;
|
||||
else switch (cyrix_addr)
|
||||
@@ -2165,6 +2168,7 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv)
|
||||
if ((ccr3 & 0xf0) == 0x10)
|
||||
{
|
||||
ccr4 = val;
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
if (machines[machine].cpu[cpu_manufacturer].cpus[cpu_effective].cpu_type >= CPU_Cx6x86)
|
||||
{
|
||||
if (val & 0x80)
|
||||
@@ -2172,6 +2176,7 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv)
|
||||
else
|
||||
CPUID = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 0xe9: /*CCR5*/
|
||||
@@ -2185,8 +2190,11 @@ void cyrix_write(uint16_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t cyrix_read(uint16_t addr, void *priv)
|
||||
static uint8_t cpu_read(uint16_t addr, void *priv)
|
||||
{
|
||||
if (addr >= 0xf0)
|
||||
return 0xff; /* FPU stuff */
|
||||
|
||||
if (addr & 1)
|
||||
{
|
||||
switch (cyrix_addr)
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
* Copyright 2016-2018 leilei.
|
||||
* Copyright 2016,2018 Miran Grca.
|
||||
*/
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#include "../cpu_new/cpu.h"
|
||||
#else
|
||||
|
||||
#ifndef EMU_CPU_H
|
||||
# define EMU_CPU_H
|
||||
|
||||
@@ -77,17 +81,16 @@
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int cpu_type;
|
||||
int speed;
|
||||
int rspeed;
|
||||
int multi;
|
||||
int pci_speed;
|
||||
uint32_t edx_reset;
|
||||
uint32_t cpuid_model;
|
||||
uint16_t cyrix_id;
|
||||
int cpu_flags;
|
||||
int mem_read_cycles, mem_write_cycles;
|
||||
int cache_read_cycles, cache_write_cycles;
|
||||
int atclk_div;
|
||||
uint8_t cpu_flags;
|
||||
int8_t mem_read_cycles, mem_write_cycles;
|
||||
int8_t cache_read_cycles, cache_write_cycles;
|
||||
int8_t atclk_div;
|
||||
} CPU;
|
||||
|
||||
extern CPU cpus_8088[];
|
||||
@@ -143,9 +146,9 @@ extern CPU cpus_Pentium2D[];
|
||||
#define CR4_PVI (1 << 1)
|
||||
#define CR4_PSE (1 << 4)
|
||||
|
||||
#define CPL ((_cs.access>>5)&3)
|
||||
#define CPL ((cpu_state.seg_cs.access>>5)&3)
|
||||
|
||||
#define IOPL ((flags>>12)&3)
|
||||
#define IOPL ((cpu_state.flags>>12)&3)
|
||||
|
||||
#define IOPLp ((!(msw&1)) || (CPL<=IOPL))
|
||||
|
||||
@@ -240,9 +243,18 @@ struct _cpustate_ {
|
||||
uint16_t old_npxc,
|
||||
new_npxc;
|
||||
uint32_t last_ea;
|
||||
|
||||
x86seg seg_cs,
|
||||
seg_ds,
|
||||
seg_es,
|
||||
seg_ss,
|
||||
seg_fs,
|
||||
seg_gs;
|
||||
|
||||
uint16_t flags, eflags;
|
||||
} cpu_state;
|
||||
|
||||
/*The flags below must match in both cpu_cur_status and block->status for a block
|
||||
/*The cpu_state.flags below must match in both cpu_cur_status and block->status for a block
|
||||
to be valid*/
|
||||
#define CPU_STATUS_USE32 (1 << 0)
|
||||
#define CPU_STATUS_STACK32 (1 << 1)
|
||||
@@ -250,7 +262,7 @@ struct _cpustate_ {
|
||||
#define CPU_STATUS_V86 (1 << 3)
|
||||
#define CPU_STATUS_FLAGS 0xffff
|
||||
|
||||
/*If the flags below are set in cpu_cur_status, they must be set in block->status.
|
||||
/*If the cpu_state.flags below are set in cpu_cur_status, they must be set in block->status.
|
||||
Otherwise they are ignored*/
|
||||
#define CPU_STATUS_NOTFLATDS (1 << 16)
|
||||
#define CPU_STATUS_NOTFLATSS (1 << 17)
|
||||
@@ -319,18 +331,20 @@ extern int cpu_cyrix_alignment; /*Cyrix 5x86/6x86 only has data misalignment
|
||||
extern int is8086, is286, is386, is486;
|
||||
extern int is_rapidcad;
|
||||
extern int hasfpu;
|
||||
extern int cpu_hasrdtsc;
|
||||
extern int cpu_hasMSR;
|
||||
extern int cpu_hasMMX;
|
||||
extern int cpu_hasCR4;
|
||||
extern int cpu_hasVME;
|
||||
#define CPU_FEATURE_RDTSC (1 << 0)
|
||||
#define CPU_FEATURE_MSR (1 << 1)
|
||||
#define CPU_FEATURE_MMX (1 << 2)
|
||||
#define CPU_FEATURE_CR4 (1 << 3)
|
||||
#define CPU_FEATURE_VME (1 << 4)
|
||||
#define CPU_FEATURE_CX8 (1 << 5)
|
||||
#define CPU_FEATURE_3DNOW (1 << 6)
|
||||
|
||||
extern uint32_t cpu_features;
|
||||
|
||||
extern uint32_t cpu_cur_status;
|
||||
extern uint64_t cpu_CR4_mask;
|
||||
extern uint64_t tsc;
|
||||
extern msr_t msr;
|
||||
extern int cpuspeed;
|
||||
extern int cycles_lost;
|
||||
extern uint8_t opcode;
|
||||
extern int insc;
|
||||
extern int fpucount;
|
||||
@@ -339,16 +353,14 @@ extern int clockrate;
|
||||
extern int cgate16;
|
||||
extern int cpl_override;
|
||||
extern int CPUID;
|
||||
extern int xt_cpu_multi;
|
||||
extern uint64_t xt_cpu_multi;
|
||||
extern int isa_cycles;
|
||||
extern uint16_t flags,eflags;
|
||||
extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
|
||||
extern int ins,output;
|
||||
extern int cycdiff;
|
||||
extern uint32_t pccache;
|
||||
extern uint8_t *pccache2;
|
||||
|
||||
extern float isa_timing, bus_timing;
|
||||
extern double bus_timing;
|
||||
extern uint64_t pmc[2];
|
||||
extern uint16_t temp_seg_data[4];
|
||||
extern uint16_t cs_msr;
|
||||
@@ -372,24 +384,22 @@ extern uint32_t dr[8];
|
||||
CS,DS,ES,SS is the 16-bit data
|
||||
cs,ds,es,ss are defines to the bases*/
|
||||
extern x86seg gdt,ldt,idt,tr;
|
||||
extern x86seg _cs,_ds,_es,_ss,_fs,_gs;
|
||||
extern x86seg _oldds;
|
||||
#define CS _cs.seg
|
||||
#define DS _ds.seg
|
||||
#define ES _es.seg
|
||||
#define SS _ss.seg
|
||||
#define FS _fs.seg
|
||||
#define GS _gs.seg
|
||||
#define cs _cs.base
|
||||
#define ds _ds.base
|
||||
#define es _es.base
|
||||
#define ss _ss.base
|
||||
#define seg_fs _fs.base
|
||||
#define gs _gs.base
|
||||
#define CS cpu_state.seg_cs.seg
|
||||
#define DS cpu_state.seg_ds.seg
|
||||
#define ES cpu_state.seg_es.seg
|
||||
#define SS cpu_state.seg_ss.seg
|
||||
#define FS cpu_state.seg_fs.seg
|
||||
#define GS cpu_state.seg_gs.seg
|
||||
#define cs cpu_state.seg_cs.base
|
||||
#define ds cpu_state.seg_ds.base
|
||||
#define es cpu_state.seg_es.base
|
||||
#define ss cpu_state.seg_ss.base
|
||||
#define fs_seg cpu_state.seg_fs.base
|
||||
#define gs cpu_state.seg_gs.base
|
||||
|
||||
|
||||
#define ISA_CYCLES_SHIFT 6
|
||||
#define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT)
|
||||
#define ISA_CYCLES(x) (x * isa_cycles)
|
||||
|
||||
extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
|
||||
extern int cpu_prefetch_cycles, cpu_prefetch_width, cpu_mem_prefetch_cycles, cpu_rom_prefetch_cycles;
|
||||
@@ -424,8 +434,8 @@ extern CPU cpus_acer[]; // FIXME: should be in machine file!
|
||||
|
||||
|
||||
/* Functions. */
|
||||
extern void cyrix_write(uint16_t addr, uint8_t val, void *priv);
|
||||
extern uint8_t cyrix_read(uint16_t addr, void *priv);
|
||||
extern int cpu_has_feature(int feature);
|
||||
|
||||
extern void loadseg(uint16_t seg, x86seg *s);
|
||||
extern void loadcs(uint16_t seg);
|
||||
|
||||
@@ -448,7 +458,7 @@ extern void exec386(int cycs);
|
||||
extern void exec386_dynarec(int cycs);
|
||||
extern int idivl(int32_t val);
|
||||
extern void loadcscall(uint16_t seg);
|
||||
extern void loadcsjmp(uint16_t seg, uint32_t oxpc);
|
||||
extern void loadcsjmp(uint16_t seg, uint32_t old_pc);
|
||||
extern void pmodeint(int num, int soft);
|
||||
extern void pmoderetf(int is32, uint16_t off);
|
||||
extern void pmodeiret(int is32);
|
||||
@@ -457,6 +467,7 @@ extern void resetx86(void);
|
||||
extern void refreshread(void);
|
||||
extern void resetreadlookup(void);
|
||||
extern void softresetx86(void);
|
||||
extern void x86_int(int num);
|
||||
extern void x86_int_sw(int num);
|
||||
extern int x86_int_sw_rm(int num);
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
@@ -470,8 +481,9 @@ extern void x87_dumpregs(void);
|
||||
extern void x87_reset(void);
|
||||
#endif
|
||||
|
||||
extern int cpu_effective;
|
||||
extern int cpu_effective, cpu_alt_reset;
|
||||
extern void cpu_dynamic_switch(int new_cpu);
|
||||
|
||||
|
||||
#endif /*EMU_CPU_H*/
|
||||
#endif
|
||||
@@ -52,371 +52,370 @@
|
||||
|
||||
CPU cpus_8088[] = {
|
||||
/*8088 standard*/
|
||||
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/7.16", CPU_8088, 1, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/10", CPU_8088, 1, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/12", CPU_8088, 1, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/16", CPU_8088, 1, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/8", CPU_8088, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/10", CPU_8088, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/12", CPU_8088, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8088/16", CPU_8088, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_pcjr[] = {
|
||||
/*8088 PCjr*/
|
||||
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_europc[] = {
|
||||
/*8088 EuroPC*/
|
||||
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8088/7.16", CPU_8088, 1, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8088/9.54", CPU_8088, 1, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"8088/4.77", CPU_8088, 4772728, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8088/7.16", CPU_8088, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8088/9.54", CPU_8088, 9545456, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_8086[] = {
|
||||
/*8086 standard*/
|
||||
{"8086/7.16", CPU_8086, 1, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8086/9.54", CPU_8086, 1, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8086/10", CPU_8086, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"8086/7.16", CPU_8086, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8086/9.54", CPU_8086, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1},
|
||||
{"8086/10", CPU_8086, 10000000, 2, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8086/12", CPU_8086, 12000000, 3, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"8086/16", CPU_8086, 16000000, 4, 0, 0, 0, 0, 0, 0,0,0,0, 2},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_pc1512[] = {
|
||||
/*8086 Amstrad*/
|
||||
{"8086/8", CPU_8086, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"8086/8", CPU_8086, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_286[] = {
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/8", CPU_286, 1, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/12", CPU_286, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ibmat[] = {
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
|
||||
{"286/8", CPU_286, 0, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
|
||||
{"286/8", CPU_286, 8000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ibmxt286[] = {
|
||||
/*286*/
|
||||
{"286/6", CPU_286, 0, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"286/6", CPU_286, 6000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_ps1_m2011[] = {
|
||||
/*286*/
|
||||
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 9}
|
||||
};
|
||||
|
||||
CPU cpus_ps2_m30_286[] = {
|
||||
/*286*/
|
||||
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"286/10", CPU_286, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2, 1},
|
||||
{"286/12", CPU_286, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/16", CPU_286, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"286/20", CPU_286, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"286/25", CPU_286, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i386SX[] = {
|
||||
/*i386SX*/
|
||||
{"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"i386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"i386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"i386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"i386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i386DX[] = {
|
||||
/*i386DX*/
|
||||
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"i386DX/16", CPU_386DX, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"i386DX/20", CPU_386DX, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"i386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"i386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"RapidCAD/25", CPU_RAPIDCAD, 25000000, 1, 0, 0x0430, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"RapidCAD/33", CPU_RAPIDCAD, 33333333, 1, 0, 0x0430, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"RapidCAD/40", CPU_RAPIDCAD, 40000000, 1, 0, 0x0430, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
#if 0
|
||||
CPU cpus_acer[] = {
|
||||
/*i386SX*/
|
||||
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4, 3},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
};
|
||||
#endif
|
||||
|
||||
CPU cpus_Am386SX[] = {
|
||||
/*Am386*/
|
||||
{"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"Am386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Am386SX/16", CPU_386SX, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3, 2},
|
||||
{"Am386SX/20", CPU_386SX, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386SX/25", CPU_386SX, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386SX/33", CPU_386SX, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"Am386SX/40", CPU_386SX, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am386DX[] = {
|
||||
/*Am386*/
|
||||
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Am386DX/25", CPU_386DX, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3, 3},
|
||||
{"Am386DX/33", CPU_386DX, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3, 4},
|
||||
{"Am386DX/40", CPU_386DX, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3, 5},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_486SLC[] = {
|
||||
/*Cx486SLC*/
|
||||
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
|
||||
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
|
||||
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
|
||||
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4},
|
||||
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
|
||||
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Cx486SLC/20", CPU_486SLC, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
|
||||
{"Cx486SLC/25", CPU_486SLC, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3, 3},
|
||||
{"Cx486SLC/33", CPU_486SLC, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3, 4},
|
||||
{"Cx486SRx2/32", CPU_486SLC, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6, 4},
|
||||
{"Cx486SRx2/40", CPU_486SLC, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
|
||||
{"Cx486SRx2/50", CPU_486SLC, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6, 6},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_486DLC[] = {
|
||||
/*Cx486DLC*/
|
||||
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3, 3},
|
||||
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3, 4},
|
||||
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3, 5},
|
||||
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6, 4},
|
||||
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 6},
|
||||
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6, 6},
|
||||
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Cx486DLC/25", CPU_486DLC, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4, 4,3,3, 3},
|
||||
{"Cx486DLC/33", CPU_486DLC, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6, 6,3,3, 4},
|
||||
{"Cx486DLC/40", CPU_486DLC, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7, 7,3,3, 5},
|
||||
{"Cx486DRx2/32", CPU_486DLC, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6, 6,6,6, 4},
|
||||
{"Cx486DRx2/40", CPU_486DLC, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
|
||||
{"Cx486DRx2/50", CPU_486DLC, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8, 8,6,6, 6},
|
||||
{"Cx486DRx2/66", CPU_486DLC, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6, 8},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_i486[] = {
|
||||
/*i486*/
|
||||
{"i486SX/16", CPU_i486SX, 0, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3,3,3,3, 2},
|
||||
{"i486SX/20", CPU_i486SX, 1, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
|
||||
{"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
|
||||
{"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
|
||||
{"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 8},
|
||||
{"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
|
||||
{"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
|
||||
{"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 6},
|
||||
{"i486DX2/40", CPU_i486DX, 4, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
|
||||
{"i486DX2/50", CPU_i486DX, 5, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
|
||||
{"i486DX2/66", CPU_i486DX, 6, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"iDX4/75", CPU_iDX4, 7, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/
|
||||
{"iDX4/100", CPU_iDX4, 10, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
|
||||
{"Pentium OverDrive/63", CPU_PENTIUM, 6, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
|
||||
{"Pentium OverDrive/83", CPU_PENTIUM, 8, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"i486SX/16", CPU_i486SX, 16000000, 1, 16000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 3, 3,3,3, 2},
|
||||
{"i486SX/20", CPU_i486SX, 20000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/25", CPU_i486SX, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486SX/33", CPU_i486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486SX2/50", CPU_i486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486SX2/66 (Q0569)", CPU_i486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 8},
|
||||
{"i486DX/25", CPU_i486DX, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4, 4,3,3, 3},
|
||||
{"i486DX/33", CPU_i486DX, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6,3,3, 4},
|
||||
{"i486DX/50", CPU_i486DX, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8, 8,4,4, 6},
|
||||
{"i486DX2/40", CPU_i486DX, 40000000, 2, 20000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486DX2/50", CPU_i486DX, 50000000, 2, 25000000, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 8, 8,6,6, 6},
|
||||
{"i486DX2/66", CPU_i486DX, 66666666, 2, 33333333, 0x430, 0x430, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"iDX4/75", CPU_iDX4, 75000000, 3, 25000000, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9}, /*CPUID available on DX4, >= 75 MHz*/
|
||||
{"iDX4/100", CPU_iDX4, 100000000, 3, 33333333, 0x481, 0x481, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 12}, /*Is on some real Intel DX2s, limit here is pretty arbitary*/
|
||||
{"Pentium OverDrive/63", CPU_PENTIUM, 62500000, 3, 25000000, 0x1531, 0x1531, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,7,7, 15/2},
|
||||
{"Pentium OverDrive/83", CPU_PENTIUM, 83333333, 3, 33333333, 0x1532, 0x1532, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,8,8, 10},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Am486[] = {
|
||||
/*Am486/5x86*/
|
||||
{"Am486SX/33", CPU_Am486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, 4, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX, 5, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX, 6, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
|
||||
{"Am486DX/33", CPU_Am486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
|
||||
{"Am486DX/40", CPU_Am486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
|
||||
{"Am486DX2/50", CPU_Am486DX, 5, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
|
||||
{"Am486DX2/66", CPU_Am486DX, 6, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"Am486DX2/80", CPU_Am486DX, 8, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14,6,6, 10},
|
||||
{"Am486DX4/75", CPU_Am486DX, 7, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9},
|
||||
{"Am486DX4/90", CPU_Am486DX, 9, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
|
||||
{"Am486DX4/100", CPU_Am486DX, 10, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
|
||||
{"Am486DX4/120", CPU_Am486DX, 11, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 15},
|
||||
{"Am5x86/P75", CPU_Am486DX, 12, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
|
||||
{"Am5x86/P75+", CPU_Am486DX, 13, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Am486SX/33", CPU_Am486SX, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486SX/40", CPU_Am486SX, 40000000, 1, 20000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486SX2/50", CPU_Am486SX, 50000000, 2, 25000000, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6}, /*CPUID available on SX2, DX2, DX4, 5x86, >= 50 MHz*/
|
||||
{"Am486SX2/66", CPU_Am486SX, 66666666, 2, 33333333, 0x45b, 0x45b, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8}, /*Isn't on all real AMD SX2s and DX2s, availability here is pretty arbitary (and distinguishes them from the Intel chips)*/
|
||||
{"Am486DX/33", CPU_Am486DX, 33333333, 1, 33333333, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Am486DX/40", CPU_Am486DX, 40000000, 1, 20000000, 0x430, 0, 0, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Am486DX2/50", CPU_Am486DX, 50000000, 2, 25000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"Am486DX2/66", CPU_Am486DX, 66666666, 2, 33333333, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Am486DX2/80", CPU_Am486DX, 80000000, 2, 20000000, 0x470, 0x470, 0, CPU_SUPPORTS_DYNAREC, 14,14, 6, 6, 10},
|
||||
{"Am486DX4/75", CPU_Am486DX, 75000000, 3, 25000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
|
||||
{"Am486DX4/90", CPU_Am486DX, 90000000, 3, 30000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
{"Am486DX4/100", CPU_Am486DX, 100000000, 3, 33333333, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
{"Am486DX4/120", CPU_Am486DX, 120000000, 3, 20000000, 0x482, 0x482, 0, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
|
||||
{"Am5x86/P75", CPU_Am486DX, 133333333, 4, 33333333, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
|
||||
{"Am5x86/P75+", CPU_Am486DX, 160000000, 4, 20000000, 0x4e0, 0x4e0, 0, CPU_SUPPORTS_DYNAREC, 28,28,12,12, 20},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Cx486[] = {
|
||||
/*Cx486/5x86*/
|
||||
{"Cx486S/25", CPU_Cx486S, 2, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4,4,3,3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, 3, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, 4, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
|
||||
{"Cx486DX/33", CPU_Cx486DX, 3, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6,6,3,3, 4},
|
||||
{"Cx486DX/40", CPU_Cx486DX, 4, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7,7,3,3, 5},
|
||||
{"Cx486DX2/50", CPU_Cx486DX, 5, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8,8,6,6, 6},
|
||||
{"Cx486DX2/66", CPU_Cx486DX, 6, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 8},
|
||||
{"Cx486DX2/80", CPU_Cx486DX, 8, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 10},
|
||||
{"Cx486DX4/75", CPU_Cx486DX, 7, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12,9,9, 9},
|
||||
{"Cx486DX4/100", CPU_Cx486DX, 10, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
|
||||
{"Cx5x86/100", CPU_Cx5x86, 10, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15,9,9, 12},
|
||||
{"Cx5x86/120", CPU_Cx5x86, 11, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21,9,9, 15},
|
||||
{"Cx5x86/133", CPU_Cx5x86, 12, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Cx486S/25", CPU_Cx486S, 25000000, 1, 25000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 4, 4, 3, 3, 3},
|
||||
{"Cx486S/33", CPU_Cx486S, 33333333, 1, 33333333, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486S/40", CPU_Cx486S, 40000000, 1, 20000000, 0x420, 0, 0x0010, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX/33", CPU_Cx486DX, 33333333, 1, 33333333, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 6, 6, 3, 3, 4},
|
||||
{"Cx486DX/40", CPU_Cx486DX, 40000000, 1, 20000000, 0x430, 0, 0x051a, CPU_SUPPORTS_DYNAREC, 7, 7, 3, 3, 5},
|
||||
{"Cx486DX2/50", CPU_Cx486DX, 50000000, 2, 25000000, 0x430, 0, 0x081b, CPU_SUPPORTS_DYNAREC, 8, 8, 6, 6, 6},
|
||||
{"Cx486DX2/66", CPU_Cx486DX, 66666666, 2, 33333333, 0x430, 0, 0x0b1b, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 8},
|
||||
{"Cx486DX2/80", CPU_Cx486DX, 80000000, 2, 20000000, 0x430, 0, 0x311b, CPU_SUPPORTS_DYNAREC, 14,14,16,16, 10},
|
||||
{"Cx486DX4/75", CPU_Cx486DX, 75000000, 3, 25000000, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 12,12, 9, 9, 9},
|
||||
{"Cx486DX4/100", CPU_Cx486DX, 100000000, 3, 33333333, 0x480, 0, 0x361f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
{"Cx5x86/100", CPU_Cx5x86, 100000000, 3, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 15,15, 9, 9, 12},
|
||||
{"Cx5x86/120", CPU_Cx5x86, 120000000, 3, 20000000, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 21,21, 9, 9, 15},
|
||||
{"Cx5x86/133", CPU_Cx5x86, 133333333, 4, 33333333, 0x480, 0, 0x002f, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#ifdef DEV_BRANCH
|
||||
#ifdef USE_CYRIX_6X86
|
||||
CPU cpus_6x86[] = {
|
||||
/*Cyrix 6x86*/
|
||||
{"6x86-P90", CPU_Cx6x86, 17, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 10},
|
||||
{"6x86-PR120+", CPU_Cx6x86, 17, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
|
||||
{"6x86-PR133+", CPU_Cx6x86, 17, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 14},
|
||||
{"6x86-PR150+", CPU_Cx6x86, 17, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"6x86-PR166+", CPU_Cx6x86, 17, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"6x86-PR200+", CPU_Cx6x86, 17, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 18},
|
||||
{"6x86-P90", CPU_Cx6x86, 80000000, 3, 40000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8, 6, 6, 10},
|
||||
{"6x86-PR120+", CPU_Cx6x86, 100000000, 3, 25000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
|
||||
{"6x86-PR133+", CPU_Cx6x86, 110000000, 3, 27500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
|
||||
{"6x86-PR150+", CPU_Cx6x86, 120000000, 3, 30000000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"6x86-PR166+", CPU_Cx6x86, 133333333, 3, 33333333, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"6x86-PR200+", CPU_Cx6x86, 150000000, 3, 37500000, 0x520, 0x520, 0x1731, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
|
||||
|
||||
/*Cyrix 6x86L*/
|
||||
{"6x86L-PR133+", CPU_Cx6x86L, 19, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 14},
|
||||
{"6x86L-PR150+", CPU_Cx6x86L, 19, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"6x86L-PR166+", CPU_Cx6x86L, 19, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"6x86L-PR200+", CPU_Cx6x86L, 19, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 18},
|
||||
{"6x86L-PR133+", CPU_Cx6x86L, 110000000, 3, 27500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 14},
|
||||
{"6x86L-PR150+", CPU_Cx6x86L, 120000000, 3, 30000000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"6x86L-PR166+", CPU_Cx6x86L, 133333333, 3, 33333333, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"6x86L-PR200+", CPU_Cx6x86L, 150000000, 3, 37500000, 0x540, 0x540, 0x2231, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 18},
|
||||
|
||||
/*Cyrix 6x86MX*/
|
||||
{"6x86MX-PR166", CPU_Cx6x86MX, 18, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"6x86MX-PR200", CPU_Cx6x86MX, 18, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"6x86MX-PR233", CPU_Cx6x86MX, 18, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 45/2},
|
||||
{"6x86MX-PR266", CPU_Cx6x86MX, 18, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, 25},
|
||||
{"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7, 28},
|
||||
{"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9, 30},
|
||||
{"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 30},
|
||||
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 33},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"6x86MX-PR166", CPU_Cx6x86MX, 133333333, 3, 33333333, 0x600, 0x600, 0x0451, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"6x86MX-PR200", CPU_Cx6x86MX, 166666666, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"6x86MX-PR233", CPU_Cx6x86MX, 188888888, 3, 37500000, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 45/2},
|
||||
{"6x86MX-PR266", CPU_Cx6x86MX, 207500000, 3, 41666667, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
|
||||
{"6x86MX-PR300", CPU_Cx6x86MX, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21, 7, 7, 28},
|
||||
{"6x86MX-PR333", CPU_Cx6x86MX, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20, 9, 9, 30},
|
||||
{"6x86MX-PR366", CPU_Cx6x86MX, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 30},
|
||||
{"6x86MX-PR400", CPU_Cx6x86MX, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 33},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
CPU cpus_WinChip[] = {
|
||||
/*IDT WinChip*/
|
||||
{"WinChip 75", CPU_WINCHIP, 7, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4, 9},
|
||||
{"WinChip 90", CPU_WINCHIP, 9, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, 21/2},
|
||||
{"WinChip 100", CPU_WINCHIP, 10, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9,9,4,4, 12},
|
||||
{"WinChip 120", CPU_WINCHIP, 11, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 14},
|
||||
{"WinChip 133", CPU_WINCHIP, 12, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12,6,6, 16},
|
||||
{"WinChip 150", CPU_WINCHIP, 13, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"WinChip 166", CPU_WINCHIP, 15, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15,7,7, 40},
|
||||
{"WinChip 180", CPU_WINCHIP, 16, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 21},
|
||||
{"WinChip 200", CPU_WINCHIP, 17, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 24},
|
||||
{"WinChip 225", CPU_WINCHIP, 17, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18,9,9, 27},
|
||||
{"WinChip 240", CPU_WINCHIP, 17, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"WinChip 75", CPU_WINCHIP, 75000000, 2, 25000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 8, 8, 4, 4, 9},
|
||||
{"WinChip 90", CPU_WINCHIP, 90000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"WinChip 100", CPU_WINCHIP, 100000000, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"WinChip 120", CPU_WINCHIP, 120000000, 2, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"WinChip 133", CPU_WINCHIP, 133333333, 2, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"WinChip 150", CPU_WINCHIP, 150000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"WinChip 166", CPU_WINCHIP, 166666666, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 15,15, 7, 7, 40},
|
||||
{"WinChip 180", CPU_WINCHIP, 180000000, 3, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 21},
|
||||
{"WinChip 200", CPU_WINCHIP, 200000000, 3, 33333333, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"WinChip 225", CPU_WINCHIP, 225000000, 3, 37500000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 18,18, 9, 9, 27},
|
||||
{"WinChip 240", CPU_WINCHIP, 240000000, 6, 30000000, 0x540, 0x540, 0, CPU_SUPPORTS_DYNAREC, 24,24,12,12, 28},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium5V[] = {
|
||||
/*Intel Pentium (5V, socket 4)*/
|
||||
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
|
||||
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
|
||||
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
|
||||
{"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
|
||||
{"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium5V50[] = {
|
||||
/*Intel Pentium (5V, socket 4, including 50 MHz FSB)*/
|
||||
{"Pentium 50 (Q0399)",CPU_PENTIUM, 5, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6},
|
||||
{"Pentium 60", CPU_PENTIUM, 6, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
|
||||
{"Pentium 66", CPU_PENTIUM, 6, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
|
||||
{"Pentium OverDrive 100",CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8,8,6,6, 12},
|
||||
{"Pentium OverDrive 120",CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 133",CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Pentium 50 (Q0399)", CPU_PENTIUM, 50000000, 1, 25000000, 0x513, 0x513, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4,3,3, 6},
|
||||
{"Pentium 60", CPU_PENTIUM, 60000000, 1, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 7},
|
||||
{"Pentium 66", CPU_PENTIUM, 66666666, 1, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6,3,3, 8},
|
||||
{"Pentium OverDrive 100", CPU_PENTIUM, 100000000, 2, 25000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 8, 8,6,6, 12},
|
||||
{"Pentium OverDrive 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x51A, 0x51A, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_PentiumS5[] = {
|
||||
/*Intel Pentium (Socket 5)*/
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
|
||||
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16},
|
||||
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Pentium 75", CPU_PENTIUM, 75000000, 2, 25000000, 0x522, 0x522, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"Pentium 90", CPU_PENTIUM, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
|
||||
{"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 16},
|
||||
{"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 40},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_Pentium[] = {
|
||||
/*Intel Pentium*/
|
||||
{"Pentium 75", CPU_PENTIUM, 9, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"Pentium OverDrive MMX 75",CPU_PENTIUMMMX,9,75000000,2,25000000,0x1542,0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"Pentium 90", CPU_PENTIUM, 12, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 13, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10,6,6, 12},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 13, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
|
||||
{"Pentium 120", CPU_PENTIUM, 14, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Pentium 133", CPU_PENTIUM, 16, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"Pentium 150", CPU_PENTIUM, 17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium 166", CPU_PENTIUM, 19, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium 200", CPU_PENTIUM, 21, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 14, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 16, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 17, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 19, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 21, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 24, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 26, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 28, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
{"Pentium OverDrive 125",CPU_PENTIUM,15, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
|
||||
{"Pentium OverDrive 150",CPU_PENTIUM,17, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive 166",CPU_PENTIUM,17, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX,15,125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,7,7, 15},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX,17,150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX,19,166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX,20,180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX,21,200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Pentium 75", CPU_PENTIUM, 75000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium OverDrive MMX 75", CPU_PENTIUMMMX, 75000000, 2, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium 90", CPU_PENTIUM, 90000000, 2, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"Pentium 100/50", CPU_PENTIUM, 100000000, 2, 25000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 10,10, 6, 6, 12},
|
||||
{"Pentium 100/66", CPU_PENTIUM, 100000000, 2, 33333333, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"Pentium 120", CPU_PENTIUM, 120000000, 2, 30000000, 0x526, 0x526, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Pentium 133", CPU_PENTIUM, 133333333, 2, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Pentium 150", CPU_PENTIUM, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium 166", CPU_PENTIUM, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium 200", CPU_PENTIUM, 200000000, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 4, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"Mobile Pentium MMX 120", CPU_PENTIUMMMX, 120000000, 2, 30000000, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"Mobile Pentium MMX 133", CPU_PENTIUMMMX, 133333333, 2, 33333333, 0x543, 0x543, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"Mobile Pentium MMX 150", CPU_PENTIUMMMX, 150000000, 3, 30000000, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Mobile Pentium MMX 166", CPU_PENTIUMMMX, 166666666, 3, 33333333, 0x544, 0x544, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Mobile Pentium MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"Mobile Pentium MMX 233", CPU_PENTIUMMMX, 233333333, 4, 33333333, 0x581, 0x581, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"Mobile Pentium MMX 266", CPU_PENTIUMMMX, 266666666, 4, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"Mobile Pentium MMX 300", CPU_PENTIUMMMX, 300000000, 5, 33333333, 0x582, 0x582, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
{"Pentium OverDrive 125", CPU_PENTIUM, 125000000, 3, 25000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
|
||||
{"Pentium OverDrive 150", CPU_PENTIUM, 150000000, 3, 30000000, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium OverDrive 166", CPU_PENTIUM, 166666666, 3, 33333333, 0x52c, 0x52c, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium OverDrive MMX 125", CPU_PENTIUMMMX, 125000000, 3, 25000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 7, 7, 15},
|
||||
{"Pentium OverDrive MMX 150/60", CPU_PENTIUMMMX, 150000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium OverDrive MMX 166", CPU_PENTIUMMMX, 166000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium OverDrive MMX 180", CPU_PENTIUMMMX, 180000000, 3, 30000000, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
|
||||
{"Pentium OverDrive MMX 200", CPU_PENTIUMMMX, 200000000, 3, 33333333, 0x1542, 0x1542, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#ifdef DEV_BRANCH
|
||||
#ifdef USE_AMD_K
|
||||
CPU cpus_K5[] = {
|
||||
/*AMD K5 (Socket 5)*/
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
|
||||
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7,4,4, 9},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 21/2},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
|
||||
{"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9,4,4, 12},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0, 0}
|
||||
};
|
||||
|
||||
CPU cpus_K56[] = {
|
||||
/*AMD K5 and K6 (Socket 7)*/
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 9, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 9, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 12, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 12, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 21/2},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 13, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
|
||||
{"K5 (SSA/5) 100 (PR100)",CPU_K5, 13, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9,9,4,4, 12},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 14, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 14},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 16, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12,6,6, 16},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 17, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"K5 (5k86) 116.5 (PR166)",CPU_5K86, 19, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 21, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"K6 (Model 6) 166", CPU_K6, 19, 166666666, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"K6 (Model 6) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"K6 (Model 6) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"K6 (Model 7) 200", CPU_K6, 21, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"K6 (Model 7) 233", CPU_K6, 24, 233333333, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"K6 (Model 7) 266", CPU_K6, 26, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"K6 (Model 7) 300", CPU_K6, 28, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"K5 (5k86) 75 (P75)", CPU_K5, 75000000, 2, 25000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"K5 (SSA/5) 75 (PR75)", CPU_K5, 75000000, 2, 25000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"K5 (5k86) 90 (P90)", CPU_K5, 90000000, 2, 30000000, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"K5 (SSA/5) 90 (PR90)", CPU_K5, 90000000, 2, 30000000, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 21/2},
|
||||
{"K5 (5k86) 100 (P100)", CPU_K5, 100000000, 2, 33333333, 0x500, 0x500, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"K5 (SSA/5) 100 (PR100)", CPU_K5, 100000000, 2, 33333333, 0x501, 0x501, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 9, 9, 4, 4, 12},
|
||||
{"K5 (5k86) 90 (PR120)", CPU_5K86, 120000000, 2, 30000000, 0x511, 0x511, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 14},
|
||||
{"K5 (5k86) 100 (PR133)", CPU_5K86, 133333333, 2, 33333333, 0x514, 0x514, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 12,12, 6, 6, 16},
|
||||
{"K5 (5k86) 105 (PR150)", CPU_5K86, 150000000, 3, 30000000, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"K5 (5k86) 116.5 (PR166)", CPU_5K86, 166666666, 3, 33333333, 0x524, 0x524, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"K5 (5k86) 133 (PR200)", CPU_5K86, 200000000, 3, 33333333, 0x534, 0x534, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"K6 (Model 6) 166", CPU_K6, 166666666, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"K6 (Model 6) 200", CPU_K6, 200000000, 3, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"K6 (Model 6) 233", CPU_K6, 233333333, 4, 33333333, 0x562, 0x562, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"K6 (Model 7) 200", CPU_K6, 200000000, 3, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"K6 (Model 7) 233", CPU_K6, 233333333, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"K6 (Model 7) 266", CPU_K6, 266666666, 4, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"K6 (Model 7) 300", CPU_K6, 300000000, 5, 33333333, 0x570, 0x570, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
@@ -425,27 +424,28 @@ CPU cpus_K56[] = {
|
||||
#ifdef USE_I686
|
||||
CPU cpus_PentiumPro[] = {
|
||||
/*Intel Pentium Pro and II Overdrive*/
|
||||
{"Pentium Pro 50", CPU_PENTIUMPRO, 5, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6},
|
||||
{"Pentium Pro 60" , CPU_PENTIUMPRO, 6, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
|
||||
{"Pentium Pro 66" , CPU_PENTIUMPRO, 6, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
|
||||
{"Pentium Pro 75", CPU_PENTIUMPRO, 9, 75000000, 2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"Pentium Pro 150", CPU_PENTIUMPRO, 17, 150000000, 3, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 35/2},
|
||||
{"Pentium Pro 166", CPU_PENTIUMPRO, 19, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15,7,7, 20},
|
||||
{"Pentium Pro 180", CPU_PENTIUMPRO, 20, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 21},
|
||||
{"Pentium Pro 200", CPU_PENTIUMPRO, 21, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9, 24},
|
||||
{"Pentium II Overdrive 50", CPU_PENTIUM2D, 5, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4,4,3,3, 6},
|
||||
{"Pentium II Overdrive 60", CPU_PENTIUM2D, 6, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 7},
|
||||
{"Pentium II Overdrive 66", CPU_PENTIUM2D, 6, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6,6,3,3, 8},
|
||||
{"Pentium II Overdrive 75", CPU_PENTIUM2D, 9, 75000000, 2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7,7,4,4, 9},
|
||||
{"Pentium II Overdrive 210", CPU_PENTIUM2D, 22, 210000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17,7,7, 25},
|
||||
{"Pentium II Overdrive 233", CPU_PENTIUM2D, 24, 233333333, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,1, 28},
|
||||
{"Pentium II Overdrive 240", CPU_PENTIUM2D, 25, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29},
|
||||
{"Pentium II Overdrive 266", CPU_PENTIUM2D, 26, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"Pentium II Overdrive 270", CPU_PENTIUM2D, 27, 270000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33},
|
||||
{"Pentium II Overdrive 300/66",CPU_PENTIUM2D, 28, 300000000, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
|
||||
{"Pentium II Overdrive 300/60",CPU_PENTIUM2D, 28, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
{"Pentium II Overdrive 333", CPU_PENTIUM2D, 29, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0}
|
||||
{"Pentium Pro 50", CPU_PENTIUMPRO, 50000000, 1, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
|
||||
{"Pentium Pro 60" , CPU_PENTIUMPRO, 60000000, 1, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
|
||||
{"Pentium Pro 66" , CPU_PENTIUMPRO, 66666666, 1, 33333333, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
|
||||
{"Pentium Pro 75", CPU_PENTIUMPRO, 75000000, 2, 25000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium Pro 150", CPU_PENTIUMPRO, 150000000, 3, 30000000, 0x612, 0x612, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 35/2},
|
||||
{"Pentium Pro 166", CPU_PENTIUMPRO, 166666666, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 15,15, 7, 7, 20},
|
||||
{"Pentium Pro 180", CPU_PENTIUMPRO, 180000000, 3, 30000000, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 21},
|
||||
{"Pentium Pro 200", CPU_PENTIUMPRO, 200000000, 3, 33333333, 0x617, 0x617, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18, 9, 9, 24},
|
||||
{"Pentium II Overdrive 50", CPU_PENTIUM2D, 50000000, 1, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 4, 4, 3, 3, 6},
|
||||
{"Pentium II Overdrive 60", CPU_PENTIUM2D, 60000000, 1, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 7},
|
||||
{"Pentium II Overdrive 66", CPU_PENTIUM2D, 66666666, 1, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 6, 6, 3, 3, 8},
|
||||
{"Pentium II Overdrive 75", CPU_PENTIUM2D, 75000000, 2, 25000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"Pentium II Overdrive 210", CPU_PENTIUM2D, 210000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 17,17, 7, 7, 25},
|
||||
{"Pentium II Overdrive 233", CPU_PENTIUM2D, 233333333, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,10,10, 28},
|
||||
{"Pentium II Overdrive 240", CPU_PENTIUM2D, 240000000, 4, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 29},
|
||||
{"Pentium II Overdrive 266", CPU_PENTIUM2D, 266666666, 4, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12, 32},
|
||||
{"Pentium II Overdrive 270", CPU_PENTIUM2D, 270000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 33},
|
||||
{"Pentium II Overdrive 300/66", CPU_PENTIUM2D, 300000000, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 25,25,12,12, 36},
|
||||
{"Pentium II Overdrive 300/60", CPU_PENTIUM2D, 300000000, 5, 30000000, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 36},
|
||||
{"Pentium II Overdrive 333", CPU_PENTIUM2D, 333333333, 5, 33333333, 0x1632, 0x1632, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 27,27,13,13, 40},
|
||||
{"Pentium II 75", CPU_PENTIUM2D, 75000000, 2, 25000000, 0x654, 0x654, 0, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 7, 7, 4, 4, 9},
|
||||
{"", -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
#ifdef USE_NEW_DYNAREC
|
||||
#include "../cpu_new/x86.h"
|
||||
#else
|
||||
|
||||
extern uint8_t opcode, opcode2;
|
||||
extern uint8_t flags_p;
|
||||
extern uint8_t znptable8[256];
|
||||
|
||||
extern uint16_t zero, oldcs;
|
||||
extern uint16_t lastcs, lastpc;
|
||||
extern uint16_t rds, ea_rseg;
|
||||
extern uint16_t znptable16[65536];
|
||||
extern uint16_t *mod1add[2][8];
|
||||
extern uint16_t znptable16[65536];
|
||||
|
||||
extern int x86_was_reset, codegen_flat_ds;
|
||||
extern int codegen_flat_ss, nmi_enable;
|
||||
extern int x86_was_reset, trap;
|
||||
extern int codegen_flat_ss, codegen_flat_ds;
|
||||
extern int timetolive, keyboardtimer, trap;
|
||||
extern int tempc, optype, use32, stack32;
|
||||
extern int optype, stack32;
|
||||
extern int oldcpl, cgate32, cpl_override, fpucount;
|
||||
extern int gpf, nmi_enable;
|
||||
extern int nmi_enable;
|
||||
extern int oddeven, inttype;
|
||||
|
||||
extern uint32_t rmdat32, easeg;
|
||||
extern uint32_t use32;
|
||||
extern uint32_t rmdat, easeg;
|
||||
extern uint32_t oxpc, flags_zn;
|
||||
extern uint32_t abrt_error;
|
||||
extern uint32_t backupregs[16];
|
||||
extern uint32_t *mod1seg[8];
|
||||
extern uint32_t *eal_r, *eal_w;
|
||||
|
||||
#define fetchdat rmdat
|
||||
|
||||
#define setznp168 setznp16
|
||||
|
||||
@@ -50,10 +55,6 @@ extern uint32_t *eal_r, *eal_w;
|
||||
#define IRET 3
|
||||
#define OPTYPE_INT 4
|
||||
|
||||
#define FLAG_N (flags_zn>>31)
|
||||
#define FLAG_Z (flags_zn)
|
||||
#define FLAG_P (znptable8[flags_p]&P_FLAG)
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -71,3 +72,4 @@ extern void x86_doabrt(int x86_abrt);
|
||||
extern void x86illegal();
|
||||
extern void x86seg_reset();
|
||||
extern void x86gpf(char *s, uint16_t error);
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/* Copyright holders: Sarah Walker
|
||||
see COPYING for more details
|
||||
*/
|
||||
extern int tempc;
|
||||
|
||||
enum
|
||||
{
|
||||
FLAGS_UNKNOWN,
|
||||
@@ -69,7 +71,7 @@ static __inline int ZF_SET()
|
||||
return !cpu_state.flags_res;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & Z_FLAG;
|
||||
return cpu_state.flags & Z_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@@ -111,7 +113,7 @@ static __inline int NF_SET()
|
||||
return cpu_state.flags_res & 0x80000000;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & N_FLAG;
|
||||
return cpu_state.flags & N_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@@ -149,7 +151,7 @@ static __inline int PF_SET()
|
||||
return znptable8[cpu_state.flags_res & 0xff] & P_FLAG;
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & P_FLAG;
|
||||
return cpu_state.flags & P_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@@ -171,20 +173,20 @@ static __inline int VF_SET()
|
||||
case FLAGS_ADD8:
|
||||
case FLAGS_INC8:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_ADD16:
|
||||
case FLAGS_INC16:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_ADD32:
|
||||
case FLAGS_INC32:
|
||||
return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
|
||||
|
||||
|
||||
case FLAGS_SUB8:
|
||||
case FLAGS_DEC8:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80);
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_DEC16:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000);
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_SUB32:
|
||||
case FLAGS_DEC32:
|
||||
return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000);
|
||||
|
||||
@@ -203,7 +205,7 @@ static __inline int VF_SET()
|
||||
return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000));
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & V_FLAG;
|
||||
return cpu_state.flags & V_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@@ -243,9 +245,9 @@ static __inline int AF_SET()
|
||||
case FLAGS_DEC16:
|
||||
case FLAGS_DEC32:
|
||||
return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10;
|
||||
|
||||
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & A_FLAG;
|
||||
return cpu_state.flags & A_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@@ -267,7 +269,7 @@ static __inline int CF_SET()
|
||||
case FLAGS_SUB16:
|
||||
case FLAGS_SUB32:
|
||||
return (cpu_state.flags_op1 < cpu_state.flags_op2);
|
||||
|
||||
|
||||
case FLAGS_SHL8:
|
||||
return (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80;
|
||||
case FLAGS_SHL16:
|
||||
@@ -299,7 +301,7 @@ static __inline int CF_SET()
|
||||
case FLAGS_INC16:
|
||||
case FLAGS_INC32:
|
||||
case FLAGS_UNKNOWN:
|
||||
return flags & C_FLAG;
|
||||
return cpu_state.flags & C_FLAG;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@@ -317,7 +319,7 @@ static __inline void flags_rebuild()
|
||||
if (ZF_SET()) tempf |= Z_FLAG;
|
||||
if (NF_SET()) tempf |= N_FLAG;
|
||||
if (VF_SET()) tempf |= V_FLAG;
|
||||
flags = (flags & ~0x8d5) | tempf;
|
||||
cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -332,9 +334,9 @@ static __inline void flags_rebuild_c()
|
||||
if (cpu_state.flags_op != FLAGS_UNKNOWN)
|
||||
{
|
||||
if (CF_SET())
|
||||
flags |= C_FLAG;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
else
|
||||
flags &= ~C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,65 +459,68 @@ static __inline void setadc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a+(uint16_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) flags|=C_FLAG;
|
||||
if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setadc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=znptable16[c&0xFFFF];
|
||||
if (c&0x10000) flags|=C_FLAG;
|
||||
if (!((a^b)&0x8000)&&((a^c)&0x8000)) flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable16[c&0xFFFF];
|
||||
if (c&0x10000) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setadc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c<a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
|
||||
if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF)+tempc)&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
|
||||
static __inline void setsbc8(uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=znptable8[c&0xFF];
|
||||
if (c&0x100) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setsbc16(uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=(znptable16[c&0xFFFF]&~4);
|
||||
flags|=(znptable8[c&0xFF]&4);
|
||||
if (c&0x10000) flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x8000) flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=(znptable16[c&0xFFFF]&~4);
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&4);
|
||||
if (c&0x10000) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x8000) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-(b&0xF))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
static __inline void setadc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a+(uint32_t)b+tempc;
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c<a) || (c==a && tempc)) flags|=C_FLAG;
|
||||
if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG;
|
||||
if (((a&0xF)+(b&0xF)+tempc)&0x10) flags|=A_FLAG;
|
||||
}
|
||||
static __inline void setsbc32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc);
|
||||
cpu_state.flags_op = FLAGS_UNKNOWN;
|
||||
flags&=~0x8D5;
|
||||
flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c>a) || (c==a && tempc)) flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80000000) flags|=V_FLAG;
|
||||
if (((a&0xF)-((b&0xF)+tempc))&0x10) flags|=A_FLAG;
|
||||
cpu_state.flags&=~0x8D5;
|
||||
cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0));
|
||||
cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG);
|
||||
if ((c>a) || (c==a && tempc)) cpu_state.flags|=C_FLAG;
|
||||
if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG;
|
||||
if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG;
|
||||
}
|
||||
|
||||
extern void cpu_386_flags_extract();
|
||||
extern void cpu_386_flags_rebuild();
|
||||
@@ -83,7 +83,9 @@ extern const OpFn dynarec_ops_winchip_0f[1024];
|
||||
|
||||
extern const OpFn dynarec_ops_pentium_0f[1024];
|
||||
extern const OpFn dynarec_ops_pentiummmx_0f[1024];
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
extern const OpFn dynarec_ops_c6x86mx_0f[1024];
|
||||
#endif
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
|
||||
extern const OpFn dynarec_ops_k6_0f[1024];
|
||||
@@ -175,7 +177,9 @@ extern const OpFn ops_winchip_0f[1024];
|
||||
extern const OpFn ops_pentium_0f[1024];
|
||||
extern const OpFn ops_pentiummmx_0f[1024];
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86)
|
||||
extern const OpFn ops_c6x86mx_0f[1024];
|
||||
#endif
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_AMD_K)
|
||||
extern const OpFn ops_k6_0f[1024];
|
||||
|
||||
@@ -40,36 +40,36 @@ static int opSYSCALL(uint32_t fetchdat)
|
||||
if (!AMD_SYSCALL_SB) return internal_illegal("SYSCALL: AMD SYSCALL SB MSR is zero");
|
||||
|
||||
/* Set VM, IF, RF to 0. */
|
||||
/* eflags &= ~0x00030200;
|
||||
flags &= ~0x0200; */
|
||||
/* cpu_state.eflags &= ~0x00030200;
|
||||
cpu_state.flags &= ~0x0200; */
|
||||
|
||||
/* Let's do this by the AMD spec. */
|
||||
ECX = cpu_state.pc;
|
||||
|
||||
eflags &= ~0x0002;
|
||||
flags &= ~0x0200;
|
||||
cpu_state.eflags &= ~0x0002;
|
||||
cpu_state.flags &= ~0x0200;
|
||||
|
||||
/* CS */
|
||||
_cs.seg = AMD_SYSCALL_SB & ~7;
|
||||
cpu_state.seg_cs.seg = AMD_SYSCALL_SB & ~7;
|
||||
if (AMD_SYSCALL_SB & 4)
|
||||
{
|
||||
if (_cs.seg >= ldt.limit)
|
||||
if (cpu_state.seg_cs.seg >= ldt.limit)
|
||||
{
|
||||
x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSCALL_SB,ldt.limit);
|
||||
x86gpf(NULL, AMD_SYSCALL_SB & ~3);
|
||||
return 1;
|
||||
}
|
||||
_cs.seg +=ldt.base;
|
||||
cpu_state.seg_cs.seg +=ldt.base;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_cs.seg >= gdt.limit)
|
||||
if (cpu_state.seg_cs.seg >= gdt.limit)
|
||||
{
|
||||
x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSCALL_SB,gdt.limit);
|
||||
x86gpf(NULL, AMD_SYSCALL_SB & ~3);
|
||||
return 1;
|
||||
}
|
||||
_cs.seg += gdt.base;
|
||||
cpu_state.seg_cs.seg += gdt.base;
|
||||
}
|
||||
cpl_override = 1;
|
||||
|
||||
@@ -83,27 +83,27 @@ static int opSYSCALL(uint32_t fetchdat)
|
||||
use32 = 0x300;
|
||||
CS = (AMD_SYSCALL_SB & ~3) | 0;
|
||||
|
||||
do_seg_load(&_cs, syscall_cs_seg_data);
|
||||
do_seg_load(&cpu_state.seg_cs, syscall_cs_seg_data);
|
||||
use32 = 0x300;
|
||||
|
||||
CS = (CS & 0xFFFC) | 0;
|
||||
|
||||
_cs.limit = 0xFFFFFFFF;
|
||||
_cs.limit_high = 0xFFFFFFFF;
|
||||
cpu_state.seg_cs.limit = 0xFFFFFFFF;
|
||||
cpu_state.seg_cs.limit_high = 0xFFFFFFFF;
|
||||
|
||||
/* SS */
|
||||
syscall_ss_seg_data[0] = 0xFFFF;
|
||||
syscall_ss_seg_data[1] = 0;
|
||||
syscall_ss_seg_data[2] = 0x9300;
|
||||
syscall_ss_seg_data[3] = 0xC0;
|
||||
do_seg_load(&_ss, syscall_ss_seg_data);
|
||||
_ss.seg = (AMD_SYSCALL_SB + 8) & 0xFFFC;
|
||||
do_seg_load(&cpu_state.seg_ss, syscall_ss_seg_data);
|
||||
cpu_state.seg_ss.seg = (AMD_SYSCALL_SB + 8) & 0xFFFC;
|
||||
stack32 = 1;
|
||||
|
||||
_ss.limit = 0xFFFFFFFF;
|
||||
_ss.limit_high = 0xFFFFFFFF;
|
||||
cpu_state.seg_ss.limit = 0xFFFFFFFF;
|
||||
cpu_state.seg_ss.limit_high = 0xFFFFFFFF;
|
||||
|
||||
_ss.checked = 0;
|
||||
cpu_state.seg_ss.checked = 0;
|
||||
|
||||
cpu_state.pc = AMD_SYSCALL_EIP;
|
||||
|
||||
@@ -125,29 +125,29 @@ static int opSYSRET(uint32_t fetchdat)
|
||||
|
||||
cpu_state.pc = ECX;
|
||||
|
||||
eflags |= (1 << 1);
|
||||
cpu_state.eflags |= (1 << 1);
|
||||
|
||||
/* CS */
|
||||
_cs.seg = AMD_SYSRET_SB & ~7;
|
||||
cpu_state.seg_cs.seg = AMD_SYSRET_SB & ~7;
|
||||
if (AMD_SYSRET_SB & 4)
|
||||
{
|
||||
if (_cs.seg >= ldt.limit)
|
||||
if (cpu_state.seg_cs.seg >= ldt.limit)
|
||||
{
|
||||
x386_dynarec_log("Bigger than LDT limit %04X %04X CS\n",AMD_SYSRET_SB,ldt.limit);
|
||||
x86gpf(NULL, AMD_SYSRET_SB & ~3);
|
||||
return 1;
|
||||
}
|
||||
_cs.seg +=ldt.base;
|
||||
cpu_state.seg_cs.seg +=ldt.base;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_cs.seg >= gdt.limit)
|
||||
if (cpu_state.seg_cs.seg >= gdt.limit)
|
||||
{
|
||||
x386_dynarec_log("Bigger than GDT limit %04X %04X CS\n",AMD_SYSRET_SB,gdt.limit);
|
||||
x86gpf(NULL, AMD_SYSRET_SB & ~3);
|
||||
return 1;
|
||||
}
|
||||
_cs.seg += gdt.base;
|
||||
cpu_state.seg_cs.seg += gdt.base;
|
||||
}
|
||||
cpl_override = 1;
|
||||
|
||||
@@ -161,28 +161,28 @@ static int opSYSRET(uint32_t fetchdat)
|
||||
use32 = 0x300;
|
||||
CS = (AMD_SYSRET_SB & ~3) | 3;
|
||||
|
||||
do_seg_load(&_cs, sysret_cs_seg_data);
|
||||
do_seg_load(&cpu_state.seg_cs, sysret_cs_seg_data);
|
||||
flushmmucache_cr3();
|
||||
use32 = 0x300;
|
||||
|
||||
CS = (CS & 0xFFFC) | 3;
|
||||
|
||||
_cs.limit = 0xFFFFFFFF;
|
||||
_cs.limit_high = 0xFFFFFFFF;
|
||||
cpu_state.seg_cs.limit = 0xFFFFFFFF;
|
||||
cpu_state.seg_cs.limit_high = 0xFFFFFFFF;
|
||||
|
||||
/* SS */
|
||||
sysret_ss_seg_data[0] = 0xFFFF;
|
||||
sysret_ss_seg_data[1] = 0;
|
||||
sysret_ss_seg_data[2] = 0xF300;
|
||||
sysret_ss_seg_data[3] = 0xC0;
|
||||
do_seg_load(&_ss, sysret_ss_seg_data);
|
||||
_ss.seg = ((AMD_SYSRET_SB + 8) & 0xFFFC) | 3;
|
||||
do_seg_load(&cpu_state.seg_ss, sysret_ss_seg_data);
|
||||
cpu_state.seg_ss.seg = ((AMD_SYSRET_SB + 8) & 0xFFFC) | 3;
|
||||
stack32 = 1;
|
||||
|
||||
_ss.limit = 0xFFFFFFFF;
|
||||
_ss.limit_high = 0xFFFFFFFF;
|
||||
cpu_state.seg_ss.limit = 0xFFFFFFFF;
|
||||
cpu_state.seg_ss.limit_high = 0xFFFFFFFF;
|
||||
|
||||
_ss.checked = 0;
|
||||
cpu_state.seg_ss.checked = 0;
|
||||
|
||||
CLOCK_CYCLES(20);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
dst = geteab(); if (cpu_state.abrt) return 1; \
|
||||
src = getr8(cpu_reg); \
|
||||
seteab(operation); if (cpu_state.abrt) return 1; \
|
||||
@@ -42,6 +43,7 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
dst = geteab(); if (cpu_state.abrt) return 1; \
|
||||
src = getr8(cpu_reg); \
|
||||
seteab(operation); if (cpu_state.abrt) return 1; \
|
||||
@@ -69,6 +71,7 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].w; \
|
||||
seteaw(operation); if (cpu_state.abrt) return 1; \
|
||||
@@ -95,6 +98,7 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].w; \
|
||||
seteaw(operation); if (cpu_state.abrt) return 1; \
|
||||
@@ -122,6 +126,7 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
dst = geteal(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].l; \
|
||||
seteal(operation); if (cpu_state.abrt) return 1; \
|
||||
@@ -148,6 +153,7 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
dst = geteal(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].l; \
|
||||
seteal(operation); if (cpu_state.abrt) return 1; \
|
||||
@@ -163,6 +169,8 @@
|
||||
uint8_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
dst = getr8(cpu_reg); \
|
||||
src = geteab(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 8 flagops; \
|
||||
@@ -176,6 +184,8 @@
|
||||
uint8_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
dst = getr8(cpu_reg); \
|
||||
src = geteab(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 8 flagops; \
|
||||
@@ -190,6 +200,8 @@
|
||||
uint16_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
dst = cpu_state.regs[cpu_reg].w; \
|
||||
src = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 16 flagops; \
|
||||
@@ -203,6 +215,8 @@
|
||||
uint16_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
dst = cpu_state.regs[cpu_reg].w; \
|
||||
src = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 16 flagops; \
|
||||
@@ -217,6 +231,8 @@
|
||||
uint32_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
dst = cpu_state.regs[cpu_reg].l; \
|
||||
src = geteal(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 32 flagops; \
|
||||
@@ -230,6 +246,8 @@
|
||||
uint32_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
dst = cpu_state.regs[cpu_reg].l; \
|
||||
src = geteal(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 32 flagops; \
|
||||
@@ -287,6 +305,8 @@ static int opCMP_b_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(dst, getr8(cpu_reg));
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -298,6 +318,8 @@ static int opCMP_b_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(dst, getr8(cpu_reg));
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -310,6 +332,8 @@ static int opCMP_w_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(dst, cpu_state.regs[cpu_reg].w);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -321,6 +345,8 @@ static int opCMP_w_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(dst, cpu_state.regs[cpu_reg].w);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -333,6 +359,8 @@ static int opCMP_l_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(dst, cpu_state.regs[cpu_reg].l);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -344,6 +372,8 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(dst, cpu_state.regs[cpu_reg].l);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -355,7 +385,9 @@ static int opCMP_l_rmw_a32(uint32_t fetchdat)
|
||||
static int opCMP_b_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(getr8(cpu_reg), src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
@@ -365,7 +397,9 @@ static int opCMP_b_rm_a16(uint32_t fetchdat)
|
||||
static int opCMP_b_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src;
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(getr8(cpu_reg), src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
@@ -376,7 +410,9 @@ static int opCMP_b_rm_a32(uint32_t fetchdat)
|
||||
static int opCMP_w_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(cpu_state.regs[cpu_reg].w, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
@@ -386,7 +422,9 @@ static int opCMP_w_rm_a16(uint32_t fetchdat)
|
||||
static int opCMP_w_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src;
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(cpu_state.regs[cpu_reg].w, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
@@ -395,9 +433,11 @@ static int opCMP_w_rm_a32(uint32_t fetchdat)
|
||||
}
|
||||
|
||||
static int opCMP_l_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
{
|
||||
uint32_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(cpu_state.regs[cpu_reg].l, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
|
||||
@@ -407,7 +447,9 @@ static int opCMP_l_rm_a16(uint32_t fetchdat)
|
||||
static int opCMP_l_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(cpu_state.regs[cpu_reg].l, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
|
||||
@@ -446,6 +488,8 @@ static int opTEST_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
temp2 = getr8(cpu_reg);
|
||||
setznp8(temp & temp2);
|
||||
@@ -458,6 +502,8 @@ static int opTEST_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
temp2 = getr8(cpu_reg);
|
||||
setznp8(temp & temp2);
|
||||
@@ -471,6 +517,8 @@ static int opTEST_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].w;
|
||||
setznp16(temp & temp2);
|
||||
@@ -483,6 +531,8 @@ static int opTEST_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].w;
|
||||
setznp16(temp & temp2);
|
||||
@@ -496,6 +546,8 @@ static int opTEST_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].l;
|
||||
setznp32(temp & temp2);
|
||||
@@ -508,6 +560,8 @@ static int opTEST_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].l;
|
||||
setznp32(temp & temp2);
|
||||
@@ -600,6 +654,8 @@ static int op80_a16(uint32_t fetchdat)
|
||||
uint8_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(b, 8);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
@@ -614,6 +670,8 @@ static int op80_a32(uint32_t fetchdat)
|
||||
uint8_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(b, 8);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
@@ -628,6 +686,8 @@ static int op81_w_a16(uint32_t fetchdat)
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getword(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(w, 16);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
@@ -642,6 +702,8 @@ static int op81_w_a32(uint32_t fetchdat)
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getword(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(w, 16);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
@@ -670,6 +732,8 @@ static int op81_l_a32(uint32_t fetchdat)
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getlong(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(l, 32);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
@@ -685,6 +749,8 @@ static int op83_w_a16(uint32_t fetchdat)
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xff00;
|
||||
ARITH_MULTI(w, 16);
|
||||
@@ -700,6 +766,8 @@ static int op83_w_a32(uint32_t fetchdat)
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xff00;
|
||||
ARITH_MULTI(w, 16);
|
||||
@@ -716,6 +784,8 @@ static int op83_l_a16(uint32_t fetchdat)
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xffffff00;
|
||||
ARITH_MULTI(l, 32);
|
||||
@@ -731,6 +801,8 @@ static int op83_l_a32(uint32_t fetchdat)
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xffffff00;
|
||||
ARITH_MULTI(l, 32);
|
||||
|
||||
752
src/cpu/x86_ops_arith_ex.h
Normal file
752
src/cpu/x86_ops_arith_ex.h
Normal file
@@ -0,0 +1,752 @@
|
||||
#define OP_ARITH(name, operation, setflags, flagops, gettempc) \
|
||||
static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint8_t dst; \
|
||||
uint8_t src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
dst = getr8(cpu_rm); \
|
||||
src = getr8(cpu_reg); \
|
||||
setflags ## 8 flagops; \
|
||||
setr8(cpu_rm, operation); \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dst = geteab(); if (cpu_state.abrt) return 1; \
|
||||
src = getr8(cpu_reg); \
|
||||
seteab(operation); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 8 flagops; \
|
||||
CLOCK_CYCLES(timing_mr); \
|
||||
PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint8_t dst; \
|
||||
uint8_t src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
dst = getr8(cpu_rm); \
|
||||
src = getr8(cpu_reg); \
|
||||
setflags ## 8 flagops; \
|
||||
setr8(cpu_rm, operation); \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dst = geteab(); if (cpu_state.abrt) return 1; \
|
||||
src = getr8(cpu_reg); \
|
||||
seteab(operation); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 8 flagops; \
|
||||
CLOCK_CYCLES(timing_mr); \
|
||||
PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 1); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t dst; \
|
||||
uint16_t src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
dst = cpu_state.regs[cpu_rm].w; \
|
||||
src = cpu_state.regs[cpu_reg].w; \
|
||||
setflags ## 16 flagops; \
|
||||
cpu_state.regs[cpu_rm].w = operation; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].w; \
|
||||
seteaw(operation); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 16 flagops; \
|
||||
CLOCK_CYCLES(timing_mr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 0); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t dst; \
|
||||
uint16_t src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
dst = cpu_state.regs[cpu_rm].w; \
|
||||
src = cpu_state.regs[cpu_reg].w; \
|
||||
setflags ## 16 flagops; \
|
||||
cpu_state.regs[cpu_rm].w = operation; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].w; \
|
||||
seteaw(operation); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 16 flagops; \
|
||||
CLOCK_CYCLES(timing_mr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 1); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t dst; \
|
||||
uint32_t src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
dst = cpu_state.regs[cpu_rm].l; \
|
||||
src = cpu_state.regs[cpu_reg].l; \
|
||||
setflags ## 32 flagops; \
|
||||
cpu_state.regs[cpu_rm].l = operation; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dst = geteal(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].l; \
|
||||
seteal(operation); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 32 flagops; \
|
||||
CLOCK_CYCLES(timing_mr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 0); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t dst; \
|
||||
uint32_t src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod == 3) \
|
||||
{ \
|
||||
dst = cpu_state.regs[cpu_rm].l; \
|
||||
src = cpu_state.regs[cpu_reg].l; \
|
||||
setflags ## 32 flagops; \
|
||||
cpu_state.regs[cpu_rm].l = operation; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
dst = geteal(); if (cpu_state.abrt) return 1; \
|
||||
src = cpu_state.regs[cpu_reg].l; \
|
||||
seteal(operation); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 32 flagops; \
|
||||
CLOCK_CYCLES(timing_mr); \
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 1); \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _b_rm_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint8_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
dst = getr8(cpu_reg); \
|
||||
src = geteab(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 8 flagops; \
|
||||
setr8(cpu_reg, operation); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## name ## _b_rm_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint8_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
dst = getr8(cpu_reg); \
|
||||
src = geteab(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 8 flagops; \
|
||||
setr8(cpu_reg, operation); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _w_rm_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
dst = cpu_state.regs[cpu_reg].w; \
|
||||
src = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 16 flagops; \
|
||||
cpu_state.regs[cpu_reg].w = operation; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## name ## _w_rm_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
dst = cpu_state.regs[cpu_reg].w; \
|
||||
src = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 16 flagops; \
|
||||
cpu_state.regs[cpu_reg].w = operation; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _l_rm_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_16(fetchdat); \
|
||||
dst = cpu_state.regs[cpu_reg].l; \
|
||||
src = geteal(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 32 flagops; \
|
||||
cpu_state.regs[cpu_reg].l = operation; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
static int op ## name ## _l_rm_a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t dst, src; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
fetch_ea_32(fetchdat); \
|
||||
dst = cpu_state.regs[cpu_reg].l; \
|
||||
src = geteal(); if (cpu_state.abrt) return 1; \
|
||||
setflags ## 32 flagops; \
|
||||
cpu_state.regs[cpu_reg].l = operation; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _AL_imm(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint8_t dst = AL; \
|
||||
uint8_t src = getbytef(); \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
setflags ## 8 flagops; \
|
||||
AL = operation; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _AX_imm(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint16_t dst = AX; \
|
||||
uint16_t src = getwordf(); \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
setflags ## 16 flagops; \
|
||||
AX = operation; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
} \
|
||||
\
|
||||
static int op ## name ## _EAX_imm(uint32_t fetchdat) \
|
||||
{ \
|
||||
uint32_t dst = EAX; \
|
||||
uint32_t src = getlong(); if (cpu_state.abrt) return 1; \
|
||||
if (gettempc) tempc = CF_SET() ? 1 : 0; \
|
||||
setflags ## 32 flagops; \
|
||||
EAX = operation; \
|
||||
CLOCK_CYCLES(timing_rr); \
|
||||
PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
OP_ARITH(ADD, dst + src, setadd, (dst, src), 0)
|
||||
OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1)
|
||||
OP_ARITH(SUB, dst - src, setsub, (dst, src), 0)
|
||||
OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1)
|
||||
OP_ARITH(OR, dst | src, setznp, (dst | src), 0)
|
||||
OP_ARITH(AND, dst & src, setznp, (dst & src), 0)
|
||||
OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0)
|
||||
|
||||
static int opCMP_b_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
dst = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(dst, getr8(cpu_reg));
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCMP_b_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
dst = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(dst, getr8(cpu_reg));
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_w_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(dst, cpu_state.regs[cpu_reg].w);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCMP_w_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(dst, cpu_state.regs[cpu_reg].w);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_l_rmw_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
fetch_ea_16(fetchdat);
|
||||
dst = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(dst, cpu_state.regs[cpu_reg].l);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCMP_l_rmw_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
fetch_ea_32(fetchdat);
|
||||
dst = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(dst, cpu_state.regs[cpu_reg].l);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_b_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
src = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(getr8(cpu_reg), src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCMP_b_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src;
|
||||
fetch_ea_32(fetchdat);
|
||||
src = geteab(); if (cpu_state.abrt) return 1;
|
||||
setsub8(getr8(cpu_reg), src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_w_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
src = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(cpu_state.regs[cpu_reg].w, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCMP_w_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src;
|
||||
fetch_ea_32(fetchdat);
|
||||
src = geteaw(); if (cpu_state.abrt) return 1;
|
||||
setsub16(cpu_state.regs[cpu_reg].w, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_l_rm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
fetch_ea_16(fetchdat);
|
||||
src = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(cpu_state.regs[cpu_reg].l, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCMP_l_rm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
fetch_ea_32(fetchdat);
|
||||
src = geteal(); if (cpu_state.abrt) return 1;
|
||||
setsub32(cpu_state.regs[cpu_reg].l, src);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_AL_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src = getbytef();
|
||||
setsub8(AL, src);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_AX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src = getwordf();
|
||||
setsub16(AX, src);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opCMP_EAX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src = getlong(); if (cpu_state.abrt) return 1;
|
||||
setsub32(EAX, src);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opTEST_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
temp2 = getr8(cpu_reg);
|
||||
setznp8(temp & temp2);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opTEST_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
temp2 = getr8(cpu_reg);
|
||||
setznp8(temp & temp2);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opTEST_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].w;
|
||||
setznp16(temp & temp2);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opTEST_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].w;
|
||||
setznp16(temp & temp2);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opTEST_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2;
|
||||
fetch_ea_16(fetchdat);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].l;
|
||||
setznp32(temp & temp2);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opTEST_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp, temp2;
|
||||
fetch_ea_32(fetchdat);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
temp2 = cpu_state.regs[cpu_reg].l;
|
||||
setznp32(temp & temp2);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int opTEST_AL(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = getbytef();
|
||||
setznp8(AL & temp);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opTEST_AX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = getwordf();
|
||||
setznp16(AX & temp);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opTEST_EAX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = getlong(); if (cpu_state.abrt) return 1;
|
||||
setznp32(EAX & temp);
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#define ARITH_MULTI(ea_width, flag_width, is32) \
|
||||
dst = read ## ea_width(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \
|
||||
switch ((rmdat >> 3) & 7) \
|
||||
{ \
|
||||
case 0x00: /*ADD ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
|
||||
write ## ea_width(easeg, cpu_state.eaaddr, dst + src); if (cpu_state.abrt) return 1; \
|
||||
setadd ## flag_width(dst, src); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
|
||||
break; \
|
||||
case 0x01: /*OR ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
|
||||
dst |= src; \
|
||||
write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \
|
||||
setznp ## flag_width(dst); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
|
||||
break; \
|
||||
case 0x02: /*ADC ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
|
||||
tempc = CF_SET() ? 1 : 0; \
|
||||
write ## ea_width(easeg, cpu_state.eaaddr, dst + src + tempc); if (cpu_state.abrt) return 1; \
|
||||
setadc ## flag_width(dst, src); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
|
||||
break; \
|
||||
case 0x03: /*SBB ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
|
||||
tempc = CF_SET() ? 1 : 0; \
|
||||
write ## ea_width(easeg, cpu_state.eaaddr, dst - (src + tempc)); if (cpu_state.abrt) return 1; \
|
||||
setsbc ## flag_width(dst, src); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
|
||||
break; \
|
||||
case 0x04: /*AND ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
|
||||
dst &= src; \
|
||||
write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \
|
||||
setznp ## flag_width(dst); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
|
||||
break; \
|
||||
case 0x05: /*SUB ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
|
||||
write ## ea_width(easeg, cpu_state.eaaddr, dst - src); if (cpu_state.abrt) return 1; \
|
||||
setsub ## flag_width(dst, src); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
|
||||
break; \
|
||||
case 0x06: /*XOR ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 1, is32) \
|
||||
dst ^= src; \
|
||||
write ## ea_width(easeg, cpu_state.eaaddr, dst); if (cpu_state.abrt) return 1; \
|
||||
setznp ## flag_width(dst); \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \
|
||||
break; \
|
||||
case 0x07: /*CMP ea, #*/ \
|
||||
if (cpu_mod != 3) x86_translate_break(cpu_state.ea_seg, cpu_state.eaaddr, 0, is32) \
|
||||
setsub ## flag_width(dst, src); \
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \
|
||||
else CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
static int op80_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(8, 8, 0);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int op80_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(8, 8, 1);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int op81_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
src = getword(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(16, 16, 0);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int op81_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
src = getword(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(16, 16, 1);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int op81_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
src = getlong(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(32, 32, 0);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int op81_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
src = getlong(); if (cpu_state.abrt) return 1;
|
||||
ARITH_MULTI(32, 32, 1);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int op83_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xff00;
|
||||
ARITH_MULTI(16, 16, 0);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int op83_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xff00;
|
||||
ARITH_MULTI(16, 16, 1);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int op83_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xffffff00;
|
||||
ARITH_MULTI(32, 32, 0);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int op83_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
src = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (src & 0x80) src |= 0xffffff00;
|
||||
ARITH_MULTI(32, 32, 1);
|
||||
if ((rmdat & 0x38) == 0x38)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
else
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ static int opCMPXCHG_b_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
if (AL == temp) seteab(getr8(cpu_reg));
|
||||
else AL = temp;
|
||||
@@ -26,6 +27,7 @@ static int opCMPXCHG_b_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
if (AL == temp) seteab(getr8(cpu_reg));
|
||||
else AL = temp;
|
||||
@@ -45,6 +47,7 @@ static int opCMPXCHG_w_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w);
|
||||
else AX = temp;
|
||||
@@ -63,6 +66,7 @@ static int opCMPXCHG_w_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w);
|
||||
else AX = temp;
|
||||
@@ -82,6 +86,7 @@ static int opCMPXCHG_l_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l);
|
||||
else EAX = temp;
|
||||
@@ -100,6 +105,7 @@ static int opCMPXCHG_l_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l);
|
||||
else EAX = temp;
|
||||
@@ -119,6 +125,7 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
if (EAX == temp && EDX == temp_hi)
|
||||
@@ -134,9 +141,9 @@ static int opCMPXCHG8B_a16(uint32_t fetchdat)
|
||||
if (cpu_state.abrt) return 0;
|
||||
flags_rebuild();
|
||||
if (temp == temp2 && temp_hi == temp2_hi)
|
||||
flags |= Z_FLAG;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else
|
||||
flags &= ~Z_FLAG;
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
return 0;
|
||||
}
|
||||
@@ -150,6 +157,7 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal();
|
||||
temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
if (EAX == temp && EDX == temp_hi)
|
||||
@@ -165,9 +173,9 @@ static int opCMPXCHG8B_a32(uint32_t fetchdat)
|
||||
if (cpu_state.abrt) return 0;
|
||||
flags_rebuild();
|
||||
if (temp == temp2 && temp_hi == temp2_hi)
|
||||
flags |= Z_FLAG;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
else
|
||||
flags &= ~Z_FLAG;
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
cycles -= (cpu_mod == 3) ? 6 : 10;
|
||||
return 0;
|
||||
}
|
||||
@@ -182,6 +190,7 @@ static int opXADD_b_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setadd8(temp, getr8(cpu_reg));
|
||||
@@ -199,6 +208,7 @@ static int opXADD_b_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(temp + getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setadd8(temp, getr8(cpu_reg));
|
||||
@@ -217,6 +227,7 @@ static int opXADD_w_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
setadd16(temp, cpu_state.regs[cpu_reg].w);
|
||||
@@ -234,6 +245,7 @@ static int opXADD_w_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp + cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
setadd16(temp, cpu_state.regs[cpu_reg].w);
|
||||
@@ -252,6 +264,7 @@ static int opXADD_l_a16(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
setadd32(temp, cpu_state.regs[cpu_reg].l);
|
||||
@@ -269,6 +282,7 @@ static int opXADD_l_a32(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp + cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
setadd32(temp, cpu_state.regs[cpu_reg].l);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
static int opAAA(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
if ((flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
{
|
||||
AL += 6;
|
||||
AH++;
|
||||
flags |= (A_FLAG | C_FLAG);
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
}
|
||||
else
|
||||
flags &= ~(A_FLAG | C_FLAG);
|
||||
cpu_state.flags &= ~(A_FLAG | C_FLAG);
|
||||
AL &= 0xF;
|
||||
CLOCK_CYCLES(is486 ? 3 : 4);
|
||||
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0);
|
||||
@@ -42,14 +42,14 @@ static int opAAM(uint32_t fetchdat)
|
||||
static int opAAS(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
if ((flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9))
|
||||
{
|
||||
AL -= 6;
|
||||
AH--;
|
||||
flags |= (A_FLAG | C_FLAG);
|
||||
cpu_state.flags |= (A_FLAG | C_FLAG);
|
||||
}
|
||||
else
|
||||
flags &= ~(A_FLAG | C_FLAG);
|
||||
cpu_state.flags &= ~(A_FLAG | C_FLAG);
|
||||
AL &= 0xF;
|
||||
CLOCK_CYCLES(is486 ? 3 : 4);
|
||||
PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0);
|
||||
@@ -61,23 +61,23 @@ static int opDAA(uint32_t fetchdat)
|
||||
uint16_t tempw;
|
||||
|
||||
flags_rebuild();
|
||||
if ((flags & A_FLAG) || ((AL & 0xf) > 9))
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9))
|
||||
{
|
||||
int tempi = ((uint16_t)AL) + 6;
|
||||
AL += 6;
|
||||
flags |= A_FLAG;
|
||||
if (tempi & 0x100) flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
if (tempi & 0x100) cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
if ((flags & C_FLAG) || (AL > 0x9f))
|
||||
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f))
|
||||
{
|
||||
AL += 0x60;
|
||||
flags |= C_FLAG;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
|
||||
tempw = flags & (C_FLAG | A_FLAG);
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
flags |= tempw;
|
||||
cpu_state.flags |= tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);
|
||||
|
||||
@@ -89,23 +89,23 @@ static int opDAS(uint32_t fetchdat)
|
||||
uint16_t tempw;
|
||||
|
||||
flags_rebuild();
|
||||
if ((flags & A_FLAG) || ((AL & 0xf) > 9))
|
||||
if ((cpu_state.flags & A_FLAG) || ((AL & 0xf) > 9))
|
||||
{
|
||||
int tempi = ((uint16_t)AL) - 6;
|
||||
AL -= 6;
|
||||
flags |= A_FLAG;
|
||||
if (tempi & 0x100) flags |= C_FLAG;
|
||||
cpu_state.flags |= A_FLAG;
|
||||
if (tempi & 0x100) cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
if ((flags & C_FLAG) || (AL > 0x9f))
|
||||
if ((cpu_state.flags & C_FLAG) || (AL > 0x9f))
|
||||
{
|
||||
AL -= 0x60;
|
||||
flags |= C_FLAG;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
}
|
||||
|
||||
tempw = flags & (C_FLAG | A_FLAG);
|
||||
tempw = cpu_state.flags & (C_FLAG | A_FLAG);
|
||||
setznp8(AL);
|
||||
flags_rebuild();
|
||||
flags |= tempw;
|
||||
cpu_state.flags |= tempw;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0);
|
||||
|
||||
|
||||
@@ -3,11 +3,12 @@ static int opBT_w_r_a16(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0);
|
||||
@@ -18,11 +19,12 @@ static int opBT_w_r_a32(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1);
|
||||
@@ -33,11 +35,12 @@ static int opBT_l_r_a16(uint32_t fetchdat)
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0);
|
||||
@@ -48,11 +51,12 @@ static int opBT_l_r_a32(uint32_t fetchdat)
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1);
|
||||
@@ -66,14 +70,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
|
||||
uint16_t temp; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
else flags &= ~C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \
|
||||
@@ -85,14 +91,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
|
||||
uint16_t temp; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
else flags &= ~C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \
|
||||
@@ -104,14 +112,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
|
||||
uint32_t temp; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
|
||||
temp = geteal(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
else flags &= ~C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \
|
||||
@@ -123,14 +133,16 @@ static int opBT_l_r_a32(uint32_t fetchdat)
|
||||
uint32_t temp; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \
|
||||
temp = geteal(); if (cpu_state.abrt) return 1; \
|
||||
tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \
|
||||
temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
else flags &= ~C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
else cpu_state.flags &= ~C_FLAG; \
|
||||
\
|
||||
CLOCK_CYCLES(6); \
|
||||
PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \
|
||||
@@ -147,6 +159,8 @@ static int opBA_w_a16(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteaw();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
@@ -155,8 +169,8 @@ static int opBA_w_a16(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
return 0;
|
||||
@@ -177,8 +191,8 @@ static int opBA_w_a16(uint32_t fetchdat)
|
||||
break;
|
||||
}
|
||||
seteaw(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return 0;
|
||||
@@ -189,6 +203,8 @@ static int opBA_w_a32(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteaw();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
@@ -197,8 +213,8 @@ static int opBA_w_a32(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
return 0;
|
||||
@@ -219,8 +235,8 @@ static int opBA_w_a32(uint32_t fetchdat)
|
||||
break;
|
||||
}
|
||||
seteaw(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
return 0;
|
||||
@@ -232,6 +248,8 @@ static int opBA_l_a16(uint32_t fetchdat)
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteal();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
@@ -240,8 +258,8 @@ static int opBA_l_a16(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
return 0;
|
||||
@@ -262,8 +280,8 @@ static int opBA_l_a16(uint32_t fetchdat)
|
||||
break;
|
||||
}
|
||||
seteal(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
return 0;
|
||||
@@ -274,6 +292,8 @@ static int opBA_l_a32(uint32_t fetchdat)
|
||||
uint32_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp = geteal();
|
||||
count = getbyte(); if (cpu_state.abrt) return 1;
|
||||
@@ -282,8 +302,8 @@ static int opBA_l_a32(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x20: /*BT w,imm*/
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
return 0;
|
||||
@@ -304,8 +324,8 @@ static int opBA_l_a32(uint32_t fetchdat)
|
||||
break;
|
||||
}
|
||||
seteal(temp); if (cpu_state.abrt) return 1;
|
||||
if (tempc) flags |= C_FLAG;
|
||||
else flags &= ~C_FLAG;
|
||||
if (tempc) cpu_state.flags |= C_FLAG;
|
||||
else cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(6);
|
||||
PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
return 0;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
if (temp) \
|
||||
{ \
|
||||
int c; \
|
||||
flags &= ~Z_FLAG; \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
for (c = start; c != end; c += dir) \
|
||||
{ \
|
||||
CLOCK_CYCLES(time); \
|
||||
@@ -17,7 +17,7 @@
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
flags |= Z_FLAG;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
|
||||
static int opBSF_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
@@ -25,6 +25,8 @@ static int opBSF_w_a16(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
|
||||
@@ -40,6 +42,8 @@ static int opBSF_w_a32(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3);
|
||||
@@ -55,6 +59,8 @@ static int opBSF_l_a16(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
|
||||
@@ -70,6 +76,8 @@ static int opBSF_l_a32(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3);
|
||||
@@ -86,6 +94,8 @@ static int opBSR_w_a16(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
|
||||
@@ -101,6 +111,8 @@ static int opBSR_w_a32(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3);
|
||||
@@ -116,6 +128,8 @@ static int opBSR_l_a16(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
|
||||
@@ -131,6 +145,8 @@ static int opBSR_l_a32(uint32_t fetchdat)
|
||||
int instr_cycles = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
|
||||
BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#define CALL_FAR_w(new_seg, new_pc) \
|
||||
old_cs = CS; \
|
||||
old_pc = cpu_state.pc; \
|
||||
oxpc = cpu_state.pc; \
|
||||
oxpc = cpu_state.pc; \
|
||||
cpu_state.pc = new_pc; \
|
||||
optype = CALL; \
|
||||
cgate16 = cgate32 = 0; \
|
||||
if (msw & 1) loadcscall(new_seg); \
|
||||
if (msw & 1) loadcscall(new_seg); \
|
||||
else \
|
||||
{ \
|
||||
loadcs(new_seg); \
|
||||
@@ -30,11 +30,11 @@
|
||||
#define CALL_FAR_l(new_seg, new_pc) \
|
||||
old_cs = CS; \
|
||||
old_pc = cpu_state.pc; \
|
||||
oxpc = cpu_state.pc; \
|
||||
oxpc = cpu_state.pc; \
|
||||
cpu_state.pc = new_pc; \
|
||||
optype = CALL; \
|
||||
cgate16 = cgate32 = 0; \
|
||||
if (msw & 1) loadcscall(new_seg); \
|
||||
if (msw & 1) loadcscall(new_seg); \
|
||||
else \
|
||||
{ \
|
||||
loadcs(new_seg); \
|
||||
@@ -104,6 +104,8 @@ static int opFF_w_a16(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp + 1); if (cpu_state.abrt) return 1;
|
||||
setadd16nc(temp, 1);
|
||||
@@ -111,6 +113,8 @@ static int opFF_w_a16(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
break;
|
||||
case 0x08: /*DEC w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp - 1); if (cpu_state.abrt) return 1;
|
||||
setsub16nc(temp, 1);
|
||||
@@ -118,6 +122,8 @@ static int opFF_w_a16(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
break;
|
||||
case 0x10: /*CALL*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteaw(); if (cpu_state.abrt) return 1;
|
||||
PUSH_W(cpu_state.pc);
|
||||
cpu_state.pc = new_pc;
|
||||
@@ -128,6 +134,8 @@ static int opFF_w_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x18: /*CALL far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = readmemw(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -137,6 +145,8 @@ static int opFF_w_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x20: /*JMP*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
CPU_BLOCK_END();
|
||||
@@ -146,6 +156,8 @@ static int opFF_w_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x28: /*JMP far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
oxpc = cpu_state.pc;
|
||||
new_pc = readmemw(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
@@ -156,6 +168,8 @@ static int opFF_w_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x30: /*PUSH w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
PUSH_W(temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
@@ -181,6 +195,8 @@ static int opFF_w_a32(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp + 1); if (cpu_state.abrt) return 1;
|
||||
setadd16nc(temp, 1);
|
||||
@@ -188,6 +204,8 @@ static int opFF_w_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
break;
|
||||
case 0x08: /*DEC w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(temp - 1); if (cpu_state.abrt) return 1;
|
||||
setsub16nc(temp, 1);
|
||||
@@ -195,6 +213,8 @@ static int opFF_w_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
break;
|
||||
case 0x10: /*CALL*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteaw(); if (cpu_state.abrt) return 1;
|
||||
PUSH_W(cpu_state.pc);
|
||||
cpu_state.pc = new_pc;
|
||||
@@ -205,6 +225,8 @@ static int opFF_w_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x18: /*CALL far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = readmemw(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -214,6 +236,8 @@ static int opFF_w_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x20: /*JMP*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
CPU_BLOCK_END();
|
||||
@@ -223,6 +247,8 @@ static int opFF_w_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x28: /*JMP far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
oxpc = cpu_state.pc;
|
||||
new_pc = readmemw(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
@@ -233,6 +259,8 @@ static int opFF_w_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x30: /*PUSH w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
PUSH_W(temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
@@ -259,6 +287,8 @@ static int opFF_l_a16(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp + 1); if (cpu_state.abrt) return 1;
|
||||
setadd32nc(temp, 1);
|
||||
@@ -266,6 +296,8 @@ static int opFF_l_a16(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
break;
|
||||
case 0x08: /*DEC l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp - 1); if (cpu_state.abrt) return 1;
|
||||
setsub32nc(temp, 1);
|
||||
@@ -273,6 +305,8 @@ static int opFF_l_a16(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
break;
|
||||
case 0x10: /*CALL*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteal(); if (cpu_state.abrt) return 1;
|
||||
PUSH_L(cpu_state.pc);
|
||||
cpu_state.pc = new_pc;
|
||||
@@ -283,6 +317,8 @@ static int opFF_l_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x18: /*CALL far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = readmeml(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -292,6 +328,8 @@ static int opFF_l_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x20: /*JMP*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteal(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
CPU_BLOCK_END();
|
||||
@@ -301,6 +339,8 @@ static int opFF_l_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x28: /*JMP far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
oxpc = cpu_state.pc;
|
||||
new_pc = readmeml(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
@@ -311,6 +351,8 @@ static int opFF_l_a16(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x30: /*PUSH l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
PUSH_L(temp);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5);
|
||||
@@ -336,6 +378,8 @@ static int opFF_l_a32(uint32_t fetchdat)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*INC l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp + 1); if (cpu_state.abrt) return 1;
|
||||
setadd32nc(temp, 1);
|
||||
@@ -343,6 +387,8 @@ static int opFF_l_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
break;
|
||||
case 0x08: /*DEC l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(temp - 1); if (cpu_state.abrt) return 1;
|
||||
setsub32nc(temp, 1);
|
||||
@@ -350,6 +396,8 @@ static int opFF_l_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
break;
|
||||
case 0x10: /*CALL*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteal(); if (cpu_state.abrt) return 1;
|
||||
PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
@@ -360,6 +408,8 @@ static int opFF_l_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x18: /*CALL far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = readmeml(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -369,6 +419,8 @@ static int opFF_l_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x20: /*JMP*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_pc = geteal(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.pc = new_pc;
|
||||
CPU_BLOCK_END();
|
||||
@@ -378,6 +430,8 @@ static int opFF_l_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x28: /*JMP far*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
oxpc = cpu_state.pc;
|
||||
new_pc = readmeml(easeg, cpu_state.eaaddr);
|
||||
new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
@@ -388,6 +442,8 @@ static int opFF_l_a32(uint32_t fetchdat)
|
||||
PREFETCH_FLUSH();
|
||||
break;
|
||||
case 0x30: /*PUSH l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
PUSH_L(temp);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
static int opCMC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags ^= C_FLAG;
|
||||
cpu_state.flags ^= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
@@ -11,14 +11,14 @@ static int opCMC(uint32_t fetchdat)
|
||||
static int opCLC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags &= ~C_FLAG;
|
||||
cpu_state.flags &= ~C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opCLD(uint32_t fetchdat)
|
||||
{
|
||||
flags &= ~D_FLAG;
|
||||
cpu_state.flags &= ~D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
@@ -27,10 +27,10 @@ static int opCLI(uint32_t fetchdat)
|
||||
{
|
||||
if (!IOPLp)
|
||||
{
|
||||
if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||
((eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||
{
|
||||
eflags &= ~VIF_FLAG;
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -39,7 +39,7 @@ static int opCLI(uint32_t fetchdat)
|
||||
}
|
||||
}
|
||||
else
|
||||
flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
@@ -49,14 +49,14 @@ static int opCLI(uint32_t fetchdat)
|
||||
static int opSTC(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags |= C_FLAG;
|
||||
cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
static int opSTD(uint32_t fetchdat)
|
||||
{
|
||||
flags |= D_FLAG;
|
||||
cpu_state.flags |= D_FLAG;
|
||||
CLOCK_CYCLES(2);
|
||||
PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
@@ -65,16 +65,16 @@ static int opSTI(uint32_t fetchdat)
|
||||
{
|
||||
if (!IOPLp)
|
||||
{
|
||||
if ((!(eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||
((eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||
if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) ||
|
||||
((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME)))
|
||||
{
|
||||
if (eflags & VIP_FLAG)
|
||||
if (cpu_state.eflags & VIP_FLAG)
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
eflags |= VIF_FLAG;
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -83,7 +83,7 @@ static int opSTI(uint32_t fetchdat)
|
||||
}
|
||||
}
|
||||
else
|
||||
flags |= I_FLAG;
|
||||
cpu_state.flags |= I_FLAG;
|
||||
|
||||
CPU_BLOCK_END();
|
||||
|
||||
@@ -95,7 +95,7 @@ static int opSTI(uint32_t fetchdat)
|
||||
static int opSAHF(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags = (flags & 0xff00) | (AH & 0xd5) | 2;
|
||||
cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
|
||||
@@ -108,7 +108,7 @@ static int opSAHF(uint32_t fetchdat)
|
||||
static int opLAHF(uint32_t fetchdat)
|
||||
{
|
||||
flags_rebuild();
|
||||
AH = flags & 0xff;
|
||||
AH = cpu_state.flags & 0xff;
|
||||
CLOCK_CYCLES(3);
|
||||
PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0);
|
||||
return 0;
|
||||
@@ -116,15 +116,15 @@ static int opLAHF(uint32_t fetchdat)
|
||||
|
||||
static int opPUSHF(uint32_t fetchdat)
|
||||
{
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
uint16_t temp;
|
||||
|
||||
flags_rebuild();
|
||||
temp = (flags & ~I_FLAG) | 0x3000;
|
||||
if (eflags & VIF_FLAG)
|
||||
temp = (cpu_state.flags & ~I_FLAG) | 0x3000;
|
||||
if (cpu_state.eflags & VIF_FLAG)
|
||||
temp |= I_FLAG;
|
||||
PUSH_W(temp);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ static int opPUSHF(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
flags_rebuild();
|
||||
PUSH_W(flags);
|
||||
PUSH_W(cpu_state.flags);
|
||||
}
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
|
||||
@@ -146,16 +146,16 @@ static int opPUSHF(uint32_t fetchdat)
|
||||
static int opPUSHFD(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (cpu_CR4_mask & CR4_VME) tempw = eflags & 0x3c;
|
||||
else if (CPUID) tempw = eflags & 0x24;
|
||||
else tempw = eflags & 4;
|
||||
if (cpu_CR4_mask & CR4_VME) tempw = cpu_state.eflags & 0x3c;
|
||||
else if (CPUID) tempw = cpu_state.eflags & 0x24;
|
||||
else tempw = cpu_state.eflags & 4;
|
||||
flags_rebuild();
|
||||
PUSH_L(flags | (tempw << 16));
|
||||
PUSH_L(cpu_state.flags | (tempw << 16));
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0);
|
||||
return cpu_state.abrt;
|
||||
@@ -165,7 +165,7 @@ static int opPOPF_286(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
@@ -173,10 +173,10 @@ static int opPOPF_286(uint32_t fetchdat)
|
||||
|
||||
tempw = POP_W(); if (cpu_state.abrt) return 1;
|
||||
|
||||
if (!(msw & 1)) flags = (flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL)) flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp) flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2;
|
||||
else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
flags_extract();
|
||||
|
||||
CLOCK_CYCLES(5);
|
||||
@@ -192,7 +192,7 @@ static int opPOPF(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
@@ -206,17 +206,17 @@ static int opPOPF(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (eflags & VIP_FLAG)))
|
||||
if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG)))
|
||||
{
|
||||
ESP = old_esp;
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (tempw & I_FLAG)
|
||||
eflags |= VIF_FLAG;
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
eflags &= ~VIF_FLAG;
|
||||
flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -231,11 +231,11 @@ static int opPOPF(uint32_t fetchdat)
|
||||
return 1;
|
||||
|
||||
if (!(CPL) || !(msw & 1))
|
||||
flags = (tempw & 0x7fd5) | 2;
|
||||
cpu_state.flags = (tempw & 0x7fd5) | 2;
|
||||
else if (IOPLp)
|
||||
flags = (flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2;
|
||||
else
|
||||
flags = (flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2;
|
||||
}
|
||||
flags_extract();
|
||||
|
||||
@@ -252,7 +252,7 @@ static int opPOPFD(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ;
|
||||
|
||||
if ((eflags & VM_FLAG) && (IOPL < 3))
|
||||
if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
@@ -260,16 +260,16 @@ static int opPOPFD(uint32_t fetchdat)
|
||||
|
||||
templ = POP_L(); if (cpu_state.abrt) return 1;
|
||||
|
||||
if (!(CPL) || !(msw & 1)) flags = (templ & 0x7fd5) | 2;
|
||||
else if (IOPLp) flags = (flags & 0x3000) | (templ & 0x4fd5) | 2;
|
||||
else flags = (flags & 0x3200) | (templ & 0x4dd5) | 2;
|
||||
if (!(CPL) || !(msw & 1)) cpu_state.flags = (templ & 0x7fd5) | 2;
|
||||
else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2;
|
||||
else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2;
|
||||
|
||||
templ &= is486 ? 0x3c0000 : 0;
|
||||
templ |= ((eflags&3) << 16);
|
||||
if (cpu_CR4_mask & CR4_VME) eflags = (templ >> 16) & 0x3f;
|
||||
else if (CPUID) eflags = (templ >> 16) & 0x27;
|
||||
else if (is486) eflags = (templ >> 16) & 7;
|
||||
else eflags = (templ >> 16) & 3;
|
||||
templ |= ((cpu_state.eflags&3) << 16);
|
||||
if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f;
|
||||
else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27;
|
||||
else if (is486) cpu_state.eflags = (templ >> 16) & 7;
|
||||
else cpu_state.eflags = (templ >> 16) & 3;
|
||||
|
||||
flags_extract();
|
||||
|
||||
|
||||
@@ -43,15 +43,15 @@ static int opSYSENTER(uint32_t fetchdat)
|
||||
x386_dynarec_log("SYSENTER called\n");
|
||||
#endif
|
||||
|
||||
if (!(cr0 & 1)) return internal_illegal("SYSENTER: CPU not in protected mode");
|
||||
if (!(msw & 1)) return internal_illegal("SYSENTER: CPU not in protected mode");
|
||||
if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSENTER: CS MSR is zero");
|
||||
|
||||
#ifdef SYSENTER_LOG
|
||||
x386_dynarec_log("SYSENTER started:\n");
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
|
||||
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32);
|
||||
#endif
|
||||
|
||||
if (cpu_state.abrt) return 1;
|
||||
@@ -63,17 +63,17 @@ static int opSYSENTER(uint32_t fetchdat)
|
||||
cgate16 = cgate32 = 0; \
|
||||
|
||||
/* Set VM, RF, and IF to 0. */
|
||||
eflags &= ~0x0003;
|
||||
flags &= ~0x0200;
|
||||
cpu_state.eflags &= ~(VM_FLAG | 0x0001);
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
|
||||
CS = (cs_msr & 0xFFFC);
|
||||
make_seg_data(sysenter_cs_seg_data, 0, 0xFFFFF, 11, 1, 0, 1, 1, 1, 0);
|
||||
do_seg_load(&_cs, sysenter_cs_seg_data);
|
||||
do_seg_load(&cpu_state.seg_cs, sysenter_cs_seg_data);
|
||||
use32 = 0x300;
|
||||
|
||||
SS = ((cs_msr + 8) & 0xFFFC);
|
||||
make_seg_data(sysenter_ss_seg_data, 0, 0xFFFFF, 3, 1, 0, 1, 1, 1, 0);
|
||||
do_seg_load(&_ss, sysenter_ss_seg_data);
|
||||
do_seg_load(&cpu_state.seg_ss, sysenter_ss_seg_data);
|
||||
stack32 = 1;
|
||||
|
||||
cycles -= timing_call_pm;
|
||||
@@ -84,10 +84,10 @@ static int opSYSENTER(uint32_t fetchdat)
|
||||
|
||||
#ifdef SYSENTER_LOG
|
||||
x386_dynarec_log("SYSENTER completed:\n");
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
|
||||
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -103,15 +103,15 @@ static int opSYSEXIT(uint32_t fetchdat)
|
||||
#endif
|
||||
|
||||
if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSEXIT: CS MSR is zero");
|
||||
if (!(cr0 & 1)) return internal_illegal("SYSEXIT: CPU not in protected mode");
|
||||
if (CS & 3) return internal_illegal("SYSEXIT: CPL not 0");
|
||||
if (!(msw & 1)) return internal_illegal("SYSEXIT: CPU not in protected mode");
|
||||
if (CPL) return internal_illegal("SYSEXIT: CPL not 0");
|
||||
|
||||
#ifdef SYSEXIT_LOG
|
||||
x386_dynarec_log("SYSEXIT start:\n");
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
|
||||
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32, ECX, EDX);
|
||||
#endif
|
||||
|
||||
if (cpu_state.abrt) return 1;
|
||||
@@ -124,12 +124,12 @@ static int opSYSEXIT(uint32_t fetchdat)
|
||||
|
||||
CS = ((cs_msr + 16) & 0xFFFC) | 3;
|
||||
make_seg_data(sysexit_cs_seg_data, 0, 0xFFFFF, 11, 1, 3, 1, 1, 1, 0);
|
||||
do_seg_load(&_cs, sysexit_cs_seg_data);
|
||||
do_seg_load(&cpu_state.seg_cs, sysexit_cs_seg_data);
|
||||
use32 = 0x300;
|
||||
|
||||
SS = CS + 8;
|
||||
make_seg_data(sysexit_ss_seg_data, 0, 0xFFFFF, 3, 1, 3, 1, 1, 1, 0);
|
||||
do_seg_load(&_ss, sysexit_ss_seg_data);
|
||||
do_seg_load(&cpu_state.seg_ss, sysexit_ss_seg_data);
|
||||
stack32 = 1;
|
||||
|
||||
flushmmucache_cr3();
|
||||
@@ -142,10 +142,10 @@ static int opSYSEXIT(uint32_t fetchdat)
|
||||
|
||||
#ifdef SYSEXIT_LOG
|
||||
x386_dynarec_log("SYSEXIT completed:\n");
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked);
|
||||
x386_dynarec_log("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.access, cpu_state.seg_cs.seg, cpu_state.seg_cs.limit_low, cpu_state.seg_cs.limit_high, cpu_state.seg_cs.checked);
|
||||
x386_dynarec_log("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.access, cpu_state.seg_ss.seg, cpu_state.seg_ss.limit_low, cpu_state.seg_ss.limit_high, cpu_state.seg_ss.checked);
|
||||
x386_dynarec_log("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX);
|
||||
x386_dynarec_log("Other information: eip=%08X esp=%08X cpu_state.eflags=%04X cpu_state.flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, cpu_state.eflags, cpu_state.flags, use32, stack32, ECX, EDX);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -202,7 +202,7 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
|
||||
/* if (cr0 & 1)
|
||||
{
|
||||
x87_pc_seg &= 0xFFFC;
|
||||
x87_pc_seg |= ((_cs.access >> 5) & 3);
|
||||
x87_pc_seg |= ((cpu_state.seg_cs.access >> 5) & 3);
|
||||
} */
|
||||
|
||||
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
|
||||
@@ -380,7 +380,7 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
|
||||
/* if (cr0 & 1)
|
||||
{
|
||||
x87_pc_seg &= 0xFFFC;
|
||||
x87_pc_seg |= ((_cs.access >> 5) & 3);
|
||||
x87_pc_seg |= ((cpu_state.seg_cs.access >> 5) & 3);
|
||||
} */
|
||||
|
||||
ftwb = readmemb(easeg, cpu_state.eaaddr + 4);
|
||||
|
||||
@@ -49,7 +49,9 @@ static int opINCDEC_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp=geteab(); if (cpu_state.abrt) return 1;
|
||||
|
||||
if (rmdat&0x38)
|
||||
@@ -70,7 +72,9 @@ static int opINCDEC_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp=geteab(); if (cpu_state.abrt) return 1;
|
||||
|
||||
if (rmdat&0x38)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
static int opINT3(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
@@ -15,7 +15,7 @@ static int opINT3(uint32_t fetchdat)
|
||||
static int opINT1(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
@@ -31,7 +31,7 @@ static int opINT(uint32_t fetchdat)
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
uint8_t temp = getbytef();
|
||||
|
||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
@@ -72,7 +72,7 @@ static int opINTO(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
|
||||
@@ -247,12 +247,12 @@ static int opJMP_r32(uint32_t fetchdat)
|
||||
static int opJMP_far_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr, seg;
|
||||
uint32_t oxpc;
|
||||
uint32_t old_pc;
|
||||
addr = getwordf();
|
||||
seg = getword(); if (cpu_state.abrt) return 1;
|
||||
oxpc = cpu_state.pc;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, oxpc);
|
||||
loadcsjmp(seg, old_pc);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
@@ -261,12 +261,12 @@ static int opJMP_far_a16(uint32_t fetchdat)
|
||||
static int opJMP_far_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t seg;
|
||||
uint32_t addr, oxpc;
|
||||
uint32_t addr, old_pc;
|
||||
addr = getlong();
|
||||
seg = getword(); if (cpu_state.abrt) return 1;
|
||||
oxpc = cpu_state.pc;
|
||||
old_pc = cpu_state.pc;
|
||||
cpu_state.pc = addr;
|
||||
loadcsjmp(seg, oxpc);
|
||||
loadcsjmp(seg, old_pc);
|
||||
CPU_BLOCK_END();
|
||||
PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0);
|
||||
PREFETCH_FLUSH();
|
||||
|
||||
@@ -70,15 +70,15 @@ static int opF6_a16(uint32_t fetchdat)
|
||||
int8_t temps;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
{
|
||||
if (cpu_mod != 3) {
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
}
|
||||
dst = geteab(); if (cpu_state.abrt) return 1;
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*TEST b,#8*/
|
||||
case 0x08:
|
||||
case 0x08:
|
||||
src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
|
||||
setznp8(src & dst);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -86,11 +86,15 @@ static int opF6_a16(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
break;
|
||||
case 0x10: /*NOT b*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteab(~dst); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
break;
|
||||
case 0x18: /*NEG b*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteab(0 - dst); if (cpu_state.abrt) return 1;
|
||||
setsub8(0, dst);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
@@ -99,8 +103,8 @@ static int opF6_a16(uint32_t fetchdat)
|
||||
case 0x20: /*MUL AL,b*/
|
||||
AX = AL * dst;
|
||||
flags_rebuild();
|
||||
if (AH) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (AH) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(13);
|
||||
PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
break;
|
||||
@@ -108,8 +112,8 @@ static int opF6_a16(uint32_t fetchdat)
|
||||
tempws = (int)((int8_t)AL) * (int)((int8_t)dst);
|
||||
AX = tempws & 0xffff;
|
||||
flags_rebuild();
|
||||
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(14);
|
||||
PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
break;
|
||||
@@ -123,8 +127,8 @@ static int opF6_a16(uint32_t fetchdat)
|
||||
if (!cpu_iscyrix)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags |= 0x8D5; /*Not a Cyrix*/
|
||||
flags &= ~1;
|
||||
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -146,8 +150,8 @@ static int opF6_a16(uint32_t fetchdat)
|
||||
if (!cpu_iscyrix)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags|=0x8D5; /*Not a Cyrix*/
|
||||
flags &= ~1;
|
||||
cpu_state.flags|=0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -173,11 +177,13 @@ static int opF6_a32(uint32_t fetchdat)
|
||||
int8_t temps;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteab(); if (cpu_state.abrt) return 1;
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*TEST b,#8*/
|
||||
case 0x08:
|
||||
case 0x08:
|
||||
src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
|
||||
setznp8(src & dst);
|
||||
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
|
||||
@@ -185,11 +191,15 @@ static int opF6_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
break;
|
||||
case 0x10: /*NOT b*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteab(~dst); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
break;
|
||||
case 0x18: /*NEG b*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteab(0 - dst); if (cpu_state.abrt) return 1;
|
||||
setsub8(0, dst);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
@@ -198,8 +208,8 @@ static int opF6_a32(uint32_t fetchdat)
|
||||
case 0x20: /*MUL AL,b*/
|
||||
AX = AL * dst;
|
||||
flags_rebuild();
|
||||
if (AH) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (AH) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(13);
|
||||
PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
break;
|
||||
@@ -207,8 +217,8 @@ static int opF6_a32(uint32_t fetchdat)
|
||||
tempws = (int)((int8_t)AL) * (int)((int8_t)dst);
|
||||
AX = tempws & 0xffff;
|
||||
flags_rebuild();
|
||||
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(14);
|
||||
PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
break;
|
||||
@@ -222,8 +232,8 @@ static int opF6_a32(uint32_t fetchdat)
|
||||
if (!cpu_iscyrix)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags |= 0x8D5; /*Not a Cyrix*/
|
||||
flags &= ~1;
|
||||
cpu_state.flags |= 0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -245,8 +255,8 @@ static int opF6_a32(uint32_t fetchdat)
|
||||
if (!cpu_iscyrix)
|
||||
{
|
||||
flags_rebuild();
|
||||
flags|=0x8D5; /*Not a Cyrix*/
|
||||
flags &= ~1;
|
||||
cpu_state.flags|=0x8D5; /*Not a Cyrix*/
|
||||
cpu_state.flags &= ~1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -275,6 +285,8 @@ static int opF7_w_a16(uint32_t fetchdat)
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1;
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
@@ -287,11 +299,15 @@ static int opF7_w_a16(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
break;
|
||||
case 0x10: /*NOT w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(~dst); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0);
|
||||
break;
|
||||
case 0x18: /*NEG w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(0 - dst); if (cpu_state.abrt) return 1;
|
||||
setsub16(0, dst);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
@@ -302,8 +318,8 @@ static int opF7_w_a16(uint32_t fetchdat)
|
||||
AX = templ & 0xFFFF;
|
||||
DX = templ >> 16;
|
||||
flags_rebuild();
|
||||
if (DX) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (DX) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(21);
|
||||
PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
break;
|
||||
@@ -312,8 +328,8 @@ static int opF7_w_a16(uint32_t fetchdat)
|
||||
AX = templ & 0xFFFF;
|
||||
DX = templ >> 16;
|
||||
flags_rebuild();
|
||||
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(22);
|
||||
PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0);
|
||||
break;
|
||||
@@ -362,11 +378,13 @@ static int opF7_w_a16(uint32_t fetchdat)
|
||||
static int opF7_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t templ, templ2;
|
||||
int tempws, tempws2 = 0;
|
||||
int tempws, tempws2 = 1;
|
||||
int16_t temps16;
|
||||
uint16_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteaw(); if (cpu_state.abrt) return 1;
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
@@ -379,11 +397,15 @@ static int opF7_w_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
break;
|
||||
case 0x10: /*NOT w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(~dst); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1);
|
||||
break;
|
||||
case 0x18: /*NEG w*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(0 - dst); if (cpu_state.abrt) return 1;
|
||||
setsub16(0, dst);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm);
|
||||
@@ -394,8 +416,8 @@ static int opF7_w_a32(uint32_t fetchdat)
|
||||
AX = templ & 0xFFFF;
|
||||
DX = templ >> 16;
|
||||
flags_rebuild();
|
||||
if (DX) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (DX) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(21);
|
||||
PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
break;
|
||||
@@ -404,8 +426,8 @@ static int opF7_w_a32(uint32_t fetchdat)
|
||||
AX = templ & 0xFFFF;
|
||||
DX = templ >> 16;
|
||||
flags_rebuild();
|
||||
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(22);
|
||||
PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1);
|
||||
break;
|
||||
@@ -458,6 +480,8 @@ static int opF7_l_a16(uint32_t fetchdat)
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteal(); if (cpu_state.abrt) return 1;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
@@ -471,11 +495,15 @@ static int opF7_l_a16(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
break;
|
||||
case 0x10: /*NOT l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(~dst); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0);
|
||||
break;
|
||||
case 0x18: /*NEG l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(0 - dst); if (cpu_state.abrt) return 1;
|
||||
setsub32(0, dst);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
|
||||
@@ -486,8 +514,8 @@ static int opF7_l_a16(uint32_t fetchdat)
|
||||
EAX = temp64 & 0xffffffff;
|
||||
EDX = temp64 >> 32;
|
||||
flags_rebuild();
|
||||
if (EDX) flags |= (C_FLAG|V_FLAG);
|
||||
else flags &= ~(C_FLAG|V_FLAG);
|
||||
if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG|V_FLAG);
|
||||
CLOCK_CYCLES(21);
|
||||
PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
break;
|
||||
@@ -496,8 +524,8 @@ static int opF7_l_a16(uint32_t fetchdat)
|
||||
EAX = temp64 & 0xffffffff;
|
||||
EDX = temp64 >> 32;
|
||||
flags_rebuild();
|
||||
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(38);
|
||||
PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0);
|
||||
break;
|
||||
@@ -528,6 +556,8 @@ static int opF7_l_a32(uint32_t fetchdat)
|
||||
uint32_t src, dst;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = geteal(); if (cpu_state.abrt) return 1;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
@@ -541,11 +571,15 @@ static int opF7_l_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
break;
|
||||
case 0x10: /*NOT l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(~dst); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
|
||||
PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1);
|
||||
break;
|
||||
case 0x18: /*NEG l*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(0 - dst); if (cpu_state.abrt) return 1;
|
||||
setsub32(0, dst);
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml);
|
||||
@@ -556,8 +590,8 @@ static int opF7_l_a32(uint32_t fetchdat)
|
||||
EAX = temp64 & 0xffffffff;
|
||||
EDX = temp64 >> 32;
|
||||
flags_rebuild();
|
||||
if (EDX) flags |= (C_FLAG|V_FLAG);
|
||||
else flags &= ~(C_FLAG|V_FLAG);
|
||||
if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG|V_FLAG);
|
||||
CLOCK_CYCLES(21);
|
||||
PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
break;
|
||||
@@ -566,8 +600,8 @@ static int opF7_l_a32(uint32_t fetchdat)
|
||||
EAX = temp64 & 0xffffffff;
|
||||
EDX = temp64 >> 32;
|
||||
flags_rebuild();
|
||||
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) flags |= (C_FLAG | V_FLAG);
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG);
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
CLOCK_CYCLES(38);
|
||||
PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1);
|
||||
break;
|
||||
@@ -596,12 +630,12 @@ static int opF7_l_a32(uint32_t fetchdat)
|
||||
|
||||
static int opHLT(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (!((flags&I_FLAG) && pic_intpending))
|
||||
if (!((cpu_state.flags&I_FLAG) && pic_intpending))
|
||||
{
|
||||
CLOCK_CYCLES_ALWAYS(100);
|
||||
cpu_state.pc--;
|
||||
@@ -637,6 +671,7 @@ static int opBOUND_w_a16(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
low = geteaw();
|
||||
high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -656,6 +691,7 @@ static int opBOUND_w_a32(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
low = geteaw();
|
||||
high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -676,6 +712,7 @@ static int opBOUND_l_a16(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
low = geteal();
|
||||
high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -695,6 +732,7 @@ static int opBOUND_l_a32(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
low = geteal();
|
||||
high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -712,7 +750,7 @@ static int opBOUND_l_a32(uint32_t fetchdat)
|
||||
|
||||
static int opCLTS(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't CLTS\n");
|
||||
x86gpf(NULL,0);
|
||||
@@ -755,7 +793,7 @@ static int opLOADALL(uint32_t fetchdat)
|
||||
return 1;
|
||||
}
|
||||
msw = (msw & 1) | readmemw(0, 0x806);
|
||||
flags = (readmemw(0, 0x818) & 0xffd5) | 2;
|
||||
cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2;
|
||||
flags_extract();
|
||||
tr.seg = readmemw(0, 0x816);
|
||||
cpu_state.pc = readmemw(0, 0x81A);
|
||||
@@ -773,22 +811,22 @@ static int opLOADALL(uint32_t fetchdat)
|
||||
CX = readmemw(0, 0x832);
|
||||
AX = readmemw(0, 0x834);
|
||||
es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16);
|
||||
_es.access = readmemb(0, 0x839);
|
||||
_es.limit = readmemw(0, 0x83A);
|
||||
cpu_state.seg_es.access = readmemb(0, 0x839);
|
||||
cpu_state.seg_es.limit = readmemw(0, 0x83A);
|
||||
cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16);
|
||||
_cs.access = readmemb(0, 0x83F);
|
||||
_cs.limit = readmemw(0, 0x840);
|
||||
cpu_state.seg_cs.access = readmemb(0, 0x83F);
|
||||
cpu_state.seg_cs.limit = readmemw(0, 0x840);
|
||||
ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16);
|
||||
_ss.access = readmemb(0, 0x845);
|
||||
_ss.limit = readmemw(0, 0x846);
|
||||
if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff)
|
||||
cpu_state.seg_ss.access = readmemb(0, 0x845);
|
||||
cpu_state.seg_ss.limit = readmemw(0, 0x846);
|
||||
if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16);
|
||||
_ds.access = readmemb(0, 0x84B);
|
||||
_ds.limit = readmemw(0, 0x84C);
|
||||
if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff)
|
||||
cpu_state.seg_ds.access = readmemb(0, 0x84B);
|
||||
cpu_state.seg_ds.limit = readmemw(0, 0x84C);
|
||||
if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
@@ -829,8 +867,8 @@ static void loadall_load_segment(uint32_t addr, x86seg *s)
|
||||
s->base = readmeml(0, addr + 4);
|
||||
s->limit = readmeml(0, addr + 8);
|
||||
|
||||
if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0;
|
||||
if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0;
|
||||
if (s == &cpu_state.seg_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0;
|
||||
if (s == &cpu_state.seg_ss) stack32 = (segdat3 & 0x40) ? 1 : 0;
|
||||
cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32);
|
||||
if (use32)
|
||||
cpu_cur_status |= CPU_STATUS_USE32;
|
||||
@@ -839,14 +877,14 @@ static void loadall_load_segment(uint32_t addr, x86seg *s)
|
||||
|
||||
set_segment_limit(s, segdat3);
|
||||
|
||||
if (s == &_ds)
|
||||
if (s == &cpu_state.seg_ds)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
}
|
||||
if (s == &_ss)
|
||||
if (s == &cpu_state.seg_ss)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
|
||||
@@ -860,8 +898,8 @@ static int opLOADALL386(uint32_t fetchdat)
|
||||
uint32_t la_addr = es + EDI;
|
||||
|
||||
cr0 = readmeml(0, la_addr);
|
||||
flags = readmemw(0, la_addr + 4);
|
||||
eflags = readmemw(0, la_addr + 6);
|
||||
cpu_state.flags = readmemw(0, la_addr + 4);
|
||||
cpu_state.eflags = readmemw(0, la_addr + 6);
|
||||
flags_extract();
|
||||
cpu_state.pc = readmeml(0, la_addr + 8);
|
||||
EDI = readmeml(0, la_addr + 0xC);
|
||||
@@ -887,12 +925,12 @@ static int opLOADALL386(uint32_t fetchdat)
|
||||
loadall_load_segment(la_addr + 0x60, &idt);
|
||||
loadall_load_segment(la_addr + 0x6c, &gdt);
|
||||
loadall_load_segment(la_addr + 0x78, &ldt);
|
||||
loadall_load_segment(la_addr + 0x84, &_gs);
|
||||
loadall_load_segment(la_addr + 0x90, &_fs);
|
||||
loadall_load_segment(la_addr + 0x9c, &_ds);
|
||||
loadall_load_segment(la_addr + 0xa8, &_ss);
|
||||
loadall_load_segment(la_addr + 0xb4, &_cs);
|
||||
loadall_load_segment(la_addr + 0xc0, &_es);
|
||||
loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs);
|
||||
loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs);
|
||||
loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds);
|
||||
loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss);
|
||||
loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs);
|
||||
loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es);
|
||||
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
@@ -915,7 +953,7 @@ static int opCPUID(uint32_t fetchdat)
|
||||
|
||||
static int opRDMSR(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_hasMSR)
|
||||
if (cpu_has_feature(CPU_FEATURE_MSR))
|
||||
{
|
||||
cpu_RDMSR();
|
||||
CLOCK_CYCLES(9);
|
||||
@@ -928,7 +966,7 @@ static int opRDMSR(uint32_t fetchdat)
|
||||
|
||||
static int opWRMSR(uint32_t fetchdat)
|
||||
{
|
||||
if (cpu_hasMSR)
|
||||
if (cpu_has_feature(CPU_FEATURE_MSR))
|
||||
{
|
||||
cpu_WRMSR();
|
||||
CLOCK_CYCLES(9);
|
||||
|
||||
@@ -11,12 +11,13 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \
|
||||
CLOCK_CYCLES(2); \
|
||||
}
|
||||
|
||||
#define MMX_ENTER() \
|
||||
if (!cpu_hasMMX) \
|
||||
if (!cpu_has_feature(CPU_FEATURE_MMX)) \
|
||||
{ \
|
||||
cpu_state.pc = cpu_state.oldpc; \
|
||||
x86illegal(); \
|
||||
@@ -31,7 +32,7 @@
|
||||
|
||||
static int opEMMS(uint32_t fetchdat)
|
||||
{
|
||||
if (!cpu_hasMMX)
|
||||
if (!cpu_has_feature(CPU_FEATURE_MMX))
|
||||
{
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
|
||||
@@ -293,7 +293,8 @@ static int opPMULLW_a16(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].w[0] *= src.w[0];
|
||||
@@ -320,7 +321,8 @@ static int opPMULLW_a32(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].w[0] *= src.w[0];
|
||||
@@ -348,7 +350,8 @@ static int opPMULHW_a16(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16;
|
||||
@@ -375,7 +378,8 @@ static int opPMULHW_a32(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
MMX_REG src;
|
||||
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src.l[0] = readmeml(easeg, cpu_state.eaaddr);
|
||||
src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16;
|
||||
|
||||
@@ -166,7 +166,7 @@ static int opPCMPEQD_a32(uint32_t fetchdat)
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0;
|
||||
@@ -195,7 +195,7 @@ static int opPCMPGTD_a32(uint32_t fetchdat)
|
||||
|
||||
MMX_ENTER();
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_32(fetchdat);
|
||||
MMX_GETSRC();
|
||||
|
||||
cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0;
|
||||
|
||||
@@ -13,6 +13,7 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].l[0] = dst;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
@@ -36,6 +37,7 @@ static int opMOVD_l_mm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].l[0] = dst;
|
||||
cpu_state.MM[cpu_reg].l[1] = 0;
|
||||
@@ -57,6 +59,7 @@ static int opMOVD_mm_l_a16(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
@@ -75,6 +78,7 @@ static int opMOVD_mm_l_a32(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
@@ -96,6 +100,7 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint64_t dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].q = dst;
|
||||
CLOCK_CYCLES(2);
|
||||
@@ -115,7 +120,8 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint64_t dst;
|
||||
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1;
|
||||
cpu_state.MM[cpu_reg].q = dst;
|
||||
CLOCK_CYCLES(2);
|
||||
@@ -135,6 +141,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
@@ -153,6 +160,7 @@ static int opMOVQ_mm_q_a32(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1;
|
||||
CLOCK_CYCLES(2);
|
||||
|
||||
@@ -12,6 +12,7 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = src;
|
||||
|
||||
@@ -33,6 +34,7 @@ static int opPUNPCKLDQ_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0;
|
||||
cpu_state.MM[cpu_reg].l[1] = src;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \
|
||||
CLOCK_CYCLES(2); \
|
||||
}
|
||||
|
||||
@@ -181,7 +181,8 @@ static int opMOV_b_imm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1;
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
seteab(temp);
|
||||
@@ -193,7 +194,8 @@ static int opMOV_b_imm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = getbyte(); if (cpu_state.abrt) return 1;
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
seteab(temp);
|
||||
@@ -206,7 +208,8 @@ static int opMOV_w_imm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = getword(); if (cpu_state.abrt) return 1;
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1);
|
||||
seteaw(temp);
|
||||
@@ -218,7 +221,8 @@ static int opMOV_w_imm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = getword(); if (cpu_state.abrt) return 1;
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1);
|
||||
seteaw(temp);
|
||||
@@ -230,7 +234,8 @@ static int opMOV_l_imm_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = getlong(); if (cpu_state.abrt) return 1;
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
seteal(temp);
|
||||
@@ -242,7 +247,8 @@ static int opMOV_l_imm_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
ILLEGAL_ON((rmdat & 0x38) != 0);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = getlong(); if (cpu_state.abrt) return 1;
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3);
|
||||
seteal(temp);
|
||||
@@ -256,6 +262,7 @@ static int opMOV_AL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint16_t addr = getwordf();
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr);
|
||||
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
AL = temp;
|
||||
@@ -267,6 +274,7 @@ static int opMOV_AL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
uint32_t addr = getlong();
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr);
|
||||
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
AL = temp;
|
||||
@@ -278,7 +286,8 @@ static int opMOV_AX_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint16_t addr = getwordf();
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr + 1);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr+1);
|
||||
temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
AX = temp;
|
||||
CLOCK_CYCLES((is486) ? 1 : 4);
|
||||
@@ -289,7 +298,8 @@ static int opMOV_AX_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
uint32_t addr = getlong();
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr + 1);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr+1);
|
||||
temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
AX = temp;
|
||||
CLOCK_CYCLES((is486) ? 1 : 4);
|
||||
@@ -300,7 +310,8 @@ static int opMOV_EAX_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint16_t addr = getwordf();
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr + 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr+3);
|
||||
temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
EAX = temp;
|
||||
CLOCK_CYCLES((is486) ? 1 : 4);
|
||||
@@ -311,7 +322,8 @@ static int opMOV_EAX_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t addr = getlong();
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr + 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, addr, addr+3);
|
||||
temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
EAX = temp;
|
||||
CLOCK_CYCLES((is486) ? 1 : 4);
|
||||
@@ -322,6 +334,7 @@ static int opMOV_EAX_a32(uint32_t fetchdat)
|
||||
static int opMOV_a16_AL(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, addr, addr);
|
||||
writememb(cpu_state.ea_seg->base, addr, AL);
|
||||
CLOCK_CYCLES((is486) ? 1 : 2);
|
||||
@@ -331,6 +344,7 @@ static int opMOV_a16_AL(uint32_t fetchdat)
|
||||
static int opMOV_a32_AL(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong();
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, addr, addr);
|
||||
writememb(cpu_state.ea_seg->base, addr, AL);
|
||||
CLOCK_CYCLES((is486) ? 1 : 2);
|
||||
@@ -340,6 +354,7 @@ static int opMOV_a32_AL(uint32_t fetchdat)
|
||||
static int opMOV_a16_AX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1);
|
||||
writememw(cpu_state.ea_seg->base, addr, AX);
|
||||
CLOCK_CYCLES((is486) ? 1 : 2);
|
||||
@@ -349,6 +364,7 @@ static int opMOV_a16_AX(uint32_t fetchdat)
|
||||
static int opMOV_a32_AX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong(); if (cpu_state.abrt) return 1;
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 1);
|
||||
writememw(cpu_state.ea_seg->base, addr, AX);
|
||||
CLOCK_CYCLES((is486) ? 1 : 2);
|
||||
@@ -358,6 +374,7 @@ static int opMOV_a32_AX(uint32_t fetchdat)
|
||||
static int opMOV_a16_EAX(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t addr = getwordf();
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3);
|
||||
writememl(cpu_state.ea_seg->base, addr, EAX);
|
||||
CLOCK_CYCLES((is486) ? 1 : 2);
|
||||
@@ -367,6 +384,7 @@ static int opMOV_a16_EAX(uint32_t fetchdat)
|
||||
static int opMOV_a32_EAX(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = getlong(); if (cpu_state.abrt) return 1;
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, addr, addr + 3);
|
||||
writememl(cpu_state.ea_seg->base, addr, EAX);
|
||||
CLOCK_CYCLES((is486) ? 1 : 2);
|
||||
@@ -378,8 +396,8 @@ static int opMOV_a32_EAX(uint32_t fetchdat)
|
||||
static int opLEA_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
/* ILLEGAL_ON(cpu_mod == 3); */
|
||||
cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr;
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
cpu_state.regs[cpu_reg].w = cpu_state.eaaddr;
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
@@ -387,8 +405,8 @@ static int opLEA_w_a16(uint32_t fetchdat)
|
||||
static int opLEA_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
/* ILLEGAL_ON(cpu_mod == 3); */
|
||||
cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr;
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
cpu_state.regs[cpu_reg].w = cpu_state.eaaddr;
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
@@ -397,8 +415,8 @@ static int opLEA_w_a32(uint32_t fetchdat)
|
||||
static int opLEA_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
/* ILLEGAL_ON(cpu_mod == 3); */
|
||||
cpu_state.regs[cpu_reg].l = ((cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr) & 0xffff;
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff;
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
@@ -406,8 +424,8 @@ static int opLEA_l_a16(uint32_t fetchdat)
|
||||
static int opLEA_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
/* ILLEGAL_ON(cpu_mod == 3); */
|
||||
cpu_state.regs[cpu_reg].l = (cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr;
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
cpu_state.regs[cpu_reg].l = cpu_state.eaaddr;
|
||||
CLOCK_CYCLES(timing_rr);
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1);
|
||||
return 0;
|
||||
@@ -419,9 +437,9 @@ static int opXLAT_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = (BX + AL)&0xFFFF;
|
||||
uint8_t temp;
|
||||
cpu_state.last_ea = addr;
|
||||
temp = readmemb(cpu_state.ea_seg->base, addr);
|
||||
if (cpu_state.abrt) return 1;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
AL = temp;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
|
||||
@@ -431,9 +449,9 @@ static int opXLAT_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t addr = EBX + AL;
|
||||
uint8_t temp;
|
||||
cpu_state.last_ea = addr;
|
||||
temp = readmemb(cpu_state.ea_seg->base, addr);
|
||||
if (cpu_state.abrt) return 1;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
|
||||
AL = temp;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1);
|
||||
@@ -451,6 +469,7 @@ static int opMOV_b_r_a16(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
seteab(getr8(cpu_reg));
|
||||
CLOCK_CYCLES(is486 ? 1 : 2);
|
||||
@@ -469,6 +488,7 @@ static int opMOV_b_r_a32(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
seteab(getr8(cpu_reg));
|
||||
CLOCK_CYCLES(is486 ? 1 : 2);
|
||||
@@ -487,6 +507,7 @@ static int opMOV_w_r_a16(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
|
||||
seteaw(cpu_state.regs[cpu_reg].w);
|
||||
CLOCK_CYCLES(is486 ? 1 : 2);
|
||||
@@ -505,6 +526,7 @@ static int opMOV_w_r_a32(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
|
||||
seteaw(cpu_state.regs[cpu_reg].w);
|
||||
CLOCK_CYCLES(is486 ? 1 : 2);
|
||||
@@ -523,6 +545,7 @@ static int opMOV_l_r_a16(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
|
||||
seteal(cpu_state.regs[cpu_reg].l);
|
||||
CLOCK_CYCLES(is486 ? 1 : 2);
|
||||
@@ -541,6 +564,7 @@ static int opMOV_l_r_a32(uint32_t fetchdat)
|
||||
}
|
||||
else
|
||||
{
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
|
||||
seteal(cpu_state.regs[cpu_reg].l);
|
||||
CLOCK_CYCLES(is486 ? 1 : 2);
|
||||
@@ -561,6 +585,7 @@ static int opMOV_r_b_a16(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint8_t temp;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
@@ -581,6 +606,7 @@ static int opMOV_r_b_a32(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint8_t temp;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
@@ -601,6 +627,7 @@ static int opMOV_r_w_a16(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint16_t temp;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
@@ -621,6 +648,7 @@ static int opMOV_r_w_a32(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint16_t temp;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
@@ -641,6 +669,7 @@ static int opMOV_r_l_a16(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint32_t temp;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
@@ -661,6 +690,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint32_t temp;
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
@@ -670,6 +700,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
|
||||
#define opCMOV(condition) \
|
||||
static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
@@ -681,6 +712,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
|
||||
else \
|
||||
{ \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].w = temp; \
|
||||
@@ -699,6 +731,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
|
||||
else \
|
||||
{ \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].w = temp; \
|
||||
@@ -717,6 +750,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
|
||||
else \
|
||||
{ \
|
||||
uint32_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \
|
||||
temp = geteal(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].l = temp; \
|
||||
@@ -736,6 +770,7 @@ static int opMOV_r_l_a32(uint32_t fetchdat)
|
||||
{ \
|
||||
uint32_t temp; \
|
||||
CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
temp = geteal(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.regs[cpu_reg].l = temp; \
|
||||
} \
|
||||
@@ -760,3 +795,4 @@ opCMOV(L)
|
||||
opCMOV(NL)
|
||||
opCMOV(LE)
|
||||
opCMOV(NLE)
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
static int opMOV_r_CRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load from CRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -21,7 +21,7 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat)
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_hasCR4)
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
@@ -38,7 +38,7 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOV_r_CRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load from CRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -59,7 +59,7 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat)
|
||||
cpu_state.regs[cpu_rm].l = cr3;
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_hasCR4)
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
cpu_state.regs[cpu_rm].l = cr4;
|
||||
break;
|
||||
@@ -77,7 +77,7 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat)
|
||||
|
||||
static int opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load from DRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -91,7 +91,7 @@ static int opMOV_r_DRx_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOV_r_DRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load from DRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -108,7 +108,7 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load CRx\n");
|
||||
x86gpf(NULL,0);
|
||||
@@ -144,7 +144,7 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat)
|
||||
flushmmucache();
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_hasCR4)
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
break;
|
||||
@@ -164,7 +164,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t old_cr0 = cr0;
|
||||
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load CRx\n");
|
||||
x86gpf(NULL,0);
|
||||
@@ -200,7 +200,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat)
|
||||
flushmmucache();
|
||||
break;
|
||||
case 4:
|
||||
if (cpu_hasCR4)
|
||||
if (cpu_has_feature(CPU_FEATURE_CR4))
|
||||
{
|
||||
cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask;
|
||||
break;
|
||||
@@ -219,7 +219,7 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat)
|
||||
|
||||
static int opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load DRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -233,7 +233,7 @@ static int opMOV_DRx_r_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load DRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -248,7 +248,7 @@ static int opMOV_DRx_r_a32(uint32_t fetchdat)
|
||||
|
||||
static int opMOV_r_TRx_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load from TRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -262,7 +262,7 @@ static int opMOV_r_TRx_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOV_r_TRx_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load from TRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -277,7 +277,7 @@ static int opMOV_r_TRx_a32(uint32_t fetchdat)
|
||||
|
||||
static int opMOV_TRx_r_a16(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load TRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
@@ -290,7 +290,7 @@ static int opMOV_TRx_r_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOV_TRx_r_a32(uint32_t fetchdat)
|
||||
{
|
||||
if ((CPL || (eflags&VM_FLAG)) && (cr0&1))
|
||||
if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Can't load TRx\n");
|
||||
x86gpf(NULL, 0);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
static int opMOV_w_seg_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
@@ -31,7 +33,9 @@ static int opMOV_w_seg_a16(uint32_t fetchdat)
|
||||
static int opMOV_w_seg_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
@@ -62,7 +66,9 @@ static int opMOV_w_seg_a32(uint32_t fetchdat)
|
||||
static int opMOV_l_seg_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
@@ -98,7 +104,9 @@ static int opMOV_l_seg_a16(uint32_t fetchdat)
|
||||
static int opMOV_l_seg_a32(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
@@ -137,34 +145,35 @@ static int opMOV_seg_w_a16(uint32_t fetchdat)
|
||||
uint16_t new_seg;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_seg=geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &_es);
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &_ds);
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &_ss);
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &_fs);
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &_gs);
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -177,34 +186,35 @@ static int opMOV_seg_w_a32(uint32_t fetchdat)
|
||||
uint16_t new_seg;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
new_seg=geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*ES*/
|
||||
loadseg(new_seg, &_es);
|
||||
loadseg(new_seg, &cpu_state.seg_es);
|
||||
break;
|
||||
case 0x18: /*DS*/
|
||||
loadseg(new_seg, &_ds);
|
||||
loadseg(new_seg, &cpu_state.seg_ds);
|
||||
break;
|
||||
case 0x10: /*SS*/
|
||||
loadseg(new_seg, &_ss);
|
||||
loadseg(new_seg, &cpu_state.seg_ss);
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8);
|
||||
return 1;
|
||||
case 0x20: /*FS*/
|
||||
loadseg(new_seg, &_fs);
|
||||
loadseg(new_seg, &cpu_state.seg_fs);
|
||||
break;
|
||||
case 0x28: /*GS*/
|
||||
loadseg(new_seg, &_gs);
|
||||
loadseg(new_seg, &cpu_state.seg_gs);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -220,9 +230,10 @@ static int opLDS_w_a16(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -235,9 +246,10 @@ static int opLDS_w_a32(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -251,9 +263,10 @@ static int opLDS_l_a16(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -267,9 +280,10 @@ static int opLDS_l_a32(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ds); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -283,9 +297,10 @@ static int opLSS_w_a16(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -298,9 +313,10 @@ static int opLSS_w_a32(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmemw(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -314,9 +330,10 @@ static int opLSS_l_a16(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -330,9 +347,10 @@ static int opLSS_l_a32(uint32_t fetchdat)
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
ILLEGAL_ON(cpu_mod == 3);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
addr = readmeml(easeg, cpu_state.eaaddr);
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &_ss); if (cpu_state.abrt) return 1;
|
||||
loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = addr;
|
||||
|
||||
CLOCK_CYCLES(7);
|
||||
@@ -346,6 +364,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
|
||||
uint16_t addr, seg; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
addr = readmemw(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
|
||||
@@ -362,6 +381,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
|
||||
uint16_t addr, seg; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
addr = readmemw(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \
|
||||
@@ -379,6 +399,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
|
||||
uint16_t seg; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
addr = readmeml(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
|
||||
@@ -396,6 +417,7 @@ static int opLSS_l_a32(uint32_t fetchdat)
|
||||
uint16_t seg; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
ILLEGAL_ON(cpu_mod == 3); \
|
||||
addr = readmeml(easeg, cpu_state.eaaddr); \
|
||||
seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \
|
||||
@@ -407,6 +429,6 @@ static int opLSS_l_a32(uint32_t fetchdat)
|
||||
return 0; \
|
||||
}
|
||||
|
||||
opLsel(ES, _es)
|
||||
opLsel(FS, _fs)
|
||||
opLsel(GS, _gs)
|
||||
opLsel(ES, cpu_state.seg_es)
|
||||
opLsel(FS, cpu_state.seg_fs)
|
||||
opLsel(GS, cpu_state.seg_gs)
|
||||
|
||||
@@ -3,6 +3,8 @@ static int opMOVZX_w_b_a16(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
|
||||
@@ -15,6 +17,8 @@ static int opMOVZX_w_b_a32(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
|
||||
@@ -27,6 +31,8 @@ static int opMOVZX_l_b_a16(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
|
||||
@@ -39,6 +45,8 @@ static int opMOVZX_l_b_a32(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
|
||||
@@ -51,6 +59,8 @@ static int opMOVZX_w_w_a16(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
|
||||
@@ -63,6 +73,8 @@ static int opMOVZX_w_w_a32(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
|
||||
@@ -75,6 +87,8 @@ static int opMOVZX_l_w_a16(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
|
||||
@@ -87,6 +101,8 @@ static int opMOVZX_l_w_a32(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
|
||||
@@ -100,6 +116,8 @@ static int opMOVSX_w_b_a16(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
if (temp & 0x80)
|
||||
@@ -114,6 +132,8 @@ static int opMOVSX_w_b_a32(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = (uint16_t)temp;
|
||||
if (temp & 0x80)
|
||||
@@ -128,6 +148,8 @@ static int opMOVSX_l_b_a16(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x80)
|
||||
@@ -142,6 +164,8 @@ static int opMOVSX_l_b_a32(uint32_t fetchdat)
|
||||
uint8_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x80)
|
||||
@@ -156,6 +180,8 @@ static int opMOVSX_l_w_a16(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x8000)
|
||||
@@ -170,6 +196,8 @@ static int opMOVSX_l_w_a32(uint32_t fetchdat)
|
||||
uint16_t temp;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = (uint32_t)temp;
|
||||
if (temp & 0x8000)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
static int opRDTSC(uint32_t fetchdat)
|
||||
{
|
||||
if (!cpu_hasrdtsc)
|
||||
if (!cpu_has_feature(CPU_FEATURE_RDTSC))
|
||||
{
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x86illegal();
|
||||
|
||||
@@ -4,14 +4,16 @@ static int opIMUL_w_iw_a16(uint32_t fetchdat)
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getword(); if (cpu_state.abrt) return 1;
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
@@ -24,14 +26,16 @@ static int opIMUL_w_iw_a32(uint32_t fetchdat)
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getword(); if (cpu_state.abrt) return 1;
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
@@ -45,14 +49,16 @@ static int opIMUL_l_il_a16(uint32_t fetchdat)
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getlong(); if (cpu_state.abrt) return 1;
|
||||
|
||||
temp64 = ((int64_t)templ) * ((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(25);
|
||||
@@ -65,14 +71,16 @@ static int opIMUL_l_il_a32(uint32_t fetchdat)
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getlong(); if (cpu_state.abrt) return 1;
|
||||
|
||||
temp64 = ((int64_t)templ) * ((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(25);
|
||||
@@ -86,6 +94,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat)
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
@@ -93,8 +103,8 @@ static int opIMUL_w_ib_a16(uint32_t fetchdat)
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
@@ -107,6 +117,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat)
|
||||
int16_t tempw, tempw2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
tempw2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
@@ -114,8 +126,8 @@ static int opIMUL_w_ib_a32(uint32_t fetchdat)
|
||||
|
||||
templ = ((int)tempw) * ((int)tempw2);
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xffff;
|
||||
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17);
|
||||
@@ -129,14 +141,17 @@ static int opIMUL_l_ib_a16(uint32_t fetchdat)
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (templ2 & 0x80) templ2 |= 0xffffff00;
|
||||
|
||||
temp64 = ((int64_t)templ)*((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(20);
|
||||
@@ -149,14 +164,17 @@ static int opIMUL_l_ib_a32(uint32_t fetchdat)
|
||||
int32_t templ, templ2;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
templ2 = getbyte(); if (cpu_state.abrt) return 1;
|
||||
if (templ2 & 0x80) templ2 |= 0xffffff00;
|
||||
|
||||
temp64 = ((int64_t)templ)*((int64_t)templ2);
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff;
|
||||
|
||||
CLOCK_CYCLES(20);
|
||||
@@ -171,12 +189,15 @@ static int opIMUL_w_w_a16(uint32_t fetchdat)
|
||||
int32_t templ;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(18);
|
||||
PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0);
|
||||
@@ -187,12 +208,15 @@ static int opIMUL_w_w_a32(uint32_t fetchdat)
|
||||
int32_t templ;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = templ & 0xFFFF;
|
||||
flags_rebuild();
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(18);
|
||||
PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1);
|
||||
@@ -204,12 +228,15 @@ static int opIMUL_l_l_a16(uint32_t fetchdat)
|
||||
int64_t temp64;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(30);
|
||||
PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0);
|
||||
@@ -220,12 +247,15 @@ static int opIMUL_l_l_a32(uint32_t fetchdat)
|
||||
int64_t temp64;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
|
||||
temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF;
|
||||
flags_rebuild();
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) flags |= C_FLAG | V_FLAG;
|
||||
else flags &= ~(C_FLAG | V_FLAG);
|
||||
if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG;
|
||||
else cpu_state.flags &= ~(C_FLAG | V_FLAG);
|
||||
|
||||
CLOCK_CYCLES(30);
|
||||
PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1);
|
||||
|
||||
@@ -5,6 +5,9 @@ static int opARPL_a16(uint32_t fetchdat)
|
||||
NOTRM
|
||||
fetch_ea_16(fetchdat);
|
||||
/* x386_dynarec_log("ARPL_a16\n"); */
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
flags_rebuild();
|
||||
@@ -12,10 +15,10 @@ static int opARPL_a16(uint32_t fetchdat)
|
||||
{
|
||||
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
|
||||
seteaw(temp_seg); if (cpu_state.abrt) return 1;
|
||||
flags |= Z_FLAG;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
}
|
||||
else
|
||||
flags &= ~Z_FLAG;
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
|
||||
CLOCK_CYCLES(is486 ? 9 : 20);
|
||||
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0);
|
||||
@@ -28,6 +31,9 @@ static int opARPL_a32(uint32_t fetchdat)
|
||||
NOTRM
|
||||
fetch_ea_32(fetchdat);
|
||||
/* x386_dynarec_log("ARPL_a32\n"); */
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
|
||||
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
|
||||
|
||||
flags_rebuild();
|
||||
@@ -35,10 +41,10 @@ static int opARPL_a32(uint32_t fetchdat)
|
||||
{
|
||||
temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3);
|
||||
seteaw(temp_seg); if (cpu_state.abrt) return 1;
|
||||
flags |= Z_FLAG;
|
||||
cpu_state.flags |= Z_FLAG;
|
||||
}
|
||||
else
|
||||
flags &= ~Z_FLAG;
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
|
||||
CLOCK_CYCLES(is486 ? 9 : 20);
|
||||
PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1);
|
||||
@@ -53,11 +59,13 @@ static int opARPL_a32(uint32_t fetchdat)
|
||||
\
|
||||
NOTRM \
|
||||
fetch_ea(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
\
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
flags_rebuild(); \
|
||||
if (!(sel & 0xfffc)) { flags &= ~Z_FLAG; return 0; } /*Null selector*/ \
|
||||
if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
|
||||
if (valid) \
|
||||
{ \
|
||||
@@ -65,7 +73,7 @@ static int opARPL_a32(uint32_t fetchdat)
|
||||
desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \
|
||||
cpl_override = 0; if (cpu_state.abrt) return 1; \
|
||||
} \
|
||||
flags &= ~Z_FLAG; \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
if ((desc & 0x1f00) == 0x000) valid = 0; \
|
||||
if ((desc & 0x1f00) == 0x800) valid = 0; \
|
||||
if ((desc & 0x1f00) == 0xa00) valid = 0; \
|
||||
@@ -77,7 +85,7 @@ static int opARPL_a32(uint32_t fetchdat)
|
||||
} \
|
||||
if (valid) \
|
||||
{ \
|
||||
flags |= Z_FLAG; \
|
||||
cpu_state.flags |= Z_FLAG; \
|
||||
cpl_override = 1; \
|
||||
if (is32) \
|
||||
cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \
|
||||
@@ -103,10 +111,12 @@ opLAR(l_a32, fetch_ea_32, 1, 1)
|
||||
\
|
||||
NOTRM \
|
||||
fetch_ea(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
\
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1; \
|
||||
flags_rebuild(); \
|
||||
flags &= ~Z_FLAG; \
|
||||
cpu_state.flags &= ~Z_FLAG; \
|
||||
if (!(sel & 0xfffc)) return 0; /*Null selector*/ \
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \
|
||||
if (valid) \
|
||||
@@ -125,7 +135,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1)
|
||||
} \
|
||||
if (valid) \
|
||||
{ \
|
||||
flags |= Z_FLAG; \
|
||||
cpu_state.flags |= Z_FLAG; \
|
||||
cpl_override = 1; \
|
||||
if (is32) \
|
||||
{ \
|
||||
@@ -163,22 +173,28 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*SLDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(ldt.seg);
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
|
||||
break;
|
||||
case 0x08: /*STR*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(tr.seg);
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
|
||||
break;
|
||||
case 0x10: /*LLDT*/
|
||||
if ((CPL || eflags&VM_FLAG) && (cr0&1))
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Invalid LLDT!\n");
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
addr = (sel & ~7) + gdt.base;
|
||||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
@@ -199,12 +215,14 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32);
|
||||
break;
|
||||
case 0x18: /*LTR*/
|
||||
if ((CPL || eflags&VM_FLAG) && (cr0&1))
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Invalid LTR!\n");
|
||||
x86gpf(NULL,0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
addr = (sel & ~7) + gdt.base;
|
||||
limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16);
|
||||
@@ -228,9 +246,11 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32);
|
||||
break;
|
||||
case 0x20: /*VERR*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
flags &= ~Z_FLAG;
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
if (!(sel & 0xfffc)) return 0; /*Null selector*/
|
||||
cpl_override = 1;
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
|
||||
@@ -243,14 +263,16 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
if (dpl < CPL || dpl < (sel & 3)) valid = 0;
|
||||
}
|
||||
if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/
|
||||
if (valid) flags |= Z_FLAG;
|
||||
if (valid) cpu_state.flags |= Z_FLAG;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32);
|
||||
break;
|
||||
case 0x28: /*VERW*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
sel = geteaw(); if (cpu_state.abrt) return 1;
|
||||
flags_rebuild();
|
||||
flags &= ~Z_FLAG;
|
||||
cpu_state.flags &= ~Z_FLAG;
|
||||
if (!(sel & 0xfffc)) return 0; /*Null selector*/
|
||||
cpl_override = 1;
|
||||
valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit);
|
||||
@@ -261,7 +283,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
|
||||
if (dpl < CPL || dpl < (sel & 3)) valid = 0;
|
||||
if (desc & 0x0800) valid = 0; /*Code*/
|
||||
if (!(desc & 0x0200)) valid = 0; /*Read-only data*/
|
||||
if (valid) flags |= Z_FLAG;
|
||||
if (valid) cpu_state.flags |= Z_FLAG;
|
||||
CLOCK_CYCLES(20);
|
||||
PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32);
|
||||
break;
|
||||
@@ -300,6 +322,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
switch (rmdat & 0x38)
|
||||
{
|
||||
case 0x00: /*SGDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(gdt.limit);
|
||||
base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */
|
||||
if (is286)
|
||||
@@ -309,6 +333,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32);
|
||||
break;
|
||||
case 0x08: /*SIDT*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(idt.limit);
|
||||
base = idt.base;
|
||||
if (is286)
|
||||
@@ -318,13 +344,15 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32);
|
||||
break;
|
||||
case 0x10: /*LGDT*/
|
||||
if ((CPL || eflags&VM_FLAG) && (cr0&1))
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Invalid LGDT!\n");
|
||||
x86gpf(NULL,0);
|
||||
break;
|
||||
}
|
||||
/* x386_dynarec_log("LGDT %08X:%08X\n", easeg, eaaddr); */
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
limit = geteaw();
|
||||
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
/* x386_dynarec_log(" %08X %04X\n", base, limit); */
|
||||
@@ -335,13 +363,15 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32);
|
||||
break;
|
||||
case 0x18: /*LIDT*/
|
||||
if ((CPL || eflags&VM_FLAG) && (cr0&1))
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Invalid LIDT!\n");
|
||||
x86gpf(NULL,0);
|
||||
break;
|
||||
}
|
||||
/* x386_dynarec_log("LIDT %08X:%08X\n", easeg, eaaddr); */
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
limit = geteaw();
|
||||
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
|
||||
/* x386_dynarec_log(" %08X %04X\n", base, limit); */
|
||||
@@ -353,6 +383,8 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
break;
|
||||
|
||||
case 0x20: /*SMSW*/
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (is486) seteaw(msw);
|
||||
else if (is386) seteaw(msw | 0xFF00);
|
||||
else seteaw(msw | 0xFFF0);
|
||||
@@ -360,12 +392,14 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
|
||||
break;
|
||||
case 0x30: /*LMSW*/
|
||||
if ((CPL || eflags&VM_FLAG) && (msw&1))
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1))
|
||||
{
|
||||
x386_dynarec_log("LMSW - ring not zero!\n");
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
tempw = geteaw(); if (cpu_state.abrt) return 1;
|
||||
if (msw & 1) tempw |= 1;
|
||||
if (is386)
|
||||
@@ -385,12 +419,13 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
|
||||
case 0x38: /*INVLPG*/
|
||||
if (is486)
|
||||
{
|
||||
if ((CPL || eflags&VM_FLAG) && (cr0&1))
|
||||
if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1))
|
||||
{
|
||||
x386_dynarec_log("Invalid INVLPG!\n");
|
||||
x86gpf(NULL, 0);
|
||||
break;
|
||||
}
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
mmu_invalidate(ds + cpu_state.eaaddr);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32);
|
||||
|
||||
@@ -63,26 +63,26 @@ static int op ## name ## _l_a32(uint32_t fetchdat) \
|
||||
return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \
|
||||
}
|
||||
|
||||
op_seg(CS, _cs, x86_opcodes, x86_opcodes)
|
||||
op_seg(DS, _ds, x86_opcodes, x86_opcodes)
|
||||
op_seg(ES, _es, x86_opcodes, x86_opcodes)
|
||||
op_seg(FS, _fs, x86_opcodes, x86_opcodes)
|
||||
op_seg(GS, _gs, x86_opcodes, x86_opcodes)
|
||||
op_seg(SS, _ss, x86_opcodes, x86_opcodes)
|
||||
op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes)
|
||||
op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes)
|
||||
op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes)
|
||||
op_seg(FS, cpu_state.seg_fs, x86_opcodes, x86_opcodes)
|
||||
op_seg(GS, cpu_state.seg_gs, x86_opcodes, x86_opcodes)
|
||||
op_seg(SS, cpu_state.seg_ss, x86_opcodes, x86_opcodes)
|
||||
|
||||
op_seg(CS_REPE, _cs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(DS_REPE, _ds, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(ES_REPE, _es, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(FS_REPE, _fs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(GS_REPE, _gs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(SS_REPE, _ss, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(CS_REPE, cpu_state.seg_cs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(DS_REPE, cpu_state.seg_ds, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(ES_REPE, cpu_state.seg_es, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(FS_REPE, cpu_state.seg_fs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(GS_REPE, cpu_state.seg_gs, x86_opcodes_REPE, x86_opcodes)
|
||||
op_seg(SS_REPE, cpu_state.seg_ss, x86_opcodes_REPE, x86_opcodes)
|
||||
|
||||
op_seg(CS_REPNE, _cs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(DS_REPNE, _ds, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(ES_REPNE, _es, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(FS_REPNE, _fs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(GS_REPNE, _gs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(SS_REPNE, _ss, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(CS_REPNE, cpu_state.seg_cs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(DS_REPNE, cpu_state.seg_ds, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes)
|
||||
op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes)
|
||||
|
||||
static int op_66(uint32_t fetchdat) /*Data size select*/
|
||||
{
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
extern int trap;
|
||||
|
||||
#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \
|
||||
static int opREP_INSB_ ## size(uint32_t fetchdat) \
|
||||
{ \
|
||||
@@ -9,11 +7,13 @@ static int opREP_INSB_ ## size(uint32_t fetchdat)
|
||||
{ \
|
||||
uint8_t temp; \
|
||||
\
|
||||
check_io_perm(DX); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
temp = inb(DX); \
|
||||
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) DEST_REG--; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG--; \
|
||||
else DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
@@ -36,12 +36,14 @@ static int opREP_INSW_ ## size(uint32_t fetchdat)
|
||||
{ \
|
||||
uint16_t temp; \
|
||||
\
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
|
||||
temp = inw(DX); \
|
||||
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) DEST_REG -= 2; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
|
||||
else DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
@@ -64,14 +66,16 @@ static int opREP_INSL_ ## size(uint32_t fetchdat)
|
||||
{ \
|
||||
uint32_t temp; \
|
||||
\
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
check_io_perm(DX+2); \
|
||||
check_io_perm(DX+3); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
check_io_perm(DX+2); \
|
||||
check_io_perm(DX+3); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
|
||||
temp = inl(DX); \
|
||||
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) DEST_REG -= 4; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
|
||||
else DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= 15; \
|
||||
@@ -93,10 +97,13 @@ static int opREP_OUTSB_ ## size(uint32_t fetchdat)
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
uint8_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
check_io_perm(DX); \
|
||||
outb(DX, temp); \
|
||||
if (flags & D_FLAG) SRC_REG--; \
|
||||
if (cpu_state.flags & D_FLAG) SRC_REG--; \
|
||||
else SRC_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
@@ -117,11 +124,14 @@ static int opREP_OUTSW_ ## size(uint32_t fetchdat)
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
uint16_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
|
||||
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
outw(DX, temp); \
|
||||
if (flags & D_FLAG) SRC_REG -= 2; \
|
||||
if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \
|
||||
else SRC_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
@@ -142,13 +152,16 @@ static int opREP_OUTSL_ ## size(uint32_t fetchdat)
|
||||
\
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
uint32_t temp; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
|
||||
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX+1); \
|
||||
check_io_perm(DX+2); \
|
||||
check_io_perm(DX+3); \
|
||||
outl(DX, temp); \
|
||||
if (flags & D_FLAG) SRC_REG -= 4; \
|
||||
if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \
|
||||
else SRC_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= 14; \
|
||||
@@ -170,15 +183,21 @@ static int opREP_MOVSB_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
} \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
uint8_t temp; \
|
||||
\
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
writememb(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
|
||||
if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
|
||||
else { DEST_REG++; SRC_REG++; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
@@ -203,15 +222,21 @@ static int opREP_MOVSW_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
} \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
uint16_t temp; \
|
||||
\
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
|
||||
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
writememw(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
|
||||
if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
|
||||
else { DEST_REG += 2; SRC_REG += 2; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
@@ -236,15 +261,21 @@ static int opREP_MOVSL_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
{ \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
} \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
uint32_t temp; \
|
||||
\
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
|
||||
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
writememl(es, DEST_REG, temp); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
|
||||
if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
|
||||
else { DEST_REG += 4; SRC_REG += 4; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 3 : 4; \
|
||||
@@ -271,11 +302,13 @@ static int opREP_STOSB_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG); \
|
||||
writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) DEST_REG--; \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG--; \
|
||||
else DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
@@ -299,11 +332,13 @@ static int opREP_STOSW_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+1); \
|
||||
writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) DEST_REG -= 2; \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
|
||||
writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
|
||||
else DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
@@ -327,11 +362,13 @@ static int opREP_STOSL_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_WRITE_REP(&_es, DEST_REG, DEST_REG+3); \
|
||||
writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) DEST_REG -= 4; \
|
||||
CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
|
||||
writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
|
||||
else DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
@@ -356,10 +393,13 @@ static int opREP_LODSB_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) SRC_REG--; \
|
||||
if (cpu_state.flags & D_FLAG) SRC_REG--; \
|
||||
else SRC_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
@@ -383,10 +423,13 @@ static int opREP_LODSW_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
|
||||
AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) SRC_REG -= 2; \
|
||||
if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \
|
||||
else SRC_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
@@ -410,10 +453,13 @@ static int opREP_LODSL_ ## size(uint32_t fetchdat)
|
||||
int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
if (CNT_REG > 0) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
while (CNT_REG > 0) \
|
||||
{ \
|
||||
CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
|
||||
EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \
|
||||
if (flags & D_FLAG) SRC_REG -= 4; \
|
||||
if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \
|
||||
else SRC_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 4 : 5; \
|
||||
@@ -441,10 +487,15 @@ static int opREP_CMPSB_ ## size(uint32_t fetchdat)
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
|
||||
uint8_t temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
uint8_t temp, temp2; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \
|
||||
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
|
||||
temp2 = readmemb(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
|
||||
if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \
|
||||
else { DEST_REG++; SRC_REG++; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
@@ -468,10 +519,15 @@ static int opREP_CMPSW_ ## size(uint32_t fetchdat)
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
|
||||
uint16_t temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
uint16_t temp, temp2; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1); \
|
||||
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
|
||||
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
|
||||
temp2 = readmemw(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
|
||||
if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \
|
||||
else { DEST_REG += 2; SRC_REG += 2; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
@@ -495,10 +551,15 @@ static int opREP_CMPSL_ ## size(uint32_t fetchdat)
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
|
||||
uint32_t temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
uint32_t temp, temp2; \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3); \
|
||||
CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
|
||||
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
|
||||
temp2 = readmeml(es, DEST_REG); if (cpu_state.abrt) return 1; \
|
||||
\
|
||||
if (flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
|
||||
if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \
|
||||
else { DEST_REG += 4; SRC_REG += 4; } \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 7 : 9; \
|
||||
@@ -523,12 +584,15 @@ static int opREP_SCASB_ ## size(uint32_t fetchdat)
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\
|
||||
setsub8(AL, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (flags & D_FLAG) DEST_REG--; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG--; \
|
||||
else DEST_REG++; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
@@ -554,12 +618,15 @@ static int opREP_SCASW_ ## size(uint32_t fetchdat)
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1); \
|
||||
uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\
|
||||
setsub16(AX, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (flags & D_FLAG) DEST_REG -= 2; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \
|
||||
else DEST_REG += 2; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
@@ -585,12 +652,15 @@ static int opREP_SCASL_ ## size(uint32_t fetchdat)
|
||||
if (trap) \
|
||||
cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \
|
||||
tempz = FV; \
|
||||
if ((CNT_REG > 0) && (FV == tempz)) \
|
||||
SEG_CHECK_READ(&cpu_state.seg_es); \
|
||||
while ((CNT_REG > 0) && (FV == tempz)) \
|
||||
{ \
|
||||
CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3); \
|
||||
uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\
|
||||
setsub32(EAX, temp); \
|
||||
tempz = (ZF_SET()) ? 1 : 0; \
|
||||
if (flags & D_FLAG) DEST_REG -= 4; \
|
||||
if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \
|
||||
else DEST_REG += 4; \
|
||||
CNT_REG--; \
|
||||
cycles -= is486 ? 5 : 8; \
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#define RETF_a16(stack_offset) \
|
||||
if ((msw&1) && !(eflags&VM_FLAG)) \
|
||||
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
|
||||
{ \
|
||||
pmoderetf(0, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
oxpc = cpu_state.pc; \
|
||||
oxpc = cpu_state.pc; \
|
||||
if (stack32) \
|
||||
{ \
|
||||
cpu_state.pc = readmemw(ss, ESP); \
|
||||
@@ -21,12 +21,12 @@
|
||||
cycles -= timing_retf_rm;
|
||||
|
||||
#define RETF_a32(stack_offset) \
|
||||
if ((msw&1) && !(eflags&VM_FLAG)) \
|
||||
if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \
|
||||
{ \
|
||||
pmoderetf(1, stack_offset); \
|
||||
return 1; \
|
||||
} \
|
||||
oxpc = cpu_state.pc; \
|
||||
oxpc = cpu_state.pc; \
|
||||
if (stack32) \
|
||||
{ \
|
||||
cpu_state.pc = readmeml(ss, ESP); \
|
||||
@@ -94,7 +94,7 @@ static int opIRET_286(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
@@ -108,19 +108,19 @@ static int opIRET_286(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
oxpc = cpu_state.pc;
|
||||
oxpc = cpu_state.pc;
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
flags = (flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
flags = (flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
@@ -139,7 +139,7 @@ static int opIRET(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
if (cr4 & CR4_VME)
|
||||
{
|
||||
@@ -151,17 +151,17 @@ static int opIRET(uint32_t fetchdat)
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
|
||||
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (eflags & VIP_FLAG)))
|
||||
if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG)))
|
||||
{
|
||||
x86gpf(NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
SP += 6;
|
||||
if (new_flags & I_FLAG)
|
||||
eflags |= VIF_FLAG;
|
||||
cpu_state.eflags |= VIF_FLAG;
|
||||
else
|
||||
eflags &= ~VIF_FLAG;
|
||||
flags = (flags & 0x3300) | (new_flags & 0x4cd5) | 2;
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2;
|
||||
loadcs(new_cs);
|
||||
cpu_state.pc = new_pc;
|
||||
|
||||
@@ -184,19 +184,19 @@ static int opIRET(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
oxpc = cpu_state.pc;
|
||||
oxpc = cpu_state.pc;
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 2);
|
||||
flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2;
|
||||
ESP += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmemw(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 2) & 0xffff));
|
||||
flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
||||
cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2;
|
||||
SP += 6;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
@@ -216,7 +216,7 @@ static int opIRETD(uint32_t fetchdat)
|
||||
{
|
||||
int cycles_old = cycles; UN_USED(cycles_old);
|
||||
|
||||
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
|
||||
if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3))
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return 1;
|
||||
@@ -230,21 +230,21 @@ static int opIRETD(uint32_t fetchdat)
|
||||
else
|
||||
{
|
||||
uint16_t new_cs;
|
||||
oxpc = cpu_state.pc;
|
||||
oxpc = cpu_state.pc;
|
||||
if (stack32)
|
||||
{
|
||||
cpu_state.pc = readmeml(ss, ESP);
|
||||
new_cs = readmemw(ss, ESP + 4);
|
||||
flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
|
||||
eflags = readmemw(ss, ESP + 10);
|
||||
cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, ESP + 10);
|
||||
ESP += 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_state.pc = readmeml(ss, SP);
|
||||
new_cs = readmemw(ss, ((SP + 4) & 0xffff));
|
||||
flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2;
|
||||
eflags = readmemw(ss, (SP + 10) & 0xffff);
|
||||
cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2;
|
||||
cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff);
|
||||
SP += 12;
|
||||
}
|
||||
loadcs(new_cs);
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
static int opSET ## condition ## _a16(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
seteab((cond_ ## condition) ? 1 : 0); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return cpu_state.abrt; \
|
||||
@@ -10,6 +12,8 @@
|
||||
static int opSET ## condition ## _a32(uint32_t fetchdat) \
|
||||
{ \
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
seteab((cond_ ## condition) ? 1 : 0); \
|
||||
CLOCK_CYCLES(4); \
|
||||
return cpu_state.abrt; \
|
||||
|
||||
@@ -6,36 +6,25 @@
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL b, c*/ \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
temp2 = (temp & 0x80) ? 1 : 0; \
|
||||
temp = (temp << 1) | temp2; \
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \
|
||||
temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp & 1) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR b,CL*/ \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
temp2 = temp & 1; \
|
||||
temp >>= 1; \
|
||||
if (temp2) temp |= 0x80; \
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \
|
||||
temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp & 0x80) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
break; \
|
||||
case 0x10: /*RCL b,CL*/ \
|
||||
temp2 = flags & C_FLAG; \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
@@ -45,14 +34,14 @@
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((flags & C_FLAG) ^ (temp >> 7)) flags |= V_FLAG; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR b,CL*/ \
|
||||
temp2 = flags & C_FLAG; \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
@@ -62,9 +51,9 @@
|
||||
c--; \
|
||||
} \
|
||||
seteab(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40) flags |= V_FLAG; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
@@ -98,36 +87,25 @@
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL w, c*/ \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
temp2 = (temp & 0x8000) ? 1 : 0; \
|
||||
temp = (temp << 1) | temp2; \
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp & 1) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR w, c*/ \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
temp2 = temp & 1; \
|
||||
temp >>= 1; \
|
||||
if (temp2) temp |= 0x8000; \
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
case 0x08: /*ROR w,CL*/ \
|
||||
temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp & 0x8000) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL w, c*/ \
|
||||
temp2 = flags & C_FLAG; \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
@@ -137,14 +115,14 @@
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((flags & C_FLAG) ^ (temp >> 15)) flags |= V_FLAG; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR w, c*/ \
|
||||
temp2 = flags & C_FLAG; \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
@@ -154,9 +132,9 @@
|
||||
c--; \
|
||||
} \
|
||||
seteaw(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x4000) flags |= V_FLAG; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
@@ -190,33 +168,22 @@
|
||||
switch (rmdat & 0x38) \
|
||||
{ \
|
||||
case 0x00: /*ROL l, c*/ \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
temp2 = (temp & 0x80000000) ? 1 : 0; \
|
||||
temp = (temp << 1) | temp2; \
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
temp = (temp << c) | (temp >> (32-c)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp & 1) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x08: /*ROR l, c*/ \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
temp2 = temp & 1; \
|
||||
temp >>= 1; \
|
||||
if (temp2) temp |= 0x80000000; \
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
case 0x08: /*ROR l,CL*/ \
|
||||
temp = (temp >> c) | (temp << (32-c)); \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \
|
||||
break; \
|
||||
case 0x10: /*RCL l, c*/ \
|
||||
temp2 = CF_SET(); \
|
||||
@@ -229,14 +196,14 @@
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((flags & C_FLAG) ^ (temp >> 31)) flags |= V_FLAG; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
case 0x18: /*RCR l, c*/ \
|
||||
temp2 = flags & C_FLAG; \
|
||||
temp2 = cpu_state.flags & C_FLAG; \
|
||||
if (is486) CLOCK_CYCLES_ALWAYS(c); \
|
||||
while (c > 0) \
|
||||
{ \
|
||||
@@ -246,9 +213,9 @@
|
||||
c--; \
|
||||
} \
|
||||
seteal(temp); if (cpu_state.abrt) return 1; \
|
||||
flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40000000) flags |= V_FLAG; \
|
||||
cpu_state.flags &= ~(C_FLAG | V_FLAG); \
|
||||
if (temp2) cpu_state.flags |= C_FLAG; \
|
||||
if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \
|
||||
CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \
|
||||
PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \
|
||||
break; \
|
||||
@@ -281,6 +248,8 @@ static int opC0_a16(uint32_t fetchdat)
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
@@ -294,6 +263,8 @@ static int opC0_a32(uint32_t fetchdat)
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
@@ -307,6 +278,8 @@ static int opC1_w_a16(uint32_t fetchdat)
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
@@ -320,6 +293,8 @@ static int opC1_w_a32(uint32_t fetchdat)
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
@@ -333,6 +308,8 @@ static int opC1_l_a16(uint32_t fetchdat)
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
@@ -346,6 +323,8 @@ static int opC1_l_a32(uint32_t fetchdat)
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++;
|
||||
PREFETCH_PREFIX();
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
@@ -360,6 +339,8 @@ static int opD0_a16(uint32_t fetchdat)
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 0);
|
||||
return 0;
|
||||
@@ -371,6 +352,8 @@ static int opD0_a32(uint32_t fetchdat)
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 1);
|
||||
return 0;
|
||||
@@ -382,6 +365,8 @@ static int opD1_w_a16(uint32_t fetchdat)
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 0);
|
||||
return 0;
|
||||
@@ -393,6 +378,8 @@ static int opD1_w_a32(uint32_t fetchdat)
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 1);
|
||||
return 0;
|
||||
@@ -404,6 +391,8 @@ static int opD1_l_a16(uint32_t fetchdat)
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 0);
|
||||
return 0;
|
||||
@@ -415,6 +404,8 @@ static int opD1_l_a32(uint32_t fetchdat)
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 1);
|
||||
return 0;
|
||||
@@ -427,6 +418,8 @@ static int opD2_a16(uint32_t fetchdat)
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 0);
|
||||
@@ -439,6 +432,8 @@ static int opD2_a32(uint32_t fetchdat)
|
||||
uint8_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_b(c, 1);
|
||||
@@ -451,6 +446,8 @@ static int opD3_w_a16(uint32_t fetchdat)
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 0);
|
||||
@@ -463,6 +460,8 @@ static int opD3_w_a32(uint32_t fetchdat)
|
||||
uint16_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_w(c, 1);
|
||||
@@ -475,6 +474,8 @@ static int opD3_l_a16(uint32_t fetchdat)
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 0);
|
||||
@@ -487,6 +488,8 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
uint32_t temp, temp2 = 0;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
c = CL & 31;
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
OP_SHIFT_l(c, 1);
|
||||
@@ -507,7 +510,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
seteaw(tempw); if (cpu_state.abrt) return 1; \
|
||||
setznp16(tempw); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
#define SHLD_l() \
|
||||
@@ -520,7 +523,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
seteal(templ); if (cpu_state.abrt) return 1; \
|
||||
setznp32(templ); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
|
||||
@@ -536,7 +539,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
seteaw(tempw); if (cpu_state.abrt) return 1; \
|
||||
setznp16(tempw); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
#define SHRD_l() \
|
||||
@@ -549,7 +552,7 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
seteal(templ); if (cpu_state.abrt) return 1; \
|
||||
setznp32(templ); \
|
||||
flags_rebuild(); \
|
||||
if (tempc) flags |= C_FLAG; \
|
||||
if (tempc) cpu_state.flags |= C_FLAG; \
|
||||
}
|
||||
|
||||
#define opSHxD(operation) \
|
||||
@@ -558,6 +561,8 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = getbyte() & 31; \
|
||||
operation() \
|
||||
\
|
||||
@@ -570,6 +575,8 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_16(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = CL & 31; \
|
||||
operation() \
|
||||
\
|
||||
@@ -582,6 +589,8 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = getbyte() & 31; \
|
||||
operation() \
|
||||
\
|
||||
@@ -594,6 +603,8 @@ static int opD3_l_a32(uint32_t fetchdat)
|
||||
int count; \
|
||||
\
|
||||
fetch_ea_32(fetchdat); \
|
||||
if (cpu_mod != 3) \
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg); \
|
||||
count = CL & 31; \
|
||||
operation() \
|
||||
\
|
||||
|
||||
@@ -236,6 +236,8 @@ static int opPOPW_a16(uint32_t fetchdat)
|
||||
temp = POP_W(); if (cpu_state.abrt) return 1;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
@@ -255,6 +257,8 @@ static int opPOPW_a32(uint32_t fetchdat)
|
||||
temp = POP_W(); if (cpu_state.abrt) return 1;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
@@ -274,7 +278,9 @@ static int opPOPL_a16(uint32_t fetchdat)
|
||||
|
||||
temp = POP_L(); if (cpu_state.abrt) return 1;
|
||||
|
||||
fetch_ea_16(fetchdat);
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
@@ -294,6 +300,8 @@ static int opPOPL_a32(uint32_t fetchdat)
|
||||
temp = POP_L(); if (cpu_state.abrt) return 1;
|
||||
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteal(temp);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
@@ -469,10 +477,10 @@ PUSH_SEG_OPS(FS)
|
||||
PUSH_SEG_OPS(GS)
|
||||
PUSH_SEG_OPS(SS)
|
||||
|
||||
POP_SEG_OPS(DS, &_ds)
|
||||
POP_SEG_OPS(ES, &_es)
|
||||
POP_SEG_OPS(FS, &_fs)
|
||||
POP_SEG_OPS(GS, &_gs)
|
||||
POP_SEG_OPS(DS, &cpu_state.seg_ds)
|
||||
POP_SEG_OPS(ES, &cpu_state.seg_es)
|
||||
POP_SEG_OPS(FS, &cpu_state.seg_fs)
|
||||
POP_SEG_OPS(GS, &cpu_state.seg_gs)
|
||||
|
||||
|
||||
static int opPOP_SS_w(uint32_t fetchdat)
|
||||
@@ -480,14 +488,14 @@ static int opPOP_SS_w(uint32_t fetchdat)
|
||||
uint16_t temp_seg;
|
||||
uint32_t temp_esp = ESP;
|
||||
temp_seg = POP_W(); if (cpu_state.abrt) return 1;
|
||||
loadseg(temp_seg, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
|
||||
loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
|
||||
CLOCK_CYCLES(is486 ? 3 : 7);
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
@@ -500,14 +508,14 @@ static int opPOP_SS_l(uint32_t fetchdat)
|
||||
uint32_t temp_seg;
|
||||
uint32_t temp_esp = ESP;
|
||||
temp_seg = POP_L(); if (cpu_state.abrt) return 1;
|
||||
loadseg(temp_seg & 0xffff, &_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
|
||||
loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; }
|
||||
CLOCK_CYCLES(is486 ? 3 : 7);
|
||||
PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0);
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
cpu_state.ssegs = 0;
|
||||
cpu_state.ea_seg = &_ds;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
cpu_state.pc++;
|
||||
if (cpu_state.abrt) return 1;
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
static int opMOVSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
writememb(es, DI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) { DI--; SI--; }
|
||||
if (cpu_state.flags & D_FLAG) { DI--; SI--; }
|
||||
else { DI++; SI++; }
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0);
|
||||
@@ -10,9 +14,13 @@ static int opMOVSB_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOVSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
writememb(es, EDI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) { EDI--; ESI--; }
|
||||
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
|
||||
else { EDI++; ESI++; }
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1);
|
||||
@@ -21,9 +29,13 @@ static int opMOVSB_a32(uint32_t fetchdat)
|
||||
|
||||
static int opMOVSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
writememw(es, DI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) { DI -= 2; SI -= 2; }
|
||||
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
|
||||
else { DI += 2; SI += 2; }
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0);
|
||||
@@ -31,9 +43,13 @@ static int opMOVSW_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOVSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
writememw(es, EDI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
|
||||
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
|
||||
else { EDI += 2; ESI += 2; }
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1);
|
||||
@@ -42,9 +58,13 @@ static int opMOVSW_a32(uint32_t fetchdat)
|
||||
|
||||
static int opMOVSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
writememl(es, DI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) { DI -= 4; SI -= 4; }
|
||||
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
|
||||
else { DI += 4; SI += 4; }
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0);
|
||||
@@ -52,9 +72,13 @@ static int opMOVSL_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opMOVSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
writememl(es, EDI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
|
||||
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
|
||||
else { EDI += 4; ESI += 4; }
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1);
|
||||
@@ -64,10 +88,14 @@ static int opMOVSL_a32(uint32_t fetchdat)
|
||||
|
||||
static int opCMPSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src = readmemb(cpu_state.ea_seg->base, SI);
|
||||
uint8_t dst = readmemb(es, DI); if (cpu_state.abrt) return 1;
|
||||
uint8_t src, dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
src = readmemb(cpu_state.ea_seg->base, SI);
|
||||
dst = readmemb(es, DI); if (cpu_state.abrt) return 1;
|
||||
setsub8(src, dst);
|
||||
if (flags & D_FLAG) { DI--; SI--; }
|
||||
if (cpu_state.flags & D_FLAG) { DI--; SI--; }
|
||||
else { DI++; SI++; }
|
||||
CLOCK_CYCLES((is486) ? 8 : 10);
|
||||
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0);
|
||||
@@ -75,10 +103,14 @@ static int opCMPSB_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opCMPSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t src = readmemb(cpu_state.ea_seg->base, ESI);
|
||||
uint8_t dst = readmemb(es, EDI); if (cpu_state.abrt) return 1;
|
||||
uint8_t src, dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
src = readmemb(cpu_state.ea_seg->base, ESI);
|
||||
dst = readmemb(es, EDI); if (cpu_state.abrt) return 1;
|
||||
setsub8(src, dst);
|
||||
if (flags & D_FLAG) { EDI--; ESI--; }
|
||||
if (cpu_state.flags & D_FLAG) { EDI--; ESI--; }
|
||||
else { EDI++; ESI++; }
|
||||
CLOCK_CYCLES((is486) ? 8 : 10);
|
||||
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1);
|
||||
@@ -87,10 +119,14 @@ static int opCMPSB_a32(uint32_t fetchdat)
|
||||
|
||||
static int opCMPSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src = readmemw(cpu_state.ea_seg->base, SI);
|
||||
uint16_t dst = readmemw(es, DI); if (cpu_state.abrt) return 1;
|
||||
uint16_t src, dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
src = readmemw(cpu_state.ea_seg->base, SI);
|
||||
dst = readmemw(es, DI); if (cpu_state.abrt) return 1;
|
||||
setsub16(src, dst);
|
||||
if (flags & D_FLAG) { DI -= 2; SI -= 2; }
|
||||
if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; }
|
||||
else { DI += 2; SI += 2; }
|
||||
CLOCK_CYCLES((is486) ? 8 : 10);
|
||||
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0);
|
||||
@@ -98,10 +134,14 @@ static int opCMPSW_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opCMPSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t src = readmemw(cpu_state.ea_seg->base, ESI);
|
||||
uint16_t dst = readmemw(es, EDI); if (cpu_state.abrt) return 1;
|
||||
uint16_t src, dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
src = readmemw(cpu_state.ea_seg->base, ESI);
|
||||
dst = readmemw(es, EDI); if (cpu_state.abrt) return 1;
|
||||
setsub16(src, dst);
|
||||
if (flags & D_FLAG) { EDI -= 2; ESI -= 2; }
|
||||
if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; }
|
||||
else { EDI += 2; ESI += 2; }
|
||||
CLOCK_CYCLES((is486) ? 8 : 10);
|
||||
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1);
|
||||
@@ -110,10 +150,14 @@ static int opCMPSW_a32(uint32_t fetchdat)
|
||||
|
||||
static int opCMPSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src = readmeml(cpu_state.ea_seg->base, SI);
|
||||
uint32_t dst = readmeml(es, DI); if (cpu_state.abrt) return 1;
|
||||
uint32_t src, dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
src = readmeml(cpu_state.ea_seg->base, SI);
|
||||
dst = readmeml(es, DI); if (cpu_state.abrt) return 1;
|
||||
setsub32(src, dst);
|
||||
if (flags & D_FLAG) { DI -= 4; SI -= 4; }
|
||||
if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; }
|
||||
else { DI += 4; SI += 4; }
|
||||
CLOCK_CYCLES((is486) ? 8 : 10);
|
||||
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0);
|
||||
@@ -121,10 +165,14 @@ static int opCMPSL_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opCMPSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t src = readmeml(cpu_state.ea_seg->base, ESI);
|
||||
uint32_t dst = readmeml(es, EDI); if (cpu_state.abrt) return 1;
|
||||
uint32_t src, dst;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
src = readmeml(cpu_state.ea_seg->base, ESI);
|
||||
dst = readmeml(es, EDI); if (cpu_state.abrt) return 1;
|
||||
setsub32(src, dst);
|
||||
if (flags & D_FLAG) { EDI -= 4; ESI -= 4; }
|
||||
if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; }
|
||||
else { EDI += 4; ESI += 4; }
|
||||
CLOCK_CYCLES((is486) ? 8 : 10);
|
||||
PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1);
|
||||
@@ -133,8 +181,9 @@ static int opCMPSL_a32(uint32_t fetchdat)
|
||||
|
||||
static int opSTOSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
writememb(es, DI, AL); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) DI--;
|
||||
if (cpu_state.flags & D_FLAG) DI--;
|
||||
else DI++;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
|
||||
@@ -142,8 +191,9 @@ static int opSTOSB_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opSTOSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
writememb(es, EDI, AL); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) EDI--;
|
||||
if (cpu_state.flags & D_FLAG) EDI--;
|
||||
else EDI++;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1);
|
||||
@@ -152,8 +202,9 @@ static int opSTOSB_a32(uint32_t fetchdat)
|
||||
|
||||
static int opSTOSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
writememw(es, DI, AX); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) DI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) DI -= 2;
|
||||
else DI += 2;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0);
|
||||
@@ -161,8 +212,9 @@ static int opSTOSW_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opSTOSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
writememw(es, EDI, AX); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) EDI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) EDI -= 2;
|
||||
else EDI += 2;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1);
|
||||
@@ -171,8 +223,9 @@ static int opSTOSW_a32(uint32_t fetchdat)
|
||||
|
||||
static int opSTOSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
writememl(es, DI, EAX); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) DI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) DI -= 4;
|
||||
else DI += 4;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0);
|
||||
@@ -180,8 +233,9 @@ static int opSTOSL_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opSTOSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
writememl(es, EDI, EAX); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) EDI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) EDI -= 4;
|
||||
else EDI += 4;
|
||||
CLOCK_CYCLES(4);
|
||||
PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1);
|
||||
@@ -191,9 +245,12 @@ static int opSTOSL_a32(uint32_t fetchdat)
|
||||
|
||||
static int opLODSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
AL = temp;
|
||||
if (flags & D_FLAG) SI--;
|
||||
if (cpu_state.flags & D_FLAG) SI--;
|
||||
else SI++;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
|
||||
@@ -201,9 +258,12 @@ static int opLODSB_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opLODSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
AL = temp;
|
||||
if (flags & D_FLAG) ESI--;
|
||||
if (cpu_state.flags & D_FLAG) ESI--;
|
||||
else ESI++;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1);
|
||||
@@ -212,9 +272,12 @@ static int opLODSB_a32(uint32_t fetchdat)
|
||||
|
||||
static int opLODSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
AX = temp;
|
||||
if (flags & D_FLAG) SI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) SI -= 2;
|
||||
else SI += 2;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0);
|
||||
@@ -222,9 +285,12 @@ static int opLODSW_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opLODSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
AX = temp;
|
||||
if (flags & D_FLAG) ESI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) ESI -= 2;
|
||||
else ESI += 2;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1);
|
||||
@@ -233,9 +299,12 @@ static int opLODSW_a32(uint32_t fetchdat)
|
||||
|
||||
static int opLODSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
EAX = temp;
|
||||
if (flags & D_FLAG) SI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) SI -= 4;
|
||||
else SI += 4;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0);
|
||||
@@ -243,9 +312,12 @@ static int opLODSL_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opLODSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
EAX = temp;
|
||||
if (flags & D_FLAG) ESI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) ESI -= 4;
|
||||
else ESI += 4;
|
||||
CLOCK_CYCLES(5);
|
||||
PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1);
|
||||
@@ -255,9 +327,12 @@ static int opLODSL_a32(uint32_t fetchdat)
|
||||
|
||||
static int opSCASB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(es, DI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
temp = readmemb(es, DI); if (cpu_state.abrt) return 1;
|
||||
setsub8(AL, temp);
|
||||
if (flags & D_FLAG) DI--;
|
||||
if (cpu_state.flags & D_FLAG) DI--;
|
||||
else DI++;
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0);
|
||||
@@ -265,9 +340,12 @@ static int opSCASB_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opSCASB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(es, EDI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
temp = readmemb(es, EDI); if (cpu_state.abrt) return 1;
|
||||
setsub8(AL, temp);
|
||||
if (flags & D_FLAG) EDI--;
|
||||
if (cpu_state.flags & D_FLAG) EDI--;
|
||||
else EDI++;
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1);
|
||||
@@ -276,9 +354,12 @@ static int opSCASB_a32(uint32_t fetchdat)
|
||||
|
||||
static int opSCASW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(es, DI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
temp = readmemw(es, DI); if (cpu_state.abrt) return 1;
|
||||
setsub16(AX, temp);
|
||||
if (flags & D_FLAG) DI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) DI -= 2;
|
||||
else DI += 2;
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0);
|
||||
@@ -286,9 +367,12 @@ static int opSCASW_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opSCASW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(es, EDI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
temp = readmemw(es, EDI); if (cpu_state.abrt) return 1;
|
||||
setsub16(AX, temp);
|
||||
if (flags & D_FLAG) EDI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) EDI -= 2;
|
||||
else EDI += 2;
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1);
|
||||
@@ -297,9 +381,12 @@ static int opSCASW_a32(uint32_t fetchdat)
|
||||
|
||||
static int opSCASL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(es, DI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
temp = readmeml(es, DI); if (cpu_state.abrt) return 1;
|
||||
setsub32(EAX, temp);
|
||||
if (flags & D_FLAG) DI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) DI -= 4;
|
||||
else DI += 4;
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0);
|
||||
@@ -307,9 +394,12 @@ static int opSCASL_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opSCASL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(es, EDI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(&cpu_state.seg_es);
|
||||
temp = readmeml(es, EDI); if (cpu_state.abrt) return 1;
|
||||
setsub32(EAX, temp);
|
||||
if (flags & D_FLAG) EDI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) EDI -= 4;
|
||||
else EDI += 4;
|
||||
CLOCK_CYCLES(7);
|
||||
PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1);
|
||||
@@ -319,10 +409,12 @@ static int opSCASL_a32(uint32_t fetchdat)
|
||||
static int opINSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
temp = inb(DX);
|
||||
writememb(es, DI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) DI--;
|
||||
if (cpu_state.flags & D_FLAG) DI--;
|
||||
else DI++;
|
||||
CLOCK_CYCLES(15);
|
||||
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0);
|
||||
@@ -331,10 +423,12 @@ static int opINSB_a16(uint32_t fetchdat)
|
||||
static int opINSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
temp = inb(DX);
|
||||
writememb(es, EDI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) EDI--;
|
||||
if (cpu_state.flags & D_FLAG) EDI--;
|
||||
else EDI++;
|
||||
CLOCK_CYCLES(15);
|
||||
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1);
|
||||
@@ -344,11 +438,13 @@ static int opINSB_a32(uint32_t fetchdat)
|
||||
static int opINSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
temp = inw(DX);
|
||||
writememw(es, DI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) DI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) DI -= 2;
|
||||
else DI += 2;
|
||||
CLOCK_CYCLES(15);
|
||||
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0);
|
||||
@@ -357,11 +453,13 @@ static int opINSW_a16(uint32_t fetchdat)
|
||||
static int opINSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
temp = inw(DX);
|
||||
writememw(es, EDI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) EDI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) EDI -= 2;
|
||||
else EDI += 2;
|
||||
CLOCK_CYCLES(15);
|
||||
PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1);
|
||||
@@ -371,13 +469,15 @@ static int opINSW_a32(uint32_t fetchdat)
|
||||
static int opINSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
temp = inl(DX);
|
||||
writememl(es, DI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) DI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) DI -= 4;
|
||||
else DI += 4;
|
||||
CLOCK_CYCLES(15);
|
||||
PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0);
|
||||
@@ -386,13 +486,15 @@ static int opINSL_a16(uint32_t fetchdat)
|
||||
static int opINSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
temp = inl(DX);
|
||||
writememl(es, EDI, temp); if (cpu_state.abrt) return 1;
|
||||
if (flags & D_FLAG) EDI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) EDI -= 4;
|
||||
else EDI += 4;
|
||||
CLOCK_CYCLES(15);
|
||||
PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1);
|
||||
@@ -401,9 +503,12 @@ static int opINSL_a32(uint32_t fetchdat)
|
||||
|
||||
static int opOUTSB_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
check_io_perm(DX);
|
||||
if (flags & D_FLAG) SI--;
|
||||
if (cpu_state.flags & D_FLAG) SI--;
|
||||
else SI++;
|
||||
outb(DX, temp);
|
||||
CLOCK_CYCLES(14);
|
||||
@@ -412,9 +517,12 @@ static int opOUTSB_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opOUTSB_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint8_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
check_io_perm(DX);
|
||||
if (flags & D_FLAG) ESI--;
|
||||
if (cpu_state.flags & D_FLAG) ESI--;
|
||||
else ESI++;
|
||||
outb(DX, temp);
|
||||
CLOCK_CYCLES(14);
|
||||
@@ -424,10 +532,13 @@ static int opOUTSB_a32(uint32_t fetchdat)
|
||||
|
||||
static int opOUTSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
if (flags & D_FLAG) SI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) SI -= 2;
|
||||
else SI += 2;
|
||||
outw(DX, temp);
|
||||
CLOCK_CYCLES(14);
|
||||
@@ -436,10 +547,13 @@ static int opOUTSW_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opOUTSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint16_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
if (flags & D_FLAG) ESI -= 2;
|
||||
if (cpu_state.flags & D_FLAG) ESI -= 2;
|
||||
else ESI += 2;
|
||||
outw(DX, temp);
|
||||
CLOCK_CYCLES(14);
|
||||
@@ -449,12 +563,15 @@ static int opOUTSW_a32(uint32_t fetchdat)
|
||||
|
||||
static int opOUTSL_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
if (flags & D_FLAG) SI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) SI -= 4;
|
||||
else SI += 4;
|
||||
outl(EDX, temp);
|
||||
CLOCK_CYCLES(14);
|
||||
@@ -463,12 +580,15 @@ static int opOUTSL_a16(uint32_t fetchdat)
|
||||
}
|
||||
static int opOUTSL_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
uint32_t temp;
|
||||
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
if (flags & D_FLAG) ESI -= 4;
|
||||
if (cpu_state.flags & D_FLAG) ESI -= 4;
|
||||
else ESI += 4;
|
||||
outl(EDX, temp);
|
||||
CLOCK_CYCLES(14);
|
||||
|
||||
@@ -2,6 +2,8 @@ static int opXCHG_b_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
@@ -13,6 +15,8 @@ static int opXCHG_b_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint8_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteab(); if (cpu_state.abrt) return 1;
|
||||
seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1;
|
||||
setr8(cpu_reg, temp);
|
||||
@@ -25,6 +29,8 @@ static int opXCHG_w_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
@@ -36,6 +42,8 @@ static int opXCHG_w_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].w = temp;
|
||||
@@ -48,6 +56,8 @@ static int opXCHG_l_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
fetch_ea_16(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
@@ -59,6 +69,8 @@ static int opXCHG_l_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint32_t temp;
|
||||
fetch_ea_32(fetchdat);
|
||||
if (cpu_mod != 3)
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp = geteal(); if (cpu_state.abrt) return 1;
|
||||
seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1;
|
||||
cpu_state.regs[cpu_reg].l = temp;
|
||||
|
||||
331
src/cpu/x86seg.c
331
src/cpu/x86seg.c
@@ -27,11 +27,12 @@
|
||||
#include "../86box.h"
|
||||
#include "cpu.h"
|
||||
#include "../device.h"
|
||||
#include "../timer.h"
|
||||
#include "../machine/machine.h"
|
||||
#include "../mem.h"
|
||||
#include "../nvr.h"
|
||||
#include "x86.h"
|
||||
#include "386.h"
|
||||
#include "x86_flags.h"
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
@@ -80,13 +81,14 @@ x86seg_log(const char *fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void x86abort(const char *format, ...)
|
||||
void x86abort(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stdlog, format, ap);
|
||||
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
fflush(stdlog);
|
||||
|
||||
nvr_save();
|
||||
#ifdef ENABLE_808X_LOG
|
||||
dumpregs(1);
|
||||
@@ -103,7 +105,7 @@ static void seg_reset(x86seg *s)
|
||||
s->limit = 0xFFFF;
|
||||
s->limit_low = 0;
|
||||
s->limit_high = 0xffff;
|
||||
if(s == &_cs)
|
||||
if(s == &cpu_state.seg_cs)
|
||||
{
|
||||
// TODO - When the PC is reset, initialization of the CS descriptor must be like the annotated line below.
|
||||
//s->base = AT ? (cpu_16bitbus ? 0xFF0000 : 0xFFFF0000) : 0xFFFF0;
|
||||
@@ -120,19 +122,19 @@ static void seg_reset(x86seg *s)
|
||||
|
||||
void x86seg_reset()
|
||||
{
|
||||
seg_reset(&_cs);
|
||||
seg_reset(&_ds);
|
||||
seg_reset(&_es);
|
||||
seg_reset(&_fs);
|
||||
seg_reset(&_gs);
|
||||
seg_reset(&_ss);
|
||||
seg_reset(&cpu_state.seg_cs);
|
||||
seg_reset(&cpu_state.seg_ds);
|
||||
seg_reset(&cpu_state.seg_es);
|
||||
seg_reset(&cpu_state.seg_fs);
|
||||
seg_reset(&cpu_state.seg_gs);
|
||||
seg_reset(&cpu_state.seg_ss);
|
||||
}
|
||||
|
||||
void x86_doabrt(int x86_abrt)
|
||||
{
|
||||
CS = oldcs;
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
_cs.access = (oldcpl << 5) | 0x80;
|
||||
cpu_state.seg_cs.access = (oldcpl << 5) | 0x80;
|
||||
|
||||
if (msw & 1)
|
||||
pmodeint(x86_abrt, 0);
|
||||
@@ -141,22 +143,22 @@ void x86_doabrt(int x86_abrt)
|
||||
uint32_t addr = (x86_abrt << 2) + idt.base;
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,flags);
|
||||
writememw(ss,ESP-2,cpu_state.flags);
|
||||
writememw(ss,ESP-4,CS);
|
||||
writememw(ss,ESP-6,cpu_state.pc);
|
||||
ESP-=6;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,((SP-2)&0xFFFF),flags);
|
||||
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
|
||||
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
|
||||
SP-=6;
|
||||
}
|
||||
|
||||
flags&=~I_FLAG;
|
||||
flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
cpu_state.flags&=~T_FLAG;
|
||||
oxpc=cpu_state.pc;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
return;
|
||||
@@ -257,14 +259,14 @@ void do_seg_load(x86seg *s, uint16_t *segdat)
|
||||
s->limit_low = s->limit + 1;
|
||||
}
|
||||
|
||||
if (s == &_ds)
|
||||
if (s == &cpu_state.seg_ds)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
}
|
||||
if (s == &_ss)
|
||||
if (s == &cpu_state.seg_ss)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
|
||||
@@ -331,11 +333,11 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
uint32_t addr;
|
||||
int dpl;
|
||||
|
||||
if (msw&1 && !(eflags&VM_FLAG))
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
if (s==&_ss)
|
||||
if (s==&cpu_state.seg_ss)
|
||||
{
|
||||
x86ss(NULL,0);
|
||||
return;
|
||||
@@ -343,14 +345,18 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
s->seg=0;
|
||||
s->access = 0x80;
|
||||
s->base=-1;
|
||||
if (s == &_ds)
|
||||
if (s == &cpu_state.seg_ds)
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
return;
|
||||
}
|
||||
addr=seg&~7;
|
||||
if (seg&4)
|
||||
{
|
||||
#if 0
|
||||
if (addr>=ldt.limit)
|
||||
#else
|
||||
if ((addr+7)>ldt.limit)
|
||||
#endif
|
||||
{
|
||||
x86gpf("loadseg(): Bigger than LDT limit",seg&~3);
|
||||
return;
|
||||
@@ -359,7 +365,11 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (addr>=gdt.limit)
|
||||
#else
|
||||
if ((addr+7)>gdt.limit)
|
||||
#endif
|
||||
{
|
||||
x86gpf("loadseg(): Bigger than GDT limit",seg&~3);
|
||||
return;
|
||||
@@ -372,7 +382,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
segdat[2]=readmemw(0,addr+4);
|
||||
segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return;
|
||||
dpl=(segdat[2]>>13)&3;
|
||||
if (s==&_ss)
|
||||
if (s==&cpu_state.seg_ss)
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
@@ -399,7 +409,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
}
|
||||
set_stack32((segdat[3] & 0x40) ? 1 : 0);
|
||||
}
|
||||
else if (s!=&_cs)
|
||||
else if (s!=&cpu_state.seg_cs)
|
||||
{
|
||||
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);
|
||||
@@ -431,7 +441,7 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
do_seg_load(s, segdat);
|
||||
|
||||
#ifndef CS_ACCESSED
|
||||
if (s != &_cs)
|
||||
if (s != &cpu_state.seg_cs)
|
||||
{
|
||||
#endif
|
||||
#ifdef SEL_ACCESSED
|
||||
@@ -444,9 +454,9 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
#endif
|
||||
s->checked = 0;
|
||||
#ifdef USE_DYNAREC
|
||||
if (s == &_ds)
|
||||
if (s == &cpu_state.seg_ds)
|
||||
codegen_flat_ds = 0;
|
||||
if (s == &_ss)
|
||||
if (s == &cpu_state.seg_ss)
|
||||
codegen_flat_ss = 0;
|
||||
#endif
|
||||
}
|
||||
@@ -455,25 +465,25 @@ void loadseg(uint16_t seg, x86seg *s)
|
||||
s->access = (3 << 5) | 2 | 0x80;
|
||||
s->base = seg << 4;
|
||||
s->seg = seg;
|
||||
if (s == &_ss)
|
||||
set_stack32(0);
|
||||
s->checked = 1;
|
||||
#ifdef USE_DYNAREC
|
||||
if (s == &_ds)
|
||||
if (s == &cpu_state.seg_ds)
|
||||
codegen_flat_ds = 0;
|
||||
if (s == &_ss)
|
||||
if (s == &cpu_state.seg_ss)
|
||||
codegen_flat_ss = 0;
|
||||
#endif
|
||||
if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG))
|
||||
set_stack32(0);
|
||||
}
|
||||
|
||||
if (s == &_ds)
|
||||
if (s == &cpu_state.seg_ds)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATDS;
|
||||
else
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
}
|
||||
if (s == &_ss)
|
||||
if (s == &cpu_state.seg_ss)
|
||||
{
|
||||
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
|
||||
cpu_cur_status &= ~CPU_STATUS_NOTFLATSS;
|
||||
@@ -491,7 +501,7 @@ void loadcs(uint16_t seg)
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
x86seg_log("Load CS %04X\n",seg);
|
||||
if (msw&1 && !(eflags&VM_FLAG))
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
@@ -549,10 +559,10 @@ void loadcs(uint16_t seg)
|
||||
}
|
||||
set_use32(segdat[3] & 0x40);
|
||||
CS=(seg&~3)|CPL;
|
||||
do_seg_load(&_cs, segdat);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
use32=(segdat[3]&0x40)?0x300:0;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/
|
||||
@@ -576,24 +586,24 @@ void loadcs(uint16_t seg)
|
||||
}
|
||||
else
|
||||
{
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
cpu_state.seg_cs.base=seg<<4;
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffff;
|
||||
CS=seg & 0xFFFF;
|
||||
if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80;
|
||||
else _cs.access=(0<<5) | 2 | 0x80;
|
||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
}
|
||||
}
|
||||
|
||||
void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
void loadcsjmp(uint16_t seg, uint32_t old_pc)
|
||||
{
|
||||
uint16_t segdat[4];
|
||||
uint32_t addr;
|
||||
uint16_t type,seg2;
|
||||
uint32_t newpc;
|
||||
if (msw&1 && !(eflags&VM_FLAG))
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (!(seg&~3))
|
||||
{
|
||||
@@ -661,7 +671,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
CS = (seg & ~3) | CPL;
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8));
|
||||
|
||||
do_seg_load(&_cs, segdat);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
cycles -= timing_jmp_pm;
|
||||
}
|
||||
@@ -757,8 +767,9 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
}
|
||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||
CS=seg2;
|
||||
do_seg_load(&_cs, segdat);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
@@ -779,11 +790,11 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
|
||||
case 0x100: /*286 Task gate*/
|
||||
case 0x900: /*386 Task gate*/
|
||||
cpu_state.pc=oxpc;
|
||||
cpu_state.pc=old_pc;
|
||||
optype=JMP;
|
||||
cpl_override=1;
|
||||
taskswitch286(seg,segdat,segdat[2]&0x800);
|
||||
flags &= ~NT_FLAG;
|
||||
cpu_state.flags &= ~NT_FLAG;
|
||||
cpl_override=0;
|
||||
return;
|
||||
|
||||
@@ -795,13 +806,13 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc)
|
||||
}
|
||||
else
|
||||
{
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
cpu_state.seg_cs.base=seg<<4;
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80;
|
||||
else _cs.access=(0<<5) | 2 | 0x80;
|
||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
cycles -= timing_jmp_rm;
|
||||
}
|
||||
@@ -885,7 +896,7 @@ void loadcscall(uint16_t seg)
|
||||
|
||||
int csout = output;
|
||||
|
||||
if (msw&1 && !(eflags&VM_FLAG))
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (csout) x86seg_log("Protected mode CS load! %04X\n",seg);
|
||||
if (!(seg&~3))
|
||||
@@ -964,8 +975,9 @@ void loadcscall(uint16_t seg)
|
||||
else /*On non-conforming segments, set RPL = CPL*/
|
||||
seg = (seg & ~3) | CPL;
|
||||
CS=seg;
|
||||
do_seg_load(&_cs, segdat);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
if (csout) x86seg_log("Complete\n");
|
||||
cycles -= timing_call_pm;
|
||||
}
|
||||
@@ -1080,7 +1092,11 @@ void loadcscall(uint16_t seg)
|
||||
addr=newss&~7;
|
||||
if (newss&4)
|
||||
{
|
||||
#if 0
|
||||
if (addr>=ldt.limit)
|
||||
#else
|
||||
if ((addr+7)>ldt.limit)
|
||||
#endif
|
||||
{
|
||||
x86abort("Bigger than LDT limit %04X %08X %04X CSC SS\n",newss,addr,ldt.limit);
|
||||
x86ts(NULL,newss&~3);
|
||||
@@ -1090,7 +1106,11 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (addr>=gdt.limit)
|
||||
#else
|
||||
if ((addr+7)>gdt.limit)
|
||||
#endif
|
||||
{
|
||||
x86abort("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit);
|
||||
x86ts(NULL,newss&~3);
|
||||
@@ -1126,7 +1146,7 @@ void loadcscall(uint16_t seg)
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
|
||||
do_seg_load(&_ss, segdat2);
|
||||
do_seg_load(&cpu_state.seg_ss, segdat2);
|
||||
|
||||
x86seg_log("Set access 1\n");
|
||||
|
||||
@@ -1137,8 +1157,9 @@ void loadcscall(uint16_t seg)
|
||||
#endif
|
||||
|
||||
CS=seg2;
|
||||
do_seg_load(&_cs, segdat);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
|
||||
@@ -1216,7 +1237,7 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/
|
||||
CS=seg2;
|
||||
do_seg_load(&_cs, segdat);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat[3]&0x40);
|
||||
cpu_state.pc=newpc;
|
||||
@@ -1251,13 +1272,13 @@ void loadcscall(uint16_t seg)
|
||||
}
|
||||
else
|
||||
{
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
cpu_state.seg_cs.base=seg<<4;
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
if (eflags&VM_FLAG) _cs.access=(3<<5) | 2 | 0x80;
|
||||
else _cs.access=(0<<5) | 2 | 0x80;
|
||||
if (cpu_state.eflags&VM_FLAG) cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
else cpu_state.seg_cs.access=(0<<5) | 2 | 0x80;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
}
|
||||
}
|
||||
@@ -1269,7 +1290,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
uint32_t addr, oaddr;
|
||||
uint16_t segdat[4],segdat2[4],seg,newss;
|
||||
uint32_t oldsp=ESP;
|
||||
x86seg_log("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,cpu_state.eflags);
|
||||
if (is32)
|
||||
{
|
||||
newpc=POPL();
|
||||
@@ -1367,8 +1388,8 @@ void pmoderetf(int is32, uint16_t off)
|
||||
if (segdat[2] & 0x400)
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
CS = seg;
|
||||
do_seg_load(&_cs, segdat);
|
||||
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
@@ -1481,7 +1502,7 @@ void pmoderetf(int is32, uint16_t off)
|
||||
set_stack32((segdat2[3] & 0x40) ? 1 : 0);
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
do_seg_load(&_ss, segdat2);
|
||||
do_seg_load(&cpu_state.seg_ss, segdat2);
|
||||
|
||||
#ifdef SEL_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -1498,24 +1519,24 @@ void pmoderetf(int is32, uint16_t off)
|
||||
|
||||
cpu_state.pc=newpc;
|
||||
CS=seg;
|
||||
do_seg_load(&_cs, segdat);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
if (stack32) ESP+=off;
|
||||
else SP+=off;
|
||||
|
||||
check_seg_valid(&_ds);
|
||||
check_seg_valid(&_es);
|
||||
check_seg_valid(&_fs);
|
||||
check_seg_valid(&_gs);
|
||||
check_seg_valid(&cpu_state.seg_ds);
|
||||
check_seg_valid(&cpu_state.seg_es);
|
||||
check_seg_valid(&cpu_state.seg_fs);
|
||||
check_seg_valid(&cpu_state.seg_gs);
|
||||
cycles -= timing_retf_pm_outer;
|
||||
}
|
||||
}
|
||||
|
||||
void restore_stack()
|
||||
{
|
||||
ss=oldss; _ss.limit=oldsslimit;
|
||||
ss=oldss; cpu_state.seg_ss.limit=oldsslimit;
|
||||
}
|
||||
|
||||
void pmodeint(int num, int soft)
|
||||
@@ -1529,7 +1550,7 @@ void pmodeint(int num, int soft)
|
||||
uint16_t seg = 0;
|
||||
int new_cpl;
|
||||
|
||||
if (eflags&VM_FLAG && IOPL!=3 && soft)
|
||||
if (cpu_state.eflags&VM_FLAG && IOPL!=3 && soft)
|
||||
{
|
||||
x86seg_log("V86 banned int\n");
|
||||
x86gpf(NULL,0);
|
||||
@@ -1628,7 +1649,7 @@ void pmodeint(int num, int soft)
|
||||
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if ((eflags&VM_FLAG) && DPL2)
|
||||
if ((cpu_state.eflags&VM_FLAG) && DPL2)
|
||||
{
|
||||
x86gpf(NULL,segdat[1]&0xFFFC);
|
||||
return;
|
||||
@@ -1698,7 +1719,7 @@ void pmodeint(int num, int soft)
|
||||
set_stack32((segdat3[3] & 0x40) ? 1 : 0);
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
do_seg_load(&_ss, segdat3);
|
||||
do_seg_load(&cpu_state.seg_ss, segdat3);
|
||||
|
||||
#ifdef CS_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -1710,20 +1731,20 @@ void pmodeint(int num, int soft)
|
||||
cpl_override=1;
|
||||
if (type>=0x800)
|
||||
{
|
||||
if (eflags & VM_FLAG)
|
||||
if (cpu_state.eflags & VM_FLAG)
|
||||
{
|
||||
PUSHL(GS);
|
||||
PUSHL(FS);
|
||||
PUSHL(DS);
|
||||
PUSHL(ES); if (cpu_state.abrt) return;
|
||||
loadseg(0,&_ds);
|
||||
loadseg(0,&_es);
|
||||
loadseg(0,&_fs);
|
||||
loadseg(0,&_gs);
|
||||
loadseg(0,&cpu_state.seg_ds);
|
||||
loadseg(0,&cpu_state.seg_es);
|
||||
loadseg(0,&cpu_state.seg_fs);
|
||||
loadseg(0,&cpu_state.seg_gs);
|
||||
}
|
||||
PUSHL(oldss);
|
||||
PUSHL(oldsp);
|
||||
PUSHL(flags|(eflags<<16));
|
||||
PUSHL(cpu_state.flags|(cpu_state.eflags<<16));
|
||||
PUSHL(CS);
|
||||
PUSHL(cpu_state.pc); if (cpu_state.abrt) return;
|
||||
}
|
||||
@@ -1731,12 +1752,12 @@ void pmodeint(int num, int soft)
|
||||
{
|
||||
PUSHW(oldss);
|
||||
PUSHW(oldsp);
|
||||
PUSHW(flags);
|
||||
PUSHW(cpu_state.flags);
|
||||
PUSHW(CS);
|
||||
PUSHW(cpu_state.pc); if (cpu_state.abrt) return;
|
||||
}
|
||||
cpl_override=0;
|
||||
_cs.access=0 | 0x80;
|
||||
cpu_state.seg_cs.access=0 | 0x80;
|
||||
cycles -= timing_int_pm_outer - timing_int_pm;
|
||||
break;
|
||||
}
|
||||
@@ -1751,20 +1772,20 @@ void pmodeint(int num, int soft)
|
||||
x86np("Int gate CS not present\n", segdat[1] & 0xfffc);
|
||||
return;
|
||||
}
|
||||
if ((eflags & VM_FLAG) && DPL2<CPL)
|
||||
if ((cpu_state.eflags & VM_FLAG) && DPL2<CPL)
|
||||
{
|
||||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
}
|
||||
if (type>0x800)
|
||||
{
|
||||
PUSHL(flags|(eflags<<16));
|
||||
PUSHL(cpu_state.flags|(cpu_state.eflags<<16));
|
||||
PUSHL(CS);
|
||||
PUSHL(cpu_state.pc); if (cpu_state.abrt) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PUSHW(flags);
|
||||
PUSHW(cpu_state.flags);
|
||||
PUSHW(CS);
|
||||
PUSHW(cpu_state.pc); if (cpu_state.abrt) return;
|
||||
}
|
||||
@@ -1774,9 +1795,9 @@ void pmodeint(int num, int soft)
|
||||
x86gpf(NULL,seg&~3);
|
||||
return;
|
||||
}
|
||||
do_seg_load(&_cs, segdat2);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat2);
|
||||
CS = (seg & ~3) | new_cpl;
|
||||
_cs.access = (_cs.access & ~(3 << 5)) | (new_cpl << 5);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | (new_cpl << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16);
|
||||
else cpu_state.pc=segdat[0];
|
||||
@@ -1788,13 +1809,13 @@ void pmodeint(int num, int soft)
|
||||
cpl_override = 0;
|
||||
#endif
|
||||
|
||||
eflags&=~VM_FLAG;
|
||||
cpu_state.eflags&=~VM_FLAG;
|
||||
cpu_cur_status &= ~CPU_STATUS_V86;
|
||||
if (!(type&0x100))
|
||||
{
|
||||
flags&=~I_FLAG;
|
||||
cpu_state.flags&=~I_FLAG;
|
||||
}
|
||||
flags&=~(T_FLAG|NT_FLAG);
|
||||
cpu_state.flags&=~(T_FLAG|NT_FLAG);
|
||||
cycles -= timing_int_pm;
|
||||
break;
|
||||
|
||||
@@ -1853,14 +1874,14 @@ void pmodeiret(int is32)
|
||||
uint16_t seg;
|
||||
uint32_t addr, oaddr;
|
||||
uint32_t oldsp=ESP;
|
||||
if (is386 && (eflags&VM_FLAG))
|
||||
if (is386 && (cpu_state.eflags&VM_FLAG))
|
||||
{
|
||||
if (IOPL!=3)
|
||||
{
|
||||
x86gpf(NULL,0);
|
||||
return;
|
||||
}
|
||||
oxpc=cpu_state.pc;
|
||||
oxpc=cpu_state.pc;
|
||||
if (is32)
|
||||
{
|
||||
newpc=POPL();
|
||||
@@ -1873,19 +1894,19 @@ void pmodeiret(int is32)
|
||||
seg=POPW();
|
||||
tempflags=POPW(); if (cpu_state.abrt) return;
|
||||
}
|
||||
cpu_state.pc=newpc;
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
_cs.access |= 0x80;
|
||||
cpu_state.pc = newpc;
|
||||
cpu_state.seg_cs.base=seg<<4;
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffff;
|
||||
cpu_state.seg_cs.access |= 0x80;
|
||||
CS=seg;
|
||||
flags=(flags&0x3000)|(tempflags&0xCFD5)|2;
|
||||
cpu_state.flags=(cpu_state.flags&0x3000)|(tempflags&0xCFD5)|2;
|
||||
cycles -= timing_iret_rm;
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags&NT_FLAG)
|
||||
if (cpu_state.flags&NT_FLAG)
|
||||
{
|
||||
seg=readmemw(tr.base,0);
|
||||
addr=seg&~7;
|
||||
@@ -1913,7 +1934,7 @@ void pmodeiret(int is32)
|
||||
cpl_override=0;
|
||||
return;
|
||||
}
|
||||
oxpc=cpu_state.pc;
|
||||
oxpc=cpu_state.pc;
|
||||
flagmask=0xFFFF;
|
||||
if (CPL) flagmask&=~0x3000;
|
||||
if (IOPL<CPL) flagmask&=~0x200;
|
||||
@@ -1930,34 +1951,34 @@ void pmodeiret(int is32)
|
||||
segs[1]=POPL();
|
||||
segs[2]=POPL();
|
||||
segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; }
|
||||
eflags=tempflags>>16;
|
||||
cpu_state.eflags=tempflags>>16;
|
||||
cpu_cur_status |= CPU_STATUS_V86;
|
||||
loadseg(segs[0],&_es);
|
||||
do_seg_v86_init(&_es);
|
||||
loadseg(segs[1],&_ds);
|
||||
do_seg_v86_init(&_ds);
|
||||
loadseg(segs[0],&cpu_state.seg_es);
|
||||
do_seg_v86_init(&cpu_state.seg_es);
|
||||
loadseg(segs[1],&cpu_state.seg_ds);
|
||||
do_seg_v86_init(&cpu_state.seg_ds);
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATDS;
|
||||
loadseg(segs[2],&_fs);
|
||||
do_seg_v86_init(&_fs);
|
||||
loadseg(segs[3],&_gs);
|
||||
do_seg_v86_init(&_gs);
|
||||
loadseg(segs[2],&cpu_state.seg_fs);
|
||||
do_seg_v86_init(&cpu_state.seg_fs);
|
||||
loadseg(segs[3],&cpu_state.seg_gs);
|
||||
do_seg_v86_init(&cpu_state.seg_gs);
|
||||
|
||||
cpu_state.pc=newpc;
|
||||
_cs.base=seg<<4;
|
||||
_cs.limit=0xFFFF;
|
||||
_cs.limit_low = 0;
|
||||
_cs.limit_high = 0xffff;
|
||||
cpu_state.seg_cs.base=seg<<4;
|
||||
cpu_state.seg_cs.limit=0xFFFF;
|
||||
cpu_state.seg_cs.limit_low = 0;
|
||||
cpu_state.seg_cs.limit_high = 0xffff;
|
||||
CS=seg;
|
||||
_cs.access=(3<<5) | 2 | 0x80;
|
||||
cpu_state.seg_cs.access=(3<<5) | 2 | 0x80;
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
|
||||
|
||||
ESP=newsp;
|
||||
loadseg(newss,&_ss);
|
||||
do_seg_v86_init(&_ss);
|
||||
loadseg(newss,&cpu_state.seg_ss);
|
||||
do_seg_v86_init(&cpu_state.seg_ss);
|
||||
cpu_cur_status |= CPU_STATUS_NOTFLATSS;
|
||||
use32=0;
|
||||
cpu_cur_status &= ~CPU_STATUS_USE32;
|
||||
flags=(tempflags&0xFFD5)|2;
|
||||
cpu_state.flags=(tempflags&0xFFD5)|2;
|
||||
cycles -= timing_iret_v86;
|
||||
return;
|
||||
}
|
||||
@@ -2040,8 +2061,8 @@ void pmodeiret(int is32)
|
||||
if ((seg&3) == CPL)
|
||||
{
|
||||
CS=seg;
|
||||
do_seg_load(&_cs, segdat);
|
||||
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat[3]&0x40);
|
||||
|
||||
@@ -2129,7 +2150,7 @@ void pmodeiret(int is32)
|
||||
set_stack32((segdat2[3] & 0x40) ? 1 : 0);
|
||||
if (stack32) ESP=newsp;
|
||||
else SP=newsp;
|
||||
do_seg_load(&_ss, segdat2);
|
||||
do_seg_load(&cpu_state.seg_ss, segdat2);
|
||||
|
||||
#ifdef SEL_ACCESSED
|
||||
cpl_override = 1;
|
||||
@@ -2145,20 +2166,20 @@ void pmodeiret(int is32)
|
||||
segdat[2] = (segdat[2] & ~(3 << (5+8))) | ((seg & 3) << (5+8));
|
||||
|
||||
CS=seg;
|
||||
do_seg_load(&_cs, segdat);
|
||||
_cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat);
|
||||
cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat[3] & 0x40);
|
||||
|
||||
check_seg_valid(&_ds);
|
||||
check_seg_valid(&_es);
|
||||
check_seg_valid(&_fs);
|
||||
check_seg_valid(&_gs);
|
||||
check_seg_valid(&cpu_state.seg_ds);
|
||||
check_seg_valid(&cpu_state.seg_es);
|
||||
check_seg_valid(&cpu_state.seg_fs);
|
||||
check_seg_valid(&cpu_state.seg_gs);
|
||||
cycles -= timing_iret_pm_outer;
|
||||
}
|
||||
cpu_state.pc=newpc;
|
||||
flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;
|
||||
if (is32) eflags=tempflags>>16;
|
||||
cpu_state.flags=(cpu_state.flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2;
|
||||
if (is32) cpu_state.eflags=tempflags>>16;
|
||||
}
|
||||
|
||||
void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
@@ -2205,12 +2226,12 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
if (cpu_state.abrt) return;
|
||||
|
||||
if (optype==IRET) flags&=~NT_FLAG;
|
||||
if (optype==IRET) cpu_state.flags&=~NT_FLAG;
|
||||
|
||||
cpu_386_flags_rebuild();
|
||||
writememl(tr.base,0x1C,cr3);
|
||||
writememl(tr.base,0x20,cpu_state.pc);
|
||||
writememl(tr.base,0x24,flags|(eflags<<16));
|
||||
writememl(tr.base,0x24,cpu_state.flags|(cpu_state.eflags<<16));
|
||||
|
||||
writememl(tr.base,0x28,EAX);
|
||||
writememl(tr.base,0x2C,ECX);
|
||||
@@ -2276,8 +2297,8 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
flushmmucache();
|
||||
|
||||
cpu_state.pc=new_pc;
|
||||
flags=new_flags;
|
||||
eflags=new_flags>>16;
|
||||
cpu_state.flags=new_flags;
|
||||
cpu_state.eflags=new_flags>>16;
|
||||
cpu_386_flags_extract();
|
||||
|
||||
ldt.seg=new_ldt;
|
||||
@@ -2290,7 +2311,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24);
|
||||
|
||||
if (eflags & VM_FLAG)
|
||||
if (cpu_state.eflags & VM_FLAG)
|
||||
{
|
||||
loadcs(new_cs);
|
||||
set_use32(0);
|
||||
@@ -2353,7 +2374,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
|
||||
CS=new_cs;
|
||||
do_seg_load(&_cs, segdat2);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(segdat2[3] & 0x40);
|
||||
cpu_cur_status &= ~CPU_STATUS_V86;
|
||||
@@ -2368,11 +2389,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ESI=new_esi;
|
||||
EDI=new_edi;
|
||||
|
||||
loadseg(new_es,&_es);
|
||||
loadseg(new_ss,&_ss);
|
||||
loadseg(new_ds,&_ds);
|
||||
loadseg(new_fs,&_fs);
|
||||
loadseg(new_gs,&_gs);
|
||||
loadseg(new_es,&cpu_state.seg_es);
|
||||
loadseg(new_ss,&cpu_state.seg_ss);
|
||||
loadseg(new_ds,&cpu_state.seg_ds);
|
||||
loadseg(new_fs,&cpu_state.seg_fs);
|
||||
loadseg(new_gs,&cpu_state.seg_gs);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2393,11 +2414,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
if (cpu_state.abrt) return;
|
||||
|
||||
if (optype==IRET) flags&=~NT_FLAG;
|
||||
if (optype==IRET) cpu_state.flags&=~NT_FLAG;
|
||||
|
||||
cpu_386_flags_rebuild();
|
||||
writememw(tr.base,0x0E,cpu_state.pc);
|
||||
writememw(tr.base,0x10,flags);
|
||||
writememw(tr.base,0x10,cpu_state.flags);
|
||||
|
||||
writememw(tr.base,0x12,AX);
|
||||
writememw(tr.base,0x14,CX);
|
||||
@@ -2454,7 +2475,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
msw |= 8;
|
||||
|
||||
cpu_state.pc=new_pc;
|
||||
flags=new_flags;
|
||||
cpu_state.flags=new_flags;
|
||||
cpu_386_flags_extract();
|
||||
|
||||
ldt.seg=new_ldt;
|
||||
@@ -2526,7 +2547,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
}
|
||||
|
||||
CS=new_cs;
|
||||
do_seg_load(&_cs, segdat2);
|
||||
do_seg_load(&cpu_state.seg_cs, segdat2);
|
||||
if (CPL==3 && oldcpl!=3) flushmmucache_cr3();
|
||||
set_use32(0);
|
||||
|
||||
@@ -2539,13 +2560,13 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32)
|
||||
ESI=new_esi | 0xFFFF0000;
|
||||
EDI=new_edi | 0xFFFF0000;
|
||||
|
||||
loadseg(new_es,&_es);
|
||||
loadseg(new_ss,&_ss);
|
||||
loadseg(new_ds,&_ds);
|
||||
loadseg(new_es,&cpu_state.seg_es);
|
||||
loadseg(new_ss,&cpu_state.seg_ss);
|
||||
loadseg(new_ds,&cpu_state.seg_ds);
|
||||
if (is386)
|
||||
{
|
||||
loadseg(0,&_fs);
|
||||
loadseg(0,&_gs);
|
||||
loadseg(0,&cpu_state.seg_fs);
|
||||
loadseg(0,&cpu_state.seg_gs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ void x87_settag(uint16_t new_tag)
|
||||
cpu_state.tag[7] = (new_tag >> 14) & 3;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_808X_LOG
|
||||
void x87_dumpregs()
|
||||
{
|
||||
|
||||
@@ -1,6 +1,24 @@
|
||||
uint32_t x87_pc_off,x87_op_off;
|
||||
uint16_t x87_pc_seg,x87_op_seg;
|
||||
|
||||
static __inline void x87_set_mmx()
|
||||
{
|
||||
uint64_t *p;
|
||||
cpu_state.TOP = 0;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
*p = 0;
|
||||
cpu_state.ismmx = 1;
|
||||
}
|
||||
|
||||
static __inline void x87_emms()
|
||||
{
|
||||
uint64_t *p;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
*p = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
}
|
||||
|
||||
|
||||
uint16_t x87_gettag();
|
||||
void x87_settag(uint16_t new_tag);
|
||||
|
||||
|
||||
@@ -1,42 +1,24 @@
|
||||
/*
|
||||
* 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.
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the VARCem Project.
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* x87 FPU instructions core.
|
||||
*
|
||||
* Version: @(#)x87_ops.h 1.0.7 2018/10/17
|
||||
* Version: @(#)x87_ops.h 1.0.8 2019/06/11
|
||||
*
|
||||
* 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.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 leilei.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
* Copyright 2018,2019 Fred N. van Kempen.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <fenv.h>
|
||||
@@ -63,41 +45,47 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ
|
||||
|
||||
#define STATUS_ZERODIVIDE 4
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define x87_div(dst, src1, src2) do \
|
||||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
picint(1 << 13); \
|
||||
if (!(cpu_state.npxc & 0x80)) { \
|
||||
cpu_state.npxs |= 0x80; \
|
||||
nmi = 1; \
|
||||
} \
|
||||
return 1; \
|
||||
} \
|
||||
return 1; \
|
||||
} \
|
||||
else \
|
||||
dst = src1 / (double)src2; \
|
||||
} while (0)
|
||||
#else
|
||||
#define x87_div(dst, src1, src2) do \
|
||||
{ \
|
||||
if (((double)src2) == 0.0) \
|
||||
{ \
|
||||
cpu_state.npxs |= STATUS_ZERODIVIDE; \
|
||||
if (cpu_state.npxc & STATUS_ZERODIVIDE) \
|
||||
dst = src1 / (double)src2; \
|
||||
else \
|
||||
{ \
|
||||
fpu_log("FPU : divide by zero\n"); \
|
||||
picint(1 << 13); \
|
||||
return 1; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
dst = src1 / (double)src2; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static __inline void x87_set_mmx()
|
||||
{
|
||||
uint64_t *p;
|
||||
cpu_state.TOP = 0;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
*p = 0;
|
||||
cpu_state.ismmx = 1;
|
||||
}
|
||||
|
||||
static __inline void x87_emms()
|
||||
{
|
||||
uint64_t *p;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
*p = 0x0303030303030303ll;
|
||||
cpu_state.ismmx = 0;
|
||||
}
|
||||
|
||||
static __inline void x87_checkexceptions()
|
||||
{
|
||||
}
|
||||
@@ -286,44 +274,24 @@ static __inline void x87_stmmx(MMX_REG r)
|
||||
writememw(easeg, cpu_state.eaaddr + 8, 0xffff);
|
||||
}
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
static __inline uint16_t x87_compare(double a, double b)
|
||||
{
|
||||
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64
|
||||
uint32_t result;
|
||||
double ea = a, eb = b;
|
||||
const uint64_t ia = 0x3fec1a6ff866a936ull;
|
||||
const uint64_t ib = 0x3fec1a6ff866a938ull;
|
||||
|
||||
if (!is386)
|
||||
{
|
||||
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
{
|
||||
/* fpu_log("Comparing infinity\n"); */
|
||||
#ifndef _MSC_VER
|
||||
__asm volatile ("" : : : "memory");
|
||||
|
||||
__asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
"fcompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m" (result)
|
||||
: "m" (a), "m" (a)
|
||||
);
|
||||
#else
|
||||
_ReadWriteBarrier();
|
||||
__asm
|
||||
{
|
||||
fld a
|
||||
fld a
|
||||
fclex
|
||||
fcompp
|
||||
fnstsw result
|
||||
}
|
||||
#endif
|
||||
/* Hack to make CHKCOP happy. */
|
||||
if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8))
|
||||
return C3;
|
||||
|
||||
if (!is386 && !(cpu_state.npxc & 0x1000) &&
|
||||
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
|
||||
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 */
|
||||
@@ -336,14 +304,14 @@ static __inline uint16_t x87_compare(double a, double b)
|
||||
"fcompp\n"
|
||||
"fnstsw %0\n"
|
||||
: "=m" (result)
|
||||
: "m" (a), "m" (b)
|
||||
: "m" (ea), "m" (eb)
|
||||
);
|
||||
#else
|
||||
_ReadWriteBarrier();
|
||||
_asm
|
||||
{
|
||||
fld b
|
||||
fld a
|
||||
fld eb
|
||||
fld ea
|
||||
fclex
|
||||
fcompp
|
||||
fnstsw result
|
||||
@@ -355,43 +323,32 @@ static __inline uint16_t x87_compare(double a, double b)
|
||||
/* Generic C version is known to give incorrect results in some
|
||||
* situations, eg comparison of infinity (Unreal) */
|
||||
uint32_t result = 0;
|
||||
double ea = a, eb = b;
|
||||
|
||||
if (is386)
|
||||
{
|
||||
if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
{
|
||||
result |= C3;
|
||||
return result;
|
||||
}
|
||||
if (!is386 && !(cpu_state.npxc & 0x1000) &&
|
||||
((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)))
|
||||
eb = ea;
|
||||
|
||||
if (a == b)
|
||||
result |= C3;
|
||||
else if (a < b)
|
||||
result |= C0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a == b)
|
||||
result |= C3;
|
||||
else if (a < b)
|
||||
result |= C0;
|
||||
}
|
||||
if (ea == eb)
|
||||
result |= C3;
|
||||
else if (ea < eb)
|
||||
result |= C0;
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
static __inline uint16_t x87_ucompare(double a, double b)
|
||||
static inline uint16_t x87_ucompare(double a, double b)
|
||||
{
|
||||
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64
|
||||
#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 || defined __amd64__
|
||||
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");
|
||||
asm volatile ("" : : : "memory");
|
||||
|
||||
__asm(
|
||||
asm(
|
||||
"fldl %2\n"
|
||||
"fldl %1\n"
|
||||
"fclex\n"
|
||||
@@ -439,6 +396,11 @@ typedef union
|
||||
uint64_t i;
|
||||
} x87_td;
|
||||
|
||||
#ifdef FPU_8087
|
||||
#define FP_ENTER() { \
|
||||
fpucount++; \
|
||||
}
|
||||
#else
|
||||
#define FP_ENTER() do \
|
||||
{ \
|
||||
if (cr0 & 0xc) \
|
||||
@@ -448,11 +410,13 @@ typedef union
|
||||
} \
|
||||
fpucount++; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#include "x87_ops_arith.h"
|
||||
#include "x87_ops_misc.h"
|
||||
#include "x87_ops_loadstore.h"
|
||||
|
||||
#ifndef FPU_8087
|
||||
static int op_nofpu_a16(uint32_t fetchdat)
|
||||
{
|
||||
if (cr0 & 0xc)
|
||||
@@ -479,7 +443,16 @@ static int op_nofpu_a32(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FPU_8087
|
||||
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
{
|
||||
geteaw();
|
||||
wait(timing_rr, 0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int FPU_ILLEGAL_a16(uint32_t fetchdat)
|
||||
{
|
||||
fetch_ea_16(fetchdat);
|
||||
@@ -495,8 +468,261 @@ static int FPU_ILLEGAL_a32(uint32_t fetchdat)
|
||||
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ILLEGAL_a16 FPU_ILLEGAL_a16
|
||||
|
||||
#ifdef FPU_8087
|
||||
const OpFn OP_TABLE(fpu_8087_d8)[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
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(fpu_8087_d9)[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,
|
||||
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
|
||||
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
|
||||
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
|
||||
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
|
||||
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
|
||||
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
|
||||
|
||||
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,
|
||||
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
|
||||
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
|
||||
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
|
||||
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
|
||||
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
|
||||
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
|
||||
|
||||
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,
|
||||
opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16,
|
||||
opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16,
|
||||
opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16,
|
||||
opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16,
|
||||
opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16,
|
||||
opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16,
|
||||
|
||||
opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD,
|
||||
opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH,
|
||||
opFNOP, 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, /*Invalid*/
|
||||
opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16,
|
||||
opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP,
|
||||
opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(fpu_8087_da)[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,
|
||||
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
|
||||
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
|
||||
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
|
||||
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
|
||||
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
|
||||
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
|
||||
|
||||
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,
|
||||
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
|
||||
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
|
||||
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
|
||||
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
|
||||
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
|
||||
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16,
|
||||
|
||||
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,
|
||||
opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16,
|
||||
opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16,
|
||||
opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16,
|
||||
opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16,
|
||||
opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16,
|
||||
opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_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, 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, 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, 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, ILLEGAL_a16,
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(fpu_8087_db)[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,
|
||||
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
|
||||
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
|
||||
|
||||
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,
|
||||
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
|
||||
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16,
|
||||
|
||||
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,
|
||||
opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16,
|
||||
opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_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, 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, ILLEGAL_a16,
|
||||
opFI, opFI, opFCLEX, opFINIT, ILLEGAL_a16, opFNOP, 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, ILLEGAL_a16, ILLEGAL_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(fpu_8087_dc)[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
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(fpu_8087_dd)[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,
|
||||
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
|
||||
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
|
||||
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
|
||||
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
|
||||
|
||||
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,
|
||||
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
|
||||
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
|
||||
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
|
||||
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
|
||||
|
||||
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,
|
||||
opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16,
|
||||
opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16,
|
||||
opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16,
|
||||
opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16,
|
||||
|
||||
opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST,
|
||||
opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP,
|
||||
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,
|
||||
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,
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(fpu_8087_de)[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,
|
||||
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
|
||||
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
|
||||
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
|
||||
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
|
||||
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
|
||||
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
|
||||
|
||||
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,
|
||||
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
|
||||
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
|
||||
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
|
||||
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
|
||||
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
|
||||
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
|
||||
|
||||
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,
|
||||
opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16,
|
||||
opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16,
|
||||
opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16,
|
||||
opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16,
|
||||
opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16,
|
||||
opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16,
|
||||
|
||||
opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP,
|
||||
opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP,
|
||||
opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP,
|
||||
opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP,
|
||||
opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP,
|
||||
};
|
||||
|
||||
const OpFn OP_TABLE(fpu_8087_df)[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,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
|
||||
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,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
|
||||
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,
|
||||
opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16,
|
||||
opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16,
|
||||
FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16,
|
||||
FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16,
|
||||
|
||||
opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16,
|
||||
};
|
||||
#else
|
||||
#define ILLEGAL_a32 FPU_ILLEGAL_a32
|
||||
|
||||
const OpFn OP_TABLE(fpu_d8_a16)[32] =
|
||||
@@ -824,6 +1050,7 @@ const OpFn OP_TABLE(fpu_da_a32)[256] =
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
};
|
||||
|
||||
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
|
||||
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,
|
||||
@@ -900,6 +1127,7 @@ const OpFn OP_TABLE(fpu_686_da_a32)[256] =
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(fpu_287_db_a16)[256] =
|
||||
{
|
||||
@@ -1055,6 +1283,7 @@ const OpFn OP_TABLE(fpu_db_a32)[256] =
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
};
|
||||
|
||||
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
|
||||
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,
|
||||
@@ -1131,6 +1360,7 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] =
|
||||
opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(fpu_287_dc_a16)[32] =
|
||||
{
|
||||
@@ -1626,6 +1856,7 @@ const OpFn OP_TABLE(fpu_df_a32)[256] =
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
};
|
||||
|
||||
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
|
||||
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,
|
||||
@@ -1702,6 +1933,7 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] =
|
||||
opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP,
|
||||
ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32,
|
||||
};
|
||||
#endif
|
||||
|
||||
const OpFn OP_TABLE(nofpu_a16)[256] =
|
||||
{
|
||||
@@ -1779,3 +2011,6 @@ 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,
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef ILLEGAL
|
||||
|
||||
@@ -4,13 +4,14 @@ static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \
|
||||
ST(0) += use_var; \
|
||||
if ((cpu_state.npxc >> 10) & 3) \
|
||||
fesetround(FE_TONEAREST); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -19,6 +20,7 @@ static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.npxs &= ~(C0|C2|C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
@@ -30,6 +32,7 @@ static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
cpu_state.npxs &= ~(C0|C2|C3); \
|
||||
cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \
|
||||
@@ -42,9 +45,10 @@ static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), ST(0), use_var); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -53,9 +57,10 @@ static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
x87_div(ST(0), use_var, ST(0)); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(73); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -64,6 +69,7 @@ static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) *= use_var; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
@@ -75,9 +81,10 @@ static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) -= use_var; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
} \
|
||||
@@ -86,23 +93,32 @@ static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \
|
||||
optype t; \
|
||||
FP_ENTER(); \
|
||||
fetch_ea_ ## a_size(fetchdat); \
|
||||
SEG_CHECK_READ(cpu_state.ea_seg); \
|
||||
load_var = get(); if (cpu_state.abrt) return 1; \
|
||||
ST(0) = use_var - ST(0); \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64; \
|
||||
CLOCK_CYCLES(8); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
opFPU(s, x87_ts, 16, t.i, geteal, t.s)
|
||||
#ifndef FPU_8087
|
||||
opFPU(s, x87_ts, 32, t.i, geteal, t.s)
|
||||
#endif
|
||||
opFPU(d, x87_td, 16, t.i, geteaq, t.d)
|
||||
#ifndef FPU_8087
|
||||
opFPU(d, x87_td, 32, t.i, geteaq, t.d)
|
||||
#endif
|
||||
|
||||
opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t)
|
||||
#ifndef FPU_8087
|
||||
opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t)
|
||||
#endif
|
||||
opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t)
|
||||
#ifndef FPU_8087
|
||||
opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -111,7 +127,6 @@ static int opFADD(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FADD\n");
|
||||
ST(0) = ST(0) + ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
@@ -121,7 +136,6 @@ static int opFADDr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FADD\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
@@ -131,7 +145,6 @@ static int opFADDP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FADDP\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -143,7 +156,6 @@ static int opFCOM(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FCOM\n");
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0;
|
||||
@@ -155,7 +167,6 @@ static int opFCOMP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FCOMP\n");
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
@@ -168,7 +179,6 @@ static int opFCOMPP(uint32_t fetchdat)
|
||||
uint64_t *p, *q;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FCOMPP\n");
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
p = (uint64_t *)&ST(0);
|
||||
q = (uint64_t *)&ST(1);
|
||||
@@ -182,11 +192,11 @@ static int opFCOMPP(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFUCOMPP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FUCOMPP\n", easeg, cpu_state.eaaddr);
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(1));
|
||||
x87_pop();
|
||||
@@ -195,15 +205,15 @@ static int opFUCOMPP(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
|
||||
static int opFCOMI(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FICOM\n");
|
||||
flags_rebuild();
|
||||
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
@@ -211,21 +221,21 @@ static int opFCOMIP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FICOMP\n");
|
||||
flags_rebuild();
|
||||
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int opFDIV(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDIV\n");
|
||||
x87_div(ST(0), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
@@ -235,7 +245,6 @@ static int opFDIVr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDIV\n");
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
@@ -245,7 +254,6 @@ static int opFDIVP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDIVP\n");
|
||||
x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -257,7 +265,6 @@ static int opFDIVR(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDIVR\n");
|
||||
x87_div(ST(0), ST(fetchdat&7), ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
@@ -267,7 +274,6 @@ static int opFDIVRr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDIVR\n");
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(73);
|
||||
@@ -277,7 +283,6 @@ static int opFDIVRP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDIVR\n");
|
||||
x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7));
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -289,7 +294,6 @@ static int opFMUL(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FMUL\n");
|
||||
ST(0) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(16);
|
||||
@@ -299,7 +303,6 @@ static int opFMULr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FMUL\n");
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(16);
|
||||
@@ -309,7 +312,6 @@ static int opFMULP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FMULP\n");
|
||||
ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -321,7 +323,6 @@ static int opFSUB(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSUB\n");
|
||||
ST(0) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
@@ -331,7 +332,6 @@ static int opFSUBr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSUB\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
@@ -341,7 +341,6 @@ static int opFSUBP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSUBP\n");
|
||||
ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -353,7 +352,6 @@ static int opFSUBR(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSUBR\n");
|
||||
ST(0) = ST(fetchdat & 7) - ST(0);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
@@ -363,7 +361,6 @@ static int opFSUBRr(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSUBR\n");
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(8);
|
||||
@@ -373,7 +370,6 @@ static int opFSUBRP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSUBRP\n");
|
||||
ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -381,11 +377,11 @@ static int opFSUBRP(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FPU_8087
|
||||
static int opFUCOM(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FUCOM\n");
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
CLOCK_CYCLES(4);
|
||||
@@ -396,7 +392,6 @@ static int opFUCOMP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FUCOMP\n");
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7));
|
||||
x87_pop();
|
||||
@@ -404,15 +399,15 @@ static int opFUCOMP(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
|
||||
static int opFUCOMI(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FUCOMI\n");
|
||||
flags_rebuild();
|
||||
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
@@ -420,12 +415,13 @@ static int opFUCOMIP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FUCOMIP\n");
|
||||
flags_rebuild();
|
||||
flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) flags |= C_FLAG;
|
||||
cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG);
|
||||
if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG;
|
||||
else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
*
|
||||
* x87 FPU instructions core.
|
||||
*
|
||||
* Version: @(#)x87_ops_loadstore.h 1.0.1 2017/10/17
|
||||
* Version: @(#)x87_ops_loadstore.h 1.0.2 2019/06/11
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2017 Sarah Walker.
|
||||
* Copyright 2016-2017 Miran Grca.
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
|
||||
static int opFILDiw_a16(uint32_t fetchdat)
|
||||
@@ -21,32 +21,32 @@ static int opFILDiw_a16(uint32_t fetchdat)
|
||||
int16_t temp;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", (double)temp);
|
||||
x87_push((double)temp);
|
||||
CLOCK_CYCLES(13);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFILDiw_a32(uint32_t fetchdat)
|
||||
{
|
||||
int16_t temp;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FILDw %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp = geteaw(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", (double)temp);
|
||||
x87_push((double)temp);
|
||||
CLOCK_CYCLES(13);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTiw_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 32767 || temp64 < -32768)
|
||||
fatal("FISTw overflow %i\n", temp64);*/
|
||||
@@ -54,12 +54,13 @@ static int opFISTiw_a16(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(29);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTiw_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 32767 || temp64 < -32768)
|
||||
fatal("FISTw overflow %i\n", temp64);*/
|
||||
@@ -67,13 +68,14 @@ static int opFISTiw_a32(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(29);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTPiw_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 32767 || temp64 < -32768)
|
||||
fatal("FISTw overflow %i\n", temp64);*/
|
||||
@@ -82,12 +84,13 @@ static int opFISTPiw_a16(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(29);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTPiw_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FISTw %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 32767 || temp64 < -32768)
|
||||
fatal("FISTw overflow %i\n", temp64);*/
|
||||
@@ -96,15 +99,15 @@ static int opFISTPiw_a32(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(29);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFILDiq_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp64 = geteaq(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4));
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP].q = temp64;
|
||||
cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
@@ -112,14 +115,14 @@ static int opFILDiq_a16(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFILDiq_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FILDl %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
temp64 = geteaq(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f %08X %08X\n", (double)temp64, readmeml(easeg,cpu_state.eaaddr), readmeml(easeg,cpu_state.eaaddr+4));
|
||||
x87_push((double)temp64);
|
||||
cpu_state.MM[cpu_state.TOP].q = temp64;
|
||||
cpu_state.tag[cpu_state.TOP] |= TAG_UINT64;
|
||||
@@ -127,6 +130,7 @@ static int opFILDiq_a32(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(10);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int FBSTP_a16(uint32_t fetchdat)
|
||||
{
|
||||
@@ -134,7 +138,7 @@ static int FBSTP_a16(uint32_t fetchdat)
|
||||
int c;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
tempd = ST(0);
|
||||
if (tempd < 0.0)
|
||||
tempd = -tempd;
|
||||
@@ -154,13 +158,14 @@ static int FBSTP_a16(uint32_t fetchdat)
|
||||
x87_pop();
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int FBSTP_a32(uint32_t fetchdat)
|
||||
{
|
||||
double tempd;
|
||||
int c;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FBSTP %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
tempd = ST(0);
|
||||
if (tempd < 0.0)
|
||||
tempd = -tempd;
|
||||
@@ -180,13 +185,14 @@ static int FBSTP_a32(uint32_t fetchdat)
|
||||
x87_pop();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int FISTPiq_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)
|
||||
temp64 = cpu_state.MM[cpu_state.TOP].q;
|
||||
else
|
||||
@@ -196,12 +202,13 @@ static int FISTPiq_a16(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(29);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int FISTPiq_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FISTPl %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
if (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)
|
||||
temp64 = cpu_state.MM[cpu_state.TOP].q;
|
||||
else
|
||||
@@ -211,38 +218,39 @@ static int FISTPiq_a32(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(29);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFILDil_a16(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f %08X %i\n", (double)templ, templ, templ);
|
||||
x87_push((double)templ);
|
||||
CLOCK_CYCLES(9);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFILDil_a32(uint32_t fetchdat)
|
||||
{
|
||||
int32_t templ;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FILDs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
templ = geteal(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f %08X %i\n", (double)templ, templ, templ);
|
||||
x87_push((double)templ);
|
||||
CLOCK_CYCLES(9);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTil_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 2147483647 || temp64 < -2147483647)
|
||||
fatal("FISTl out of range! %i\n", temp64);*/
|
||||
@@ -250,12 +258,13 @@ static int opFISTil_a16(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(28);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTil_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 2147483647 || temp64 < -2147483647)
|
||||
fatal("FISTl out of range! %i\n", temp64);*/
|
||||
@@ -263,13 +272,14 @@ static int opFISTil_a32(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(28);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFISTPil_a16(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 2147483647 || temp64 < -2147483647)
|
||||
fatal("FISTl out of range! %i\n", temp64);*/
|
||||
@@ -278,12 +288,13 @@ static int opFISTPil_a16(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(28);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFISTPil_a32(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FISTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
temp64 = x87_fround(ST(0));
|
||||
/* if (temp64 > 2147483647 || temp64 < -2147483647)
|
||||
fatal("FISTl out of range! %i\n", temp64);*/
|
||||
@@ -292,197 +303,208 @@ static int opFISTPil_a32(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(28);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFLDe_a16(uint32_t fetchdat)
|
||||
{
|
||||
double t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t=x87_ld80(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", t);
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES(6);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDe_a32(uint32_t fetchdat)
|
||||
{
|
||||
double t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FLDe %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t=x87_ld80(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", t);
|
||||
x87_push(t);
|
||||
CLOCK_CYCLES(6);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTPe_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(6);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTPe_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FSTPe %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
x87_st80(ST(0)); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(6);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFLDd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", t.d);
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FLDd %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
t.i = geteaq(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", t.d);
|
||||
x87_push(t.d);
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES(8);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i);
|
||||
CLOCK_CYCLES(8);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTPd_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTPd_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_td t;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7);
|
||||
fpu_log("FSTd %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
t.d = ST(0);
|
||||
seteaq(t.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFLDs_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", ts.s);
|
||||
x87_push((double)ts.s);
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDs_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FLDs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
ts.i = geteal(); if (cpu_state.abrt) return 1;
|
||||
fpu_log(" %f\n", ts.s);
|
||||
x87_push((double)ts.s);
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTs_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES(7);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTs_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i);
|
||||
CLOCK_CYCLES(7);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTPs_a16(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(7);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTPs_a32(uint32_t fetchdat)
|
||||
{
|
||||
x87_ts ts;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FSTs %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
ts.s = (float)ST(0);
|
||||
seteal(ts.i); if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(7);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
#ifdef FPU_8087
|
||||
static int opFI(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
cpu_state.npxc &= ~0x80;
|
||||
if (rmdat == 0xe1)
|
||||
cpu_state.npxc |= 0x80;
|
||||
wait(3, 0);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int opFSTSW_AX(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSTSW\n");
|
||||
AX = cpu_state.npxs;
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -32,7 +44,11 @@ static int opFINIT(uint32_t fetchdat)
|
||||
uint64_t *p;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
#ifdef FPU_8087
|
||||
cpu_state.npxc = 0x3FF;
|
||||
#else
|
||||
cpu_state.npxc = 0x37F;
|
||||
#endif
|
||||
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
|
||||
cpu_state.npxs = 0;
|
||||
p = (uint64_t *)cpu_state.tag;
|
||||
@@ -40,6 +56,7 @@ static int opFINIT(uint32_t fetchdat)
|
||||
cpu_state.TOP = 0;
|
||||
cpu_state.ismmx = 0;
|
||||
CLOCK_CYCLES(17);
|
||||
CPU_BLOCK_END();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -48,7 +65,6 @@ static int opFFREE(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FFREE\n");
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3;
|
||||
CLOCK_CYCLES(3);
|
||||
return 0;
|
||||
@@ -58,7 +74,6 @@ static int opFFREEP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FFREE\n");
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1;
|
||||
x87_pop();
|
||||
CLOCK_CYCLES(3);
|
||||
@@ -69,7 +84,6 @@ static int opFST(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FST\n");
|
||||
ST(fetchdat & 7) = ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
|
||||
CLOCK_CYCLES(3);
|
||||
@@ -80,7 +94,6 @@ static int opFSTP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSTP\n");
|
||||
ST(fetchdat & 7) = ST(0);
|
||||
cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7];
|
||||
x87_pop();
|
||||
@@ -135,30 +148,32 @@ static int FSTOR()
|
||||
cpu_state.ismmx = 1;
|
||||
|
||||
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
|
||||
fpu_log("FRSTOR %08X:%08X %i %i %04X\n", easeg, cpu_state.eaaddr, cpu_state.ismmx, cpu_state.TOP, x87_gettag());
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
static int opFSTOR_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
FSTOR();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTOR_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
FSTOR();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int FSAVE()
|
||||
{
|
||||
uint64_t *p;
|
||||
|
||||
FP_ENTER();
|
||||
fpu_log("FSAVE %08X:%08X %i\n", easeg, cpu_state.eaaddr, cpu_state.ismmx);
|
||||
cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11);
|
||||
|
||||
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
|
||||
@@ -305,35 +320,41 @@ static int opFSAVE_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
FSAVE();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSAVE_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
FSAVE();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTSW_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11));
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTSW_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FSTSW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw((cpu_state.npxs & 0xC7FF) | (cpu_state.TOP << 11));
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int opFLD(uint32_t fetchdat)
|
||||
@@ -343,7 +364,6 @@ static int opFLD(uint32_t fetchdat)
|
||||
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLD %f\n", ST(fetchdat & 7));
|
||||
old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7];
|
||||
old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q;
|
||||
x87_push(ST(fetchdat&7));
|
||||
@@ -360,7 +380,6 @@ static int opFXCH(uint32_t fetchdat)
|
||||
uint64_t old_i64;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FXCH\n");
|
||||
td = ST(0);
|
||||
ST(0) = ST(fetchdat&7);
|
||||
ST(fetchdat&7) = td;
|
||||
@@ -379,7 +398,6 @@ static int opFCHS(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FCHS\n");
|
||||
ST(0) = -ST(0);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(6);
|
||||
@@ -390,7 +408,6 @@ static int opFABS(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FABS %f\n", ST(0));
|
||||
ST(0) = fabs(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(3);
|
||||
@@ -401,7 +418,6 @@ static int opFTST(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FTST\n");
|
||||
cpu_state.npxs &= ~(C0|C2|C3);
|
||||
if (ST(0) == 0.0) cpu_state.npxs |= C3;
|
||||
else if (ST(0) < 0.0) cpu_state.npxs |= C0;
|
||||
@@ -413,9 +429,8 @@ static int opFXAM(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FXAM %i %f\n", cpu_state.tag[cpu_state.TOP&7], ST(0));
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
|
||||
if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3);
|
||||
else if (ST(0) == 0.0) cpu_state.npxs |= C3;
|
||||
else cpu_state.npxs |= C2;
|
||||
if (ST(0) < 0.0) cpu_state.npxs |= C1;
|
||||
@@ -427,7 +442,6 @@ static int opFLD1(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLD1\n");
|
||||
x87_push(1.0);
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
@@ -437,7 +451,6 @@ static int opFLDL2T(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLDL2T\n");
|
||||
x87_push(3.3219280948873623);
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
@@ -447,7 +460,6 @@ static int opFLDL2E(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLDL2E\n");
|
||||
x87_push(1.4426950408889634);
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
@@ -457,7 +469,6 @@ static int opFLDPI(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLDPI\n");
|
||||
x87_push(3.141592653589793);
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
@@ -467,7 +478,6 @@ static int opFLDEG2(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLDEG2\n");
|
||||
x87_push(0.3010299956639812);
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
@@ -477,7 +487,6 @@ static int opFLDLN2(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLDLN2\n");
|
||||
x87_push_u64(0x3fe62e42fefa39f0ull);
|
||||
CLOCK_CYCLES(8);
|
||||
return 0;
|
||||
@@ -487,7 +496,6 @@ static int opFLDZ(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FLDZ\n");
|
||||
x87_push(0.0);
|
||||
cpu_state.tag[cpu_state.TOP&7] = 1;
|
||||
CLOCK_CYCLES(4);
|
||||
@@ -498,7 +506,6 @@ static int opF2XM1(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("F2XM1\n");
|
||||
ST(0) = pow(2.0, ST(0)) - 1.0;
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(200);
|
||||
@@ -509,7 +516,6 @@ static int opFYL2X(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FYL2X\n");
|
||||
ST(1) = ST(1) * (log(ST(0)) / log(2.0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -521,7 +527,6 @@ static int opFYL2XP1(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FYL2XP1\n");
|
||||
ST(1) = ST(1) * (log1p(ST(0)) / log(2.0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -533,7 +538,6 @@ static int opFPTAN(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FPTAN\n");
|
||||
ST(0) = tan(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
x87_push(1.0);
|
||||
@@ -546,7 +550,6 @@ static int opFPATAN(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FPATAN\n");
|
||||
ST(1) = atan2(ST(1), ST(0));
|
||||
cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64;
|
||||
x87_pop();
|
||||
@@ -558,7 +561,6 @@ static int opFDECSTP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDECSTP\n");
|
||||
cpu_state.TOP = (cpu_state.TOP - 1) & 7;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
@@ -568,7 +570,6 @@ static int opFINCSTP(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FDECSTP\n");
|
||||
cpu_state.TOP = (cpu_state.TOP + 1) & 7;
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
@@ -579,11 +580,9 @@ static int opFPREM(uint32_t fetchdat)
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FPREM %f %f ", ST(0), ST(1));
|
||||
temp64 = (int64_t)(ST(0) / ST(1));
|
||||
ST(0) = ST(0) - (ST(1) * (double)temp64);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
fpu_log("%f\n", ST(0));
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
@@ -591,16 +590,15 @@ static int opFPREM(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(100);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFPREM1(uint32_t fetchdat)
|
||||
{
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FPREM1 %f %f ", ST(0), ST(1));
|
||||
temp64 = (int64_t)(ST(0) / ST(1));
|
||||
ST(0) = ST(0) - (ST(1) * (double)temp64);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
fpu_log("%f\n", ST(0));
|
||||
cpu_state.npxs &= ~(C0|C1|C2|C3);
|
||||
if (temp64 & 4) cpu_state.npxs|=C0;
|
||||
if (temp64 & 2) cpu_state.npxs|=C3;
|
||||
@@ -608,24 +606,24 @@ static int opFPREM1(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(100);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSQRT(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSQRT\n");
|
||||
ST(0) = sqrt(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
CLOCK_CYCLES(83);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FPU_8087
|
||||
static int opFSINCOS(uint32_t fetchdat)
|
||||
{
|
||||
double td;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSINCOS\n");
|
||||
td = ST(0);
|
||||
ST(0) = sin(td);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
@@ -634,15 +632,14 @@ static int opFSINCOS(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(330);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFRNDINT(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FRNDINT %g ", ST(0));
|
||||
ST(0) = (double)x87_fround(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
fpu_log("%g\n", ST(0));
|
||||
CLOCK_CYCLES(21);
|
||||
return 0;
|
||||
}
|
||||
@@ -652,7 +649,6 @@ static int opFSCALE(uint32_t fetchdat)
|
||||
int64_t temp64;
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSCALE\n");
|
||||
temp64 = (int64_t)ST(1);
|
||||
ST(0) = ST(0) * pow(2.0, (double)temp64);
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
@@ -660,11 +656,11 @@ static int opFSCALE(uint32_t fetchdat)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef FPU_8087
|
||||
static int opFSIN(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FSIN\n");
|
||||
ST(0) = sin(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.npxs &= ~C2;
|
||||
@@ -676,19 +672,18 @@ static int opFCOS(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.pc++;
|
||||
fpu_log("FCOS\n");
|
||||
ST(0) = cos(ST(0));
|
||||
cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64;
|
||||
cpu_state.npxs &= ~C2;
|
||||
CLOCK_CYCLES(300);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int FLDENV()
|
||||
{
|
||||
FP_ENTER();
|
||||
fpu_log("FLDENV %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
@@ -716,23 +711,27 @@ static int opFLDENV_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
FLDENV();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDENV_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
FLDENV();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFLDCW_a16(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.npxc = tempw;
|
||||
@@ -740,12 +739,13 @@ static int opFLDCW_a16(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFLDCW_a32(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t tempw;
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FLDCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_READ(cpu_state.ea_seg);
|
||||
tempw = geteaw();
|
||||
if (cpu_state.abrt) return 1;
|
||||
cpu_state.npxc = tempw;
|
||||
@@ -753,11 +753,11 @@ static int opFLDCW_a32(uint32_t fetchdat)
|
||||
CLOCK_CYCLES(4);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int FSTENV()
|
||||
{
|
||||
FP_ENTER();
|
||||
fpu_log("FSTENV %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
@@ -802,42 +802,49 @@ static int opFSTENV_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
FSTENV();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTENV_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
FSTENV();
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int opFSTCW_a16(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_16(fetchdat);
|
||||
fpu_log("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(cpu_state.npxc);
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#ifndef FPU_8087
|
||||
static int opFSTCW_a32(uint32_t fetchdat)
|
||||
{
|
||||
FP_ENTER();
|
||||
fetch_ea_32(fetchdat);
|
||||
fpu_log("FSTCW %08X:%08X\n", easeg, cpu_state.eaaddr);
|
||||
SEG_CHECK_WRITE(cpu_state.ea_seg);
|
||||
seteaw(cpu_state.npxc);
|
||||
CLOCK_CYCLES(3);
|
||||
return cpu_state.abrt;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef FPU_8087
|
||||
#if defined(DEV_BRANCH) && (defined(USE_CYRIX_6X86) || defined(USE_I686))
|
||||
#define opFCMOV(condition) \
|
||||
static int opFCMOV ## condition(uint32_t fetchdat) \
|
||||
{ \
|
||||
FP_ENTER(); \
|
||||
cpu_state.pc++; \
|
||||
fpu_log("FCMOV %f\n", ST(fetchdat & 7)); \
|
||||
if (cond_ ## condition) \
|
||||
{ \
|
||||
cpu_state.tag[cpu_state.TOP] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \
|
||||
@@ -859,3 +866,5 @@ opFCMOV(NB)
|
||||
opFCMOV(NE)
|
||||
opFCMOV(NBE)
|
||||
opFCMOV(NU)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
303
src/cpu_new/386.c
Normal file
303
src/cpu_new/386.c
Normal file
@@ -0,0 +1,303 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
#endif
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "cpu.h"
|
||||
#include "../timer.h"
|
||||
#include "x86.h"
|
||||
#include "x87.h"
|
||||
#include "../nmi.h"
|
||||
#include "../mem.h"
|
||||
#include "../pic.h"
|
||||
#include "../pit.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "386_common.h"
|
||||
#include "codegen.h"
|
||||
|
||||
|
||||
#ifdef ENABLE_386_LOG
|
||||
int x386_do_log = ENABLE_386_LOG;
|
||||
|
||||
|
||||
void
|
||||
x386_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (x386_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define x386_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#undef CPU_BLOCK_END
|
||||
#define CPU_BLOCK_END()
|
||||
|
||||
|
||||
extern int codegen_flags_changed;
|
||||
|
||||
int tempc, oldcpl, optype, inttype, oddeven = 0;
|
||||
int timetolive;
|
||||
|
||||
uint16_t oldcs;
|
||||
|
||||
uint32_t oldds, oldss, olddslimit, oldsslimit,
|
||||
olddslimitw, oldsslimitw;
|
||||
uint32_t oxpc;
|
||||
uint32_t rmdat32;
|
||||
uint32_t backupregs[16];
|
||||
|
||||
x86seg _oldds;
|
||||
|
||||
|
||||
static __inline void
|
||||
fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
uint8_t sib;
|
||||
uint32_t addr;
|
||||
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
if (cpu_rm == 4) {
|
||||
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;
|
||||
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;
|
||||
cpu_state.ea_seg = &cpu_state.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;
|
||||
cpu_state.ea_seg = &cpu_state.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) {
|
||||
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)
|
||||
{
|
||||
uint32_t addr;
|
||||
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
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;
|
||||
cpu_state.ea_seg = &cpu_state.seg_ss;
|
||||
}
|
||||
cpu_state.eaaddr &= 0xFFFF;
|
||||
}
|
||||
|
||||
if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#include "x86_flags.h"
|
||||
|
||||
#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++
|
||||
#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2
|
||||
#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++
|
||||
#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2
|
||||
|
||||
|
||||
#define OP_TABLE(name) ops_ ## name
|
||||
|
||||
#define CLOCK_CYCLES(c) cycles -= (c)
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
#include "x86_ops.h"
|
||||
|
||||
|
||||
void
|
||||
exec386(int cycs)
|
||||
{
|
||||
uint8_t opcode;
|
||||
int vector, tempi, cycdiff, oldcyc;
|
||||
int cycle_period, ins_cycles;
|
||||
uint32_t addr;
|
||||
|
||||
cycles += cycs;
|
||||
|
||||
while (cycles > 0) {
|
||||
cycle_period = (timer_target - (uint32_t)tsc) + 1;
|
||||
|
||||
x86_was_reset = 0;
|
||||
cycdiff = 0;
|
||||
oldcyc = cycles;
|
||||
while (cycdiff < cycle_period) {
|
||||
ins_cycles = cycles;
|
||||
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt) {
|
||||
opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
|
||||
if (cpu_state.abrt) {
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
if (cpu_state.abrt) {
|
||||
cpu_state.abrt = 0;
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x386_log("Double fault %i\n", ins);
|
||||
pmodeint(8, 0);
|
||||
if (cpu_state.abrt) {
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
#ifdef ENABLE_386_LOG
|
||||
x386_log("Triple fault - reset\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ins_cycles -= cycles;
|
||||
tsc += ins_cycles;
|
||||
|
||||
cycdiff = oldcyc - cycles;
|
||||
|
||||
if (trap) {
|
||||
flags_rebuild();
|
||||
if (msw&1)
|
||||
pmodeint(1,0);
|
||||
else {
|
||||
writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags);
|
||||
writememw(ss, (SP - 4) & 0xFFFF, CS);
|
||||
writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc);
|
||||
SP -= 6;
|
||||
addr = (1 << 2) + idt.base;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
}
|
||||
} else if (nmi && nmi_enable && nmi_mask) {
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
if (nmi_auto_clear) {
|
||||
nmi_auto_clear = 0;
|
||||
nmi = 0;
|
||||
}
|
||||
} else if ((cpu_state.flags & I_FLAG) && pic_intpending) {
|
||||
vector = picinterrupt();
|
||||
if (vector != 0xFF) {
|
||||
flags_rebuild();
|
||||
if (msw & 1)
|
||||
pmodeint(vector, 0);
|
||||
else {
|
||||
writememw(ss, (SP - 2) & 0xFFFF, cpu_state.flags);
|
||||
writememw(ss, (SP - 4) & 0xFFFF, CS);
|
||||
writememw(ss, (SP - 6) & 0xFFFF, cpu_state.pc);
|
||||
SP -= 6;
|
||||
addr = (vector << 2) + idt.base;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = readmemw(0, addr);
|
||||
loadcs(readmemw(0, addr + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ins++;
|
||||
|
||||
if (timetolive) {
|
||||
timetolive--;
|
||||
if (!timetolive)
|
||||
fatal("Life expired\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc))
|
||||
timer_process();
|
||||
}
|
||||
}
|
||||
292
src/cpu_new/386_common.c
Normal file
292
src/cpu_new/386_common.c
Normal file
@@ -0,0 +1,292 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
#endif
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "cpu.h"
|
||||
#include "../timer.h"
|
||||
#include "x86.h"
|
||||
#include "x87.h"
|
||||
#include "../nmi.h"
|
||||
#include "../mem.h"
|
||||
#include "../pic.h"
|
||||
#include "../pit.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#include "386_common.h"
|
||||
#include "x86_flags.h"
|
||||
#include "codegen.h"
|
||||
|
||||
x86seg gdt, ldt, idt, tr;
|
||||
|
||||
uint32_t cr2, cr3, cr4;
|
||||
uint32_t dr[8];
|
||||
|
||||
uint32_t use32;
|
||||
int stack32;
|
||||
int optype;
|
||||
|
||||
int trap;
|
||||
|
||||
uint32_t rmdat;
|
||||
|
||||
uint32_t *eal_r, *eal_w;
|
||||
|
||||
int nmi_enable = 1;
|
||||
|
||||
int cpl_override=0;
|
||||
|
||||
int fpucount=0;
|
||||
|
||||
uint16_t cpu_cur_status = 0;
|
||||
|
||||
uint32_t pccache;
|
||||
uint8_t *pccache2;
|
||||
|
||||
|
||||
#ifdef ENABLE_386_COMMON_LOG
|
||||
int x386_common_do_log = ENABLE_386_COMMON_LOG;
|
||||
|
||||
|
||||
void
|
||||
x386_common_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (x386_common_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define x386_common_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void x86_int(int num)
|
||||
{
|
||||
uint32_t addr;
|
||||
flags_rebuild();
|
||||
cpu_state.pc=cpu_state.oldpc;
|
||||
if (msw&1)
|
||||
{
|
||||
pmodeint(num,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
if ((num << 2) + 3 > idt.limit)
|
||||
{
|
||||
if (idt.limit < 35)
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
#ifdef ENABLE_386_COMMON_LOG
|
||||
x386_log("Triple fault in real mode - reset\n");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
x86_int(8);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,cpu_state.flags);
|
||||
writememw(ss,ESP-4,CS);
|
||||
writememw(ss,ESP-6,cpu_state.pc);
|
||||
ESP-=6;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
|
||||
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
|
||||
SP-=6;
|
||||
}
|
||||
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
}
|
||||
cycles-=70;
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
void x86_int_sw(int num)
|
||||
{
|
||||
uint32_t addr;
|
||||
flags_rebuild();
|
||||
cycles -= timing_int;
|
||||
if (msw&1)
|
||||
{
|
||||
pmodeint(num,1);
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = (num << 2) + idt.base;
|
||||
|
||||
if ((num << 2) + 3 > idt.limit)
|
||||
{
|
||||
x86_int(13);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stack32)
|
||||
{
|
||||
writememw(ss,ESP-2,cpu_state.flags);
|
||||
writememw(ss,ESP-4,CS);
|
||||
writememw(ss,ESP-6,cpu_state.pc);
|
||||
ESP-=6;
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
|
||||
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
|
||||
SP-=6;
|
||||
}
|
||||
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
cycles -= timing_int_rm;
|
||||
}
|
||||
}
|
||||
trap = 0;
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
int x86_int_sw_rm(int num)
|
||||
{
|
||||
uint32_t addr;
|
||||
uint16_t new_pc, new_cs;
|
||||
|
||||
flags_rebuild();
|
||||
cycles -= timing_int;
|
||||
|
||||
addr = num << 2;
|
||||
new_pc = readmemw(0, addr);
|
||||
new_cs = readmemw(0, addr + 2);
|
||||
|
||||
if (cpu_state.abrt) return 1;
|
||||
|
||||
writememw(ss,((SP-2)&0xFFFF),cpu_state.flags);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
writememw(ss,((SP-4)&0xFFFF),CS);
|
||||
writememw(ss,((SP-6)&0xFFFF),cpu_state.pc);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
SP-=6;
|
||||
|
||||
cpu_state.eflags &= ~VIF_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc = new_pc;
|
||||
loadcs(new_cs);
|
||||
|
||||
cycles -= timing_int_rm;
|
||||
trap = 0;
|
||||
CPU_BLOCK_END();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void x86illegal()
|
||||
{
|
||||
x86_int(6);
|
||||
}
|
||||
|
||||
int checkio(int port)
|
||||
{
|
||||
uint16_t t;
|
||||
uint8_t d;
|
||||
cpl_override = 1;
|
||||
t = readmemw(tr.base, 0x66);
|
||||
cpl_override = 0;
|
||||
if (cpu_state.abrt) return 0;
|
||||
if ((t+(port>>3))>tr.limit) return 1;
|
||||
cpl_override = 1;
|
||||
d = readmembl(tr.base + t + (port >> 3));
|
||||
cpl_override = 0;
|
||||
return d&(1<<(port&7));
|
||||
}
|
||||
|
||||
#define divexcp() { \
|
||||
x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \
|
||||
x86_int(0); \
|
||||
}
|
||||
|
||||
int divl(uint32_t val)
|
||||
{
|
||||
uint64_t num, quo;
|
||||
uint32_t rem, quo32;
|
||||
|
||||
if (val==0)
|
||||
{
|
||||
divexcp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
num=(((uint64_t)EDX)<<32)|EAX;
|
||||
quo=num/val;
|
||||
rem=num%val;
|
||||
quo32=(uint32_t)(quo&0xFFFFFFFF);
|
||||
|
||||
if (quo!=(uint64_t)quo32)
|
||||
{
|
||||
divexcp();
|
||||
return 1;
|
||||
}
|
||||
EDX=rem;
|
||||
EAX=quo32;
|
||||
return 0;
|
||||
}
|
||||
int idivl(int32_t val)
|
||||
{
|
||||
int64_t num, quo;
|
||||
int32_t rem, quo32;
|
||||
|
||||
if (val==0)
|
||||
{
|
||||
divexcp();
|
||||
return 1;
|
||||
}
|
||||
|
||||
num=(((uint64_t)EDX)<<32)|EAX;
|
||||
quo=num/val;
|
||||
rem=num%val;
|
||||
quo32=(int32_t)(quo&0xFFFFFFFF);
|
||||
|
||||
if (quo!=(int64_t)quo32)
|
||||
{
|
||||
divexcp();
|
||||
return 1;
|
||||
}
|
||||
EDX=rem;
|
||||
EAX=quo32;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void cpu_386_flags_extract()
|
||||
{
|
||||
flags_extract();
|
||||
}
|
||||
void cpu_386_flags_rebuild()
|
||||
{
|
||||
flags_rebuild();
|
||||
}
|
||||
317
src/cpu_new/386_common.h
Normal file
317
src/cpu_new/386_common.h
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* Common 386 CPU code.
|
||||
*
|
||||
* Version: @(#)386_common.h 1.0.1 2019/02/19
|
||||
*
|
||||
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Copyright 2008-2019 Sarah Walker.
|
||||
* Copyright 2016-2019 Miran Grca.
|
||||
*/
|
||||
|
||||
#ifndef _386_COMMON_H_
|
||||
#define _386_COMMON_H_
|
||||
|
||||
#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) )
|
||||
#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
|
||||
#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
|
||||
#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
|
||||
|
||||
#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
|
||||
#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
|
||||
#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
|
||||
#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
|
||||
|
||||
int checkio(int port);
|
||||
|
||||
#define check_io_perm(port) if (!IOPLp || (cpu_state.eflags&VM_FLAG)) \
|
||||
{ \
|
||||
int tempi = checkio(port); \
|
||||
if (cpu_state.abrt) return 1; \
|
||||
if (tempi) \
|
||||
{ \
|
||||
x86gpf(NULL,0); \
|
||||
return 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SEG_CHECK_READ(seg) \
|
||||
do \
|
||||
{ \
|
||||
if ((seg)->base == 0xffffffff) \
|
||||
{ \
|
||||
x86gpf("Segment can't read", 0);\
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SEG_CHECK_WRITE(seg) \
|
||||
do \
|
||||
{ \
|
||||
if ((seg)->base == 0xffffffff) \
|
||||
{ \
|
||||
x86gpf("Segment can't write", 0);\
|
||||
return 1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_READ(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \
|
||||
{ \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 0); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 0); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CHECK_READ_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check (READ)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Read from seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 0); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 0); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \
|
||||
{ \
|
||||
x86gpf("Limit check (WRITE)", 0); \
|
||||
return 1; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write to seg not present", (chseg)->seg & 0xfffc); \
|
||||
return 1; \
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 1); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 1); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
#define CHECK_WRITE_REP(chseg, low, high) \
|
||||
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
|
||||
{ \
|
||||
x86gpf("Limit check (WRITE REP)", 0); \
|
||||
break; \
|
||||
} \
|
||||
if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \
|
||||
{ \
|
||||
if ((chseg) == &cpu_state.seg_ss) \
|
||||
x86ss(NULL,(chseg)->seg & 0xfffc); \
|
||||
else \
|
||||
x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \
|
||||
break; \
|
||||
} \
|
||||
if (cr0 >> 31) { \
|
||||
(void) mmutranslatereal((chseg)->base + low, 1); \
|
||||
(void) mmutranslatereal((chseg)->base + high, 1); \
|
||||
if (cpu_state.abrt) \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\
|
||||
{ \
|
||||
x86_int(6); \
|
||||
return 1; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static inline uint8_t fastreadb(uint32_t a)
|
||||
{
|
||||
uint8_t *t;
|
||||
|
||||
if ((a >> 12) == pccache)
|
||||
return *((uint8_t *)&pccache2[a]);
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
return *((uint8_t *)&pccache2[a]);
|
||||
}
|
||||
|
||||
static inline uint16_t fastreadw(uint32_t a)
|
||||
{
|
||||
uint8_t *t;
|
||||
uint16_t val;
|
||||
if ((a&0xFFF)>0xFFE)
|
||||
{
|
||||
val = fastreadb(a);
|
||||
val |= (fastreadb(a + 1) << 8);
|
||||
return val;
|
||||
}
|
||||
if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]);
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
|
||||
pccache = a >> 12;
|
||||
pccache2 = t;
|
||||
return *((uint16_t *)&pccache2[a]);
|
||||
}
|
||||
|
||||
static inline uint32_t fastreadl(uint32_t a)
|
||||
{
|
||||
uint8_t *t;
|
||||
uint32_t val;
|
||||
if ((a&0xFFF)<0xFFD)
|
||||
{
|
||||
if ((a>>12)!=pccache)
|
||||
{
|
||||
t = getpccache(a);
|
||||
if (cpu_state.abrt)
|
||||
return 0;
|
||||
pccache2 = t;
|
||||
pccache=a>>12;
|
||||
}
|
||||
return *((uint32_t *)&pccache2[a]);
|
||||
}
|
||||
val = fastreadw(a);
|
||||
val |= (fastreadw(a + 2) << 16);
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline void *get_ram_ptr(uint32_t a)
|
||||
{
|
||||
if ((a >> 12) == pccache)
|
||||
return &pccache2[a];
|
||||
else
|
||||
{
|
||||
uint8_t *t = getpccache(a);
|
||||
return &t[a];
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t getbyte()
|
||||
{
|
||||
cpu_state.pc++;
|
||||
return fastreadb(cs + (cpu_state.pc - 1));
|
||||
}
|
||||
|
||||
static inline uint16_t getword()
|
||||
{
|
||||
cpu_state.pc+=2;
|
||||
return fastreadw(cs+(cpu_state.pc-2));
|
||||
}
|
||||
|
||||
static inline uint32_t getlong()
|
||||
{
|
||||
cpu_state.pc+=4;
|
||||
return fastreadl(cs+(cpu_state.pc-4));
|
||||
}
|
||||
|
||||
static inline uint64_t getquad()
|
||||
{
|
||||
cpu_state.pc+=8;
|
||||
return fastreadl(cs+(cpu_state.pc-8)) | ((uint64_t)fastreadl(cs+(cpu_state.pc-4)) << 32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline uint8_t geteab()
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l;
|
||||
if (eal_r)
|
||||
return *(uint8_t *)eal_r;
|
||||
return readmemb(easeg,cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static inline uint16_t geteaw()
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].w;
|
||||
if (eal_r)
|
||||
return *(uint16_t *)eal_r;
|
||||
return readmemw(easeg,cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static inline uint32_t geteal()
|
||||
{
|
||||
if (cpu_mod == 3)
|
||||
return cpu_state.regs[cpu_rm].l;
|
||||
if (eal_r)
|
||||
return *eal_r;
|
||||
return readmeml(easeg,cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static inline uint64_t geteaq()
|
||||
{
|
||||
return readmemq(easeg,cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static inline uint8_t geteab_mem()
|
||||
{
|
||||
if (eal_r) return *(uint8_t *)eal_r;
|
||||
return readmemb(easeg,cpu_state.eaaddr);
|
||||
}
|
||||
static inline uint16_t geteaw_mem()
|
||||
{
|
||||
if (eal_r) return *(uint16_t *)eal_r;
|
||||
return readmemw(easeg,cpu_state.eaaddr);
|
||||
}
|
||||
static inline uint32_t geteal_mem()
|
||||
{
|
||||
if (eal_r) return *eal_r;
|
||||
return readmeml(easeg,cpu_state.eaaddr);
|
||||
}
|
||||
|
||||
static inline void seteaq(uint64_t v)
|
||||
{
|
||||
writememql(easeg+cpu_state.eaaddr, v);
|
||||
}
|
||||
|
||||
#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v
|
||||
#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v
|
||||
#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v
|
||||
|
||||
#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v);
|
||||
#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v);
|
||||
#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v);
|
||||
|
||||
#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++
|
||||
#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2
|
||||
#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++
|
||||
#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2
|
||||
|
||||
#endif
|
||||
661
src/cpu_new/386_dynarec.c
Normal file
661
src/cpu_new/386_dynarec.c
Normal file
@@ -0,0 +1,661 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
#endif
|
||||
#define HAVE_STDARG_H
|
||||
#include "../86box.h"
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../nmi.h"
|
||||
#include "../pic.h"
|
||||
#include "../timer.h"
|
||||
#include "../floppy/fdd.h"
|
||||
#include "../floppy/fdc.h"
|
||||
#ifdef USE_DYNAREC
|
||||
#include "codegen.h"
|
||||
#include "codegen_backend.h"
|
||||
#endif
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG;
|
||||
|
||||
|
||||
void
|
||||
x386_dynarec_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (x386_dynarec_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define x386_dynarec_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
int inrecomp = 0;
|
||||
int cpu_recomp_blocks, cpu_recomp_full_ins, cpu_new_blocks;
|
||||
int cpu_recomp_blocks_latched, cpu_recomp_ins_latched, cpu_recomp_full_ins_latched, cpu_new_blocks_latched;
|
||||
|
||||
int cpu_block_end = 0;
|
||||
|
||||
|
||||
static __inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
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;
|
||||
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;
|
||||
cpu_state.ea_seg = &cpu_state.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;
|
||||
cpu_state.ea_seg = &cpu_state.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);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
static __inline void fetch_ea_16_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
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;
|
||||
cpu_state.ea_seg = &cpu_state.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);
|
||||
}
|
||||
cpu_state.last_ea = cpu_state.eaaddr;
|
||||
}
|
||||
|
||||
#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 1; }
|
||||
#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 1
|
||||
|
||||
#include "x86_flags.h"
|
||||
|
||||
|
||||
/*Prefetch emulation is a fairly simplistic model:
|
||||
- All instruction bytes must be fetched before it starts.
|
||||
- Cycles used for non-instruction memory accesses are counted and subtracted
|
||||
from the total cycles taken
|
||||
- Any remaining cycles are used to refill the prefetch queue.
|
||||
|
||||
Note that this is only used for 286 / 386 systems. It is disabled when the
|
||||
internal cache on 486+ CPUs is enabled.
|
||||
*/
|
||||
static int prefetch_bytes = 0;
|
||||
static int prefetch_prefixes = 0;
|
||||
|
||||
static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32)
|
||||
{
|
||||
int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l;
|
||||
|
||||
if (instr_cycles < mem_cycles)
|
||||
instr_cycles = mem_cycles;
|
||||
|
||||
prefetch_bytes -= prefetch_prefixes;
|
||||
prefetch_bytes -= bytes;
|
||||
if (modrm != -1)
|
||||
{
|
||||
if (ea32)
|
||||
{
|
||||
if ((modrm & 7) == 4)
|
||||
{
|
||||
if ((modrm & 0x700) == 0x500)
|
||||
prefetch_bytes -= 5;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x05)
|
||||
prefetch_bytes -= 4;
|
||||
else if ((modrm & 0xc0) == 0x40)
|
||||
prefetch_bytes--;
|
||||
else if ((modrm & 0xc0) == 0x80)
|
||||
prefetch_bytes -= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((modrm & 0xc7) == 0x06)
|
||||
prefetch_bytes -= 2;
|
||||
else if ((modrm & 0xc0) != 0xc0)
|
||||
prefetch_bytes -= ((modrm & 0xc0) >> 6);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill up prefetch queue */
|
||||
while (prefetch_bytes < 0)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
/* Subtract cycles used for memory access by instruction */
|
||||
instr_cycles -= mem_cycles;
|
||||
|
||||
while (instr_cycles >= cpu_prefetch_cycles)
|
||||
{
|
||||
prefetch_bytes += cpu_prefetch_width;
|
||||
instr_cycles -= cpu_prefetch_cycles;
|
||||
}
|
||||
|
||||
prefetch_prefixes = 0;
|
||||
if (prefetch_bytes > 16)
|
||||
prefetch_bytes = 16;
|
||||
}
|
||||
|
||||
static void prefetch_flush()
|
||||
{
|
||||
prefetch_bytes = 0;
|
||||
}
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \
|
||||
do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0)
|
||||
|
||||
#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0)
|
||||
#define PREFETCH_FLUSH() prefetch_flush()
|
||||
|
||||
|
||||
#define OP_TABLE(name) ops_ ## name
|
||||
#define CLOCK_CYCLES(c) cycles -= (c)
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
#include "386_ops.h"
|
||||
|
||||
|
||||
#define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG))
|
||||
|
||||
#ifdef USE_DYNAREC
|
||||
static int cycles_main = 0;
|
||||
|
||||
|
||||
void exec386_dynarec(int cycs)
|
||||
{
|
||||
int vector;
|
||||
uint32_t addr;
|
||||
int tempi;
|
||||
int cycdiff;
|
||||
int oldcyc;
|
||||
int cyc_period = cycs / 2000; /*5us*/
|
||||
|
||||
cycles_main += cycs;
|
||||
while (cycles_main > 0)
|
||||
{
|
||||
int cycles_start;
|
||||
|
||||
cycles += cyc_period;
|
||||
cycles_start = cycles;
|
||||
|
||||
while (cycles>0)
|
||||
{
|
||||
oldcyc=cycles;
|
||||
if (!CACHE_ON()) /*Interpret block*/
|
||||
{
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
uint8_t opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
}
|
||||
|
||||
if (((cs + cpu_state.pc) >> 12) != pccache)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
CPU_BLOCK_END();
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
ins++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t phys_addr = get_phys(cs+cpu_state.pc);
|
||||
int hash = HASH(phys_addr);
|
||||
codeblock_t *block = &codeblock[codeblock_hash[hash]];
|
||||
int valid_block = 0;
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
page_t *page = &pages[phys_addr >> 12];
|
||||
|
||||
/*Block must match current CS, PC, code segment size,
|
||||
and physical address. The physical address check will
|
||||
also catch any page faults at this stage*/
|
||||
valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) &&
|
||||
(block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
|
||||
if (!valid_block)
|
||||
{
|
||||
uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
|
||||
int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK;
|
||||
uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f);
|
||||
|
||||
if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask))
|
||||
{
|
||||
/*Walk page tree to see if we find the correct block*/
|
||||
codeblock_t *new_block = codeblock_tree_find(phys_addr, cs);
|
||||
if (new_block)
|
||||
{
|
||||
valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) &&
|
||||
(new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) &&
|
||||
((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK));
|
||||
if (valid_block)
|
||||
{
|
||||
block = new_block;
|
||||
codeblock_hash[hash] = get_block_nr(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_block && (block->page_mask & *block->dirty_mask))
|
||||
{
|
||||
codegen_check_flush(page, page->dirty_mask, phys_addr);
|
||||
if (block->pc == BLOCK_PC_INVALID)
|
||||
valid_block = 0;
|
||||
else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
|
||||
block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
|
||||
}
|
||||
if (valid_block && block->page_mask2)
|
||||
{
|
||||
/*We don't want the second page to cause a page
|
||||
fault at this stage - that would break any
|
||||
code crossing a page boundary where the first
|
||||
page is present but the second isn't. Instead
|
||||
allow the first page to be interpreted and for
|
||||
the page fault to occur when the page boundary
|
||||
is actually crossed.*/
|
||||
uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400));
|
||||
page_t *page_2 = &pages[phys_addr_2 >> 12];
|
||||
if ((block->phys_2 ^ phys_addr_2) & ~0xfff)
|
||||
valid_block = 0;
|
||||
else if (block->page_mask2 & *block->dirty_mask2)
|
||||
{
|
||||
codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2);
|
||||
if (block->pc == BLOCK_PC_INVALID)
|
||||
valid_block = 0;
|
||||
else if (block->flags & CODEBLOCK_IN_DIRTY_LIST)
|
||||
block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
|
||||
}
|
||||
}
|
||||
if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST))
|
||||
{
|
||||
block->flags &= ~CODEBLOCK_WAS_RECOMPILED;
|
||||
if (block->flags & CODEBLOCK_BYTE_MASK)
|
||||
block->flags |= CODEBLOCK_NO_IMMEDIATES;
|
||||
else
|
||||
block->flags |= CODEBLOCK_BYTE_MASK;
|
||||
}
|
||||
if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7))
|
||||
{
|
||||
/*FPU top-of-stack does not match the value this block was compiled
|
||||
with, re-compile using dynamic top-of-stack*/
|
||||
block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED);
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED))
|
||||
{
|
||||
void (*code)() = (void *)&block->data[BLOCK_START];
|
||||
|
||||
inrecomp=1;
|
||||
code();
|
||||
inrecomp=0;
|
||||
|
||||
cpu_recomp_blocks++;
|
||||
}
|
||||
else if (valid_block && !cpu_state.abrt)
|
||||
{
|
||||
uint32_t start_pc = cs+cpu_state.pc;
|
||||
const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
cpu_new_blocks++;
|
||||
|
||||
codegen_block_start_recompile(block);
|
||||
codegen_in_recompile = 1;
|
||||
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
uint8_t opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
|
||||
codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
|
||||
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
|
||||
/*Cap source code at 4000 bytes per block; this
|
||||
will prevent any block from spanning more than
|
||||
2 pages. In practice this limit will never be
|
||||
hit, as host block size is only 2kB*/
|
||||
if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
codegen_block_end_recompile(block);
|
||||
|
||||
if (x86_was_reset)
|
||||
codegen_reset();
|
||||
|
||||
codegen_in_recompile = 0;
|
||||
}
|
||||
else if (!cpu_state.abrt)
|
||||
{
|
||||
/*Mark block but do not recompile*/
|
||||
uint32_t start_pc = cs+cpu_state.pc;
|
||||
const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000;
|
||||
|
||||
cpu_block_end = 0;
|
||||
x86_was_reset = 0;
|
||||
|
||||
codegen_block_init(phys_addr);
|
||||
|
||||
while (!cpu_block_end)
|
||||
{
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
cpu_state.op32 = use32;
|
||||
|
||||
cpu_state.ea_seg = &cpu_state.seg_ds;
|
||||
cpu_state.ssegs = 0;
|
||||
|
||||
codegen_endpc = (cs + cpu_state.pc) + 8;
|
||||
fetchdat = fastreadl(cs + cpu_state.pc);
|
||||
|
||||
if (!cpu_state.abrt)
|
||||
{
|
||||
uint8_t opcode = fetchdat & 0xFF;
|
||||
fetchdat >>= 8;
|
||||
|
||||
trap = cpu_state.flags & T_FLAG;
|
||||
|
||||
cpu_state.pc++;
|
||||
|
||||
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
|
||||
|
||||
if (x86_was_reset)
|
||||
break;
|
||||
}
|
||||
|
||||
/*Cap source code at 4000 bytes per block; this
|
||||
will prevent any block from spanning more than
|
||||
2 pages. In practice this limit will never be
|
||||
hit, as host block size is only 2kB*/
|
||||
if (((cs+cpu_state.pc) - start_pc) >= max_block_size)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (trap)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
CPU_BLOCK_END();
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
codegen_block_remove();
|
||||
CPU_BLOCK_END();
|
||||
}
|
||||
|
||||
ins++;
|
||||
}
|
||||
|
||||
if (!cpu_state.abrt && !x86_was_reset)
|
||||
codegen_block_end();
|
||||
|
||||
if (x86_was_reset)
|
||||
codegen_reset();
|
||||
}
|
||||
else
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
|
||||
}
|
||||
|
||||
cycdiff=oldcyc-cycles;
|
||||
tsc += cycdiff;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
flags_rebuild();
|
||||
tempi = cpu_state.abrt;
|
||||
cpu_state.abrt = 0;
|
||||
x86_doabrt(tempi);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
cpu_state.pc = cpu_state.oldpc;
|
||||
x386_dynarec_log("Double fault %i\n", ins);
|
||||
pmodeint(8, 0);
|
||||
if (cpu_state.abrt)
|
||||
{
|
||||
cpu_state.abrt = 0;
|
||||
softresetx86();
|
||||
cpu_set_edx();
|
||||
#ifdef ENABLE_386_DYNAREC_LOG
|
||||
x386_dynarec_log("Triple fault - reset\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trap)
|
||||
{
|
||||
trap = 0;
|
||||
flags_rebuild();
|
||||
if (msw&1)
|
||||
{
|
||||
pmodeint(1,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
|
||||
writememw(ss,(SP-4)&0xFFFF,CS);
|
||||
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
|
||||
SP-=6;
|
||||
addr = (1 << 2) + idt.base;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
}
|
||||
else if (nmi && nmi_enable && nmi_mask)
|
||||
{
|
||||
cpu_state.oldpc = cpu_state.pc;
|
||||
x86_int(2);
|
||||
nmi_enable = 0;
|
||||
if (nmi_auto_clear)
|
||||
{
|
||||
nmi_auto_clear = 0;
|
||||
nmi = 0;
|
||||
}
|
||||
}
|
||||
else if ((cpu_state.flags & I_FLAG) && pic_intpending)
|
||||
{
|
||||
vector = picinterrupt();
|
||||
if (vector != -1)
|
||||
{
|
||||
CPU_BLOCK_END();
|
||||
flags_rebuild();
|
||||
if (msw&1)
|
||||
{
|
||||
pmodeint(vector,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
writememw(ss,(SP-2)&0xFFFF,cpu_state.flags);
|
||||
writememw(ss,(SP-4)&0xFFFF,CS);
|
||||
writememw(ss,(SP-6)&0xFFFF,cpu_state.pc);
|
||||
SP-=6;
|
||||
addr=vector<<2;
|
||||
cpu_state.flags &= ~I_FLAG;
|
||||
cpu_state.flags &= ~T_FLAG;
|
||||
cpu_state.pc=readmemw(0,addr);
|
||||
loadcs(readmemw(0,addr+2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc))
|
||||
timer_process();
|
||||
cycles_main -= (cycles_start - cycles);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
68
src/cpu_new/386_dynarec_ops.c
Normal file
68
src/cpu_new/386_dynarec_ops.c
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#ifndef INFINITY
|
||||
# define INFINITY (__builtin_inff())
|
||||
#endif
|
||||
#include "../86box.h"
|
||||
#include "cpu.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x87.h"
|
||||
#include "x86_flags.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../nmi.h"
|
||||
#include "../pic.h"
|
||||
#include "codegen.h"
|
||||
|
||||
#define CPU_BLOCK_END() cpu_block_end = 1
|
||||
|
||||
#include "386_common.h"
|
||||
|
||||
|
||||
static inline void fetch_ea_32_long(uint32_t rmdat)
|
||||
{
|
||||
eal_r = eal_w = NULL;
|
||||
easeg = cpu_state.ea_seg->base;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat);
|
||||
#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat);
|
||||
|
||||
|
||||
#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32)
|
||||
#define PREFETCH_PREFIX()
|
||||
#define PREFETCH_FLUSH()
|
||||
|
||||
#define OP_TABLE(name) dynarec_ops_ ## name
|
||||
/*Temporary*/
|
||||
#define CLOCK_CYCLES(c)
|
||||
#define CLOCK_CYCLES_ALWAYS(c) cycles -= (c)
|
||||
|
||||
#include "386_ops.h"
|
||||
1822
src/cpu_new/386_ops.h
Normal file
1822
src/cpu_new/386_ops.h
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user