/***************************************************************************
 * 
 * All modifications in this file to the original code are
 * (C) Copyright 1992, ..., 2000 the "DOSEMU-Development-Team".
 *
 * for details see file COPYING in the DOSEMU distribution
 *
 *
 *  SIMX86 a Intel 80x86 cpu emulator
 *  Copyright (C) 1997,2000 Alberto Vignani, FIAT Research Center
 *				a.vignani@crf.it
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Additional copyright notes:
 *
 * 1. The kernel-level vm86 handling was taken out of the Linux kernel
 *  (linux/arch/i386/kernel/vm86.c). This code originaly was written by
 *  Linus Torvalds with later enhancements by Lutz Molgedey and Hans Lermen.
 *
 ***************************************************************************/

#include "emu86.h"
#include "codegen.h"

/////////////////////////////////////////////////////////////////////////////

unsigned char byrev[256] = {
	0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,
	0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
	0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,
	0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
	0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,
	0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
	0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,
	0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
	0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,
	0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
	0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,
	0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
	0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,
	0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
	0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,
	0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
	0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,
	0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
	0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,
	0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
	0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,
	0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
	0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,
	0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
	0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,
	0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
	0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,
	0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
	0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,
	0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
	0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,
	0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
};

/////////////////////////////////////////////////////////////////////////////

/* table of opcode properties
 *
 *	bit 7	1=unimplemented or reserved
 *	bit 6	1=special subtable
 *	bit 3	1=has mod/r_m
 *	bit 2	1=prefix
 *	bit 1	1=force DPMI_TRACE registers display(?)
 *	bit 0	0=can be compiled	1=always interpreted
 */

char InterOps[256] =
{
	0x08,	// ADDbfrm		0x00
	0x08,	// ADDwfrm		0x01
	0x08,	// ADDbtrm		0x02
	0x08,	// ADDwtrm		0x03
	0x08,	// ADDbia		0x04
	0x08,	// ADDwia		0x05
	0x00,	// PUSHes		0x06
	0x02,	// POPes		0x07
	0x08,	// ORbfrm		0x08
	0x08,	// ORwfrm		0x09
	0x08,	// ORbtrm		0x0a
	0x08,	// ORwtrm		0x0b
	0x08,	// ORbi			0x0c
	0x08,	// ORwi			0x0d
	0x00,	// PUSHcs		0x0e
	0x42,	// TwoByteESC		0x0f
	0x08,	// ADCbfrm		0x10
	0x08,	// ADCwfrm		0x11
	0x08,	// ADCbtrm		0x12
	0x08,	// ADCwtrm		0x13
	0x08,	// ADCbi		0x14
	0x08,	// ADCwi		0x15
	0x00,	// PUSHss		0x16
	0x02,	// POPss		0x17
	0x08,	// SBBbfrm		0x18
	0x08,	// SBBwfrm		0x19
	0x08,	// SBBbtrm		0x1a
	0x08,	// SBBwtrm		0x1b
	0x08,	// SBBbi		0x1c
	0x08,	// SBBwi		0x1d
	0x00,	// PUSHds		0x1e
	0x02,	// POPds		0x1f
	0x08,	// ANDbfrm		0x20
	0x08,	// ANDwfrm		0x21
	0x08,	// ANDbtrm		0x22
	0x08,	// ANDwtrm		0x23
	0x08,	// ANDbi		0x24
	0x08,	// ANDwi		0x25
	0x04,	// SEGes		0x26
	0x00,	// DAA			0x27
	0x08,	// SUBbfrm		0x28
	0x08,	// SUBwfrm		0x29
	0x08,	// SUBbtrm		0x2a
	0x08,	// SUBwtrm		0x2b
	0x08,	// SUBbi		0x2c
	0x08,	// SUBwi		0x2d
	0x04,	// SEGcs		0x2e
	0x00,	// DAS			0x2f
	0x08,	// XORbfrm		0x30
	0x08,	// XORwfrm		0x31
	0x08,	// XORbtrm		0x32
	0x08,	// XORwtrm		0x33
	0x08,	// XORbi		0x34
	0x08,	// XORwi		0x35
	0x04,	// SEGss		0x36
	0x00,	// AAA			0x37
	0x08,	// CMPbfrm		0x38
	0x08,	// CMPwfrm		0x39
	0x08,	// CMPbtrm		0x3a
	0x08,	// CMPwtrm		0x3b
	0x08,	// CMPbi		0x3c
	0x08,	// CMPwi		0x3d
	0x04,	// SEGds		0x3e
	0x00,	// AAS			0x3f
	0x00,	// INCax		0x40
	0x00,	// INCcx		0x41
	0x00,	// INCdx		0x42
	0x00,	// INCbx		0x43
	0x00,	// INCsp		0x44
	0x00,	// INCbp		0x45
	0x00,	// INCsi		0x46
	0x00,	// INCdi		0x47
	0x00,	// DECax		0x48
	0x00,	// DECcx		0x49
	0x00,	// DECdx		0x4a
	0x00,	// DECbx		0x4b
	0x00,	// DECsp		0x4c
	0x00,	// DECbp		0x4d
	0x00,	// DECsi		0x4e
	0x00,	// DECdi		0x4f
	0x00,	// PUSHax		0x50
	0x00,	// PUSHcx		0x51
	0x00,	// PUSHdx		0x52
	0x00,	// PUSHbx		0x53
	0x00,	// PUSHsp		0x54
	0x00,	// PUSHbp		0x55
	0x00,	// PUSHsi		0x56
	0x00,	// PUSHdi		0x57
	0x00,	// POPax		0x58
	0x00,	// POPcx		0x59
	0x00,	// POPdx		0x5a
	0x00,	// POPbx		0x5b
	0x00,	// POPsp		0x5c
	0x00,	// POPbp		0x5d
	0x00,	// POPsi		0x5e
	0x00,	// POPdi		0x5f
	0x00,	// PUSHA		0x60
	0x00,	// POPA			0x61
	0x81,	// BOUND		0x62
	0x81,	// ARPL			0x63
	0x04,	// SEGfs		0x64
	0x04,	// SEGgs		0x65
	0x04,	// OPERoverride		0x66
	0x04,	// ADDRoverride		0x67
	0x00,	// PUSHwi		0x68
	0x08,	// IMULwrm		0x69 
	0x00,	// PUSHbi		0x6a
	0x08,	// IMULbrm		0x6b
	0x01,	// INSb			0x6c
	0x01,	// INSw			0x6d
	0x01,	// OUTSb		0x6e
	0x01,	// OUTSw		0x6f
	0x02,	// JO			0x70
	0x02,	// JNO			0x71
	0x02,	// JB_JNAE		0x72
	0x02,	// JNB_JAE		0x73
	0x02,	// JE_JZ		0x74
	0x02,	// JNE_JNZ		0x75
	0x02,	// JBE_JNA		0x76
	0x02,	// JNBE_JA		0x77
	0x02,	// JS			0x78
	0x02,	// JNS			0x79
	0x02,	// JP_JPE		0x7a
	0x02,	// JNP_JPO		0x7b
	0x02,	// JL_JNGE		0x7c
	0x02,	// JNL_JGE		0x7d
	0x02,	// JLE_JNG		0x7e
	0x02,	// JNLE_JG		0x7f
	0x40,	// IMMEDbrm		0x80
	0x40,	// IMMEDwrm		0x81
	0x40,	// IMMEDbrm2		0x82
	0x40,	// IMMEDisrm		0x83
	0x08,	// TESTbrm		0x84
	0x08,	// TESTwrm		0x85
	0x08,	// XCHGbrm		0x86
	0x08,	// XCHGwrm		0x87
	0x08,	// MOVbfrm		0x88
	0x08,	// MOVwfrm		0x89
	0x08,	// MOVbtrm		0x8a
	0x08,	// MOVwtrm		0x8b
	0x08,	// MOVsrtrm		0x8c
	0x08,	// LEA			0x8d
	0x0a,	// MOVsrfrm		0x8e
	0x08,	// POPrm		0x8f
	0x01,	// NOP			0x90
	0x00,	// XCHGcx		0x91
	0x00,	// XCHGdx		0x92
	0x00,	// XCHGbx		0x93
	0x00,	// XCHGsp		0x94
	0x00,	// XCHGbp		0x95
	0x00,	// XCHGsi		0x96
	0x00,	// XCHGdi		0x97
	0x00,	// CBW			0x98
	0x00,	// CWD			0x99
	0x01,	// CALLl		0x9a
	0x01,	// WAIT			0x9b
	0x01,	// PUSHF		0x9c
	0x01,	// POPF			0x9d
	0x00,	// SAHF			0x9e
	0x00,	// LAHF			0x9f
	0x00,	// MOVmal		0xa0
	0x00,	// MOVmax		0xa1
	0x00,	// MOValm		0xa2
	0x00,	// MOVaxm		0xa3
	0x00,	// MOVSb		0xa4
	0x00,	// MOVSw		0xa5
	0x00,	// CMPSb		0xa6
	0x00,	// CMPSw		0xa7
	0x00,	// TESTbi		0xa8
	0x00,	// TESTwi		0xa9
	0x00,	// STOSb		0xaa
	0x00,	// STOSw		0xab
	0x00,	// LODSb		0xac
	0x00,	// LODSw		0xad
	0x00,	// SCASb		0xae
	0x00,	// SCASw		0xaf
	0x00,	// MOVial		0xb0
	0x00,	// MOVicl		0xb1
	0x00,	// MOVidl		0xb2
	0x00,	// MOVibl		0xb3
	0x00,	// MOViah		0xb4
	0x00,	// MOVich		0xb5
	0x00,	// MOVidh		0xb6
	0x00,	// MOVibh		0xb7
	0x00,	// MOViax		0xb8
	0x00,	// MOVicx		0xb9
	0x00,	// MOVidx		0xba
	0x00,	// MOVibx		0xbb
	0x00,	// MOVisp		0xbc
	0x00,	// MOVibp		0xbd
	0x00,	// MOVisi		0xbe
	0x00,	// MOVidi		0xbf
	0x08,	// SHIFTbi		0xc0
	0x08,	// SHIFTwi		0xc1 
	0x01,	// RETisp		0xc2
	0x01,	// RET			0xc3
	0x02,	// LES			0xc4
	0x02,	// LDS			0xc5
	0x08,	// MOVbirm		0xc6
	0x08,	// MOVwirm		0xc7
	0x01,	// ENTER		0xc8
	0x01,	// LEAVE		0xc9 
	0x01,	// RETlisp		0xca
	0x01,	// RETl			0xcb
	0x01,	// INT3			0xcc
	0x01,	// INT			0xcd
	0x01,	// INTO			0xce
	0x01,	// IRET			0xcf
	0x08,	// SHIFTb		0xd0
	0x08,	// SHIFTw		0xd1
	0x08,	// SHIFTbv		0xd2
	0x08,	// SHIFTwv		0xd3
	0x00,	// AAM			0xd4
	0x00,	// AAD			0xd5
	0x81,	// RESERVED1		0xd6
	0x00,	// XLAT			0xd7
	0x42,	// ESC0			0xd8
	0x42,	// ESC1			0xd9
	0x42,	// ESC2			0xda
	0x42,	// ESC3			0xdb
	0x42,	// ESC4			0xdc
	0x42,	// ESC5			0xdd
	0x42,	// ESC6			0xde
	0x42,	// ESC7			0xdf
	0x02,	// LOOPNZ_LOOPNE	0xe0
	0x02,	// LOOPZ_LOOPE		0xe1
	0x02,	// LOOP			0xe2
	0x02,	// JCXZ			0xe3
	0x01,	// INb			0xe4
	0x01,	// INw			0xe5
	0x01,	// OUTb			0xe6
	0x01,	// OUTw			0xe7
	0x01,	// CALLd		0xe8
	0x01,	// JMPd			0xe9
	0x01,	// JMPld		0xea
	0x02,	// JMPsid		0xeb
#ifdef CPUEMU_DIRECT_IO
	0x00,	// INvb			0xec
	0x00,	// INvw			0xed
	0x00,	// OUTvb		0xee
	0x00,	// OUTvw		0xef
#else
	0x01,	// INvb			0xec
	0x01,	// INvw			0xed
	0x01,	// OUTvb		0xee
	0x01,	// OUTvw		0xef
#endif
	0x85,	// LOCK			0xf0
	0x81,	// BARTS_OP		0xf1
	0x04,	// REPNE		0xf2
	0x04,	// REP			0xf3
	0x01,	// HLT			0xf4
	0x00,	// CMC			0xf5
	0x40,	// GRP1brm 		0xf6
	0x40,	// GRP1wrm 		0xf7
	0x00,	// CLC			0xf8
	0x00,	// STC			0xf9
	0x01,	// CLI			0xfa
	0x01,	// STI			0xfb
	0x00,	// CLD			0xfc
	0x00,	// STD			0xfd
	0x40,	// GRP2brm		0xfe
	0x42,	// GRP2wrm		0xff
};

/////////////////////////////////////////////////////////////////////////////

