mirror of
https://github.com/86Box/86Box.git
synced 2026-02-23 09:58:19 -07:00
Merge remote-tracking branch 'refs/remotes/OBattler/master'
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# 86Box [](http://polar.rol.im/job/86Box)
|
||||
# 86Box [](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.
|
||||
|
||||
---
|
||||
|
||||
46
src/86box.h
46
src/86box.h
@@ -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*/
|
||||
|
||||
@@ -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++)
|
||||
@@ -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 )
|
||||
@@ -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 )
|
||||
@@ -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 )
|
||||
@@ -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); */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
@@ -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
@@ -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)();
|
||||
@@ -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)
|
||||
{
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "ibm.h"
|
||||
#include "../ibm.h"
|
||||
#include "../mem.h"
|
||||
#include "x86.h"
|
||||
#include "x86_ops.h"
|
||||
#include "x86_flags.h"
|
||||
@@ -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)
|
||||
@@ -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; \
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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)
|
||||
{
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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:
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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];
|
||||
@@ -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); \
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
@@ -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))
|
||||
{
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
@@ -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))
|
||||
{
|
||||
@@ -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); \
|
||||
@@ -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
17
src/CPU/x86seg.h
Normal 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);
|
||||
@@ -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;
|
||||
@@ -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
1702
src/CPU/x87_ops.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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));
|
||||
@@ -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;
|
||||
@@ -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
23
src/H
Normal 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
18
src/M
Normal 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.
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
2956
src/Makefile.in
2956
src/Makefile.in
File diff suppressed because it is too large
Load Diff
42
src/Makefile.local
Normal file
42
src/Makefile.local
Normal 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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
198
src/NETWORK/bswap.h
Normal 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
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
29
src/NETWORK/net_ne2000.h
Normal 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
278
src/NETWORK/net_pcap.c
Normal 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
194
src/NETWORK/net_slirp.c
Normal 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
Reference in New Issue
Block a user