Merge remote-tracking branch 'refs/remotes/OBattler/master'

This commit is contained in:
basic2004
2017-07-12 16:29:11 +09:00
795 changed files with 81624 additions and 39635 deletions

View File

@@ -1,4 +1,4 @@
# 86Box [![Build Status](http://polar.rol.im/job/86Box/badge/icon)](http://polar.rol.im/job/86Box)
# 86Box [![Build Status](http://dome.rol.im/job/86Box/badge/icon)](http://dome.rol.im/job/86Box)
86Box (formerly PCem Unofficial, PCem Experimental, or PCem-X) is an unofficial branch of the PCem emulator, which aims to emulate IBM compatible machines from 1981-2000 period. This branch adds several emulated motherboards.
---

View File

@@ -1,4 +1,42 @@
/* Copyright holders: Tenshi
see COPYING for more details
*/
#define emulator_version "1.00"
/*
* 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.
*
* Main emulator include file.
*
* Version: @(#)86box.h 1.0.2 2017/06/04
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2017 Miran Grca.
*/
#ifndef BOX_H
# define BOX_H
#if defined(ENABLE_BUSLOGIC_LOG) || \
defined(ENABLE_CDROM_LOG) || \
defined(ENABLE_D86F_LOG) || \
defined(ENABLE_FDC_LOG) || \
defined(ENABLE_IDE_LOG) || \
defined(ENABLE_NIC_LOG)
# define ENABLE_LOG_TOGGLES 1
#endif
#if defined(ENABLE_LOG_BREAKPOINT) || defined(ENABLE_VRAM_DUMP)
# define ENABLE_LOG_COMMANDS 1
#endif
#define EMU_VERSION "2.00"
#define EMU_VERSION_W L"2.00"
#define EMU_NAME "86Box"
#define EMU_NAME_W L"86Box"
#define CONFIG_FILE_W L"86box.cfg"
#endif /*BOX_H*/

View File

@@ -1,55 +0,0 @@
cmake_minimum_required(VERSION 2.8.8)
project(86box)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeModules)
set(SRCS
386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c acerm3a.c aha154x.c ali1429.c amstrad.c cdrom-ioctl.c cdrom-iso.c
cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c dac.c
device.c disc.c disc_86f.c disc_fdi.c disc_imd.c disc_img.c disc_random.c disc_td0.c dma.c fdc.c fdc37c665.c fdc37c932fr.c fdd.c fdi2raw.c gameport.c headland.c i430hx.c i430lx.c i430fx.c
i430nx.c i430vx.c i440fx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c
keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c lpt.c mcr.c mem.c memregs.c model.c mouse.c mouse_amstrad.c mouse_ps2.c
mouse_serial.c ne2000.c neat.c nethandler.c nmi.c nvr.c olivetti_m24.c opti.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c rtc.c
scat.c scattergather.c scsi.c scsi_cdrom.c serial.c sis496.c sis85c471.c sio.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c
sound_dbopl.cc sound_emu8k.c sound_gus.c sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_resid.cc
sound_sb.c sound_sb_dsp.c sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c
soundopenal.c tandy_eeprom.c tandy_rom.c timer.c um8669f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c
vid_ati28800.c vid_ati68860_ramdac.c vid_bt485_ramdac.c vid_cga.c vid_cl_gd.c vid_cl_gd_blit.c vid_cl_ramdac.c vid_colorplus.c vid_ega.c vid_et4000.c
vid_et4000w32.c vid_hercules.c vid_herculesplus.c vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_nv_riva128.c
vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc1512.c vid_pc1640.c vid_pc200.c
vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c
vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c
vid_vga.c vid_voodoo.c video.c wd76c10.c win.c win-config.c win-d3d.cc win-d3d-fs.cc win-ddraw.cc
win-ddraw-fs.cc win-ddraw-screenshot.cc win-deviceconfig.c win-hdconf.c win-joystick.cc win-joystickconfig.c win-keyboard.cc win-midi.c win-mouse.cc
win-status.c win-video.c x86seg.c x87.c xtide.c pc.rc
dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c
lzf/lzf_c.c lzf/lzf_d.c
resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc resid-fp/voice.cc resid-fp/wave6581__ST.cc resid-fp/wave6581_P_T.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc resid-fp/wave8580__ST.cc resid-fp/wave8580_P_T.cc resid-fp/wave8580_PS_.cc resid-fp/wave8580_PST.cc resid-fp/wave.cc
slirp/bootp.c slirp/ip_icmp.c slirp/misc.c slirp/socket.c slirp/tcp_timer.c slirp/cksum.c slirp/ip_input.c slirp/queue.c slirp/tcp_input.c slirp/tftp.c slirp/debug.c slirp/ip_output.c slirp/sbuf.c slirp/tcp_output.c slirp/udp.c slirp/if.c slirp/mbuf.c slirp/slirp.c slirp/tcp_subr.c
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_ARCH_64 1)
else()
set(_ARCH_32 1)
endif()
include(FindOpenAL REQUIRED)
include(FindDirectInput REQUIRED)
include(FindDirectDraw REQUIRED)
if(_ARCH_32)
set(SRCS ${SRCS}
codegen_x86.c
)
else()
set(SRCS ${SRCS}
codegen_x86-64.c
)
endif()
add_definitions(-msse2 -mstackrealign -mwindows)
add_executable(86box ${SRCS})
target_link_libraries(86box winmm openal.dll openal ddraw dinput8 dxguid d3d9 d3dx9 wsock32 iphlpapi stdc++)

View File

@@ -1,53 +0,0 @@
# Locate directdraw
# This module defines
# D3D9_LIBRARIES
# D3D9_FOUND, if false, do not try to link to directinput
# D3D9_INCLUDE_DIR, where to find the headers
#
# $D3D9_DIR is an environment variable that would
# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow)
#
# Created by Cedric Pinson.
#
SET( D3D9_FOUND FALSE )
IF( WIN32 )
FIND_PATH( D3D9_ROOT_DIR Include/D3D9.h
PATHS
$ENV{PATH}
$ENV{PROGRAMFILES}
)
FIND_PATH( D3D9_INCLUDE_DIR d3d9.h
PATHS
${D3D9_ROOT_DIR}/Include
)
FIND_LIBRARY( D3D9_LIBRARY d3d9.lib d3dx9
PATHS
${D3D9_ROOT_DIR}/lib/x86
)
FIND_LIBRARY( D3D9_GUID_LIBRARY dxguid.lib
PATHS
${D3D9_ROOT_DIR}/lib/x86
)
FIND_LIBRARY( D3D9_ERR_LIBRARY dxerr.lib
PATHS
${D3D9_ROOT_DIR}/lib/x86
)
SET( D3D9_LIBRARIES
${D3D9_LIBRARY}
${D3D9_GUID_LIBRARY}
${D3D9_ERR_LIBRARY}
)
IF ( D3D9_INCLUDE_DIR AND D3D9_LIBRARIES )
SET( D3D9_FOUND TRUE )
ENDIF ( D3D9_INCLUDE_DIR AND D3D9_LIBRARIES )
ENDIF( WIN32 )
MARK_AS_ADVANCED( D3D9_FOUND )

View File

@@ -1,53 +0,0 @@
# Locate directdraw
# This module defines
# DDRAW_LIBRARIES
# DDRAW_FOUND, if false, do not try to link to directinput
# DDRAW_INCLUDE_DIR, where to find the headers
#
# $DDRAW_DIR is an environment variable that would
# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow)
#
# Created by Cedric Pinson.
#
SET( DDRAW_FOUND FALSE )
IF( WIN32 )
FIND_PATH( DDRAW_ROOT_DIR Include/D3D10.h
PATHS
$ENV{PATH}
$ENV{PROGRAMFILES}
)
FIND_PATH( DDRAW_INCLUDE_DIR ddraw.h
PATHS
${DDRAW_ROOT_DIR}/Include
)
FIND_LIBRARY( DDRAW_LIBRARY ddraw.lib
PATHS
${DDRAW_ROOT_DIR}/lib/x86
)
FIND_LIBRARY( DDRAW_GUID_LIBRARY dxguid.lib
PATHS
${DDRAW_ROOT_DIR}/lib/x86
)
FIND_LIBRARY( DDRAW_ERR_LIBRARY dxerr.lib
PATHS
${DDRAW_ROOT_DIR}/lib/x86
)
SET( DDRAW_LIBRARIES
${DDRAW_LIBRARY}
${DDRAW_GUID_LIBRARY}
${DDRAW_ERR_LIBRARY}
)
IF ( DDRAW_INCLUDE_DIR AND DDRAW_LIBRARIES )
SET( DDRAW_FOUND TRUE )
ENDIF ( DDRAW_INCLUDE_DIR AND DDRAW_LIBRARIES )
ENDIF( WIN32 )
MARK_AS_ADVANCED( DDRAW_FOUND )

View File

@@ -1,53 +0,0 @@
# Locate directinput
# This module defines
# DIRECTINPUT_LIBRARIES
# DIRECTINPUT_FOUND, if false, do not try to link to directinput
# DIRECTINPUT_INCLUDE_DIR, where to find the headers
#
# $DIRECTINPUT_DIR is an environment variable that would
# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow)
#
# Created by Cedric Pinson.
#
SET( DIRECTINPUT_FOUND FALSE )
IF( WIN32 )
FIND_PATH( DIRECTINPUT_ROOT_DIR Include/D3D10.h
PATHS
$ENV{PATH}
$ENV{PROGRAMFILES}
)
FIND_PATH( DIRECTINPUT_INCLUDE_DIR dinput.h
PATHS
${DIRECTINPUT_ROOT_DIR}/Include
)
FIND_LIBRARY( DIRECTINPUT_LIBRARY dinput7.lib dinput8.lib
PATHS
${DIRECTINPUT_ROOT_DIR}/lib/x86
)
FIND_LIBRARY( DIRECTINPUT_GUID_LIBRARY dxguid.lib
PATHS
${DIRECTINPUT_ROOT_DIR}/lib/x86
)
FIND_LIBRARY( DIRECTINPUT_ERR_LIBRARY dxerr.lib
PATHS
${DIRECTINPUT_ROOT_DIR}/lib/x86
)
SET( DIRECTINPUT_LIBRARIES
${DIRECTINPUT_LIBRARY}
${DIRECTINPUT_GUID_LIBRARY}
${DIRECTINPUT_ERR_LIBRARY}
)
IF ( DIRECTINPUT_INCLUDE_DIR AND DIRECTINPUT_LIBRARIES )
SET( DIRECTINPUT_FOUND TRUE )
ENDIF ( DIRECTINPUT_INCLUDE_DIR AND DIRECTINPUT_LIBRARIES )
ENDIF( WIN32 )
MARK_AS_ADVANCED( DIRECTINPUT_FOUND )

View File

@@ -1,14 +1,19 @@
#include <math.h>
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "ibm.h"
#include "../ibm.h"
#include "cpu.h"
#include "x86.h"
#include "x87.h"
#include "mem.h"
#include "cpu.h"
#include "disc.h"
#include "fdc.h"
#include "timer.h"
#include "../mem.h"
#include "../disc.h"
#include "../fdc.h"
#include "../pic.h"
#include "../timer.h"
#include "386_common.h"
@@ -23,6 +28,13 @@ uint32_t oldpc2;
int trap;
uint16_t flags,eflags;
uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw;
x86seg gdt,ldt,idt,tr;
x86seg _cs,_ds,_es,_ss,_fs,_gs;
x86seg _oldds;
extern int cpl_override;
@@ -35,6 +47,8 @@ uint16_t ea_rseg;
int is486;
int cgate32;
uint32_t cr2, cr3, cr4;
uint32_t dr[8];
uint8_t romext[32768];
@@ -56,7 +70,7 @@ uint32_t *eal_r, *eal_w;
uint16_t *mod1add[2][8];
uint32_t *mod1seg[8];
static inline void fetch_ea_32_long(uint32_t rmdat)
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
@@ -74,7 +88,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
case 1:
cpu_state.pc++;
cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
// pc++;
/* pc++; */
break;
case 2:
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
@@ -129,7 +143,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
}
}
static inline void fetch_ea_16_long(uint32_t rmdat)
static __inline void fetch_ea_16_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
@@ -215,22 +229,23 @@ void exec386(int cycs)
int tempi;
int cycdiff;
int oldcyc;
int cycle_period = cycs / 2000; /*Use a 5us timing granularity*/
cycles+=cycs;
// output=3;
/* output=3; */
while (cycles>0)
{
cycdiff=0;
oldcyc=cycles;
timer_start_period(cycles << TIMER_SHIFT);
// pclog("%i %02X\n", ins, ram[8]);
while (cycdiff<100)
/* pclog("%i %02X\n", ins, ram[8]); */
while (cycdiff < cycle_period)
{
/* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX;
testr[4]=ESI; testr[5]=EDI; testr[6]=EBP; testr[7]=ESP;*/
/* testr[8]=flags;*/
// oldcs2=oldcs;
// oldpc2=oldpc;
/* oldcs2=oldcs; */
/* oldpc2=oldpc; */
oldcs=CS;
cpu_state.oldpc = cpu_state.pc;
oldcpl=CPL;
@@ -262,8 +277,8 @@ dontprint=0;
if (cpu_state.abrt)
{
flags_rebuild();
// pclog("Abort\n");
// if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,cpu_state.abrt);
/* pclog("Abort\n"); */
/* if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,cpu_state.abrt); */
/* if (testr[0]!=EAX) pclog("EAX corrupted %08X\n",pc);
if (testr[1]!=EBX) pclog("EBX corrupted %08X\n",pc);
if (testr[2]!=ECX) pclog("ECX corrupted %08X\n",pc);
@@ -297,8 +312,8 @@ dontprint=0;
if (trap)
{
flags_rebuild();
// oldpc=pc;
// oldcs=CS;
/* oldpc=pc; */
/* oldcs=CS; */
if (msw&1)
{
pmodeint(1,0);
@@ -320,19 +335,24 @@ dontprint=0;
{
cpu_state.oldpc = cpu_state.pc;
oldcs = CS;
// pclog("NMI\n");
/* pclog("NMI\n"); */
x86_int(2);
nmi_enable = 0;
if (nmi_auto_clear)
{
nmi_auto_clear = 0;
nmi = 0;
}
}
else if ((flags&I_FLAG) && pic_intpending)
{
temp=picinterrupt();
if (temp!=0xFF)
{
// if (temp == 0x54) pclog("Take int 54\n");
// if (output) output=3;
// if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc);
// if (temp==0x54) output=3;
/* if (temp == 0x54) pclog("Take int 54\n"); */
/* if (output) output=3; */
/* if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc); */
/* if (temp==0x54) output=3; */
flags_rebuild();
if (msw&1)
{
@@ -350,9 +370,9 @@ dontprint=0;
oxpc=cpu_state.pc;
cpu_state.pc=readmemw(0,addr);
loadcs(readmemw(0,addr+2));
// if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc);
/* if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc); */
}
// pclog("Now at %04X(%08X):%08X\n", CS, cs, pc);
/* pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); */
}
}

View File

@@ -1,6 +1,21 @@
/* Copyright holders: Sarah Walker, Tenshi
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Common 386 CPU code.
*
* Version: @(#)386_common.h 1.0.0 2017/05/30
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
*/
extern uint16_t ea_rseg;
#undef readmemb
@@ -8,39 +23,15 @@ extern uint16_t ea_rseg;
#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) )
#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8)?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a))))
#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((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 || (s)==0xFFFFFFFF) writememb386l(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)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) 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)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) 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)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8) writememql(s,a,v); else *(uint64_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)==0xFFFFFFFF || (((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)==0xFFFFFFFF || (((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)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v
#if 0
#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \
{ \
int tempi = checkio(port); \
if (cpu_state.abrt) return 1; \
if (tempi) \
{ \
x86gpf("check_io_perm(): no permission",0); \
return 1; \
} \
}
#define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \
{ \
tempi = checkio(port); \
if (cpu_state.abrt) break; \
if (tempi) \
{ \
x86gpf("checkio_perm(): no permission",0); \
break; \
} \
}
#endif
#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \
{ \
int tempi = checkio(port); \
@@ -64,7 +55,7 @@ extern uint16_t ea_rseg;
}
#define CHECK_READ(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \
{ \
x86gpf("Limit check", 0); \
return 1; \
@@ -79,7 +70,7 @@ extern uint16_t ea_rseg;
}
#define CHECK_WRITE(chseg, low, high) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2)) \
if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(eflags & VM_FLAG) && ((chseg)->access & 8))) \
{ \
x86gpf("Limit check", 0); \
return 1; \
@@ -118,7 +109,7 @@ extern uint16_t ea_rseg;
static inline uint8_t fastreadb(uint32_t a)
static __inline uint8_t fastreadb(uint32_t a)
{
uint8_t *t;
@@ -126,33 +117,33 @@ static inline uint8_t fastreadb(uint32_t a)
return *((uint8_t *)&pccache2[a]);
t = getpccache(a);
if (cpu_state.abrt)
return;
return 0xFF;
pccache = a >> 12;
pccache2 = t;
return *((uint8_t *)&pccache2[a]);
}
static inline uint16_t fastreadw(uint32_t a)
static __inline uint16_t fastreadw(uint32_t a)
{
uint8_t *t;
uint16_t val;
if ((a&0xFFF)>0xFFE)
{
val = readmemb(0, a);
val |= (readmemb(0, a + 1) << 8);
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;
return 0xff;
pccache = a >> 12;
pccache2 = t;
return *((uint16_t *)&pccache2[a]);
}
static inline uint32_t fastreadl(uint32_t a)
static __inline uint32_t fastreadl(uint32_t a)
{
uint8_t *t;
uint32_t val;
@@ -165,36 +156,34 @@ static inline uint32_t fastreadl(uint32_t a)
return 0;
pccache2 = t;
pccache=a>>12;
//return *((uint32_t *)&pccache2[a]);
/* return *((uint32_t *)&pccache2[a]); */
}
return *((uint32_t *)&pccache2[a]);
}
val =readmemb(0,a);
val |=(readmemb(0,a+1)<<8);
val |=(readmemb(0,a+2)<<16);
val |=(readmemb(0,a+3)<<24);
val = fastreadw(a);
val |= (fastreadw(a + 2) << 16);
return val;
}
static inline uint8_t getbyte()
static __inline uint8_t getbyte()
{
cpu_state.pc++;
return fastreadb(cs + (cpu_state.pc - 1));
}
static inline uint16_t getword()
static __inline uint16_t getword()
{
cpu_state.pc+=2;
return fastreadw(cs+(cpu_state.pc-2));
}
static inline uint32_t getlong()
static __inline uint32_t getlong()
{
cpu_state.pc+=4;
return fastreadl(cs+(cpu_state.pc-4));
}
static inline uint64_t getquad()
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);
@@ -202,7 +191,7 @@ static inline uint64_t getquad()
static inline uint8_t geteab()
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;
@@ -211,48 +200,48 @@ static inline uint8_t geteab()
return readmemb(easeg, cpu_state.eaaddr);
}
static inline uint16_t geteaw()
static __inline uint16_t geteaw()
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].w;
// cycles-=3;
/* cycles-=3; */
if (eal_r)
return *(uint16_t *)eal_r;
return readmemw(easeg, cpu_state.eaaddr);
}
static inline uint32_t geteal()
static __inline uint32_t geteal()
{
if (cpu_mod == 3)
return cpu_state.regs[cpu_rm].l;
// cycles-=3;
/* cycles-=3; */
if (eal_r)
return *eal_r;
return readmeml(easeg, cpu_state.eaaddr);
}
static inline uint64_t geteaq()
static __inline uint64_t geteaq()
{
return readmemq(easeg, cpu_state.eaaddr);
}
static inline uint8_t geteab_mem()
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()
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()
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)
static __inline void seteaq(uint64_t v)
{
writememql(easeg, cpu_state.eaaddr, v);
}

View File

@@ -1,21 +1,28 @@
#include <math.h>
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "ibm.h"
#include "../ibm.h"
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
#include "mem.h"
#include "../mem.h"
#include "codegen.h"
#include "cpu.h"
#include "disc.h"
#include "fdc.h"
#include "timer.h"
#include "../disc.h"
#include "../fdc.h"
#include "../pic.h"
#include "../timer.h"
#include "386_common.h"
#define CPU_BLOCK_END() cpu_block_end = 1
uint32_t cpu_cur_status = 0;
int cpu_reps, cpu_reps_latched;
int cpu_notreps, cpu_notreps_latched;
@@ -62,7 +69,7 @@ uint32_t *eal_r, *eal_w;
uint16_t *mod1add[2][8];
uint32_t *mod1seg[8];
static inline void fetch_ea_32_long(uint32_t rmdat)
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
@@ -80,7 +87,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
case 1:
cpu_state.pc++;
cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l;
// cpu_state.pc++;
break;
case 2:
cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l;
@@ -136,7 +142,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
cpu_state.last_ea = cpu_state.eaaddr;
}
static inline void fetch_ea_16_long(uint32_t rmdat)
static __inline void fetch_ea_16_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
@@ -187,7 +193,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat)
void x86_int(int num)
{
uint32_t addr;
// pclog("x86_int %02x %04x:%04x\n", num, CS,pc);
flags_rebuild();
cpu_state.pc=cpu_state.oldpc;
if (msw&1)
@@ -225,8 +230,6 @@ void x86_int(int num)
void x86_int_sw(int num)
{
uint32_t addr;
// pclog("x86_int_sw %02x %04x:%04x\n", num, CS,pc);
// pclog("x86_int\n");
flags_rebuild();
cycles -= timing_int;
if (msw&1)
@@ -264,14 +267,6 @@ void x86_int_sw(int num)
void x86illegal()
{
uint16_t addr;
// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode);
// if (output)
// {
// dumpregs();
// exit(-1);
// }
x86_int(6);
}
@@ -359,14 +354,28 @@ static void prefetch_flush()
#define PREFETCH_FLUSH() prefetch_flush()
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 = readmemb386l(0, tr.base + t + (port >> 3));
cpl_override = 0;
return d&(1<<(port&7));
}
int rep386(int fv)
{
uint8_t temp;
uint32_t c;//=CX;
uint32_t c;
uint8_t temp2;
uint16_t tempw,tempw2,of;
uint32_t ipc = cpu_state.oldpc;//pc-1;
uint32_t oldds;
uint32_t ipc = cpu_state.oldpc;
uint32_t rep32 = cpu_state.op32;
uint32_t templ,templ2;
int tempz;
@@ -384,16 +393,9 @@ int rep386(int fv)
flags_rebuild();
of = flags;
// if (inrecomp) pclog("REP32 %04X %04X ",use32,rep32);
startrep:
temp=opcode2=readmemb(cs,cpu_state.pc); cpu_state.pc++;
// if (firstrepcycle && temp==0xA5) pclog("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI);
// if (inrecomp) pclog("REP %02X %04X\n",temp,ipc);
c=(rep32&0x200)?ECX:CX;
/* if (rep32 && (msw&1))
{
if (temp!=0x67 && temp!=0x66 && (rep32|temp)!=0x1AB && (rep32|temp)!=0x3AB) pclog("32-bit REP %03X %08X %04X:%06X\n",temp|rep32,c,CS,pc);
}*/
switch (temp|rep32)
{
case 0xC3: case 0x1C3: case 0x2C3: case 0x3C3:
@@ -436,7 +438,6 @@ int rep386(int fv)
PREFETCH_PREFIX();
goto startrep;
case 0x6C: case 0x16C: /*REP INSB*/
// cpu_notreps++;
if (c>0)
{
checkio_perm(DX);
@@ -453,7 +454,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x26C: case 0x36C: /*REP INSB*/
// cpu_notreps++;
if (c>0)
{
checkio_perm(DX);
@@ -470,10 +470,8 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x6D: /*REP INSW*/
// cpu_notreps++;
if (c>0)
{
// pclog("REP INSW %04x %04x:%04x %04x\n", DX, ES, DI, CX);
tempw=inw(DX);
writememw(es,DI,tempw);
if (cpu_state.abrt) break;
@@ -487,7 +485,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x16D: /*REP INSL*/
// cpu_notreps++;
if (c>0)
{
templ=inl(DX);
@@ -503,7 +500,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x26D: /*REP INSW*/
// cpu_notreps++;
if (c>0)
{
tempw=inw(DX);
@@ -519,7 +515,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x36D: /*REP INSL*/
// cpu_notreps++;
if (c>0)
{
templ=inl(DX);
@@ -535,7 +530,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x6E: case 0x16E: /*REP OUTSB*/
// cpu_notreps++;
if (c>0)
{
temp2 = readmemb(cpu_state.ea_seg->base, SI);
@@ -552,7 +546,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x26E: case 0x36E: /*REP OUTSB*/
// cpu_notreps++;
if (c>0)
{
temp2 = readmemb(cpu_state.ea_seg->base, ESI);
@@ -569,12 +562,10 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x6F: /*REP OUTSW*/
// cpu_notreps++;
if (c>0)
{
tempw = readmemw(cpu_state.ea_seg->base, SI);
if (cpu_state.abrt) break;
// pclog("OUTSW %04X -> %04X\n",SI,tempw);
outw(DX,tempw);
if (flags&D_FLAG) SI-=2;
else SI+=2;
@@ -586,7 +577,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x16F: /*REP OUTSL*/
// cpu_notreps++;
if (c > 0)
{
templ = readmeml(cpu_state.ea_seg->base, SI);
@@ -602,7 +592,6 @@ int rep386(int fv)
else firstrepcycle = 1;
break;
case 0x26F: /*REP OUTSW*/
// cpu_notreps++;
if (c>0)
{
tempw = readmemw(cpu_state.ea_seg->base, ESI);
@@ -618,7 +607,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x36F: /*REP OUTSL*/
// cpu_notreps++;
if (c > 0)
{
templ = readmeml(cpu_state.ea_seg->base, ESI);
@@ -635,7 +623,6 @@ int rep386(int fv)
break;
case 0x90: case 0x190: /*REP NOP*/
case 0x290: case 0x390:
// cpu_notreps++;
break;
case 0xA4: case 0x1A4: /*REP MOVSB*/
while (c > 0)
@@ -643,7 +630,6 @@ int rep386(int fv)
CHECK_WRITE_REP(&_es, DI, DI);
temp2 = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break;
writememb(es,DI,temp2); if (cpu_state.abrt) break;
// if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2);
if (flags&D_FLAG) { DI--; SI--; }
else { DI++; SI++; }
c--;
@@ -700,7 +686,6 @@ int rep386(int fv)
{
CHECK_WRITE_REP(&_es, DI, DI+3);
templ = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break;
// pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc);
writememl(es,DI,templ); if (cpu_state.abrt) break;
if (flags&D_FLAG) { DI-=4; SI-=4; }
else { DI+=4; SI+=4; }
@@ -721,7 +706,6 @@ int rep386(int fv)
CHECK_WRITE_REP(&_es, EDI, EDI+1);
tempw = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break;
writememw(es,EDI,tempw); if (cpu_state.abrt) break;
// if (output) pclog("Written %04X from %08X to %08X %i %08X %04X %08X %04X\n",tempw,ds+ESI,es+EDI,c,ds,ES,es,ES);
if (flags&D_FLAG) { EDI-=2; ESI-=2; }
else { EDI+=2; ESI+=2; }
c--;
@@ -740,9 +724,7 @@ int rep386(int fv)
{
CHECK_WRITE_REP(&_es, EDI, EDI+3);
templ = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break;
// if ((EDI&0xFFFF0000)==0xA0000) cycles-=12;
writememl(es,EDI,templ); if (cpu_state.abrt) break;
// if (output) pclog("Load %08X from %08X to %08X %04X %08X %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es);
if (flags&D_FLAG) { EDI-=4; ESI-=4; }
else { EDI+=4; ESI+=4; }
c--;
@@ -757,7 +739,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0xA6: case 0x1A6: /*REP CMPSB*/
// cpu_notreps++;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
@@ -776,7 +757,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x2A6: case 0x3A6: /*REP CMPSB*/
// cpu_notreps++;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
@@ -795,14 +775,11 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0xA7: /*REP CMPSW*/
// cpu_notreps++;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
// pclog("CMPSW (%04x:%04x)%05X (%04x:%04x)%05X ", DS,SI, ds+SI, ES,DI, es+DI);
tempw = readmemw(cpu_state.ea_seg->base, SI);
tempw2=readmemw(es,DI);
// pclog("%04X %04X %c%c %c%c\n", tempw, tempw2, tempw & 0xff, tempw >> 8, tempw2 & 0xff, tempw2 >> 8);
if (cpu_state.abrt) { flags=of; break; }
if (flags&D_FLAG) { DI-=2; SI-=2; }
@@ -817,7 +794,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x1A7: /*REP CMPSL*/
// cpu_notreps++;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
@@ -836,7 +812,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x2A7: /*REP CMPSW*/
// cpu_notreps++;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
@@ -855,7 +830,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x3A7: /*REP CMPSL*/
// cpu_notreps++;
tempz = (fv) ? 1 : 0;
if ((c>0) && (fv==tempz))
{
@@ -989,8 +963,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0xAC: case 0x1AC: /*REP LODSB*/
// cpu_notreps++;
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AL = readmemb(cpu_state.ea_seg->base, SI);
@@ -1005,8 +977,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x2AC: case 0x3AC: /*REP LODSB*/
// cpu_notreps++;
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AL = readmemb(cpu_state.ea_seg->base, ESI);
@@ -1021,8 +991,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0xAD: /*REP LODSW*/
// cpu_notreps++;
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AX = readmemw(cpu_state.ea_seg->base, SI);
@@ -1037,8 +1005,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x1AD: /*REP LODSL*/
// cpu_notreps++;
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
EAX = readmeml(cpu_state.ea_seg->base, SI);
@@ -1053,8 +1019,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x2AD: /*REP LODSW*/
// cpu_notreps++;
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
AX = readmemw(cpu_state.ea_seg->base, ESI);
@@ -1069,8 +1033,6 @@ int rep386(int fv)
else firstrepcycle=1;
break;
case 0x3AD: /*REP LODSL*/
// cpu_notreps++;
// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc);
if (c>0)
{
EAX = readmeml(cpu_state.ea_seg->base, ESI);
@@ -1086,8 +1048,6 @@ int rep386(int fv)
break;
case 0xAE: case 0x1AE: /*REP SCASB*/
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
// tempz=(fv)?1:0;
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz))
{
@@ -1110,14 +1070,11 @@ int rep386(int fv)
break;
case 0x2AE: case 0x3AE: /*REP SCASB*/
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc);
// tempz=(fv)?1:0;
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz))
{
temp2=readmemb(es,EDI);
if (cpu_state.abrt) { flags=of; break; }
// if (output) pclog("Compare %02X,%02X\n",temp2,AL);
setsub8(AL,temp2);
tempz = (ZF_SET()) ? 1 : 0;
if (flags&D_FLAG) EDI--;
@@ -1135,7 +1092,6 @@ int rep386(int fv)
break;
case 0xAF: /*REP SCASW*/
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz))
{
@@ -1158,7 +1114,6 @@ int rep386(int fv)
break;
case 0x1AF: /*REP SCASL*/
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz))
{
@@ -1181,7 +1136,6 @@ int rep386(int fv)
break;
case 0x2AF: /*REP SCASW*/
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz))
{
@@ -1204,7 +1158,6 @@ int rep386(int fv)
break;
case 0x3AF: /*REP SCASL*/
cpu_notreps++;
// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc);
tempz = (fv) ? 1 : 0;
while ((c > 0) && (fv == tempz))
{
@@ -1229,7 +1182,6 @@ int rep386(int fv)
default:
cpu_state.pc = ipc+1;
//pclog("Bad REP %02X %i\n", temp, rep32 >> 8);
break;
}
if (rep32&0x200) ECX=c;
@@ -1237,27 +1189,6 @@ int rep386(int fv)
CPU_BLOCK_END();
PREFETCH_RUN(total_cycles, 1, -1, reads, reads_l, writes, writes_l, 0);
return cpu_state.abrt;
//pclog("rep cpu_block_end=%d %p\n", cpu_block_end, (void *)&cpu_block_end);
// if (output) pclog("%03X %03X\n",rep32,use32);
}
int checkio(int port)
{
uint16_t t;
uint8_t d;
cpl_override = 1;
t = readmemw(tr.base, 0x66);
cpl_override = 0;
// pclog("CheckIO 1 %08X %04x %02x\n",tr.base, eflags, _cs.access);
if (cpu_state.abrt) return 0;
// pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3));
if ((t+(port>>3))>tr.limit) return 1;
cpl_override = 1;
d = readmemb386l(0, tr.base + t + (port >> 3));
// d=readmemb(tr.base,t+(port>>3));
cpl_override = 0;
// pclog("%02X %02X\n",d,d&(1<<(port&7)));
return d&(1<<(port&7));
}
int xout=0;
@@ -1276,15 +1207,20 @@ int xout=0;
int divl(uint32_t val)
{
uint64_t num, quo;
uint32_t rem, quo32;
if (val==0)
{
divexcp();
return 1;
}
uint64_t num=(((uint64_t)EDX)<<32)|EAX;
uint64_t quo=num/val;
uint32_t rem=num%val;
uint32_t quo32=(uint32_t)(quo&0xFFFFFFFF);
num=(((uint64_t)EDX)<<32)|EAX;
quo=num/val;
rem=num%val;
quo32=(uint32_t)(quo&0xFFFFFFFF);
if (quo!=(uint64_t)quo32)
{
divexcp();
@@ -1296,15 +1232,20 @@ int divl(uint32_t val)
}
int idivl(int32_t val)
{
int64_t num, quo;
int32_t rem, quo32;
if (val==0)
{
divexcp();
return 1;
}
int64_t num=(((uint64_t)EDX)<<32)|EAX;
int64_t quo=num/val;
int32_t rem=num%val;
int32_t quo32=(int32_t)(quo&0xFFFFFFFF);
num=(((uint64_t)EDX)<<32)|EAX;
quo=num/val;
rem=num%val;
quo32=(int32_t)(quo&0xFFFFFFFF);
if (quo!=(int64_t)quo32)
{
divexcp();
@@ -1338,7 +1279,19 @@ int dontprint=0;
#define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG))
//#define CACHE_ON() 0
static int cpu_cycle_period(void)
{
switch(cpu_pci_speed)
{
case 333333333:
return is_pentium ? 1000 : 1333;
break;
default:
return 1000;
break;
}
}
static int cycles_main = 0;
void exec386_dynarec(int cycs)
@@ -1348,18 +1301,51 @@ void exec386_dynarec(int cycs)
int tempi;
int cycdiff;
int oldcyc;
uint32_t start_pc = 0;
//output = 3;
cycles_main += cycs;
while (cycles_main > 0)
{
int cycles_start;
cycles += 1000;
#if 0
switch(cpu_pci_speed)
{
case 16000000:
cycles += 640;
break;
case 20000000:
cycles += 800;
break;
case 25000000:
default:
cycles += 1000;
break;
case 27500000:
cycles += 1100;
break;
case 30000000:
cycles += 1200;
break;
case 333333333:
cycles += 1333;
break;
case 37500000:
cycles += 1500;
break;
case 40000000:
cycles += 1600;
break;
case 41666667:
cycles += 1666;
break;
}
#endif
cycles += cpu_cycle_period();
cycles_start = cycles;
timer_start_period(cycles << TIMER_SHIFT);
// output=3;
while (cycles>0)
{
oldcs = CS;
@@ -1370,11 +1356,9 @@ void exec386_dynarec(int cycs)
cycdiff=0;
oldcyc=cycles;
// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP);
if (!CACHE_ON()) /*Interpret block*/
{
cpu_block_end = 0;
// if (output) pclog("Interpret block at %04x:%04x %04x %04x %04x %04x %04x %04x %04x\n", CS, pc, AX, BX, CX, DX, SI, DI, SP);
while (!cpu_block_end)
{
oldcs=CS;
@@ -1385,19 +1369,13 @@ void exec386_dynarec(int cycs)
cpu_state.ea_seg = &_ds;
cpu_state.ssegs = 0;
opcodestart:
fetchdat = fastreadl(cs + cpu_state.pc);
// if (!fetchdat)
// fatal("Dead with cache off\n");
if (!cpu_state.abrt)
{
trap = flags & T_FLAG;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
// if (output == 3)
// pclog("int %04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0x8f13f], ram[0x8f13e], ram[0x8f141], ram[0x8f140]);
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
}
@@ -1443,28 +1421,29 @@ void exec386_dynarec(int cycs)
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->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32);
(block->phys == phys_addr) && (block->status == cpu_cur_status);
if (!valid_block)
{
uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK);
if (page->code_present_mask & mask)
if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & 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->use32 == use32) && (new_block->phys == phys_addr) && (new_block->stack32 == stack32);
(new_block->phys == phys_addr) && (new_block->status == cpu_cur_status);
if (valid_block)
block = new_block;
}
}
}
if (valid_block && (block->page_mask & page->dirty_mask))
if (valid_block && (block->page_mask & *block->dirty_mask))
{
codegen_check_flush(page, page->dirty_mask, phys_addr);
page->dirty_mask = 0;
codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr);
page->dirty_mask[(phys_addr >> 10) & 3] = 0;
if (!block->pc)
valid_block = 0;
}
@@ -1477,15 +1456,15 @@ void exec386_dynarec(int cycs)
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->endpc) & ~0xfff;
uint32_t phys_addr_2 = get_phys_noabrt(block->endpc);
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 & page_2->dirty_mask)
else if (block->page_mask2 & *block->dirty_mask2)
{
codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2);
page_2->dirty_mask = 0;
codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2);
page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0;
if (!block->pc)
valid_block = 0;
}
@@ -1504,13 +1483,11 @@ void exec386_dynarec(int cycs)
void (*code)() = (void *)&block->data[BLOCK_START];
codeblock_hash[hash] = block;
// if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, block->page_mask, block->endpc);
inrecomp=1;
code();
inrecomp=0;
if (!use32) cpu_state.pc &= 0xffff;
// cpu_recomp_ins += block->ins;
cpu_recomp_blocks++;
/* ins += codeblock_ins[index];
insc += codeblock_ins[index];*/
@@ -1518,10 +1495,8 @@ inrecomp=0;
}
else if (valid_block && !cpu_state.abrt)
{
uint32_t start_page = cpu_state.pc >> 12;
uint32_t start_pc = cpu_state.pc;
start_pc = cpu_state.pc;
// pclog("Hash %08x %i\n", codeblock_hash_pc[HASH(cs + pc)], codeblock_page_dirty[(cs + pc) >> 12]);
cpu_block_end = 0;
x86_was_reset = 0;
@@ -1530,7 +1505,6 @@ inrecomp=0;
codegen_block_start_recompile(block);
codegen_in_recompile = 1;
// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]);
while (!cpu_block_end)
{
oldcs=CS;
@@ -1541,21 +1515,13 @@ inrecomp=0;
cpu_state.ea_seg = &_ds;
cpu_state.ssegs = 0;
opcodestart_compile:
fetchdat = fastreadl(cs + cpu_state.pc);
// if (fetchdat == 0xffffffff)
// fatal("Dead ffffffff\n");
// if (!fetchdat)
// fatal("Dead\n");
if (!cpu_state.abrt)
{
trap = flags & T_FLAG;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
// if (output == 3)
// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache);
cpu_state.pc++;
codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1);
@@ -1572,7 +1538,7 @@ inrecomp=0;
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 ((cpu_state.pc - start_pc) > 4000)
if ((cpu_state.pc - start_pc) > 1000)
CPU_BLOCK_END();
if (trap)
@@ -1596,23 +1562,17 @@ inrecomp=0;
codegen_reset();
codegen_in_recompile = 0;
// output &= ~2;
}
else if (!cpu_state.abrt)
{
/*Mark block but do not recompile*/
uint32_t start_page = cpu_state.pc >> 12;
uint32_t start_pc = cpu_state.pc;
start_pc = cpu_state.pc;
// pclog("Hash %08x %i\n", codeblock_hash_pc[HASH(cs + pc)], codeblock_page_dirty[(cs + pc) >> 12]);
cpu_block_end = 0;
x86_was_reset = 0;
// cpu_new_blocks++;
codegen_block_init(phys_addr);
// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]);
while (!cpu_block_end)
{
oldcs=CS;
@@ -1632,9 +1592,6 @@ inrecomp=0;
opcode = fetchdat & 0xFF;
fetchdat >>= 8;
// if (output == 3)
// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache);
cpu_state.pc++;
x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat);
@@ -1649,7 +1606,7 @@ inrecomp=0;
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 ((cpu_state.pc - start_pc) > 4000)
if ((cpu_state.pc - start_pc) > 1000)
CPU_BLOCK_END();
if (trap)
@@ -1671,18 +1628,12 @@ inrecomp=0;
if (x86_was_reset)
codegen_reset();
// output &= ~2;
}
// if (output && (SP & 1))
// fatal("odd SP\n");
}
cycdiff=oldcyc-cycles;
tsc += cycdiff;
// timer_end_period(cycles);
if (cpu_state.abrt)
{
flags_rebuild();
@@ -1710,8 +1661,6 @@ inrecomp=0;
{
flags_rebuild();
// oldpc=pc;
// oldcs=CS;
if (msw&1)
{
pmodeint(1,0);
@@ -1734,7 +1683,6 @@ inrecomp=0;
temp=picinterrupt();
if (temp!=0xFF)
{
// pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc);
CPU_BLOCK_END();
flags_rebuild();
if (msw&1)

View File

@@ -1,11 +1,16 @@
#include "ibm.h"
#include <math.h>
#ifndef INFINITY
# define INFINITY (__builtin_inff())
#endif
#include "../ibm.h"
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
#include "x86_flags.h"
#include "mem.h"
#include "../mem.h"
#include "codegen.h"
#include "../pic.h"
#define CPU_BLOCK_END() cpu_block_end = 1
@@ -15,7 +20,7 @@
extern uint16_t *mod1add[2][8];
extern uint32_t *mod1seg[8];
static inline void fetch_ea_32_long(uint32_t rmdat)
static __inline void fetch_ea_32_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;
@@ -31,7 +36,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat)
cpu_state.last_ea = cpu_state.eaaddr;
}
static inline void fetch_ea_16_long(uint32_t rmdat)
static __inline void fetch_ea_16_long(uint32_t rmdat)
{
eal_r = eal_w = NULL;
easeg = cpu_state.ea_seg->base;

View File

@@ -1,6 +1,23 @@
/* Copyright holders: Sarah Walker, Tenshi, leilei
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* 286/386+ instruction handlers list.
*
* Version: @(#)386_ops.h 1.0.0 2017/05/30
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 leilei.
* Copyright 2016-2017 Miran Grca.
*/
#include "x86_ops.h"
@@ -15,7 +32,7 @@
} \
} while (0)
static inline void PUSH_W(uint16_t val)
static __inline void PUSH_W(uint16_t val)
{
if (stack32)
{
@@ -31,7 +48,7 @@ static inline void PUSH_W(uint16_t val)
}
}
static inline void PUSH_L(uint32_t val)
static __inline void PUSH_L(uint32_t val)
{
if (stack32)
{
@@ -47,7 +64,7 @@ static inline void PUSH_L(uint32_t val)
}
}
static inline uint16_t POP_W()
static __inline uint16_t POP_W()
{
uint16_t ret;
if (stack32)
@@ -65,7 +82,7 @@ static inline uint16_t POP_W()
return ret;
}
static inline uint32_t POP_L()
static __inline uint32_t POP_L()
{
uint32_t ret;
if (stack32)
@@ -83,7 +100,7 @@ static inline uint32_t POP_L()
return ret;
}
static inline uint16_t POP_W_seg(uint32_t seg)
static __inline uint16_t POP_W_seg(uint32_t seg)
{
uint16_t ret;
if (stack32)
@@ -101,7 +118,7 @@ static inline uint16_t POP_W_seg(uint32_t seg)
return ret;
}
static inline uint32_t POP_L_seg(uint32_t seg)
static __inline uint32_t POP_L_seg(uint32_t seg)
{
uint32_t ret;
if (stack32)
@@ -119,6 +136,17 @@ static inline uint32_t POP_L_seg(uint32_t seg)
return ret;
}
static int fopcode;
static int ILLEGAL(uint32_t fetchdat)
{
cpu_state.pc = cpu_state.oldpc;
pclog("Illegal instruction %08X (%02X)\n", fetchdat, fopcode);
x86illegal();
return 0;
}
#include "x86seg.h"
#include "x86_ops_arith.h"
#include "x86_ops_atomic.h"
@@ -133,6 +161,8 @@ static inline uint32_t POP_L_seg(uint32_t seg)
#include "x86_ops_io.h"
#include "x86_ops_jump.h"
#include "x86_ops_misc.h"
#include "x87_ops.h"
#include "x86_ops_i686.h"
#include "x86_ops_mmx.h"
#include "x86_ops_mmx_arith.h"
#include "x86_ops_mmx_cmp.h"
@@ -156,25 +186,12 @@ static inline uint32_t POP_L_seg(uint32_t seg)
#include "x86_ops_string.h"
#include "x86_ops_xchg.h"
static int fopcode;
static int ILLEGAL(uint32_t fetchdat)
{
cpu_state.pc = cpu_state.oldpc;
// fatal("Illegal instruction %08X\n", fetchdat);
pclog("Illegal instruction %08X (%02X)\n", fetchdat, fopcode);
x86illegal();
return 0;
}
static int op0F_w_a16(uint32_t fetchdat)
{
int opcode = fetchdat & 0xff;
fopcode = opcode;
cpu_state.pc++;
// pclog("A16W: 0F %02X\n", opcode);
PREFETCH_PREFIX();
return x86_opcodes_0f[opcode](fetchdat >> 8);
@@ -185,7 +202,6 @@ static int op0F_l_a16(uint32_t fetchdat)
fopcode = opcode;
cpu_state.pc++;
// pclog("A16L: 0F %02X\n", opcode);
PREFETCH_PREFIX();
return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8);
@@ -196,7 +212,6 @@ static int op0F_w_a32(uint32_t fetchdat)
fopcode = opcode;
cpu_state.pc++;
// pclog("A32W: 0F %02X\n", opcode);
PREFETCH_PREFIX();
return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8);
@@ -207,15 +222,11 @@ static int op0F_l_a32(uint32_t fetchdat)
fopcode = opcode;
cpu_state.pc++;
// pclog("A32L: 0F %02X\n", opcode);
PREFETCH_PREFIX();
return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8);
}
#include "x87_ops.h"
#include "x86_ops_i686.h"
OpFn OP_TABLE(286_0f)[1024] =
{
/*16-bit data, 16-bit addr*/
@@ -1241,7 +1252,7 @@ OpFn OP_TABLE(286)[1024] =
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286,
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*32-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1263,7 +1274,7 @@ OpFn OP_TABLE(286)[1024] =
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286,
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*16-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1285,7 +1296,7 @@ OpFn OP_TABLE(286)[1024] =
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286,
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*32-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1307,7 +1318,7 @@ OpFn OP_TABLE(286)[1024] =
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286,
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
};
OpFn OP_TABLE(386)[1024] =
@@ -1332,7 +1343,7 @@ OpFn OP_TABLE(386)[1024] =
/*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET,
/*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16,
/*32-bit data, 16-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1354,7 +1365,7 @@ OpFn OP_TABLE(386)[1024] =
/*c0*/ opC0_a16, opC1_l_a16, opRET_l_imm, opRET_l, opLES_l_a16, opLDS_l_a16, opMOV_b_imm_a16,opMOV_l_imm_a16,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD,
/*d0*/ opD0_a16, opD1_l_a16, opD2_a16, opD3_l_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16,
/*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_l_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_l_a16,
/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_l_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_l_a16,
/*16-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1376,7 +1387,7 @@ OpFn OP_TABLE(386)[1024] =
/*c0*/ opC0_a32, opC1_w_a32, opRET_w_imm, opRET_w, opLES_w_a32, opLDS_w_a32, opMOV_b_imm_a32,opMOV_w_imm_a32,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET,
/*d0*/ opD0_a32, opD1_w_a32, opD2_a32, opD3_w_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32,
/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_w_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_w_a32,
/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_w_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_w_a32,
/*32-bit data, 32-bit addr*/
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/
@@ -1398,5 +1409,5 @@ OpFn OP_TABLE(386)[1024] =
/*c0*/ opC0_a32, opC1_l_a32, opRET_l_imm, opRET_l, opLES_l_a32, opLDS_l_a32, opMOV_b_imm_a32,opMOV_l_imm_a32,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD,
/*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32,
/*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX,
/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32,
/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32,
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
#include "ibm.h"
#include "../ibm.h"
#include "x86_ops.h"
#include "mem.h"
#include "../mem.h"
#include "codegen.h"
void (*codegen_timing_start)();

View File

@@ -1,4 +1,4 @@
#include "mem.h"
#include "../mem.h"
#ifdef __amd64__
#include "codegen_x86-64.h"
@@ -35,6 +35,10 @@
typedef struct codeblock_t
{
uint64_t page_mask, page_mask2;
uint64_t *dirty_mask, *dirty_mask2;
uint64_t cmp;
/*Previous and next pointers, for the codeblock list associated with
each physical page. Two sets of pointers, as a codeblock can be
present in two pages.*/
@@ -45,22 +49,19 @@ typedef struct codeblock_t
fails.*/
struct codeblock_t *parent, *left, *right;
int pnt;
int ins;
int was_recompiled;
int TOP;
uint32_t pc;
uint32_t _cs;
uint32_t endpc;
uint32_t phys, phys_2;
uint32_t use32;
int stack32;
int pnt;
int ins;
uint64_t page_mask, page_mask2;
int was_recompiled;
uint32_t status;
uint32_t flags;
int TOP;
uint64_t cmp;
uint8_t data[2048];
} codeblock_t;
@@ -69,7 +70,7 @@ typedef struct codeblock_t
/*Code block is always entered with the same FPU top-of-stack*/
#define CODEBLOCK_STATIC_TOP 2
static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
static __inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
{
codeblock_t *block = pages[phys >> 12].head;
uint64_t a = _cs | ((uint64_t)phys << 32);
@@ -87,7 +88,7 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs)
return block;
}
static inline void codeblock_tree_add(codeblock_t *new_block)
static __inline void codeblock_tree_add(codeblock_t *new_block)
{
codeblock_t *block = pages[new_block->phys >> 12].head;
uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32);
@@ -121,7 +122,7 @@ static inline void codeblock_tree_add(codeblock_t *new_block)
}
}
static inline void codeblock_tree_delete(codeblock_t *block)
static __inline void codeblock_tree_delete(codeblock_t *block)
{
codeblock_t *parent = block->parent;
@@ -236,8 +237,10 @@ static inline void codeblock_tree_delete(codeblock_t *block)
}
}
#define PAGE_MASK_INDEX_MASK 3
#define PAGE_MASK_INDEX_SHIFT 10
#define PAGE_MASK_MASK 63
#define PAGE_MASK_SHIFT 6
#define PAGE_MASK_SHIFT 4
extern codeblock_t *codeblock;
@@ -297,7 +300,7 @@ extern int block_pos;
#define CPU_BLOCK_END() cpu_block_end = 1
static inline void addbyte(uint8_t val)
static __inline void addbyte(uint8_t val)
{
codeblock[block_current].data[block_pos++] = val;
if (block_pos >= BLOCK_MAX)
@@ -306,9 +309,10 @@ static inline void addbyte(uint8_t val)
}
}
static inline void addword(uint16_t val)
static __inline void addword(uint16_t val)
{
*(uint16_t *)&codeblock[block_current].data[block_pos] = val;
uint16_t *p = (uint16_t *)&codeblock[block_current].data[block_pos];
*p = val;
block_pos += 2;
if (block_pos >= BLOCK_MAX)
{
@@ -316,9 +320,10 @@ static inline void addword(uint16_t val)
}
}
static inline void addlong(uint32_t val)
static __inline void addlong(uint32_t val)
{
*(uint32_t *)&codeblock[block_current].data[block_pos] = val;
uint32_t *p = (uint32_t *)&codeblock[block_current].data[block_pos];
*p = val;
block_pos += 4;
if (block_pos >= BLOCK_MAX)
{
@@ -326,9 +331,10 @@ static inline void addlong(uint32_t val)
}
}
static inline void addquad(uint64_t val)
static __inline void addquad(uint64_t val)
{
*(uint64_t *)&codeblock[block_current].data[block_pos] = val;
uint64_t *p = (uint64_t *)&codeblock[block_current].data[block_pos];
*p = val;
block_pos += 8;
if (block_pos >= BLOCK_MAX)
{

View File

@@ -1,4 +1,5 @@
#include "ibm.h"
#include "../ibm.h"
#include "../mem.h"
#include "x86.h"
#include "x86_ops.h"
#include "x86_flags.h"

View File

@@ -2,15 +2,15 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
int host_reg;
CALL_FUNC(flags_rebuild_c);
CALL_FUNC((uintptr_t)flags_rebuild_c);
host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -21,15 +21,15 @@ static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
int host_reg;
CALL_FUNC(flags_rebuild_c);
CALL_FUNC((uintptr_t)flags_rebuild_c);
host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -40,15 +40,15 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
int host_reg;
CALL_FUNC(flags_rebuild_c);
CALL_FUNC((uintptr_t)flags_rebuild_c);
host_reg = LOAD_REG_W(opcode & 7);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -59,15 +59,15 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
{
int host_reg;
CALL_FUNC(flags_rebuild_c);
CALL_FUNC((uintptr_t)flags_rebuild_c);
host_reg = LOAD_REG_L(opcode & 7);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -93,12 +93,12 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
MEM_CHECK_WRITE(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \
src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \
op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) \
{ \
if ((fetchdat & 0xc0) == 0xc0) \
@@ -133,12 +133,12 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
MEM_CHECK_WRITE_W(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \
src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \
op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) \
{ \
if ((fetchdat & 0xc0) == 0xc0) \
@@ -173,12 +173,12 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
MEM_CHECK_WRITE_L(target_seg); \
dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \
} \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \
src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \
op ## _HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) \
{ \
if ((fetchdat & 0xc0) == 0xc0) \
@@ -215,11 +215,11 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
} \
\
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \
op ## _HOST_REG_B(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg); \
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) STORE_REG_B_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
@@ -244,11 +244,11 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
} \
\
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \
op ## _HOST_REG_W(dst_reg, src_reg); \
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg); \
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) STORE_REG_W_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
@@ -273,11 +273,11 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
} \
\
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \
op ## _HOST_REG_L(dst_reg, src_reg); \
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg); \
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \
if (writeback) STORE_REG_L_RELEASE(dst_reg); \
else RELEASE_REG(dst_reg); \
RELEASE_REG(src_reg); \
@@ -308,11 +308,11 @@ static uint32_t ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
}
dst_reg = LOAD_REG_B((fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg);
dst_reg = CMP_HOST_REG_B(dst_reg, src_reg);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
@@ -336,11 +336,11 @@ static uint32_t ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
}
dst_reg = LOAD_REG_W((fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg);
dst_reg = CMP_HOST_REG_W(dst_reg, src_reg);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
@@ -364,11 +364,11 @@ static uint32_t ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
}
dst_reg = LOAD_REG_L((fetchdat >> 3) & 7);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg);
dst_reg = CMP_HOST_REG_L(dst_reg, src_reg);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
@@ -392,12 +392,12 @@ static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
dst_reg = 0;
}
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8);
src_reg = LOAD_REG_B((fetchdat >> 3) & 7);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg);
dst_reg = CMP_HOST_REG_B(dst_reg, src_reg);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
@@ -420,12 +420,12 @@ static uint32_t ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
dst_reg = 0;
} \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
src_reg = LOAD_REG_W((fetchdat >> 3) & 7);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg);
dst_reg = CMP_HOST_REG_W(dst_reg, src_reg);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
@@ -448,12 +448,12 @@ static uint32_t ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
dst_reg = 0;
}
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
src_reg = LOAD_REG_L((fetchdat >> 3) & 7);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg);
dst_reg = CMP_HOST_REG_L(dst_reg, src_reg);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg);
RELEASE_REG(dst_reg);
RELEASE_REG(src_reg);
@@ -466,11 +466,11 @@ static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
{
int host_reg = LOAD_REG_B(REG_AL);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD8);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -480,11 +480,11 @@ static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
{
int host_reg = LOAD_REG_W(REG_AX);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -494,12 +494,12 @@ static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
{
int host_reg = LOAD_REG_L(REG_EAX);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
fetchdat = fastreadl(cs + op_pc);
ADD_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -510,11 +510,11 @@ static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
{
int host_reg = LOAD_REG_B(REG_AL);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
host_reg = CMP_HOST_REG_IMM_B(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
codegen_flags_changed = 1;
@@ -524,11 +524,11 @@ static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
{
int host_reg = LOAD_REG_W(REG_AX);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
host_reg = CMP_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
codegen_flags_changed = 1;
@@ -538,12 +538,12 @@ static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
{
int host_reg = LOAD_REG_L(REG_EAX);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
fetchdat = fastreadl(cs + op_pc);
host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
RELEASE_REG(host_reg);
codegen_flags_changed = 1;
@@ -554,11 +554,11 @@ static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
{
int host_reg = LOAD_REG_B(REG_AL);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_B_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -568,11 +568,11 @@ static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
{
int host_reg = LOAD_REG_W(REG_AX);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_W_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -582,12 +582,12 @@ static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32
{
int host_reg = LOAD_REG_L(REG_EAX);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
fetchdat = fastreadl(cs + op_pc);
SUB_HOST_REG_IMM(host_reg, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
STORE_REG_L_RELEASE(host_reg);
codegen_flags_changed = 1;
@@ -598,7 +598,7 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
{
int host_reg;
uint32_t imm;
x86seg *target_seg;
x86seg *target_seg = NULL;
if ((fetchdat & 0x30) == 0x10)
return 0;
@@ -629,38 +629,38 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD8);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8);
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN8);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm | 0xffffff00);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN8);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8);
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN8);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8);
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
host_reg = CMP_HOST_REG_IMM_B(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8);
break;
}
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
{
if ((fetchdat & 0xc0) != 0xc0)
@@ -684,7 +684,7 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
{
int host_reg;
uint32_t imm;
x86seg *target_seg;
x86seg *target_seg = NULL;
if ((fetchdat & 0x30) == 0x10)
return 0;
@@ -715,38 +715,38 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16);
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm | 0xffff0000);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
host_reg = CMP_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
break;
}
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
{
if ((fetchdat & 0xc0) != 0xc0)
@@ -769,7 +769,7 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
{
int host_reg;
uint32_t imm;
x86seg *target_seg;
x86seg *target_seg = NULL;
if ((fetchdat & 0x30) == 0x10)
return 0;
@@ -799,38 +799,38 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32);
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
host_reg = CMP_HOST_REG_IMM_L(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
break;
}
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
{
if ((fetchdat & 0xc0) != 0xc0)
@@ -854,7 +854,7 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
{
int host_reg;
uint32_t imm;
x86seg *target_seg;
x86seg *target_seg = NULL;
if ((fetchdat & 0x30) == 0x10)
return 0;
@@ -888,38 +888,38 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16);
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm | 0xffff0000);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16);
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
host_reg = CMP_HOST_REG_IMM_W(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16);
break;
}
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
{
if ((fetchdat & 0xc0) != 0xc0)
@@ -942,7 +942,7 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
{
int host_reg;
uint32_t imm;
x86seg *target_seg;
x86seg *target_seg = NULL;
if ((fetchdat & 0x30) == 0x10)
return 0;
@@ -976,38 +976,38 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
switch (fetchdat & 0x38)
{
case 0x00: /*ADD*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32);
break;
case 0x08: /*OR*/
OR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
break;
case 0x20: /*AND*/
AND_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
break;
case 0x28: /*SUB*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
break;
case 0x30: /*XOR*/
XOR_HOST_REG_IMM(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32);
break;
case 0x38: /*CMP*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
host_reg = CMP_HOST_REG_IMM_L(host_reg, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32);
break;
}
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0x38) != 0x38)
{
if ((fetchdat & 0xc0) != 0xc0)

View File

@@ -491,7 +491,7 @@ static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u
int host_reg;
FP_ENTER();
host_reg = LOAD_VAR_W(&cpu_state.npxs);
host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs);
STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX);
return op_pc;
@@ -622,9 +622,11 @@ static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
static double fp_imm = v; \
static uint64_t *fpp; \
\
FP_ENTER(); \
FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \
fpp = (uint64_t *)&fp_imm; \
FP_LOAD_IMM_Q(*fpp); \
\
return op_pc; \
}

View File

@@ -75,16 +75,16 @@ static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
return op_pc+1;
}
static int BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
CALL_FUNC(CF_SET);
CALL_FUNC((uintptr_t)CF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
}
static int BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
int host_reg;
@@ -122,7 +122,7 @@ static int BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not
break;
case FLAGS_UNKNOWN:
CALL_FUNC(ZF_SET);
CALL_FUNC((uintptr_t)ZF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
@@ -131,25 +131,25 @@ static int BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not
}
}
static int BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
CALL_FUNC(VF_SET);
CALL_FUNC((uintptr_t)VF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
}
static int BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
CALL_FUNC(PF_SET);
CALL_FUNC((uintptr_t)PF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else
TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
}
static int BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not)
{
int host_reg;
@@ -204,7 +204,7 @@ static int BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not
break;
case FLAGS_UNKNOWN:
CALL_FUNC(NF_SET);
CALL_FUNC((uintptr_t)NF_SET);
if (not)
TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt);
else

View File

@@ -27,13 +27,13 @@ static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32
static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int host_reg;
if ((fetchdat & 0x30) != 0x00)
return 0;
CALL_FUNC(flags_rebuild_c);
CALL_FUNC((uintptr_t)flags_rebuild_c);
if ((fetchdat & 0xc0) == 0xc0)
host_reg = LOAD_REG_B(fetchdat & 7);
@@ -50,18 +50,18 @@ static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
switch (fetchdat & 0x38)
{
case 0x00: /*INC*/
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_B(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC8);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
break;
case 0x08: /*DEC*/
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_B(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC8);
STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8);
STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg);
break;
}
@@ -79,14 +79,14 @@ static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
static uint32_t codegen_temp;
static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int host_reg;
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
return 0;
if ((fetchdat & 0x30) == 0x00)
CALL_FUNC(flags_rebuild_c);
CALL_FUNC((uintptr_t)flags_rebuild_c);
if ((fetchdat & 0xc0) == 0xc0)
host_reg = LOAD_REG_W(fetchdat & 7);
@@ -111,11 +111,11 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
switch (fetchdat & 0x38)
{
case 0x00: /*INC*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM_W(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_W_RELEASE(host_reg);
else
@@ -126,11 +126,11 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
codegen_flags_changed = 1;
return op_pc + 1;
case 0x08: /*DEC*/
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM_W(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC16);
STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16);
STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_W_RELEASE(host_reg);
else
@@ -168,17 +168,18 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
SP_MODIFY(-2);
return op_pc + 1;
}
return 0;
}
static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int host_reg;
if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08))
return 0;
if ((fetchdat & 0x30) == 0x00)
CALL_FUNC(flags_rebuild_c);
CALL_FUNC((uintptr_t)flags_rebuild_c);
if ((fetchdat & 0xc0) == 0xc0)
host_reg = LOAD_REG_L(fetchdat & 7);
@@ -203,11 +204,11 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
switch (fetchdat & 0x38)
{
case 0x00: /*INC*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
ADD_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_L_RELEASE(host_reg);
else
@@ -218,11 +219,11 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
codegen_flags_changed = 1;
return op_pc + 1;
case 0x08: /*DEC*/
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg);
SUB_HOST_REG_IMM(host_reg, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC32);
STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1);
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32);
STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg);
if ((fetchdat & 0xc0) == 0xc0)
STORE_REG_L_RELEASE(host_reg);
else
@@ -260,4 +261,5 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint
SP_MODIFY(-4);
return op_pc + 1;
}
return 0;
}

View File

@@ -512,22 +512,22 @@ static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
switch (fetchdat & 0x38)
{
case 0x00: /*ES*/
host_reg = LOAD_VAR_WL(&ES);
host_reg = LOAD_VAR_WL((uintptr_t)&ES);
break;
case 0x08: /*CS*/
host_reg = LOAD_VAR_WL(&CS);
host_reg = LOAD_VAR_WL((uintptr_t)&CS);
break;
case 0x18: /*DS*/
host_reg = LOAD_VAR_WL(&DS);
host_reg = LOAD_VAR_WL((uintptr_t)&DS);
break;
case 0x10: /*SS*/
host_reg = LOAD_VAR_WL(&SS);
host_reg = LOAD_VAR_WL((uintptr_t)&SS);
break;
case 0x20: /*FS*/
host_reg = LOAD_VAR_WL(&FS);
host_reg = LOAD_VAR_WL((uintptr_t)&FS);
break;
case 0x28: /*GS*/
host_reg = LOAD_VAR_WL(&GS);
host_reg = LOAD_VAR_WL((uintptr_t)&GS);
break;
default:
return 0;

View File

@@ -13,29 +13,29 @@
reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \
if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \
} \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, count); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \
\
res_store((uint32_t)&cpu_state.flags_op1, reg); \
res_store((uintptr_t)&cpu_state.flags_op1, reg); \
\
switch (fetchdat & 0x38) \
{ \
case 0x20: case 0x30: /*SHL*/ \
SHL_ ## size ## _IMM(reg, count); \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \
break; \
\
case 0x28: /*SHR*/ \
SHR_ ## size ## _IMM(reg, count); \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \
break; \
\
case 0x38: /*SAR*/ \
SAR_ ## size ## _IMM(reg, count); \
STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \
break; \
} \
\
res_store((uint32_t)&cpu_state.flags_res, reg); \
res_store((uintptr_t)&cpu_state.flags_res, reg); \
if ((fetchdat & 0xc0) == 0xc0) \
STORE_REG_ ## size ## _RELEASE(reg); \
else \
@@ -46,7 +46,7 @@
static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int count;
int reg;
@@ -59,7 +59,7 @@ static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
}
static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int count;
int reg;
@@ -72,7 +72,7 @@ static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
}
static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int count;
int reg;
@@ -86,7 +86,7 @@ static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int count = 1;
int reg;
@@ -99,7 +99,7 @@ static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_
}
static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int count = 1;
int reg;
@@ -112,7 +112,7 @@ static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3
}
static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
x86seg *target_seg;
x86seg *target_seg = NULL;
int count = 1;
int reg;

View File

@@ -85,8 +85,6 @@ static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_3
static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
@@ -97,8 +95,6 @@ static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
}
static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
@@ -110,8 +106,6 @@ static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_W(&_ss);
@@ -122,8 +116,6 @@ static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
}
static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
MEM_LOAD_ADDR_EA_L(&_ss);
@@ -136,7 +128,6 @@ static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin
static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t offset = fetchdat & 0xffff;
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
@@ -149,7 +140,6 @@ static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32,
static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block)
{
uint16_t offset = fetchdat & 0xffff;
int host_reg;
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc);
LOAD_STACK_TO_EA(0);
@@ -254,8 +244,6 @@ ROP_PUSH_SEG(SS)
#define ROP_POP_SEG(seg, rseg) \
static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&_ss); \
@@ -266,8 +254,6 @@ static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_
} \
static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \
{ \
int host_reg; \
\
STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \
LOAD_STACK_TO_EA(0); \
MEM_LOAD_ADDR_EA_W(&_ss); \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,9 +1,9 @@
#include "ibm.h"
#include "../ibm.h"
#include "../mem.h"
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
#include "mem.h"
#include "codegen.h"
#define CYCLES(c) (int *)c
@@ -251,7 +251,7 @@ static int *opcode_timings_8x[8] =
static int timing_count;
static uint8_t last_prefix;
static inline int COUNT(int *c, int op_32)
static __inline int COUNT(int *c, int op_32)
{
if ((uintptr_t)c <= 10000)
return (int)c;

View File

@@ -8,12 +8,12 @@
- Out of order execution (beyond most simplistic approximation)
*/
#include "ibm.h"
#include "../ibm.h"
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
#include "mem.h"
#include "../mem.h"
#include "codegen.h"
/*Instruction has different execution time for 16 and 32 bit data. Does not pair */
@@ -855,7 +855,7 @@ void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat)
void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
{
int *timings;
uint32_t *timings;
int mod3 = ((fetchdat & 0xc0) == 0xc0);
int bit8 = !(opcode & 1);
@@ -863,48 +863,39 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
{
case 0x0f:
timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f;
// pclog("timings 0f\n");
break;
case 0xd8:
timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8;
opcode = (opcode >> 3) & 7;
// pclog("timings d8\n");
break;
case 0xd9:
timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
// pclog("timings d9\n");
break;
case 0xda:
timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da;
opcode = (opcode >> 3) & 7;
// pclog("timings da\n");
break;
case 0xdb:
timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db;
opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7;
// pclog("timings db\n");
break;
case 0xdc:
timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc;
opcode = (opcode >> 3) & 7;
// pclog("timings dc\n");
break;
case 0xdd:
timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd;
opcode = (opcode >> 3) & 7;
// pclog("timings dd\n");
break;
case 0xde:
timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de;
opcode = (opcode >> 3) & 7;
// pclog("timings de\n");
break;
case 0xdf:
timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df;
opcode = (opcode >> 3) & 7;
// pclog("timings df\n");
break;
default:
@@ -914,7 +905,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x;
if (!mod3)
opcode = (fetchdat >> 3) & 7;
// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x);
break;
case 0xc0: case 0xc1:
@@ -935,22 +925,18 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
case 0xf6:
timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6;
opcode = (fetchdat >> 3) & 7;
// pclog("timings f6\n");
break;
case 0xf7:
timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7;
opcode = (fetchdat >> 3) & 7;
// pclog("timings f7\n");
break;
case 0xff:
timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff;
opcode = (fetchdat >> 3) & 7;
// pclog("timings ff\n");
break;
default:
timings = mod3 ? opcode_timings_mod3 : opcode_timings;
// pclog("timings normal\n");
break;
}
}
@@ -970,7 +956,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1;
prev_full = 0;
// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay);
}
else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH)
&& (prev_timings[opcode] & PAIR_MASK) == PAIR_X)
@@ -980,7 +965,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1;
prev_full = 0;
// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay);
}
else if (prev_regmask & regmask)
{
@@ -989,7 +973,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay;
decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1;
prev_full = 0;
// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay);
}
else
{
@@ -1003,7 +986,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
decode_delay = (-t_pair) + 1;
prev_full = 0;
// pclog("Pairable %i %i %i %02x %02x\n", t_pair, t1, t2, opcode, prev_opcode);
return;
}
}
@@ -1016,12 +998,10 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32)
/*Instruction not pairable*/
codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay;
decode_delay = (-COUNT(timings[opcode], op_32)) + 1;
// pclog("Not pairable %i\n", COUNT(timings[opcode], op_32) + decode_delay);
}
else
{
/*Instruction might pair with next*/
// pclog("Might pair - %02x %02x %08x %08x %08x %p %p %p\n", last_prefix, opcode, timings[opcode], timings[opcode] & PAIR_MASK, PAIR_X_BRANCH, timings, opcode_timings_0f, opcode_timings_0f_mod3);
prev_full = 1;
prev_opcode = opcode;
prev_timings = timings;

View File

@@ -1,9 +1,9 @@
#include "ibm.h"
#include "../ibm.h"
#include "../mem.h"
#include "cpu.h"
#include "x86.h"
#include "x86_ops.h"
#include "x87.h"
#include "mem.h"
#include "codegen.h"
#define CYCLES(c) (int *)c
@@ -251,7 +251,7 @@ static int *opcode_timings_8x[8] =
static int timing_count;
static uint8_t last_prefix;
static inline int COUNT(int *c, int op_32)
static __inline int COUNT(int *c, int op_32)
{
if ((uintptr_t)c <= 10000)
return (int)c;

View File

@@ -1,16 +1,14 @@
#ifdef __amd64__
#include <stdlib.h>
#include "ibm.h"
#include "../ibm.h"
#include "../mem.h"
#include "cpu.h"
#include "x86.h"
#include "x86_flags.h"
#include "x86_ops.h"
#include "x87.h"
#include "mem.h"
#include "386_common.h"
#include "codegen.h"
#include "codegen_ops.h"
#include "codegen_ops_x86-64.h"
@@ -24,6 +22,7 @@
#endif
int codegen_flat_ds, codegen_flat_ss;
int codegen_flags_changed = 0;
int codegen_fpu_entered = 0;
int codegen_fpu_loaded_iq[8];
@@ -88,7 +87,6 @@ void codegen_init()
exit(-1);
}
#endif
// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block);
}
void codegen_reset()
@@ -100,25 +98,11 @@ void codegen_reset()
void dump_block()
{
codeblock_t *block = pages[0x119000 >> 12].block;
pclog("dump_block:\n");
while (block)
{
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff);
uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff);
pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next);
if (!block->pc)
fatal("Dead PC=0\n");
block = block->next;
}
pclog("dump_block done\n");
}
static void add_to_block_list(codeblock_t *block)
{
codeblock_t *block_prev = pages[block->phys >> 12].block;
codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3];
if (!block->page_mask)
fatal("add_to_block_list - mask = 0\n");
@@ -127,12 +111,12 @@ static void add_to_block_list(codeblock_t *block)
{
block->next = block_prev;
block_prev->prev = block;
pages[block->phys >> 12].block = block;
pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
}
else
{
block->next = NULL;
pages[block->phys >> 12].block = block;
pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block;
}
if (block->next)
@@ -143,18 +127,18 @@ static void add_to_block_list(codeblock_t *block)
if (block->page_mask2)
{
block_prev = pages[block->phys_2 >> 12].block_2;
block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3];
if (block_prev)
{
block->next_2 = block_prev;
block_prev->prev_2 = block;
pages[block->phys_2 >> 12].block_2 = block;
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
}
else
{
block->next_2 = NULL;
pages[block->phys_2 >> 12].block_2 = block;
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block;
}
}
}
@@ -172,7 +156,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
}
else
{
pages[block->phys >> 12].block = block->next;
pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next;
if (block->next)
block->next->prev = NULL;
else
@@ -193,8 +177,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc)
}
else
{
// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2);
pages[block->phys_2 >> 12].block_2 = block->next_2;
pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2;
if (block->next_2)
block->next_2->prev_2 = NULL;
else
@@ -219,7 +202,7 @@ static void delete_block(codeblock_t *block)
void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
{
struct codeblock_t *block = page->block;
struct codeblock_t *block = page->block[(phys_addr >> 10) & 3];
while (block)
{
@@ -233,7 +216,7 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr)
block = block->next;
}
block = page->block_2;
block = page->block_2[(phys_addr >> 10) & 3];
while (block)
{
@@ -254,17 +237,14 @@ void codegen_block_init(uint32_t phys_addr)
int has_evicted = 0;
page_t *page = &pages[phys_addr >> 12];
if (!page->block)
if (!page->block[(phys_addr >> 10) & 3])
mem_flush_write_page(phys_addr, cs+cpu_state.pc);
block_current = (block_current + 1) & BLOCK_MASK;
block = &codeblock[block_current];
// if (block->pc == 0xb00b4ff5)
// pclog("Init target block\n");
if (block->pc != 0)
{
// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc);
delete_block(block);
cpu_recomp_reuse++;
}
@@ -276,13 +256,15 @@ void codegen_block_init(uint32_t phys_addr)
block->_cs = cs;
block->pnt = block_current;
block->phys = phys_addr;
block->use32 = use32;
block->stack32 = stack32;
block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
block->dirty_mask2 = NULL;
block->next = block->prev = NULL;
block->next_2 = block->prev_2 = NULL;
block->page_mask = 0;
block->flags = 0;
block->status = cpu_cur_status;
block->was_recompiled = 0;
recomp_page = block->phys & ~0xfff;
@@ -295,7 +277,7 @@ void codegen_block_start_recompile(codeblock_t *block)
int has_evicted = 0;
page_t *page = &pages[block->phys >> 12];
if (!page->block)
if (!page->block[(block->phys >> 10) & 3])
mem_flush_write_page(block->phys, cs+cpu_state.pc);
block_num = HASH(block->phys);
@@ -361,8 +343,6 @@ void codegen_block_start_recompile(codeblock_t *block)
addbyte(0xBD);
addquad(((uintptr_t)&cpu_state) + 128);
// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num);
last_op32 = -1;
last_ea_seg = NULL;
last_ssegs = -1;
@@ -388,6 +368,9 @@ void codegen_block_start_recompile(codeblock_t *block)
codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0;
block->was_recompiled = 1;
codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS;
codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS;
}
void codegen_block_remove()
@@ -403,59 +386,60 @@ void codegen_block_remove()
void codegen_block_generate_end_mask()
{
codeblock_t *block = &codeblock[block_current];
uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff);
uint32_t end_pc = ((codegen_endpc + 3) & 0xffc) | (block->phys & ~0xfff);
uint32_t start_pc;
uint32_t end_pc;
block->endpc = codegen_endpc;
block->page_mask = 0;
start_pc = block->pc & 0xffc;
start_pc &= ~PAGE_MASK_MASK;
end_pc = ((block->endpc & 0xffc) + PAGE_MASK_MASK) & ~PAGE_MASK_MASK;
if (end_pc > 0xfff || end_pc < start_pc)
end_pc = 0xfff;
start_pc = (block->pc & 0x3ff) & ~15;
if ((block->pc ^ block->endpc) & ~0x3ff)
end_pc = 0x3ff & ~15;
else
end_pc = (block->endpc & 0x3ff) & ~15;
if (end_pc < start_pc)
end_pc = 0x3ff;
start_pc >>= PAGE_MASK_SHIFT;
end_pc >>= PAGE_MASK_SHIFT;
// pclog("block_end: %08x %08x\n", start_pc, end_pc);
for (; start_pc <= end_pc; start_pc++)
{
block->page_mask |= ((uint64_t)1 << start_pc);
// pclog(" %08x %llx\n", start_pc, block->page_mask);
}
pages[block->phys >> 12].code_present_mask |= block->page_mask;
pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask;
block->phys_2 = -1;
block->page_mask2 = 0;
block->next_2 = block->prev_2 = NULL;
if ((block->pc ^ block->endpc) & ~0xfff)
if ((block->pc ^ block->endpc) & ~0x3ff)
{
block->phys_2 = get_phys_noabrt(block->endpc);
if (block->phys_2 != -1)
{
// pclog("start block - %08x %08x %p %p %p %08x\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, (void *)pages[block->phys_2 >> 12].block_2, block->phys_2);
page_t *page_2 = &pages[block->phys_2 >> 12];
start_pc = 0;
end_pc = (block->endpc & 0xfff) >> PAGE_MASK_SHIFT;
end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT;
for (; start_pc <= end_pc; start_pc++)
block->page_mask2 |= ((uint64_t)1 << start_pc);
if (!pages[block->phys_2 >> 12].block_2)
page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2;
if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3])
mem_flush_write_page(block->phys_2, block->endpc);
// pclog("New block - %08x %08x %p %p phys %08x %08x %016llx\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, block->phys, block->phys_2, block->page_mask2);
if (!block->page_mask2)
fatal("!page_mask2\n");
if (block->next_2)
{
// pclog(" next_2->pc=%08x\n", block->next_2->pc);
if (!block->next_2->pc)
fatal("block->next_2->pc=0 %p\n", (void *)block->next_2);
}
block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK];
}
}
// pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask);
recomp_page = -1;
}
@@ -485,16 +469,6 @@ void codegen_block_end_recompile(codeblock_t *block)
addbyte(cpu_state_offset(cpu_recomp_ins));
addlong(codegen_block_ins);
}
#if 0
if (codegen_block_full_ins)
{
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)&cpu_recomp_full_ins);
addlong(codegen_block_full_ins);
}
#endif
addbyte(0x48); /*ADDL $40,%rsp*/
addbyte(0x83);
addbyte(0xC4);
@@ -521,7 +495,6 @@ void codegen_block_end_recompile(codeblock_t *block)
block->next_2 = block->prev_2 = NULL;
codegen_block_generate_end_mask();
add_to_block_list(block);
// pclog("End block %i\n", block_num);
}
void codegen_flush()
@@ -728,7 +701,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat,
}
return op_ea_seg;
}
//#if 0
static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset)
{
uint32_t new_eaaddr;
@@ -930,7 +903,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat,
}
return op_ea_seg;
}
//#endif
void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc)
{
codeblock_t *block = &codeblock[block_current];
@@ -1115,17 +1088,6 @@ generate_call:
addlong(codegen_block_ins);
codegen_block_ins = 0;
}
#if 0
if (codegen_block_full_ins)
{
addbyte(0x81); /*ADD $codegen_block_ins,ins*/
addbyte(0x04);
addbyte(0x25);
addlong((uint32_t)&cpu_recomp_full_ins);
addlong(codegen_block_full_ins);
codegen_block_full_ins = 0;
}
#endif
}
if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff])
{
@@ -1145,8 +1107,6 @@ generate_call:
}
op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask];
// if (output)
// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]);
if (op_ssegs != last_ssegs)
{
last_ssegs = op_ssegs;
@@ -1155,7 +1115,7 @@ generate_call:
addbyte(cpu_state_offset(ssegs));
addbyte(op_ssegs);
}
//#if 0
if ((!test_modrm ||
(op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) ||
(op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/)
@@ -1181,10 +1141,9 @@ generate_call:
op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset);
op_pc -= pc_off;
}
//#endif
if (op_ea_seg != last_ea_seg)
{
// last_ea_seg = op_ea_seg;
addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/
addbyte(0x45);
addbyte(cpu_state_offset(ea_seg));
@@ -1221,8 +1180,6 @@ generate_call:
addbyte(0x0F); addbyte(0x85); /*JNZ 0*/
addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4]));
// call(block, codegen_debug);
codegen_endpc = (cs + cpu_state.pc) + 8;
}

View File

@@ -10,7 +10,7 @@
#define BLOCK_EXIT_OFFSET 0x7e0
#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20)
#define BLOCK_MAX 1650
#define BLOCK_MAX 1620
enum
{

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,30 @@
/* Copyright holders: Sarah Walker, Tenshi, leilei
see COPYING for more details
*/
#include "ibm.h"
/*
* 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.
*
* CPU type handler.
*
* Version: @(#)cpu.c 1.0.1 2017/06/03
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 leilei.
* Copyright 2016-2017 Miran Grca.
*/
#include "../ibm.h"
#include "cpu.h"
#include "model.h"
#include "io.h"
#include "../device.h"
#include "../model.h"
#include "../io.h"
#include "x86_ops.h"
#include "mem.h"
#include "pci.h"
#include "../mem.h"
#include "../pci.h"
#include "codegen.h"
int isa_cycles;
@@ -74,6 +91,9 @@ int cpu_hasrdtsc;
int cpu_hasMMX, cpu_hasMSR;
int cpu_hasCR4;
int cpu_use_dynarec;
int cpu_cyrix_alignment;
int hasfpu;
uint64_t cpu_CR4_mask;
@@ -81,6 +101,7 @@ int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
int cpu_prefetch_cycles, cpu_prefetch_width;
int cpu_waitstates;
int cpu_cache_int_enabled, cpu_cache_ext_enabled;
int cpu_pci_speed;
int is286, is386;
int israpidcad, is_pentium;
@@ -132,6 +153,7 @@ int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer;
int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner;
int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
int timing_misaligned;
static struct
{
@@ -166,11 +188,13 @@ CPU cpus_8088[] =
{
/*8088 standard*/
{"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0},
{"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0},
{"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
#if 0
{"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0},
{"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
{"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
{"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0},
#endif
{"", -1, 0, 0, 0, 0, 0,0,0,0}
};
@@ -181,6 +205,15 @@ CPU cpus_pcjr[] =
{"", -1, 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, 0, 0,0,0,0},
{"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0},
{"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_8086[] =
{
/*8086 standard*/
@@ -228,28 +261,31 @@ CPU cpus_ps1_m2011[] =
{"", -1, 0, 0, 0, 0}
};
CPU cpus_i386[] =
CPU cpus_ps2_m30_286[] =
{
/*i386*/
/*286*/
{"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2},
{"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3},
{"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3},
{"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4},
{"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4},
{"", -1, 0, 0, 0, 0}
};
CPU cpus_i386SX[] =
{
/*i386SX*/
{"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3},
{"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3},
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3},
{"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3},
{"i386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3},
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3},
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
{"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
{"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3},
{"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0, 4,4,3,3},
{"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0, 6,6,3,3},
{"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0, 7,7,3,3},
{"", -1, 0, 0, 0}
};
CPU cpus_i386DX[] =
{
/*i386*/
/*i386DX*/
{"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3},
{"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
{"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
@@ -263,12 +299,12 @@ CPU cpus_i386DX[] =
CPU cpus_acer[] =
{
/*i386*/
/*i386SX*/
{"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4},
{"", -1, 0, 0, 0}
};
CPU cpus_Am386[] =
CPU cpus_Am386SX[] =
{
/*Am386*/
{"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3},
@@ -276,9 +312,6 @@ CPU cpus_Am386[] =
{"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3},
{"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3},
{"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3},
{"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3},
{"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3},
{"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3},
{"", -1, 0, 0, 0}
};
@@ -292,22 +325,15 @@ CPU cpus_Am386DX[] =
{"", -1, 0, 0, 0}
};
CPU cpus_486SDLC[] =
CPU cpus_486SLC[] =
{
/*Cx486SLC/DLC*/
/*Cx486SLC*/
{"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3},
{"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3},
{"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3},
{"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6},
{"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6},
{"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6},
{"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3},
{"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3},
{"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3},
{"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6},
{"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6},
{"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6},
{"", -1, 0, 0, 0}
};
@@ -332,6 +358,7 @@ CPU cpus_i486[] =
{"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3},
{"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
{"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
{"i486SX2/66 (Q0569)", CPU_i486SX, 6, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6},
{"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3},
{"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3},
{"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4},
@@ -409,7 +436,7 @@ CPU cpus_Cx486[] =
{"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7},
{"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9},
{"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12},
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
{"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9},
{"", -1, 0, 0, 0}
};
@@ -581,6 +608,8 @@ void cpu_set_edx()
EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset;
}
int enable_external_fpu = 0;
void cpu_set()
{
CPU *cpu_s;
@@ -603,8 +632,8 @@ void cpu_set()
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);
hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD);
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);
cpu_16bitbus = cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC);
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);
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;
cpu_multi = cpu_s->multi;
@@ -614,6 +643,14 @@ void cpu_set()
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;
}
}
cpu_update_waitstates();
isa_cycles = (int)(((int64_t)cpu_s->rspeed << ISA_CYCLES_SHIFT) / 8000000ll);
@@ -720,7 +757,10 @@ void cpu_set()
}
memset(&msr, 0, sizeof(msr));
timing_misaligned = 0;
cpu_cyrix_alignment = 0;
switch (cpu_s->cpu_type)
{
case CPU_8088:
@@ -729,6 +769,37 @@ void cpu_set()
case CPU_286:
x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f);
if (enable_external_fpu)
{
x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16;
x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32;
x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16;
x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32;
x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16;
x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32;
x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16;
x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32;
x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16;
x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32;
x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16;
x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32;
x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16;
x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32;
x86_opcodes_d9_a16 = ops_fpu_287_d9_a16;
x86_opcodes_d9_a32 = ops_fpu_287_d9_a32;
x86_opcodes_da_a16 = ops_fpu_287_da_a16;
x86_opcodes_da_a32 = ops_fpu_287_da_a32;
x86_opcodes_db_a16 = ops_fpu_287_db_a16;
x86_opcodes_db_a32 = ops_fpu_287_db_a32;
x86_opcodes_dc_a16 = ops_fpu_287_dc_a16;
x86_opcodes_dc_a32 = ops_fpu_287_dc_a32;
x86_opcodes_dd_a16 = ops_fpu_287_dd_a16;
x86_opcodes_dd_a32 = ops_fpu_287_dd_a32;
x86_opcodes_de_a16 = ops_fpu_287_de_a16;
x86_opcodes_de_a32 = ops_fpu_287_de_a32;
x86_opcodes_df_a16 = ops_fpu_287_df_a16;
x86_opcodes_df_a32 = ops_fpu_287_df_a32;
}
timing_rr = 2; /*register dest - register src*/
timing_rm = 7; /*register dest - memory src*/
timing_mr = 7; /*memory dest - register src*/
@@ -883,6 +954,7 @@ void cpu_set()
timing_jmp_rm = 9;
timing_jmp_pm = 26;
timing_jmp_pm_gate = 37;
timing_misaligned = 3;
break;
case CPU_486DLC:
@@ -916,6 +988,7 @@ void cpu_set()
timing_jmp_rm = 9;
timing_jmp_pm = 26;
timing_jmp_pm_gate = 37;
timing_misaligned = 3;
break;
case CPU_i486SX:
@@ -949,6 +1022,7 @@ void cpu_set()
timing_jmp_rm = 17;
timing_jmp_pm = 19;
timing_jmp_pm_gate = 32;
timing_misaligned = 3;
break;
case CPU_Am486SX:
@@ -983,6 +1057,7 @@ void cpu_set()
timing_jmp_rm = 17;
timing_jmp_pm = 19;
timing_jmp_pm_gate = 32;
timing_misaligned = 3;
break;
case CPU_Cx486S:
@@ -1016,6 +1091,7 @@ void cpu_set()
timing_jmp_rm = 9;
timing_jmp_pm = 26;
timing_jmp_pm_gate = 37;
timing_misaligned = 3;
break;
case CPU_Cx5x86:
@@ -1048,6 +1124,8 @@ void cpu_set()
timing_jmp_rm = 5;
timing_jmp_pm = 7;
timing_jmp_pm_gate = 17;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
break;
case CPU_WINCHIP:
@@ -1086,6 +1164,8 @@ void cpu_set()
timing_jmp_pm = 7;
timing_jmp_pm_gate = 17;
codegen_timing_set(&codegen_timing_winchip);
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
break;
case CPU_PENTIUM:
@@ -1118,6 +1198,7 @@ void cpu_set()
timing_jmp_rm = 3;
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
@@ -1157,6 +1238,7 @@ void cpu_set()
timing_jmp_rm = 3;
timing_jmp_pm = 3;
timing_jmp_pm_gate = 18;
timing_misaligned = 3;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
@@ -1195,6 +1277,8 @@ void cpu_set()
timing_jmp_rm = 1;
timing_jmp_pm = 4;
timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
@@ -1233,6 +1317,8 @@ void cpu_set()
timing_jmp_rm = 1;
timing_jmp_pm = 4;
timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
@@ -1254,6 +1340,8 @@ void cpu_set()
timing_mml = 2;
timing_bt = 5-1; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
@@ -1305,6 +1393,8 @@ void cpu_set()
timing_jmp_rm = 1;
timing_jmp_pm = 4;
timing_jmp_pm_gate = 14;
timing_misaligned = 2;
cpu_cyrix_alignment = 1;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
@@ -1327,6 +1417,7 @@ void cpu_set()
timing_mml = 3;
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
@@ -1346,6 +1437,7 @@ void cpu_set()
timing_mml = 3;
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
@@ -1378,6 +1470,7 @@ void cpu_set()
timing_mml = 1;
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 0;
@@ -1411,6 +1504,7 @@ void cpu_set()
timing_mml = 1;
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
@@ -1444,6 +1538,7 @@ void cpu_set()
timing_mml = 1;
timing_bt = 0; /*branch taken*/
timing_bnt = 1; /*branch not taken*/
timing_misaligned = 3;
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = 1;
@@ -1823,8 +1918,6 @@ void cpu_CPUID()
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_CMOV;
// EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_CMOV;
// EDX = 0x0183FBFF;
}
else if (EAX == 2)
{
@@ -1849,8 +1942,6 @@ void cpu_CPUID()
EAX = CPUID;
EBX = ECX = 0;
EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_FXSR | CPUID_CMOV;
// EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_FXSR | CPUID_CMOV;
// EDX = 0x0183FBFF;
}
else if (EAX == 2)
{
@@ -1939,9 +2030,9 @@ void cpu_RDMSR()
switch (ECX)
{
case 0x10:
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
break;
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
break;
}
break;
case CPU_Cx6x86:
@@ -1958,10 +2049,8 @@ void cpu_RDMSR()
break;
case CPU_PENTIUMPRO:
// case CPU_PENTIUM2:
case CPU_PENTIUM2D:
EAX = EDX = 0;
// pclog("RDMSR, ECX=%08X\n", ECX);
switch (ECX)
{
case 0x10:
@@ -1985,11 +2074,11 @@ void cpu_RDMSR()
EAX = ecx79_msr & 0xffffffff;
EDX = ecx79_msr >> 32;
break;
case 0x88 ... 0x8B:
case 0x88: case 0x89: case 0x8A: case 0x8B:
EAX = ecx8x_msr[ECX - 0x88] & 0xffffffff;
EDX = ecx8x_msr[ECX - 0x88] >> 32;
break;
case 0xC1 ... 0xC8:
case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8:
EAX = msr_ia32_pmc[ECX - 0xC1] & 0xffffffff;
EDX = msr_ia32_pmc[ECX - 0xC1] >> 32;
break;
@@ -2001,7 +2090,7 @@ void cpu_RDMSR()
EAX = ecx116_msr & 0xffffffff;
EDX = ecx116_msr >> 32;
break;
case 0x118 ... 0x11B:
case 0x118: case 0x119: case 0x11A: case 0x11B:
EAX = ecx11x_msr[ECX - 0x118] & 0xffffffff;
EDX = ecx11x_msr[ECX - 0x118] >> 32;
break;
@@ -2034,7 +2123,8 @@ void cpu_RDMSR()
EAX = ecx1e0_msr & 0xffffffff;
EDX = ecx1e0_msr >> 32;
break;
case 0x200 ... 0x20F:
case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207:
case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F:
if (ECX & 1)
{
EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff;
@@ -2058,8 +2148,7 @@ void cpu_RDMSR()
EAX = mtrr_fix16k_a000_msr & 0xffffffff;
EDX = mtrr_fix16k_a000_msr >> 32;
break;
case 0x268 ... 0x26F:
// ((ECX - 0x268) * 0x8000)
case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F:
EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff;
EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32;
break;
@@ -2150,8 +2239,8 @@ void cpu_WRMSR()
switch (ECX)
{
case 0x10:
tsc = EAX | ((uint64_t)EDX << 32);
break;
tsc = EAX | ((uint64_t)EDX << 32);
break;
}
break;
case CPU_Cx6x86:
@@ -2167,9 +2256,7 @@ void cpu_WRMSR()
break;
case CPU_PENTIUMPRO:
// case CPU_PENTIUM2:
case CPU_PENTIUM2D:
// pclog("WRMSR, ECX=%08X\n", ECX);
switch (ECX)
{
case 0x10:
@@ -2185,10 +2272,10 @@ void cpu_WRMSR()
case 0x79:
ecx79_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x88 ... 0x8B:
case 0x88: case 0x89: case 0x8A: case 0x8B:
ecx8x_msr[ECX - 0x88] = EAX | ((uint64_t)EDX << 32);
break;
case 0xC1 ... 0xC8:
case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8:
msr_ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32);
break;
case 0xFE:
@@ -2197,7 +2284,7 @@ void cpu_WRMSR()
case 0x116:
ecx116_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x118 ... 0x011B:
case 0x118: case 0x119: case 0x11A: case 0x11B:
ecx11x_msr[ECX - 0x118] = EAX | ((uint64_t)EDX << 32);
break;
case 0x11E:
@@ -2205,17 +2292,14 @@ void cpu_WRMSR()
break;
case 0x174:
if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
// pclog("WRMSR SYSENTER_CS: old=%04X, new=%04X\n", cs_msr, (uint16_t) (EAX & 0xFFFF));
cs_msr = EAX & 0xFFFF;
break;
case 0x175:
if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
// pclog("WRMSR SYSENTER_ESP: old=%08X, new=%08X\n", esp_msr, EAX);
esp_msr = EAX;
break;
case 0x176:
if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr;
// pclog("WRMSR SYSENTER_EIP: old=%08X, new=%08X\n", eip_msr, EAX);
eip_msr = EAX;
break;
case 0x186:
@@ -2227,7 +2311,8 @@ void cpu_WRMSR()
case 0x1E0:
ecx1e0_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x200 ... 0x20F:
case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207:
case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F:
if (ECX & 1)
mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32);
else
@@ -2242,8 +2327,7 @@ void cpu_WRMSR()
case 0x259:
mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32);
break;
case 0x268 ... 0x26F:
// ((ECX - 0x268) * 0x8000)
case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F:
mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32);
break;
case 0x277:

View File

@@ -1,6 +1,23 @@
/* Copyright holders: Sarah Walker, Tenshi, leilei
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* CPU type handler.
*
* Version: @(#)cpu.h 1.0.0 2017/05/30
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* leilei,
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 leilei.
* Copyright 2016-2017 Miran Grca.
*/
#ifndef _CPU_H_
#define _CPU_H_
@@ -65,6 +82,8 @@ extern int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_g
extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer;
extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate;
extern int timing_misaligned;
typedef struct
{
@@ -85,11 +104,11 @@ typedef struct
extern CPU cpus_8088[];
extern CPU cpus_8086[];
extern CPU cpus_286[];
extern CPU cpus_i386[];
extern CPU cpus_i386SX[];
extern CPU cpus_i386DX[];
extern CPU cpus_Am386[];
extern CPU cpus_Am386SX[];
extern CPU cpus_Am386DX[];
extern CPU cpus_486SDLC[];
extern CPU cpus_486SLC[];
extern CPU cpus_486DLC[];
extern CPU cpus_i486[];
extern CPU cpus_Am486[];
@@ -107,15 +126,19 @@ extern CPU cpus_Pentium2[];
extern CPU cpus_Pentium2D[];
extern CPU cpus_pcjr[];
extern CPU cpus_europc[];
extern CPU cpus_pc1512[];
extern CPU cpus_ibmat[];
extern CPU cpus_ps1_m2011[];
extern CPU cpus_ps2_m30_286[];
extern CPU cpus_acer[];
extern int cpu_iscyrix;
extern int cpu_16bitbus;
extern int cpu_busspeed;
extern int cpu_multi;
/*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/
extern int cpu_cyrix_alignment;
extern int cpu_hasrdtsc;
extern int cpu_hasMSR;
@@ -132,12 +155,12 @@ extern uint64_t cpu_CR4_mask;
#define CPU_SUPPORTS_DYNAREC 1
#define CPU_REQUIRES_DYNAREC 2
// #define CPU_REQUIRES_DYNAREC 0
extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l;
extern int cpu_prefetch_cycles, cpu_prefetch_width;
extern int cpu_waitstates;
extern int cpu_cache_int_enabled, cpu_cache_ext_enabled;
extern int cpu_pci_speed;
extern uint64_t tsc;
@@ -160,5 +183,6 @@ extern int isa_cycles;
#define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT)
void cpu_update_waitstates();
void cpu_set();
#endif

View File

@@ -102,3 +102,6 @@ void x86gpf(char *s, uint16_t error);
extern uint16_t zero;
extern int x86_was_reset;
extern int codegen_flat_ds;
extern int codegen_flat_ss;

View File

@@ -35,10 +35,10 @@ enum
FLAGS_DEC8,
FLAGS_DEC16,
FLAGS_DEC32,
FLAGS_DEC32
};
static inline int ZF_SET()
static __inline int ZF_SET()
{
switch (cpu_state.flags_op)
{
@@ -70,10 +70,13 @@ static inline int ZF_SET()
case FLAGS_UNKNOWN:
return flags & Z_FLAG;
default:
return 0;
}
}
static inline int NF_SET()
static __inline int NF_SET()
{
switch (cpu_state.flags_op)
{
@@ -109,10 +112,13 @@ static inline int NF_SET()
case FLAGS_UNKNOWN:
return flags & N_FLAG;
default:
return 0;
}
}
static inline int PF_SET()
static __inline int PF_SET()
{
switch (cpu_state.flags_op)
{
@@ -144,10 +150,13 @@ static inline int PF_SET()
case FLAGS_UNKNOWN:
return flags & P_FLAG;
default:
return 0;
}
}
static inline int VF_SET()
static __inline int VF_SET()
{
switch (cpu_state.flags_op)
{
@@ -195,10 +204,13 @@ static inline int VF_SET()
case FLAGS_UNKNOWN:
return flags & V_FLAG;
default:
return 0;
}
}
static inline int AF_SET()
static __inline int AF_SET()
{
switch (cpu_state.flags_op)
{
@@ -234,10 +246,13 @@ static inline int AF_SET()
case FLAGS_UNKNOWN:
return flags & A_FLAG;
default:
return 0;
}
}
static inline int CF_SET()
static __inline int CF_SET()
{
switch (cpu_state.flags_op)
{
@@ -285,17 +300,13 @@ static inline int CF_SET()
case FLAGS_INC32:
case FLAGS_UNKNOWN:
return flags & C_FLAG;
default:
return 0;
}
}
//#define ZF_SET() (flags & Z_FLAG)
//#define NF_SET() (flags & N_FLAG)
//#define PF_SET() (flags & P_FLAG)
//#define VF_SET() (flags & V_FLAG)
//#define CF_SET() (flags & C_FLAG)
//#define AF_SET() (flags & A_FLAG)
static inline void flags_rebuild()
static __inline void flags_rebuild()
{
if (cpu_state.flags_op != FLAGS_UNKNOWN)
{
@@ -311,12 +322,12 @@ static inline void flags_rebuild()
}
}
static inline void flags_extract()
static __inline void flags_extract()
{
cpu_state.flags_op = FLAGS_UNKNOWN;
}
static inline void flags_rebuild_c()
static __inline void flags_rebuild_c()
{
if (cpu_state.flags_op != FLAGS_UNKNOWN)
{
@@ -327,17 +338,17 @@ static inline void flags_rebuild_c()
}
}
static inline void setznp8(uint8_t val)
static __inline void setznp8(uint8_t val)
{
cpu_state.flags_op = FLAGS_ZN8;
cpu_state.flags_res = val;
}
static inline void setznp16(uint16_t val)
static __inline void setznp16(uint16_t val)
{
cpu_state.flags_op = FLAGS_ZN16;
cpu_state.flags_res = val;
}
static inline void setznp32(uint32_t val)
static __inline void setznp32(uint32_t val)
{
cpu_state.flags_op = FLAGS_ZN32;
cpu_state.flags_res = val;
@@ -349,28 +360,28 @@ static inline void setznp32(uint32_t val)
cpu_state.flags_op1 = orig; \
cpu_state.flags_op2 = shift;
static inline void setadd8(uint8_t a, uint8_t b)
static __inline void setadd8(uint8_t a, uint8_t b)
{
cpu_state.flags_op1 = a;
cpu_state.flags_op2 = b;
cpu_state.flags_res = (a + b) & 0xff;
cpu_state.flags_op = FLAGS_ADD8;
}
static inline void setadd16(uint16_t a, uint16_t b)
static __inline void setadd16(uint16_t a, uint16_t b)
{
cpu_state.flags_op1 = a;
cpu_state.flags_op2 = b;
cpu_state.flags_res = (a + b) & 0xffff;
cpu_state.flags_op = FLAGS_ADD16;
}
static inline void setadd32(uint32_t a, uint32_t b)
static __inline void setadd32(uint32_t a, uint32_t b)
{
cpu_state.flags_op1 = a;
cpu_state.flags_op2 = b;
cpu_state.flags_res = a + b;
cpu_state.flags_op = FLAGS_ADD32;
}
static inline void setadd8nc(uint8_t a, uint8_t b)
static __inline void setadd8nc(uint8_t a, uint8_t b)
{
flags_rebuild_c();
cpu_state.flags_op1 = a;
@@ -378,7 +389,7 @@ static inline void setadd8nc(uint8_t a, uint8_t b)
cpu_state.flags_res = (a + b) & 0xff;
cpu_state.flags_op = FLAGS_INC8;
}
static inline void setadd16nc(uint16_t a, uint16_t b)
static __inline void setadd16nc(uint16_t a, uint16_t b)
{
flags_rebuild_c();
cpu_state.flags_op1 = a;
@@ -386,7 +397,7 @@ static inline void setadd16nc(uint16_t a, uint16_t b)
cpu_state.flags_res = (a + b) & 0xffff;
cpu_state.flags_op = FLAGS_INC16;
}
static inline void setadd32nc(uint32_t a, uint32_t b)
static __inline void setadd32nc(uint32_t a, uint32_t b)
{
flags_rebuild_c();
cpu_state.flags_op1 = a;
@@ -395,21 +406,21 @@ static inline void setadd32nc(uint32_t a, uint32_t b)
cpu_state.flags_op = FLAGS_INC32;
}
static inline void setsub8(uint8_t a, uint8_t b)
static __inline void setsub8(uint8_t a, uint8_t b)
{
cpu_state.flags_op1 = a;
cpu_state.flags_op2 = b;
cpu_state.flags_res = (a - b) & 0xff;
cpu_state.flags_op = FLAGS_SUB8;
}
static inline void setsub16(uint16_t a, uint16_t b)
static __inline void setsub16(uint16_t a, uint16_t b)
{
cpu_state.flags_op1 = a;
cpu_state.flags_op2 = b;
cpu_state.flags_res = (a - b) & 0xffff;
cpu_state.flags_op = FLAGS_SUB16;
}
static inline void setsub32(uint32_t a, uint32_t b)
static __inline void setsub32(uint32_t a, uint32_t b)
{
cpu_state.flags_op1 = a;
cpu_state.flags_op2 = b;
@@ -417,7 +428,7 @@ static inline void setsub32(uint32_t a, uint32_t b)
cpu_state.flags_op = FLAGS_SUB32;
}
static inline void setsub8nc(uint8_t a, uint8_t b)
static __inline void setsub8nc(uint8_t a, uint8_t b)
{
flags_rebuild_c();
cpu_state.flags_op1 = a;
@@ -425,7 +436,7 @@ static inline void setsub8nc(uint8_t a, uint8_t b)
cpu_state.flags_res = (a - b) & 0xff;
cpu_state.flags_op = FLAGS_DEC8;
}
static inline void setsub16nc(uint16_t a, uint16_t b)
static __inline void setsub16nc(uint16_t a, uint16_t b)
{
flags_rebuild_c();
cpu_state.flags_op1 = a;
@@ -433,7 +444,7 @@ static inline void setsub16nc(uint16_t a, uint16_t b)
cpu_state.flags_res = (a - b) & 0xffff;
cpu_state.flags_op = FLAGS_DEC16;
}
static inline void setsub32nc(uint32_t a, uint32_t b)
static __inline void setsub32nc(uint32_t a, uint32_t b)
{
flags_rebuild_c();
cpu_state.flags_op1 = a;
@@ -442,7 +453,7 @@ static inline void setsub32nc(uint32_t a, uint32_t b)
cpu_state.flags_op = FLAGS_DEC32;
}
static inline void setadc8(uint8_t a, uint8_t b)
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;
@@ -452,7 +463,7 @@ static inline void setadc8(uint8_t a, uint8_t b)
if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG;
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
}
static inline void setadc16(uint16_t a, uint16_t b)
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;
@@ -463,7 +474,7 @@ static inline void setadc16(uint16_t a, uint16_t b)
if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG;
}
static inline void setsbc8(uint8_t a, uint8_t b)
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;
@@ -473,7 +484,7 @@ static inline void setsbc8(uint8_t a, uint8_t b)
if ((a^b)&(a^c)&0x80) flags|=V_FLAG;
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
}
static inline void setsbc16(uint16_t a, uint16_t b)
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;
@@ -485,7 +496,7 @@ static inline void setsbc16(uint16_t a, uint16_t b)
if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG;
}
static inline void setadc32(uint32_t a, uint32_t b)
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;
@@ -496,7 +507,7 @@ static inline void setadc32(uint32_t a, uint32_t b)
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)
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;

View File

@@ -46,6 +46,21 @@ extern OpFn dynarec_ops_k6_0f[1024];
extern OpFn dynarec_ops_pentiumpro_0f[1024];
extern OpFn dynarec_ops_pentium2d_0f[1024];
extern OpFn dynarec_ops_fpu_287_d9_a16[256];
extern OpFn dynarec_ops_fpu_287_d9_a32[256];
extern OpFn dynarec_ops_fpu_287_da_a16[256];
extern OpFn dynarec_ops_fpu_287_da_a32[256];
extern OpFn dynarec_ops_fpu_287_db_a16[256];
extern OpFn dynarec_ops_fpu_287_db_a32[256];
extern OpFn dynarec_ops_fpu_287_dc_a16[32];
extern OpFn dynarec_ops_fpu_287_dc_a32[32];
extern OpFn dynarec_ops_fpu_287_dd_a16[256];
extern OpFn dynarec_ops_fpu_287_dd_a32[256];
extern OpFn dynarec_ops_fpu_287_de_a16[256];
extern OpFn dynarec_ops_fpu_287_de_a32[256];
extern OpFn dynarec_ops_fpu_287_df_a16[256];
extern OpFn dynarec_ops_fpu_287_df_a32[256];
extern OpFn dynarec_ops_fpu_d8_a16[32];
extern OpFn dynarec_ops_fpu_d8_a32[32];
extern OpFn dynarec_ops_fpu_d9_a16[256];
@@ -111,6 +126,21 @@ extern OpFn ops_k6_0f[1024];
extern OpFn ops_pentiumpro_0f[1024];
extern OpFn ops_pentium2d_0f[1024];
extern OpFn ops_fpu_287_d9_a16[256];
extern OpFn ops_fpu_287_d9_a32[256];
extern OpFn ops_fpu_287_da_a16[256];
extern OpFn ops_fpu_287_da_a32[256];
extern OpFn ops_fpu_287_db_a16[256];
extern OpFn ops_fpu_287_db_a32[256];
extern OpFn ops_fpu_287_dc_a16[32];
extern OpFn ops_fpu_287_dc_a32[32];
extern OpFn ops_fpu_287_dd_a16[256];
extern OpFn ops_fpu_287_dd_a32[256];
extern OpFn ops_fpu_287_de_a16[256];
extern OpFn ops_fpu_287_de_a32[256];
extern OpFn ops_fpu_287_df_a16[256];
extern OpFn ops_fpu_287_df_a32[256];
extern OpFn ops_fpu_d8_a16[32];
extern OpFn ops_fpu_d8_a32[32];
extern OpFn ops_fpu_d9_a16[256];

View File

@@ -1,12 +1,14 @@
#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) \
{ \
uint8_t dst = getr8(cpu_rm); \
uint8_t src = getr8(cpu_reg); \
dst = getr8(cpu_rm); \
src = getr8(cpu_reg); \
setflags ## 8 flagops; \
setr8(cpu_rm, operation); \
CLOCK_CYCLES(timing_rr); \
@@ -14,8 +16,8 @@
} \
else \
{ \
uint8_t dst = geteab(); if (cpu_state.abrt) return 1; \
uint8_t src = getr8(cpu_reg); \
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); \
@@ -25,12 +27,14 @@
} \
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) \
{ \
uint8_t dst = getr8(cpu_rm); \
uint8_t src = getr8(cpu_reg); \
dst = getr8(cpu_rm); \
src = getr8(cpu_reg); \
setflags ## 8 flagops; \
setr8(cpu_rm, operation); \
CLOCK_CYCLES(timing_rr); \
@@ -38,8 +42,8 @@
} \
else \
{ \
uint8_t dst = geteab(); if (cpu_state.abrt) return 1; \
uint8_t src = getr8(cpu_reg); \
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); \
@@ -50,12 +54,14 @@
\
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) \
{ \
uint16_t dst = cpu_state.regs[cpu_rm].w; \
uint16_t src = cpu_state.regs[cpu_reg].w; \
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); \
@@ -63,8 +69,8 @@
} \
else \
{ \
uint16_t dst = geteaw(); if (cpu_state.abrt) return 1; \
uint16_t src = cpu_state.regs[cpu_reg].w; \
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); \
@@ -74,12 +80,14 @@
} \
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) \
{ \
uint16_t dst = cpu_state.regs[cpu_rm].w; \
uint16_t src = cpu_state.regs[cpu_reg].w; \
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); \
@@ -87,8 +95,8 @@
} \
else \
{ \
uint16_t dst = geteaw(); if (cpu_state.abrt) return 1; \
uint16_t src = cpu_state.regs[cpu_reg].w; \
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); \
@@ -99,12 +107,14 @@
\
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) \
{ \
uint32_t dst = cpu_state.regs[cpu_rm].l; \
uint32_t src = cpu_state.regs[cpu_reg].l; \
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); \
@@ -112,8 +122,8 @@
} \
else \
{ \
uint32_t dst = geteal(); if (cpu_state.abrt) return 1; \
uint32_t src = cpu_state.regs[cpu_reg].l; \
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); \
@@ -123,12 +133,14 @@
} \
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) \
{ \
uint32_t dst = cpu_state.regs[cpu_rm].l; \
uint32_t src = cpu_state.regs[cpu_reg].l; \
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); \
@@ -136,8 +148,8 @@
} \
else \
{ \
uint32_t dst = geteal(); if (cpu_state.abrt) return 1; \
uint32_t src = cpu_state.regs[cpu_reg].l; \
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); \

View File

@@ -1,5 +1,6 @@
#define BS_common(start, end, dir, dest, time) \
flags_rebuild(); \
instr_cycles = 0; \
if (temp) \
{ \
int c; \
@@ -21,7 +22,7 @@
static int opBSF_w_a16(uint32_t fetchdat)
{
uint16_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_16(fetchdat);
temp = geteaw(); if (cpu_state.abrt) return 1;
@@ -36,7 +37,7 @@ static int opBSF_w_a16(uint32_t fetchdat)
static int opBSF_w_a32(uint32_t fetchdat)
{
uint16_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_32(fetchdat);
temp = geteaw(); if (cpu_state.abrt) return 1;
@@ -51,7 +52,7 @@ static int opBSF_w_a32(uint32_t fetchdat)
static int opBSF_l_a16(uint32_t fetchdat)
{
uint32_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_16(fetchdat);
temp = geteal(); if (cpu_state.abrt) return 1;
@@ -66,7 +67,7 @@ static int opBSF_l_a16(uint32_t fetchdat)
static int opBSF_l_a32(uint32_t fetchdat)
{
uint32_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_32(fetchdat);
temp = geteal(); if (cpu_state.abrt) return 1;
@@ -82,7 +83,7 @@ static int opBSF_l_a32(uint32_t fetchdat)
static int opBSR_w_a16(uint32_t fetchdat)
{
uint16_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_16(fetchdat);
temp = geteaw(); if (cpu_state.abrt) return 1;
@@ -97,7 +98,7 @@ static int opBSR_w_a16(uint32_t fetchdat)
static int opBSR_w_a32(uint32_t fetchdat)
{
uint16_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_32(fetchdat);
temp = geteaw(); if (cpu_state.abrt) return 1;
@@ -112,7 +113,7 @@ static int opBSR_w_a32(uint32_t fetchdat)
static int opBSR_l_a16(uint32_t fetchdat)
{
uint32_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_16(fetchdat);
temp = geteal(); if (cpu_state.abrt) return 1;
@@ -127,7 +128,7 @@ static int opBSR_l_a16(uint32_t fetchdat)
static int opBSR_l_a32(uint32_t fetchdat)
{
uint32_t temp;
int instr_cycles;
int instr_cycles = 0;
fetch_ea_32(fetchdat);
temp = geteal(); if (cpu_state.abrt) return 1;

View File

@@ -61,7 +61,7 @@ static int opCALL_far_w(uint32_t fetchdat)
{
uint32_t old_cs, old_pc;
uint16_t new_cs, new_pc;
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
new_pc = getwordf();
new_cs = getword(); if (cpu_state.abrt) return 1;
@@ -77,7 +77,7 @@ static int opCALL_far_l(uint32_t fetchdat)
{
uint32_t old_cs, old_pc;
uint32_t new_cs, new_pc;
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
new_pc = getlong();
new_cs = getword(); if (cpu_state.abrt) return 1;
@@ -95,7 +95,7 @@ static int opFF_w_a16(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
uint16_t temp;
@@ -172,7 +172,7 @@ static int opFF_w_a32(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
uint16_t temp;
@@ -250,7 +250,7 @@ static int opFF_l_a16(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
uint32_t temp;
@@ -327,7 +327,7 @@ static int opFF_l_a32(uint32_t fetchdat)
{
uint16_t old_cs, new_cs;
uint32_t old_pc, new_pc;
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
uint32_t temp;

View File

@@ -1,6 +1,19 @@
/* Copyright holders: Sarah Walker, Tenshi
see COPYING for more details
*/
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* x86 i686 (Pentium Pro/Pentium II) CPU Instructions.
*
* Version: @(#)x86_ops_i686.h 1.0.0 2017/05/30
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2017 Miran Grca.
*/
static int internal_illegal(char *s)
{
cpu_state.pc = cpu_state.oldpc;
@@ -33,16 +46,20 @@ static int opSYSENTER(uint32_t fetchdat)
uint16_t sysenter_cs_seg_data[4];
uint16_t sysenter_ss_seg_data[4];
#ifdef SYSENTER_LOG
pclog("SYSENTER called\n");
#endif
if (!(cr0 & 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
pclog("SYSENTER started:\n");
pclog("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);
pclog("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);
pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32);
#endif
if (cpu_state.abrt) return 1;
@@ -72,11 +89,13 @@ static int opSYSENTER(uint32_t fetchdat)
CPU_BLOCK_END();
#ifdef SYSENTER_LOG
pclog("SYSENTER completed:\n");
pclog("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);
pclog("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);
pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32);
#endif
return 0;
}
@@ -86,17 +105,21 @@ static int opSYSEXIT(uint32_t fetchdat)
uint16_t sysexit_cs_seg_data[4];
uint16_t sysexit_ss_seg_data[4];
#ifdef SYSEXIT_LOG
pclog("SYSEXIT called\n");
#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");
#ifdef SYSEXIT_LOG
pclog("SYSEXIT start:\n");
pclog("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);
pclog("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);
pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
pclog("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);
#endif
if (cpu_state.abrt) return 1;
@@ -124,11 +147,13 @@ static int opSYSEXIT(uint32_t fetchdat)
CPU_BLOCK_END();
#ifdef SYSEXIT_LOG
pclog("SYSEXIT completed:\n");
pclog("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);
pclog("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);
pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr);
pclog("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);
#endif
return 0;
}
@@ -138,10 +163,10 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
uint8_t fxinst = 0;
uint16_t twd = x87_gettag();
uint16_t old_eaaddr = 0;
int old_ismmx = cpu_state.ismmx;
uint8_t ftwb = 0;
uint16_t rec_ftw = 0;
uint16_t fpus = 0;
uint64_t *p;
if (CPUID < 0x650) return ILLEGAL(fetchdat);
@@ -160,9 +185,6 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
if ((fxinst > 1) || (cpu_mod == 3))
{
// if (fxinst > 1) pclog("FX instruction is: %02X\n", fxinst);
// if (cpu_mod == 3) pclog("MOD is 3\n");
x86illegal();
return cpu_state.abrt;
}
@@ -174,8 +196,6 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
if (fxinst == 1)
{
/* FXRSTOR */
// pclog("FXRSTOR issued\n");
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
fpus = readmemw(easeg, cpu_state.eaaddr + 2);
cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040;
@@ -239,10 +259,11 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
cpu_state.ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
if (cpu_state.MM[0].w[4] == 0xffff && cpu_state.MM[1].w[4] == 0xffff && cpu_state.MM[2].w[4] == 0xffff && cpu_state.MM[3].w[4] == 0xffff &&
cpu_state.MM[4].w[4] == 0xffff && cpu_state.MM[5].w[4] == 0xffff && cpu_state.MM[6].w[4] == 0xffff && cpu_state.MM[7].w[4] == 0xffff &&
!cpu_state.TOP && !(*(uint64_t *)cpu_state.tag))
cpu_state.ismmx = old_ismmx;
p = (uint64_t *)cpu_state.tag;
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && !(*p))
cpu_state.ismmx = 1;
x87_settag(rec_ftw);
@@ -253,8 +274,6 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
else
{
/* FXSAVE */
// pclog("FXSAVE issued\n");
if ((twd & 0x0003) == 0x0003) ftwb |= 0x01;
if ((twd & 0x000C) == 0x000C) ftwb |= 0x02;
if ((twd & 0x0030) == 0x0030) ftwb |= 0x04;
@@ -301,6 +320,14 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat)
cpu_state.eaaddr = old_eaaddr;
cpu_state.npxc = 0x37F;
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0x0303030303030303ll;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
if(cpu_state.abrt) pclog("FXSAVE: abrt != 0\n");
@@ -314,10 +341,10 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
uint8_t fxinst = 0;
uint16_t twd = x87_gettag();
uint32_t old_eaaddr = 0;
int old_ismmx = cpu_state.ismmx;
uint8_t ftwb = 0;
uint16_t rec_ftw = 0;
uint16_t fpus = 0;
uint64_t *p;
if (CPUID < 0x650) return ILLEGAL(fetchdat);
@@ -336,9 +363,6 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
if ((fxinst > 1) || (cpu_mod == 3))
{
// if (fxinst > 1) pclog("FX instruction is: %02X\n", fxinst);
// if (cpu_mod == 3) pclog("MOD is 3\n");
x86illegal();
return cpu_state.abrt;
}
@@ -350,8 +374,6 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
if (fxinst == 1)
{
/* FXRSTOR */
// pclog("FXRSTOR issued\n");
cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr);
fpus = readmemw(easeg, cpu_state.eaaddr + 2);
cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040;
@@ -415,10 +437,11 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
cpu_state.ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
if (cpu_state.MM[0].w[4] == 0xffff && cpu_state.MM[1].w[4] == 0xffff && cpu_state.MM[2].w[4] == 0xffff && cpu_state.MM[3].w[4] == 0xffff &&
cpu_state.MM[4].w[4] == 0xffff && cpu_state.MM[5].w[4] == 0xffff && cpu_state.MM[6].w[4] == 0xffff && cpu_state.MM[7].w[4] == 0xffff &&
!cpu_state.TOP && !(*(uint64_t *)cpu_state.tag))
cpu_state.ismmx = old_ismmx;
p = (uint64_t *)cpu_state.tag;
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && !(*p))
cpu_state.ismmx = 1;
x87_settag(rec_ftw);
@@ -429,8 +452,6 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
else
{
/* FXSAVE */
// pclog("FXSAVE issued\n");
if ((twd & 0x0003) == 0x0003) ftwb |= 0x01;
if ((twd & 0x000C) == 0x000C) ftwb |= 0x02;
if ((twd & 0x0030) == 0x0030) ftwb |= 0x04;
@@ -477,6 +498,14 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat)
cpu_state.eaaddr = old_eaaddr;
cpu_state.npxc = 0x37F;
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0x0303030303030303ll;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
if(cpu_state.abrt) pclog("FXSAVE: abrt != 0\n");

View File

@@ -1,6 +1,6 @@
static int opINT3(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);
@@ -12,9 +12,23 @@ static int opINT3(uint32_t fetchdat)
return 1;
}
static int opINT1(uint32_t fetchdat)
{
int cycles_old = cycles; UNUSED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
{
x86gpf(NULL,0);
return 1;
}
x86_int_sw(1);
CLOCK_CYCLES((is486) ? 44 : 59);
PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0);
return 1;
}
static int opINT(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
uint8_t temp;
/*if (msw&1) pclog("INT %i %i %i\n",cr0&1,eflags&VM_FLAG,IOPL);*/
@@ -64,7 +78,7 @@ static int opINT(uint32_t fetchdat)
static int opINTO(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
{

View File

@@ -103,7 +103,6 @@ static int opOUT_AL_DX(uint32_t fetchdat)
}
static int opOUT_AX_DX(uint32_t fetchdat)
{
//pclog("OUT_AX_DX %04X %04X\n", DX, AX);
check_io_perm(DX);
check_io_perm(DX + 1);
outw(DX, AX);

View File

@@ -246,9 +246,11 @@ static int opJMP_r32(uint32_t fetchdat)
static int opJMP_far_a16(uint32_t fetchdat)
{
uint16_t addr = getwordf();
uint16_t seg = getword(); if (cpu_state.abrt) return 1;
uint32_t oxpc = cpu_state.pc;
uint16_t addr, seg;
uint32_t oxpc;
addr = getwordf();
seg = getword(); if (cpu_state.abrt) return 1;
oxpc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, oxpc);
CPU_BLOCK_END();
@@ -258,9 +260,11 @@ static int opJMP_far_a16(uint32_t fetchdat)
}
static int opJMP_far_a32(uint32_t fetchdat)
{
uint32_t addr = getlong();
uint16_t seg = getword(); if (cpu_state.abrt) return 1;
uint32_t oxpc = cpu_state.pc;
uint16_t seg;
uint32_t addr, oxpc;
addr = getlong();
seg = getword(); if (cpu_state.abrt) return 1;
oxpc = cpu_state.pc;
cpu_state.pc = addr;
loadcsjmp(seg, oxpc);
CPU_BLOCK_END();
@@ -321,8 +325,8 @@ static int opRET_l(uint32_t fetchdat)
static int opRET_w_imm(uint32_t fetchdat)
{
uint16_t offset = getwordf();
uint16_t ret;
uint16_t offset = getwordf();
ret = POP_W(); if (cpu_state.abrt) return 1;
if (stack32) ESP += offset;
@@ -337,8 +341,8 @@ static int opRET_w_imm(uint32_t fetchdat)
}
static int opRET_l_imm(uint32_t fetchdat)
{
uint16_t offset = getwordf();
uint32_t ret;
uint16_t offset = getwordf();
ret = POP_L(); if (cpu_state.abrt) return 1;
if (stack32) ESP += offset;

View File

@@ -1,3 +1,21 @@
/*
* 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.
*
* Miscellaneous x86 CPU Instructions.
*
* Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
*/
static int opCBW(uint32_t fetchdat)
{
AH = (AL & 0x80) ? 0xff : 0;
@@ -56,6 +74,7 @@ static int opF6_a16(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*TEST b,#8*/
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);
@@ -127,7 +146,6 @@ static int opF6_a16(uint32_t fetchdat)
}
else
{
// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2);
x86_int(0);
return 1;
}
@@ -153,6 +171,7 @@ static int opF6_a32(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*TEST b,#8*/
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);
@@ -224,7 +243,6 @@ static int opF6_a32(uint32_t fetchdat)
}
else
{
// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2);
x86_int(0);
return 1;
}
@@ -253,6 +271,7 @@ static int opF7_w_a16(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*TEST w*/
case 0x08:
src = getword(); if (cpu_state.abrt) return 1;
setznp16(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -301,7 +320,6 @@ static int opF7_w_a16(uint32_t fetchdat)
}
else
{
// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins);
x86_int(0);
return 1;
}
@@ -320,7 +338,6 @@ static int opF7_w_a16(uint32_t fetchdat)
}
else
{
// pclog("IDIVw exception - %X / %08X = %X\n",tempws, dst, tempws2);
x86_int(0);
return 1;
}
@@ -346,6 +363,7 @@ static int opF7_w_a32(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*TEST w*/
case 0x08:
src = getword(); if (cpu_state.abrt) return 1;
setznp16(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -394,7 +412,6 @@ static int opF7_w_a32(uint32_t fetchdat)
}
else
{
// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins);
x86_int(0);
return 1;
}
@@ -413,7 +430,6 @@ static int opF7_w_a32(uint32_t fetchdat)
}
else
{
// pclog("IDIVw exception - %X / %08X = %X\n", tempws, dst, tempws2);
x86_int(0);
return 1;
}
@@ -439,6 +455,7 @@ static int opF7_l_a16(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*TEST l*/
case 0x08:
src = getlong(); if (cpu_state.abrt) return 1;
setznp32(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -508,6 +525,7 @@ static int opF7_l_a32(uint32_t fetchdat)
switch (rmdat & 0x38)
{
case 0x00: /*TEST l*/
case 0x08:
src = getlong(); if (cpu_state.abrt) return 1;
setznp32(src & dst);
if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2);
@@ -721,13 +739,19 @@ static int opWBINVD(uint32_t fetchdat)
return 0;
}
static int opLOADALL(uint32_t fetchdat)
{
if (CPL && (cr0&1))
{
x86gpf(NULL,0);
return 1;
}
msw = (msw & 1) | readmemw(0, 0x806);
flags = (readmemw(0, 0x818) & 0xffd5) | 2;
flags_extract();
tr.seg = readmemw(0, 0x816);
cpu_state.pc = readmemw(0, 0x81A);
ldt.seg = readmemw(0, 0x81C);
DS = readmemw(0, 0x81E);
SS = readmemw(0, 0x820);
CS = readmemw(0, 0x822);
@@ -741,14 +765,41 @@ 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);
cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16);
_cs.access = readmemb(0, 0x83F);
_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_cur_status |= CPU_STATUS_FLATSS;
else
cpu_cur_status &= ~CPU_STATUS_FLATSS;
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_cur_status |= CPU_STATUS_FLATDS;
else
cpu_cur_status &= ~CPU_STATUS_FLATDS;
gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16);
gdt.limit = readmemw(0, 0x852);
ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16);
ldt.access = readmemb(0, 0x857);
ldt.limit = readmemw(0, 0x858);
idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16);
idt.limit = readmemw(0, 0x85E);
tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16);
tr.access = readmemb(0, 0x863);
tr.limit = readmemw(0, 0x864);
CLOCK_CYCLES(195);
PREFETCH_RUN(195, 1, -1, 51,0,0,0, 0);
return 0;
}
static int set_segment_limit(x86seg *s, uint8_t segdat3)
static void set_segment_limit(x86seg *s, uint8_t segdat3)
{
if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/
{
@@ -762,7 +813,7 @@ static int set_segment_limit(x86seg *s, uint8_t segdat3)
}
}
static int loadall_load_segment(uint32_t addr, x86seg *s)
static void loadall_load_segment(uint32_t addr, x86seg *s)
{
uint32_t attrib = readmeml(0, addr);
uint32_t segdat3 = (attrib >> 16) & 0xff;
@@ -772,8 +823,29 @@ static int loadall_load_segment(uint32_t addr, x86seg *s)
if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0;
if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0;
cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32);
if (use32)
cpu_cur_status |= CPU_STATUS_USE32;
if (stack32)
cpu_cur_status |= CPU_STATUS_STACK32;
set_segment_limit(s, segdat3);
if (s == &_ds)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status |= CPU_STATUS_FLATDS;
else
cpu_cur_status &= ~CPU_STATUS_FLATDS;
}
if (s == &_ss)
{
if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff)
cpu_cur_status |= CPU_STATUS_FLATSS;
else
cpu_cur_status &= ~CPU_STATUS_FLATSS;
}
}
static int opLOADALL386(uint32_t fetchdat)

View File

@@ -181,6 +181,7 @@ static int opMOV_b_imm_a16(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_16(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
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);
@@ -192,6 +193,7 @@ static int opMOV_b_imm_a32(uint32_t fetchdat)
{
uint8_t temp;
fetch_ea_32(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
temp = getbyte(); if (cpu_state.abrt) return 1;
seteab(temp);
CLOCK_CYCLES(timing_rr);
@@ -203,6 +205,7 @@ static int opMOV_w_imm_a16(uint32_t fetchdat)
{
uint16_t temp;
fetch_ea_16(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
temp = getword(); if (cpu_state.abrt) return 1;
seteaw(temp);
CLOCK_CYCLES(timing_rr);
@@ -213,6 +216,7 @@ static int opMOV_w_imm_a32(uint32_t fetchdat)
{
uint16_t temp;
fetch_ea_32(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
temp = getword(); if (cpu_state.abrt) return 1;
seteaw(temp);
CLOCK_CYCLES(timing_rr);
@@ -223,6 +227,7 @@ static int opMOV_l_imm_a16(uint32_t fetchdat)
{
uint32_t temp;
fetch_ea_16(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
temp = getlong(); if (cpu_state.abrt) return 1;
seteal(temp);
CLOCK_CYCLES(timing_rr);
@@ -233,6 +238,7 @@ static int opMOV_l_imm_a32(uint32_t fetchdat)
{
uint32_t temp;
fetch_ea_32(fetchdat);
ILLEGAL_ON((rmdat & 0x38) != 0);
temp = getlong(); if (cpu_state.abrt) return 1;
seteal(temp);
CLOCK_CYCLES(timing_rr);
@@ -243,8 +249,9 @@ static int opMOV_l_imm_a32(uint32_t fetchdat)
static int opMOV_AL_a16(uint32_t fetchdat)
{
uint8_t temp;
uint16_t addr = getwordf();
uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AL = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0);
@@ -252,8 +259,9 @@ static int opMOV_AL_a16(uint32_t fetchdat)
}
static int opMOV_AL_a32(uint32_t fetchdat)
{
uint8_t temp;
uint32_t addr = getlong();
uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AL = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1);
@@ -261,8 +269,9 @@ static int opMOV_AL_a32(uint32_t fetchdat)
}
static int opMOV_AX_a16(uint32_t fetchdat)
{
uint16_t temp;
uint16_t addr = getwordf();
uint16_t temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0);
@@ -270,8 +279,9 @@ static int opMOV_AX_a16(uint32_t fetchdat)
}
static int opMOV_AX_a32(uint32_t fetchdat)
{
uint16_t temp;
uint32_t addr = getlong();
uint16_t temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
AX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1);
@@ -279,8 +289,9 @@ static int opMOV_AX_a32(uint32_t fetchdat)
}
static int opMOV_EAX_a16(uint32_t fetchdat)
{
uint32_t temp;
uint16_t addr = getwordf();
uint32_t temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
EAX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
PREFETCH_RUN(4, 3, -1, 0,1,0,0, 0);
@@ -288,8 +299,9 @@ static int opMOV_EAX_a16(uint32_t fetchdat)
}
static int opMOV_EAX_a32(uint32_t fetchdat)
{
uint32_t temp;
uint32_t addr = getlong();
uint32_t temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1;
EAX = temp;
CLOCK_CYCLES((is486) ? 1 : 4);
PREFETCH_RUN(4, 5, -1, 0,1,0,0, 1);
@@ -349,7 +361,7 @@ 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);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
@@ -358,7 +370,7 @@ 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);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1);
@@ -368,7 +380,7 @@ 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);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].l = ((cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr) & 0xffff;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0);
@@ -377,7 +389,7 @@ 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);
/* ILLEGAL_ON(cpu_mod == 3); */
cpu_state.regs[cpu_reg].l = (cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr;
CLOCK_CYCLES(timing_rr);
PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1);

View File

@@ -4,7 +4,7 @@ static int opARPL_a16(uint32_t fetchdat)
NOTRM
fetch_ea_16(fetchdat);
pclog("ARPL_a16\n");
/* pclog("ARPL_a16\n"); */
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
@@ -27,7 +27,7 @@ static int opARPL_a32(uint32_t fetchdat)
NOTRM
fetch_ea_32(fetchdat);
pclog("ARPL_a32\n");
/* pclog("ARPL_a32\n"); */
temp_seg = geteaw(); if (cpu_state.abrt) return 1;
flags_rebuild();
@@ -49,7 +49,7 @@ static int opARPL_a32(uint32_t fetchdat)
static int opLAR_ ## name(uint32_t fetchdat) \
{ \
int valid; \
uint16_t sel, desc; \
uint16_t sel, desc = 0; \
\
NOTRM \
fetch_ea(fetchdat); \
@@ -99,7 +99,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1)
static int opLSL_ ## name(uint32_t fetchdat) \
{ \
int valid; \
uint16_t sel, desc; \
uint16_t sel, desc = 0; \
\
NOTRM \
fetch_ea(fetchdat); \
@@ -159,7 +159,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32)
uint16_t desc, sel;
uint8_t access;
// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
/* pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */
switch (rmdat & 0x38)
{
case 0x00: /*SLDT*/
@@ -293,12 +293,12 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
{
uint32_t base;
uint16_t limit, tempw;
// pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc);
/* pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */
switch (rmdat & 0x38)
{
case 0x00: /*SGDT*/
seteaw(gdt.limit);
base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff);
base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */
if (is286)
base |= 0xff000000;
writememl(easeg, cpu_state.eaaddr + 2, base);
@@ -321,10 +321,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
x86gpf(NULL,0);
break;
}
// pclog("LGDT %08X:%08X\n", easeg, eaaddr);
/* pclog("LGDT %08X:%08X\n", easeg, eaaddr); */
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
// pclog(" %08X %04X\n", base, limit);
/* pclog(" %08X %04X\n", base, limit); */
gdt.limit = limit;
gdt.base = base;
if (!is32) gdt.base &= 0xffffff;
@@ -338,10 +338,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
x86gpf(NULL,0);
break;
}
// pclog("LIDT %08X:%08X\n", easeg, eaaddr);
/* pclog("LIDT %08X:%08X\n", easeg, eaaddr); */
limit = geteaw();
base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1;
// pclog(" %08X %04X\n", base, limit);
/* pclog(" %08X %04X\n", base, limit); */
idt.limit = limit;
idt.base = base;
if (!is32) idt.base &= 0xffffff;
@@ -350,8 +350,9 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
break;
case 0x20: /*SMSW*/
if (is486) seteaw(msw);
else seteaw(msw | 0xFF00);
if (is486) seteaw(msw);
else if (is386) seteaw(msw | 0xFF00);
else seteaw(msw | 0xFFF0);
CLOCK_CYCLES(2);
PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
break;
@@ -364,6 +365,7 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32)
}
tempw = geteaw(); if (cpu_state.abrt) return 1;
if (msw & 1) tempw |= 1;
if (!is386) tempw &= 0xF;
msw = tempw;
PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32);
break;

View File

@@ -44,7 +44,7 @@
static int opRETF_a16(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a16(0);
@@ -55,7 +55,7 @@ static int opRETF_a16(uint32_t fetchdat)
}
static int opRETF_a32(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a32(0);
@@ -67,8 +67,8 @@ static int opRETF_a32(uint32_t fetchdat)
static int opRETF_a16_imm(uint32_t fetchdat)
{
int cycles_old = cycles;
uint16_t offset = getwordf();
int cycles_old = cycles; UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a16(offset);
@@ -79,8 +79,8 @@ static int opRETF_a16_imm(uint32_t fetchdat)
}
static int opRETF_a32_imm(uint32_t fetchdat)
{
int cycles_old = cycles;
uint16_t offset = getwordf();
int cycles_old = cycles; UNUSED(cycles_old);
CPU_BLOCK_END();
RETF_a32(offset);
@@ -92,7 +92,7 @@ static int opRETF_a32_imm(uint32_t fetchdat)
static int opIRET_286(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
{
@@ -137,7 +137,7 @@ static int opIRET_286(uint32_t fetchdat)
static int opIRET(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
{
@@ -182,7 +182,7 @@ static int opIRET(uint32_t fetchdat)
static int opIRETD(uint32_t fetchdat)
{
int cycles_old = cycles;
int cycles_old = cycles; UNUSED(cycles_old);
if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3))
{

View File

@@ -497,9 +497,11 @@ static int opD3_l_a32(uint32_t fetchdat)
#define SHLD_w() \
if (count) \
{ \
int tempc; \
uint32_t templ; \
uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \
int tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \
uint32_t templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \
tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \
templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \
if (count <= 16) tempw = templ >> (16 - count); \
else tempw = (templ << count) >> 16; \
seteaw(tempw); if (cpu_state.abrt) return 1; \
@@ -511,8 +513,9 @@ static int opD3_l_a32(uint32_t fetchdat)
#define SHLD_l() \
if (count) \
{ \
int tempc; \
uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \
int tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \
tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \
templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \
seteal(templ); if (cpu_state.abrt) return 1; \
setznp32(templ); \
@@ -523,10 +526,12 @@ static int opD3_l_a32(uint32_t fetchdat)
#define SHRD_w() \
if (count) \
{ \
{ \
int tempc; \
uint32_t templ; \
uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \
int tempc = (tempw >> (count - 1)) & 1; \
uint32_t templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \
tempc = (tempw >> (count - 1)) & 1; \
templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \
tempw = templ >> count; \
seteaw(tempw); if (cpu_state.abrt) return 1; \
setznp16(tempw); \
@@ -537,8 +542,9 @@ static int opD3_l_a32(uint32_t fetchdat)
#define SHRD_l() \
if (count) \
{ \
int tempc; \
uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \
int tempc = (templ >> (count - 1)) & 1; \
tempc = (templ >> (count - 1)) & 1; \
templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \
seteal(templ); if (cpu_state.abrt) return 1; \
setznp32(templ); \
@@ -553,7 +559,7 @@ static int opD3_l_a32(uint32_t fetchdat)
\
fetch_ea_16(fetchdat); \
count = getbyte() & 31; \
operation(); \
operation() \
\
CLOCK_CYCLES(3); \
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \
@@ -565,7 +571,7 @@ static int opD3_l_a32(uint32_t fetchdat)
\
fetch_ea_16(fetchdat); \
count = CL & 31; \
operation(); \
operation() \
\
CLOCK_CYCLES(3); \
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \
@@ -577,7 +583,7 @@ static int opD3_l_a32(uint32_t fetchdat)
\
fetch_ea_32(fetchdat); \
count = getbyte() & 31; \
operation(); \
operation() \
\
CLOCK_CYCLES(3); \
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \
@@ -589,7 +595,7 @@ static int opD3_l_a32(uint32_t fetchdat)
\
fetch_ea_32(fetchdat); \
count = CL & 31; \
operation(); \
operation() \
\
CLOCK_CYCLES(3); \
PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \

View File

@@ -310,10 +310,16 @@ static int opPOPL_a32(uint32_t fetchdat)
static int opENTER_w(uint32_t fetchdat)
{
uint16_t offset = getwordf();
int count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr;
uint16_t offset;
int count;
uint32_t tempEBP, tempESP, frame_ptr;
int reads = 0, writes = 1, instr_cycles = 0;
uint16_t tempw;
offset = getwordf();
count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
tempEBP = EBP;
tempESP = ESP;
PUSH_W(BP); if (cpu_state.abrt) return 1;
frame_ptr = ESP;
@@ -322,8 +328,6 @@ static int opENTER_w(uint32_t fetchdat)
{
while (--count)
{
uint16_t tempw;
BP -= 2;
tempw = readmemw(ss, BP);
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
@@ -348,10 +352,15 @@ static int opENTER_w(uint32_t fetchdat)
}
static int opENTER_l(uint32_t fetchdat)
{
uint16_t offset = getwordf();
int count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr;
uint16_t offset;
int count;
uint32_t tempEBP, tempESP, frame_ptr;
int reads = 0, writes = 1, instr_cycles = 0;
uint32_t templ;
offset = getwordf();
count = (fetchdat >> 16) & 0xff; cpu_state.pc++;
tempEBP = EBP; tempESP = ESP;
PUSH_L(EBP); if (cpu_state.abrt) return 1;
frame_ptr = ESP;
@@ -360,8 +369,6 @@ static int opENTER_l(uint32_t fetchdat)
{
while (--count)
{
uint32_t templ;
EBP -= 4;
templ = readmeml(ss, EBP);
if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; }
@@ -455,17 +462,17 @@ static int opLEAVE_l(uint32_t fetchdat)
}
PUSH_SEG_OPS(CS);
PUSH_SEG_OPS(DS);
PUSH_SEG_OPS(ES);
PUSH_SEG_OPS(FS);
PUSH_SEG_OPS(GS);
PUSH_SEG_OPS(SS);
PUSH_SEG_OPS(CS)
PUSH_SEG_OPS(DS)
PUSH_SEG_OPS(ES)
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, &_ds)
POP_SEG_OPS(ES, &_es)
POP_SEG_OPS(FS, &_fs)
POP_SEG_OPS(GS, &_gs)
static int opPOP_SS_w(uint32_t fetchdat)

File diff suppressed because it is too large Load Diff

17
src/CPU/x86seg.h Normal file
View File

@@ -0,0 +1,17 @@
/*
* 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.
*
* x86 CPU segment emulation.
*
* Version: @(#)x86seg.h 1.0.0 2017/05/30
*
* Author: Miran Grca, <mgrca8@gmail.com>
* Copyright 2016-2017 Miran Grca.
*/
void do_seg_load(x86seg *s, uint16_t *segdat);

View File

@@ -1,24 +1,14 @@
//Quake timedemo demo1 - 8.1FPS
//11A00 - D_SCAlloc
//11C1C - D_CacheSurface
//36174 - SCR_CalcRefdef
//SCR_CalcRefdef
//Calls R_SetVrect and R_ViewChanged
#define fplog 0
#include <math.h>
#include "ibm.h"
#include "pic.h"
#include "../ibm.h"
#include "../pic.h"
#include "x86.h"
#include "x86_flags.h"
#include "x86_ops.h"
#include "x87.h"
#include "386_common.h"
uint16_t x87_gettag()
{
uint16_t ret = 0;

View File

@@ -1,9 +1,6 @@
uint32_t x87_pc_off,x87_op_off;
uint16_t x87_pc_seg,x87_op_seg;
static inline void x87_set_mmx();
static inline void x87_emms();
uint16_t x87_gettag();
void x87_settag(uint16_t new_tag);

1702
src/CPU/x87_ops.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -165,11 +165,14 @@ static int opFCOMP(uint32_t fetchdat)
static int opFCOMPP(uint32_t fetchdat)
{
uint64_t *p, *q;
FP_ENTER();
cpu_state.pc++;
if (fplog) pclog("FCOMPP\n");
cpu_state.npxs &= ~(C0|C2|C3);
if (*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0)
p = (uint64_t *)&ST(0);
q = (uint64_t *)&ST(1);
if ((*p == ((uint64_t)1 << 63) && *q == 0) && is386)
cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/
else
cpu_state.npxs |= x87_compare(ST(0), ST(1));

View File

@@ -1,3 +1,21 @@
/*
* 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.
*
* x87 FPU instructions core.
*
* Version: @(#)x87_ops_loadstore.h 1.0.0 2017/05/30
*
* Author: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
*/
static int opFILDiw_a16(uint32_t fetchdat)
{
int16_t temp;

View File

@@ -29,13 +29,16 @@ static int opFCLEX(uint32_t fetchdat)
static int opFINIT(uint32_t fetchdat)
{
uint64_t *p;
FP_ENTER();
cpu_state.pc++;
cpu_state.npxc = 0x37F;
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
cpu_state.npxs = 0;
*(uint64_t *)cpu_state.tag = 0x0303030303030303ll;
p = (uint64_t *)cpu_state.tag;
*p = 0x0303030303030303ll;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES(17);
return 0;
}
@@ -90,6 +93,7 @@ static int opFSTP(uint32_t fetchdat)
static int FSTOR()
{
uint64_t *p;
FP_ENTER();
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
{
@@ -124,9 +128,10 @@ static int FSTOR()
cpu_state.ismmx = 0;
/*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times
something like this is needed*/
p = (uint64_t *)cpu_state.tag;
if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff &&
cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff &&
!cpu_state.TOP && !(*(uint64_t *)cpu_state.tag))
!cpu_state.TOP && !(*p))
cpu_state.ismmx = 1;
CLOCK_CYCLES((cr0 & 1) ? 34 : 44);
@@ -150,6 +155,8 @@ static int opFSTOR_a32(uint32_t fetchdat)
static int FSAVE()
{
uint64_t *p;
FP_ENTER();
if (fplog) pclog("FSAVE %08X:%08X %i\n", easeg, cpu_state.eaaddr, cpu_state.ismmx);
cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11);
@@ -282,6 +289,15 @@ static int FSAVE()
}
break;
}
cpu_state.npxc = 0x37F;
cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00);
cpu_state.npxs = 0;
p = (uint64_t *)cpu_state.tag;
*p = 0x0303030303030303ll;
cpu_state.TOP = 0;
cpu_state.ismmx = 0;
CLOCK_CYCLES((cr0 & 1) ? 56 : 67);
return cpu_state.abrt;
}

23
src/H Normal file
View File

@@ -0,0 +1,23 @@
/*
* 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 machines.
*
* Version: @(#)xxx.h 1.0.1 2017/06/21
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
*/
#ifndef EMU_xxx_H
# define EMU_xxx_H
#endif /*EMU_xxx_H*/

18
src/M Normal file
View File

@@ -0,0 +1,18 @@
/*
* 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 machines.
*
* Version: @(#)xxx.c 1.0.1 2017/06/21
*
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Fred N. van Kempen, <decwiz@yahoo.com>
* Copyright 2008-2017 Sarah Walker.
* Copyright 2016-2017 Miran Grca.
*/

View File

@@ -1,51 +0,0 @@
# Makefile.am for PCem
bin_PROGRAMS = pcem
noinst_SCRIPTS = ../pcem
CLEANFILES = $(noinst_SCRIPTS)
../pcem: pcem
cp pcem ..
amrefresh:
pcem_CFLAGS = $(allegro_CFLAGS)
pcem_LDADD = $(allegro_LIBS) -lopenal -lalut
pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \
allegro-gui-configure.c allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c allegro-main.c \
allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-iso.c cdrom-null.c \
codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \
dac.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \
headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c \
keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \
linux-time.c lpt.c mcr.c mem.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c \
olivetti_m24.c opti.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c scat.c serial.c sis496.c sound.c \
sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \
sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb.c sound_sb_dsp.c sound_sn76489.c \
sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.c thread-pthread.c \
timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \
vid_ati68860_ramdac.c vid_cga.c vid_cl_gd.c vid_cl_gd_blit.c vid_cl_ramdac.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_hercules.c vid_herculesplus.c\
vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_nv_riva128.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \
vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c \
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c \
x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \
resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \
resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc \
resid-fp/voice.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \
resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc resid-fp/wave8580_PS_.cc \
resid-fp/wave8580_PST.cc resid-fp/wave8580_P_T.cc resid-fp/wave8580__ST.cc \
resid-fp/wave.cc
if CPU_I386
pcem_SOURCES += codegen_x86.c
pcem_CFLAGS += -msse2
endif
if CPU_X86_64
pcem_SOURCES += codegen_x86-64.c
endif

File diff suppressed because it is too large Load Diff

42
src/Makefile.local Normal file
View File

@@ -0,0 +1,42 @@
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box distribution.
#
# Prefix for localizing the general Makefile.mingw for local
# settings, so we can avoid changing the main one for all of
# our local setups.
#
# Version: @(#)Makefile.local 1.0.2 2017/05/23
#
# Author: Fred N. van Kempen, <decwiz@yahoo.com>
#
#########################################################################
# Anything here will override defaults in Makefile.MinGW. #
#########################################################################
DEBUG = y
OPTIM = n
COPTIM = -O1
# Name of the executable.
PROG = yourexe
# Various compile-time options.
STUFF = #-DROM_TRACE=0xC800 -DIO_TRACE=0x70
EXTRAS = #-DYOURNAME
#########################################################################
# Include the master Makefile.MinGW for the rest. #
#########################################################################
include Makefile.mingw
# End of Makefile.local.

View File

@@ -1,51 +1,551 @@
VPATH = . dosbox lzf resid-fp slirp
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign
DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom-ioctl.o cdrom-iso.o \
cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \
device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \
mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
scat.o scsi.o scsi_cdrom.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \
sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
vid_ati28800.o vid_ati68860_ramdac.o vid_bt485_ramdac.o vid_cga.o vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o vid_colorplus.o vid_ega.o vid_et4000.o \
vid_et4000w32.o vid_hercules.o vid_herculesplus.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o
LZFOBJ = lzf_c.o lzf_d.o
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o
#
# 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.
#
# Modified Makefile for Win32 (MinGW32) environment.
#
# Version: @(#)Makefile.mingw 1.0.31 2017/06/19
#
# Authors: Miran Grca, <mgrca8@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
#
# Name of the executable.
ifndef PROG
PROG = 86Box
endif
# Various compile-time options.
# -DROM_TRACE=0xcd800 traces ROM access from segment C800
# -DIO_TACE=0x66 traces I/O on port 0x66
ifndef STUFF
STUFF =
endif
# Add feature selections here.
# -DANSI_CFG forces the config file to ANSI encoding.
# -DENABLE_VRAM_DUMP enables Video Ram dumping.
# -DENABLE_LOG_BREAKPOINT enables extra logging.
# -DENABLE_BUSLOGIC_LOG enables extra logging.
# -DENABLE_CDROM_LOG enables extra logging.
# -DENABLE_D86F_LOG enables extra logging.
# -DENABLE_FDC_LOG enables extra logging.
# -DENABLE_IDE_LOG enables extra logging.
# -DENABLE_SERIAL_LOG enables extra logging.
# -DENABLE_NIC_LOG enables extra logging.
ifndef EXTRAS
EXTRAS =
endif
# Defaults for several build options (possibly defined in a chained file.)
ifndef DEBUG
DEBUG = n
endif
ifndef OPTIM
OPTIM = n
endif
ifndef RELEASE
RELEASE = n
endif
ifndef USB
USB = n
endif
ifndef X64
X64 = n
endif
LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static
#########################################################################
# Nothing should need changing from here on.. #
#########################################################################
VPATH = . cpu \
sound \
sound/munt sound/munt/c_interface sound/munt/sha1 \
sound/munt/srchelper \
sound/resid-fp \
video lzf network network/slirp win
PLAT = win/
ifeq ($(X64), y)
CPP = g++.exe -m64
CC = gcc.exe -m64
else
CPP = g++.exe -m32
CC = gcc.exe -m32
endif
WINDRES = windres.exe
86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ)
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS)
strip "86Box.exe"
OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF)
all : 86Box.exe
ifeq ($(X64), y)
ifeq ($(OPTIM), y)
DFLAGS = -march=native
else
DFLAGS =
endif
else
ifeq ($(OPTIM), y)
DFLAGS = -march=native
else
DFLAGS = -march=i686
endif
endif
ifeq ($(DEBUG), y)
DFLAGS += -ggdb -DDEBUG
AOPTIM =
ifndef COPTIM
COPTIM = -Og
endif
else
ifeq ($(OPTIM), y)
AOPTIM = -mtune=native
ifndef COPTIM
COPTIM = -O6
endif
else
ifndef COPTIM
COPTIM = -O3
endif
endif
endif
AFLAGS = -msse -msse2 -mfpmath=sse
CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \
-fomit-frame-pointer -mstackrealign -Wall
RFLAGS = --input-format=rc -O coff
ifeq ($(RELEASE), y)
CFLAGS += -DRELEASE_BUILD
RFLAGS += -DRELEASE_BUILD
endif
ifeq ($(VRAMDUMP), y)
CFLAGS += -DENABLE_VRAM_DUMP
RFLAGS += -DENABLE_VRAM_DUMP
endif
clean :
rm *.o
rm *.exe
rm *.res
ifeq ($(X64), y)
PLATCG = codegen_x86-64.o
else
PLATCG = codegen_x86.o
endif
%.o : %.c
$(CC) $(CFLAGS) -c $<
%.o : %.cc
$(CPP) $(CFLAGS) -c $<
MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \
mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \
memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o
CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \
codegen.o \
codegen_ops.o codegen_timing_486.o \
codegen_timing_686.o codegen_timing_pentium.o \
codegen_timing_winchip.o $(PLATCG) \
x86seg.o x87.o
SYSOBJ = model.o \
headland.o \
i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \
neat.o \
ali1429.o \
opti495.o \
scat.o \
sis496.o \
wd76c10.o \
acer386sx.o acerm3a.o amstrad.o \
compaq.o laserxt.o jim.o \
olivetti_m24.o ps1.o ps2.o ps2_mca.o \
tandy_eeprom.o tandy_rom.o
DEVOBJ = bugger.o lpt.o serial.o \
fdc37c665.o fdc37c669.o fdc37c932fr.o \
pc87306.o sis85c471.o w83877f.o \
keyboard.o \
keyboard_xt.o keyboard_at.o keyboard_pcjr.o \
keyboard_amstrad.o keyboard_olim24.o \
gameport.o \
joystick_standard.o joystick_ch_flightstick_pro.o \
joystick_sw_pad.o joystick_tm_fcs.o \
mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \
fdd.o fdc.o fdi2raw.o \
hdd.o hdd_image.o \
mfm_at.o mfm_xebec.o hdd_esdi.o ide.o xtide.o piix.o \
disc.o \
disc_86f.o disc_fdi.o disc_imd.o disc_img.o \
disc_random.o disc_td0.o \
cdrom.o \
cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o
ifdef USB
USBOBJ = usb.o
endif
NETOBJ = network.o \
net_pcap.o \
net_slirp.o \
bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \
ip_input.o queue.o tcp_input.o debug.o ip_output.o \
sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \
net_ne2000.o
SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o
SNDOBJ = sound.o \
openal.o \
dbopl.o nukedopl.o \
convolve.o convolve-sse.o envelope.o extfilt.o \
filter.o pot.o sid.o voice.o wave6581__ST.o \
wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \
wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \
wave8580_PST.o wave.o \
midi.o \
midi_mt32.o \
Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \
LA32FloatWaveGenerator.o LA32WaveGenerator.o \
MidiStreamParser.o Part.o Partial.o PartialManager.o \
Poly.o ROMInfo.o Synth.o Tables.o TVA.o TVF.o TVP.o \
sha1.o c_interface.o \
midi_system.o \
snd_speaker.o snd_ps1.o snd_pssj.o \
snd_adlib.o snd_adlibgold.o snd_ad1848.o \
snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \
snd_emu8k.o snd_gus.o snd_opl.o \
snd_mpu401.o snd_pas16.o snd_resid.o \
snd_sn76489.o snd_ssi2001.o snd_wss.o \
snd_ym7128.o
VIDOBJ = video.o \
vid_cga.o vid_cga_comp.o vid_mda.o \
vid_ega.o vid_ega_render.o \
vid_vga.o vid_svga.o vid_svga_render.o \
vid_hercules.o vid_herculesplus.o vid_incolor.o \
vid_colorplus.o \
vid_genius.o \
vid_s3.o vid_s3_virge.o \
vid_et4000.o vid_et4000w32.o vid_icd2061.o \
vid_oti067.o \
vid_paradise.o \
vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \
vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \
vid_ati68860_ramdac.o vid_ati_mach64.o \
vid_ics2595.o \
vid_sdac_ramdac.o \
vid_stg_ramdac.o \
vid_unk_ramdac.o \
vid_wy700.o \
vid_voodoo.o \
vid_pcjr.o vid_ps1_svga.o \
vid_olivetti_m24.o \
vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_tandy.o vid_tandysl.o
WINOBJ = win.o \
win_ddraw.o win_ddraw_fs.o win_ddraw_screenshot.o \
win_d3d.o win_d3d_fs.o \
win_language.o win_status.o win_opendir.o win_dynld.o \
win_video.o win_serial.o win_keyboard.o win_mouse.o \
win_iodev.o win_joystick.o win_midi.o \
win_settings.o win_deviceconfig.o win_joystickconfig.o \
86Box.res
OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \
$(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ)
pc.res: pc.rc
$(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff
LZFOBJ = lzf_c.o lzf_d.o
LIBS = -mwindows \
-lopenal.dll \
-lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \
-lcomctl32 -lkernel32 -lwsock32 -lwinmm -liphlpapi -lpsapi \
-static -lstdc++ -lgcc
# Build rules.
%.o: %.c
@echo $<
@$(CC) $(CFLAGS) -c $<
%.o: %.cc
@echo $<
@$(CPP) $(CFLAGS) -c $<
%.o: %.cpp
@echo $<
@$(CPP) $(CFLAGS) -c $<
all: $(PROG).exe pcap_if.exe
$(PROG).exe: $(OBJ) $(LZFOBJ)
@echo Linking $(PROG).exe ..
@$(CC) -o $(PROG).exe $(OBJ) $(LZFOBJ) $(LIBS)
ifneq ($(DEBUG), y)
@strip $(PROG).exe
endif
pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res
@echo Linking pcap_if.exe ..
@$(CC) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res
ifneq ($(DEBUG), y)
@strip pcap_if.exe
endif
clean:
-rm *.o
-rm *.exe
-rm *.res
86Box.res: 86Box.rc
@echo Processing $<
@$(WINDRES) $(RFLAGS) $(EXTRAS) -i win/86Box.rc -o 86Box.res
pcap_if.res: pcap_if.rc
@echo Processing $<
@$(WINDRES) $(RFLAGS) -i win/pcap_if.rc -o pcap_if.res
# Module dependencies.
acer386sx.o: ibm.h cpu/cpu.h io.h device.h model.h
acerm3a.o: ibm.h cpu/cpu.h io.h device.h model.h
ali1429.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h
amstrad.o: ibm.h cpu/cpu.h io.h device.h model.h keyboard.h lpt.h mouse.h
bugger.o: ibm.h io.h bugger.h
cdrom.o: 86box.h cdrom.h ibm.h ide.h piix.h scsi.h timer.h \
win/plat_iodev.h
cdrom_ioctl.o: ibm.h cdrom.h cdrom_ioctl.h scsi.h
cdrom_null.o: ibm.h cdrom.h cdrom_ioctl.h
compaq.o: ibm.h cpu/cpu.h mem.h device.h model.h
config.o: cdrom.h config.h device.h disc.h fdc.h fdd.h ibm.h \
cpu/cpu.h gameport.h ide.h hdd.h model.h mouse.h \
network/network.h nvr.h scsi.h win/plat_joystick.h \
win/plat_midi.h sound/snd_dbopl.h sound/snd_mpu401.h \
sound/snd_opl.h sound/sound.h video/video.h win/win.h \
win/win_language.h
device.o: ibm.h cpu/cpu.h config.h device.h model.h sound/sound.h
disc.o: ibm.h config.h disc.h disc_fdi.h disc_img.h disc_86f.h \
disc_td0.h disc_imd.h fdc.h fdd.h timer.h
disc_86f.o: lzf/lzf.h config.h dma.h disc.h disc_86f.h disc_random.h \
fdc.h fdd.h ibm.h
disc_fdi.o: ibm.h disc.h disc_img.h disc_fdi.h fdc.h fdd.h fdi2raw.h \
ibm.h disc.h disc_imd.h fdc.h fdd.h ibm.h config.h disc.h \
disc_img.h fdc.h fdd.h
disc_random.o: disc_random.h
disc_td0.o: ibm.h disc.h disc_td0.h fdc.h fdd.h
dma.o: ibm.h cpu/x86.h mem.h io.h dma.h
fdc.o: ibm.h disc.h dma.h fdc.h fdd.h io.h pic.h timer.h
fdc37c665.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h \
fdc37c665.h ibm.h disc.h fdc.h fdd.h io.h ide.h \
lpt.h serial.h fdc37c669.h
fdc37c932fr.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h \
fdc37c932fr.h
fdd.o: ibm.h disc.h fdc.h fdd.h
fdi2raw.o: fdi2raw.h ibm.h
gameport.o: ibm.h cpu/cpu.h device.h io.h timer.h gameport.h \
joystick_ch_flightstick_pro.h joystick_standard.h \
joystick_sw_pad.h joystick_tm_fcs.h plat_joystick.h
hdd.o: ibm.h cpu/cpu.h device.h hdd.h model.h hdd_esdi.h \
mfm_at.h mfm_xebec.h xtide.h
hdd_image.o: ibm.h ide.h hdd_image.h
hdd_esdi.o: ibm.h device.h dma.h hdd_image.h io.h mca.h mem.h \
pic.h rom.h timer.h hdd_esdi.h
headland.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h
i430fx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h
i430hx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h
i430lx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h
i430nx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h
i430vx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h
i440fx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h
i82335.o: ibm.h io.h mem.h
ide.o: 86box.h cdrom.h hdd_image.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h
intel.o: ibm.h cpu/cpu.h io.h mem.h pit.h timer.h intel.h
intel_flash.o: ibm.h cpu/cpu.h device.h mem.h model.h rom.h
io.o: ibm.h io.h
jim.o: ibm.h cpu/cpu.h io.h device.h model.h
joystick_ch_flightstick_pro.o: ibm.h device.h timer.h gameport.h \
joystick_standard.h plat_joystick.h
joystick_standard.o: ibm.h device.h timer.h gameport.h \
joystick_standard.h plat_joystick.h
joystick_sw_pad.o: ibm.h device.h timer.h gameport.h \
joystick_sw_pad.h plat_joystick.h
joystick_tm_fcs.o: ibm.h device.h timer.h gameport.h \
joystick_standard.h plat_joystick.h
keyboard.o: ibm.h plat_keyboard.h keyboard.h
keyboard_amstrad.o: ibm.h io.h mem.h pic.h pit.h timer.h sound/sound.h \
sound/snd_speaker.h keyboard.h keyboard_amstrad.h
keyboard_at.o: ibm.h io.h mem.h pic.h pit.h timer.h disc.h fdc.h \
sound/sound.h sound/snd_speaker.h keyboard.h keyboard_at.h
keyboard_olim24.o: ibm.h io.h mem.h pic.h pit.h timer.h mouse.h \
sound/sound.h sound/snd_speaker.h keyboard.h keyboard_olim24.h
keyboard_pcjr.o: ibm.h io.h mem.h nmi.h pic.h pit.h timer.h \
device.h sound/sound.h sound/snd_speaker.h \
sound/snd_sn76489.h keyboard.h keyboard_pcjr.h
keyboard_xt.o: ibm.h io.h mem.h pic.h pit.h timer.h device.h tandy_eeprom.h \
sound/sound.h sound/snd_speaker.h keyboard.h keyboard_xt.h
laserxt.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h
lpt.o: ibm.h io.h lpt.h
mca.o: ibm.h io.h mem.h mca.h
mcr.o: ibm.h
mem.o: ibm.h cpu/cpu.h cpu/x86_ops.h cpu/x86.h config.h \
io.h mem.h rom.h cpu/codegen.h video/video.h
memregs.o: ibm.h io.h memregs.h
mfm_at.o: ibm.h device.h hdd_image.h io.h pic.h timer.h mfm_at.h
mfm_xebec.o: ibm.h device.h dma.h hdd_image.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h
model.o: ibm.h io.h mem.h rom.h device.h model.h cpu/cpu.h \
mouse.h mouse_ps2.h cdrom.h disc.h dma.h fdc.h \
fdc37c665.h fdc37c669.h fdc37c932fr.h \
gameport.h i82335.h ide.h intel.h intel_flash.h \
keyboard_amstrad.h keyboard_at.h keyboard_olim24.h \
keyboard_pcjr.h keyboard_xt.h lpt.h mem.h memregs.h \
nmi.h nvr.h pc87306.h pci.h pic.h piix.h pit.h ps2_mca.h \
serial.h sis85c471.h sio.h sound/snd_ps1.h sound/snd_pssj.h \
sound/snd_sn76489.h tandy_eeprom.h tandy_rom.h \
video/vid_pcjr.h video/vid_tandy.h w83877f.h wd76c10.h \
xtide.h bugger.h
mouse.o: ibm.h cpu/cpu.h device.h model.h \
mouse.h mouse_serial.h mouse_ps2.h mouse_bus.h keyboard_olim24.h
mouse_bus.o: ibm.h io.h pic.h mouse.h mouse_bus.h plat_mouse.h
mouse_ps2.o: ibm.h keyboard_at.h mouse.h mouse_ps2.h plat_mouse.h
mouse_serial.o: ibm.h timer.h serial.h mouse.h mouse_serial.h
neat.o: ibm.h cpu/cpu.h io.h device.h model.h
nmi.o: ibm.h io.h nmi.h
nvr.o: ibm.h cpu/cpu.h device.h io.h mem.h model.h nvr.h \
pic.h rom.h timer.h rtc.h
olivetti_m24.o: ibm.h cpu/cpu.h io.h device.h model.h
opti495.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h
pc.o: 86box.h ibm.h mem.h cpu/cpu.h cpu/x86_ops.h cpu/codegen.h \
dma.h nvr.h pic.h pit.h timer.h device.h model.h disc.h \
disc_86f.h disc_fdi.h disc_imd.h disc_img.h disc_td0.h \
disc_random.h config.h fdc.h fdd.h gameport.h plat_joystick.h \
plat_midi.h hdd.h ide.h cdrom.h cdrom_ioctl.h cdrom_image.h \
cdrom_null.h scsi.h keyboard.h plat_keyboard.h keyboard_at.h \
mouse.h plat_mouse.h network/network.h serial.h \
sound/sound.h sound/snd_cms.h sound/snd_dbopl.h \
sound/snd_mpu401.h sound/snd_opl.h sound/snd_gus.h \
sound/snd_sb.h sound/snd_speaker.h sound/snd_ssi2001.h \
video/video.h video/vid_voodoo.h win/plat_ui.h
pc87306.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h pc87306.h
pci.o: ibm.h io.h mem.h pic.h pci.h
pic.o: ibm.h io.h pic.h pit.h
piix.o: ibm.h dma.h ide.h io.h mem.h pci.h piix.h
pit.o: ibm.h cpu/cpu.h dma.h io.h pic.h pit.h device.h timer.h \
model.h sound/snd_speaker.h video/video.h
ppi.o: ibm.h pit.h plat_keyboard.h plat_mouse.h
ps1.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h lpt.h serial.h
ps2.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h lpt.h serial.h
ps2_mca.o: ibm.h cpu/cpu.h cpu/x86.h io.h mca.h mem.h rom.h device.h \
lpt.h ps2_mca.h ps2_nvr.h serial.h
ps2_nvr.o: ibm.h device.h io.h mem.h rom.h ps2_nvr.h
rom.o: config.h ibm.h mem.h rom.h
rtc.o: nvr.h rtc.h
scat.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h
scsi.o: 86box.h ibm.h timer.h device.h cdrom.h scsi.h \
scsi_aha154x.h scsi_buslogic.h
scsi_aha154x.o: ibm.h io.h mca.h mem.h mca.h rom.h dma.h pic.h timer.h \
device.h cdrom.h scsi.h scsi_disk.h scsi_aha154x.h \
scsi_buslogic.o: ibm.h io.h mem.h rom.h dma.h pic.h pci.h timer.h \
device.h scsi.h scsi_disk.h cdrom.h scsi_buslogic.h
scsi_disk.o: 86box.h cdrom.h hdd_image.h ibm.h ide.h piix.h scsi.h \
scsi_disk.h timer.h win/plat_iodev.h
serial.o: ibm.h io.h pic.h timer.h serial.h plat_serial.h
sio.o: ibm.h cdrom.h disc.h dma.h fdc.h keyboard_at.h ide.h \
io.h mem.h pci.h sio.h
sis496.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h
sis50x.o: ibm.h device.h io.h mem.h pci.h sis50x.h
sis85c471.o: ibm.h ide.h disc.h fdc.h fdd.h io.h lpt.h serial.h sis85c471.h
tandy_eeprom.o: ibm.h device.h mem.h io.h rom.h tandy_eeprom.h
tandy_rom.o: ibm.h device.h io.h mem.h rom.h tandy_rom.h
timer.o: ibm.h timer.h
usb.o: ibm.h io.h mem.h usb.h
w83877f.o: ibm.h disc.h fdc.h fdd.h io.h lpt.h serial.h w83877f.h
wd76c10.o: ibm.h disc.h fdc.h io.h mem.h serial.h wd76c10.h
xtide.o: ibm.h io.h mem.h rom.h device.h ide.h xtide.h
# End of Makefile.mingw.

View File

@@ -1,52 +1,33 @@
VPATH = . dosbox lzf resid-fp slirp
CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign
DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign
OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom-ioctl.o cdrom-iso.o \
cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \
device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \
i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \
keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \
mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \
scat.o scsi.o scsi_cdrom.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \
sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \
sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \
soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
vid_ati28800.o vid_ati68860_ramdac.o vid_bt485_ramdac.o vid_cga.o vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o vid_colorplus.o vid_ega.o vid_et4000.o \
vid_et4000w32.o vid_hercules.o vid_herculesplus.ovid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \
vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \
vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \
vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \
vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
win-status.o win-video.o x86seg.o x87.o xtide.o pc.res
DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o
LZFOBJ = lzf_c.o lzf_d.o
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o
#
# 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.
#
# Modified Makefile for Win64 MinGW 64-bit environment.
#
# Version: @(#)Makefile.mingw64 1.0.2 2017/05/06
#
# Authors: Kotori, <oubattler@gmail.com>
# Fred N. van Kempen, <decwiz@yahoo.com>
# Sarah Walker,
# Richard G.,
#
# Include the default Makefile.
include Makefile.mingw
# Name of the executable.
PROG = 86Box64
# Various compile-time options.
STUFF =
EXTRAS =
DEBUG = n
OPTIM = n
X64 = y
LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static -lopenal.dll -lgcov -lPacket -lwpcap
86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ)
$(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS)
strip "86Box64.exe"
peflags --bigaddr=false 86Box64.exe
all : 86Box64.exe
clean :
rm *.o
rm *.exe
rm *.res
%.o : %.c
$(CC) $(CFLAGS) -c $<
%.o : %.cc
$(CPP) $(CFLAGS) -c $<
pc.res: pc.rc
$(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff
# End of Makefile.mingw64.

View File

@@ -1,2 +0,0 @@
include Makefile.mingw
CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign

View File

@@ -1,2 +0,0 @@
include Makefile.mingw64
CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign

198
src/NETWORK/bswap.h Normal file
View File

@@ -0,0 +1,198 @@
/* Copyright holders: neozeed
see COPYING for more details
*/
#ifndef BSWAP_H
#define BSWAP_H
#include <stdint.h>
#ifdef HAVE_BYTESWAP_H
#include <byteswap.h>
#else
# define bswap_16(x) \
( \
((uint16_t)( \
(((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
(((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) \
)
# define bswap_32(x) \
( \
((uint32_t)( \
(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
(((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) \
)
# define bswap_64(x) \
( \
((uint64_t)( \
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
(uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
(uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
(uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
(uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
(uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
(uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) \
)
#endif /*HAVE_BYTESWAP_H*/
static __inline uint16_t bswap16(uint16_t x)
{
return bswap_16(x);
}
static __inline uint32_t bswap32(uint32_t x)
{
return bswap_32(x);
}
static __inline uint64_t bswap64(uint64_t x)
{
return bswap_64(x);
}
static __inline void bswap16s(uint16_t *s)
{
*s = bswap16(*s);
}
static __inline void bswap32s(uint32_t *s)
{
*s = bswap32(*s);
}
static __inline void bswap64s(uint64_t *s)
{
*s = bswap64(*s);
}
#if defined(WORDS_BIGENDIAN)
# define be_bswap(v, size) (v)
# define le_bswap(v, size) bswap ## size(v)
# define be_bswaps(v, size)
# define le_bswaps(p, size) *p = bswap ## size(*p);
#else
# define le_bswap(v, size) (v)
# define be_bswap(v, size) bswap ## size(v)
# define le_bswaps(v, size)
# define be_bswaps(p, size) *p = bswap ## size(*p);
#endif
#define CPU_CONVERT(endian, size, type)\
static __inline type endian ## size ## _to_cpu(type v)\
{\
return endian ## _bswap(v, size);\
}\
\
static __inline type cpu_to_ ## endian ## size(type v)\
{\
return endian ## _bswap(v, size);\
}\
\
static __inline void endian ## size ## _to_cpus(type *p)\
{\
endian ## _bswaps(p, size)\
}\
\
static __inline void cpu_to_ ## endian ## size ## s(type *p)\
{\
endian ## _bswaps(p, size)\
}\
\
static __inline type endian ## size ## _to_cpup(const type *p)\
{\
return endian ## size ## _to_cpu(*p);\
}\
\
static __inline void cpu_to_ ## endian ## size ## w(type *p, type v)\
{\
*p = cpu_to_ ## endian ## size(v);\
}
CPU_CONVERT(be, 16, uint16_t)
CPU_CONVERT(be, 32, uint32_t)
CPU_CONVERT(be, 64, uint64_t)
CPU_CONVERT(le, 16, uint16_t)
CPU_CONVERT(le, 32, uint32_t)
CPU_CONVERT(le, 64, uint64_t)
/* unaligned versions (optimized for frequent unaligned accesses)*/
#if defined(__i386__) || defined(__powerpc__)
#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v)
#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v)
#define le16_to_cpupu(p) le16_to_cpup(p)
#define le32_to_cpupu(p) le32_to_cpup(p)
#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v)
#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v)
#else
static __inline void cpu_to_le16wu(uint16_t *p, uint16_t v)
{
uint8_t *p1 = (uint8_t *)p;
p1[0] = v;
p1[1] = v >> 8;
}
static __inline void cpu_to_le32wu(uint32_t *p, uint32_t v)
{
uint8_t *p1 = (uint8_t *)p;
p1[0] = v;
p1[1] = v >> 8;
p1[2] = v >> 16;
p1[3] = v >> 24;
}
static __inline uint16_t le16_to_cpupu(const uint16_t *p)
{
const uint8_t *p1 = (const uint8_t *)p;
return p1[0] | (p1[1] << 8);
}
static __inline uint32_t le32_to_cpupu(const uint32_t *p)
{
const uint8_t *p1 = (const uint8_t *)p;
return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24);
}
static __inline void cpu_to_be16wu(uint16_t *p, uint16_t v)
{
uint8_t *p1 = (uint8_t *)p;
p1[0] = v >> 8;
p1[1] = v;
}
static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v)
{
uint8_t *p1 = (uint8_t *)p;
p1[0] = v >> 24;
p1[1] = v >> 16;
p1[2] = v >> 8;
p1[3] = v;
}
#endif
#ifdef WORDS_BIGENDIAN
#define cpu_to_32wu cpu_to_be32wu
#else
#define cpu_to_32wu cpu_to_le32wu
#endif
#undef le_bswap
#undef be_bswap
#undef le_bswaps
#undef be_bswaps
#endif /* BSWAP_H */

2300
src/NETWORK/net_ne2000.c Normal file

File diff suppressed because it is too large Load Diff

29
src/NETWORK/net_ne2000.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* 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.
*
* Definitions for the NE2000 ethernet controller.
*
* Version: @(#)net_ne2000.h 1.0.3 2017/05/17
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/
#ifndef NET_NE2000_H
# define NET_NE2000_H
#define NE2K_NE1000 1 /* 8bit ISA NE1000 */
#define NE2K_NE2000 2 /* 16bit ISA NE2000 */
#define NE2K_RTL8029AS 3 /* 32bi PCI Realtek 8029AS */
extern device_t ne1000_device;
extern device_t ne2000_device;
extern device_t rtl8029as_device;
#endif /*NET_NE2000_H*/

278
src/NETWORK/net_pcap.c Normal file
View File

@@ -0,0 +1,278 @@
/*
* 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.
*
* Handle WinPcap library processing.
*
* Version: @(#)net_pcap.c 1.0.5 2017/06/04
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcap.h>
#include "../ibm.h"
#include "../config.h"
#include "../device.h"
#include "network.h"
#include "../WIN/plat_dynld.h"
#include "../WIN/plat_thread.h"
static void *pcap_handle; /* handle to WinPcap DLL */
static pcap_t *pcap; /* handle to WinPcap library */
static thread_t *poll_tid;
static NETRXCB poll_rx; /* network RX function to call */
static void *poll_arg; /* network RX function arg */
/* Pointers to the real functions. */
static const char *(*f_pcap_lib_version)(void);
static int (*f_pcap_findalldevs)(pcap_if_t **,char *);
static void (*f_pcap_freealldevs)(pcap_if_t *);
static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *);
static int (*f_pcap_compile)(pcap_t *,struct bpf_program *,
const char *,int,bpf_u_int32);
static int (*f_pcap_setfilter)(pcap_t *,struct bpf_program *);
static const u_char *(*f_pcap_next)(pcap_t *,struct pcap_pkthdr *);
static int (*f_pcap_sendpacket)(pcap_t *,const u_char *,int);
static void (*f_pcap_close)(pcap_t *);
static dllimp_t pcap_imports[] = {
{ "pcap_lib_version", &f_pcap_lib_version },
{ "pcap_findalldevs", &f_pcap_findalldevs },
{ "pcap_freealldevs", &f_pcap_freealldevs },
{ "pcap_open_live", &f_pcap_open_live },
{ "pcap_compile", &f_pcap_compile },
{ "pcap_setfilter", &f_pcap_setfilter },
{ "pcap_next", &f_pcap_next },
{ "pcap_sendpacket", &f_pcap_sendpacket },
{ "pcap_close", &f_pcap_close },
{ NULL, NULL },
};
/* Handle the receiving of frames from the channel. */
static void
poll_thread(void *arg)
{
uint8_t *mac = (uint8_t *)arg;
const uint8_t *data = NULL;
struct pcap_pkthdr h;
uint32_t mac_cmp32[2];
uint16_t mac_cmp16[2];
event_t *evt;
pclog("PCAP: polling thread started, arg %08lx\n", arg);
/* Create a waitable event. */
evt = thread_create_event();
/* As long as the channel is open.. */
while (pcap != NULL) {
/* Wait for the next packet to arrive. */
data = f_pcap_next(pcap, &h);
if (data != NULL) {
/* Received MAC. */
mac_cmp32[0] = *(uint32_t *)(data+6);
mac_cmp16[0] = *(uint16_t *)(data+10);
/* Local MAC. */
mac_cmp32[1] = *(uint32_t *)mac;
mac_cmp16[1] = *(uint16_t *)(mac+4);
if ((mac_cmp32[0] != mac_cmp32[1]) ||
(mac_cmp16[0] != mac_cmp16[1])) {
if (poll_rx != NULL)
poll_rx(poll_arg, (uint8_t *)data, h.caplen);
} else {
/* Mark as invalid packet. */
data = NULL;
}
}
/* If we did not get anything, wait a while. */
if (data == NULL)
thread_wait_event(evt, 10);
}
thread_destroy_event(evt);
poll_tid = NULL;
pclog("PCAP: polling stopped.\n");
}
/* Initialize the (Win)Pcap module for use. */
int
network_pcap_init(netdev_t *list)
{
char errbuf[PCAP_ERRBUF_SIZE];
pcap_if_t *devlist, *dev;
int i = 0;
/* Local variables. */
pcap = NULL;
/* Try loading the DLL. */
pcap_handle = dynld_module("wpcap.dll", pcap_imports);
if (pcap_handle == NULL) return(-1);
/* Retrieve the device list from the local machine */
if (f_pcap_findalldevs(&devlist, errbuf) == -1) {
pclog("PCAP: error in pcap_findalldevs: %s\n", errbuf);
return(-1);
}
for (dev=devlist; dev!=NULL; dev=dev->next) {
strcpy(list->device, dev->name);
if (dev->description)
strcpy(list->description, dev->description);
else
memset(list->description, '\0', sizeof(list->description));
list++; i++;
}
/* Release the memory. */
f_pcap_freealldevs(devlist);
return(i);
}
/* Initialize the (Win)Pcap module for use. */
void
network_pcap_reset(void)
{
/* Try loading the DLL. */
pcap_handle = dynld_module("wpcap.dll", pcap_imports);
return;
}
/* Initialize WinPcap for us. */
int
network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg)
{
char temp[PCAP_ERRBUF_SIZE];
char filter_exp[255];
struct bpf_program fp;
char *dev;
/* Did we already load the DLL? */
if (pcap_handle == NULL) return(-1);
#if 1
/* Get the value of our capture interface. */
dev = network_pcap;
if (dev == NULL) {
pclog(" PCap device is a null pointer!\n");
return(-1);
}
if ((dev[0] == '\0') || !strcmp(dev, "none")) {
pclog(" No network device configured!\n");
return(-1);
}
pclog(" Network interface: '%s'\n", dev);
#endif
strcpy(temp, f_pcap_lib_version());
dev = strchr(temp, '(');
if (dev != NULL) *(dev-1) = '\0';
pclog("PCAP: initializing, %s\n", temp);
#if 0
/* Get the value of our capture interface. */
dev = network_pcap;
if ((dev[0] == '\0') || !strcmp(dev, "none")) {
pclog(" No network device configured!\n");
return(-1);
}
pclog(" Network interface: '%s'\n", dev);
#else
dev = network_pcap;
#endif
pcap = f_pcap_open_live(dev, /* interface name */
1518, /* maximum packet size */
1, /* promiscuous mode? */
10, /* timeout in msec */
temp); /* error buffer */
if (pcap == NULL) {
pclog(" Unable to open device: %s!\n", temp);
return(-1);
}
/* Create a MAC address based packet filter. */
pclog(" Installing packet filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sprintf(filter_exp,
"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
if (f_pcap_compile(pcap, &fp, filter_exp, 0, 0xffffffff) != -1) {
if (f_pcap_setfilter(pcap, &fp) == -1)
pclog(" Error installing filter (%s) !\n", filter_exp);
} else {
pclog(" Could not compile filter (%s) !\n", filter_exp);
}
/* Save the callback info. */
poll_rx = func;
poll_arg = arg;
pclog(" Starting thread..\n");
poll_tid = thread_create(poll_thread, mac);
return(0);
}
/* Close up shop. */
void
network_pcap_close(void)
{
pcap_t *pc;
if (pcap != NULL) {
pclog("Closing WinPcap\n");
/* Tell the polling thread to shut down. */
pc = pcap; pcap = NULL;
#if 1
/* Terminate the polling thread. */
if (poll_tid != NULL) {
thread_kill(poll_tid);
poll_tid = NULL;
}
#else
/* Wait for the polling thread to shut down. */
while (poll_tid != NULL)
;
#endif
/* OK, now shut down WinPcap itself. */
f_pcap_close(pc);
/* Unload the DLL if possible. */
if (pcap_handle != NULL) {
dynld_close(pcap_handle);
pcap_handle = NULL;
}
}
poll_rx = NULL;
poll_arg = NULL;
}
/* Send a packet to the Pcap interface. */
void
network_pcap_in(uint8_t *bufp, int len)
{
if (pcap != NULL)
f_pcap_sendpacket(pcap, bufp, len);
}

194
src/NETWORK/net_slirp.c Normal file
View File

@@ -0,0 +1,194 @@
/*
* 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.
*
* Handle SLiRP library processing.
*
* Version: @(#)net_slirp.c 1.0.4 2017/06/14
*
* Author: Fred N. van Kempen, <decwiz@yahoo.com>
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "slirp/slirp.h"
#include "slirp/queue.h"
#include "../ibm.h"
#include "../config.h"
#include "../device.h"
#include "network.h"
#include "../WIN/plat_thread.h"
static queueADT slirpq; /* SLiRP library handle */
static thread_t *poll_tid;
static NETRXCB poll_rx; /* network RX function to call */
static void *poll_arg; /* network RX function arg */
/* Instead of calling this and crashing some times
or experencing jitter, this is called by the
60Hz clock which seems to do the job. */
static void
slirp_tic(void)
{
int ret2, nfds;
struct timeval tv;
fd_set rfds, wfds, xfds;
int tmo;
/* Let SLiRP create a list of all open sockets. */
nfds = -1;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&xfds);
tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */
if (tmo < 0)
tmo = 500;
tv.tv_sec = 0;
tv.tv_usec = tmo;
/* Now wait for something to happen, or at most 'tmo' usec. */
ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv);
/* If something happened, let SLiRP handle it. */
if (ret2 >= 0)
slirp_select_poll(&rfds, &wfds, &xfds);
}
/* Handle the receiving of frames. */
static void
poll_thread(void *arg)
{
struct queuepacket *qp;
event_t *evt;
pclog("SLiRP: polling thread started, arg %08lx\n", arg);
/* Create a waitable event. */
evt = thread_create_event();
while (slirpq != NULL) {
/* See if there is any work. */
slirp_tic();
/* Wait for the next packet to arrive. */
if (QueuePeek(slirpq) == 0) {
/* If we did not get anything, wait a while. */
thread_wait_event(evt, 10);
continue;
}
/* Grab a packet from the queue. */
qp = QueueDelete(slirpq);
#if 0
pclog("SLiRP: inQ:%d got a %dbyte packet @%08lx\n",
QueuePeek(slirpq), qp->len, qp);
#endif
if (poll_rx != NULL)
poll_rx(poll_arg, (uint8_t *)&qp->data, qp->len);
/* Done with this one. */
free(qp);
}
thread_destroy_event(evt);
poll_tid = NULL;
pclog("SLiRP: polling stopped.\n");
}
/* Initialize SLiRP for us. */
int
network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg)
{
pclog("SLiRP: initializing..\n");
if (slirp_init() != 0) {
pclog("SLiRP could not be initialized!\n");
return(-1);
}
slirpq = QueueCreate();
pclog(" Packet queue is at %08lx\n", &slirpq);
/* Save the callback info. */
poll_rx = func;
poll_arg = arg;
pclog("SLiRP: starting thread..\n");
poll_tid = thread_create(poll_thread, mac);
return(0);
}
void
network_slirp_close(void)
{
queueADT sl;
if (slirpq != NULL) {
pclog("Closing SLiRP\n");
/* Tell the polling thread to shut down. */
sl = slirpq; slirpq = NULL;
#if 1
/* Terminate the polling thread. */
if (poll_tid != NULL) {
thread_kill(poll_tid);
poll_tid = NULL;
}
#else
/* Wait for the polling thread to shut down. */
while (poll_tid != NULL)
;
#endif
/* OK, now shut down SLiRP itself. */
QueueDestroy(sl);
slirp_exit(0);
}
poll_rx = NULL;
poll_arg = NULL;
}
/* Send a packet to the SLiRP interface. */
void
network_slirp_in(uint8_t *pkt, int pkt_len)
{
if (slirpq != NULL)
slirp_input((const uint8_t *)pkt, pkt_len);
}
void
slirp_output(const uint8_t *pkt, int pkt_len)
{
struct queuepacket *qp;
if (slirpq != NULL) {
qp = (struct queuepacket *)malloc(sizeof(struct queuepacket));
qp->len = pkt_len;
memcpy(qp->data, pkt, pkt_len);
QueueEnter(slirpq, qp);
}
}
int
slirp_can_output(void)
{
return((slirpq != NULL)?1:0);
}

Some files were not shown because too many files have changed in this diff Show More