/*************************************************************************** * * All modifications in this file to the original code are * (C) Copyright 1992, ..., 2004 the "DOSEMU-Development-Team". * * for details see file COPYING in the DOSEMU distribution * * * SIMX86 a Intel 80x86 cpu emulator * Copyright (C) 1997,2001 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. * ***************************************************************************/ #ifndef _EMU86_CODEGEN_X86_H #define _EMU86_CODEGEN_X86_H #include "codegen.h" #include "vgaemu.h" #define HOST_ARCH_SIM #define TAILSIZE 7 #define TAILFIX 1 /* If you undefine this, in 16-bit stack mode the high 16 bits of ESP * will be zeroed after every push/pop operation. There's a small * possibility of breaking some code, you can easily figure out how. * For 32-bit stacks, keeping ESP is also a waste of time. */ #undef KEEP_ESP ///////////////////////////////////////////////////////////////////////////// #ifndef __KERNEL__ /* This comes from the kernel, include/asm/string.h */ static inline void * __memcpy(void * to, const void * from, size_t n) { int d0, d1, d2; __asm__ __volatile__( "cld\n\t" "rep ; movsl\n\t" "testb $2,%b4\n\t" "je 1f\n\t" "movsw\n" "1:\ttestb $1,%b4\n\t" "je 2f\n\t" "movsb\n" "2:" : "=&c" (d0), "=&D" (d1), "=&S" (d2) :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) : "memory"); return (to); } #endif ///////////////////////////////////////////////////////////////////////////// typedef union { unsigned long d; signed long ds; signed char *ps; unsigned char *pu; signed short *pws; unsigned short *pwu; signed long *pds; unsigned long *pdu; float *pff; double *pfd; struct { unsigned short l,h; } w; struct { signed short l,h; } ws; struct { unsigned char bl,bh,b2,b3; } b; struct { signed char bl,bh,b2,b3; } bs; } wkreg; typedef struct { int valid, mode; long S1,S2; wkreg RES; } flgtmp; #define V_INVALID 0 #define V_GEN 1 // general/add case #define V_SUB 2 #define V_SBB 3 #define V_ADC 4 extern wkreg DR1; // "eax" extern wkreg DR2; // "edx" extern wkreg AR1; // "edi" extern wkreg AR2; // "esi" extern wkreg SR1; // "ebp" extern wkreg TR1; // "ecx" extern flgtmp RFL; extern unsigned e_VgaRead(unsigned offs, int mode); extern void e_VgaWrite(unsigned offs, unsigned u, int mode); extern int TrapVgaOn; #define GTRACE0(s) if (debug_level('e')>2) e_printf("(G) %-12s [%s]\n",(s),showmode(mode)) #define GTRACE1(s,r) if (debug_level('e')>2) e_printf("(G) %-12s %s [%s]\n",(s),\ showreg(r),showmode(mode)) #define GTRACE2(s,r1,r2) if (debug_level('e')>2) e_printf("(G) %-12s %s %s [%s]\n",(s),\ showreg(r1),showreg(r2),showmode(mode)) #define GTRACE3(s,r1,r2,a) if (debug_level('e')>2) e_printf("(G) %-12s %s %s %08x [%s]\n",(s),\ showreg(r1),showreg(r2),(int)(a),showmode(mode)) #define GTRACE4(s,r1,r2,a,b) if (debug_level('e')>2) e_printf("(G) %-12s %s %s %08x %08x [%s]\n",\ (s),showreg(r1),showreg(r2),(int)(a),(int)(b),showmode(mode)) #define GTRACE5(s,r1,r2,a,b,c) if (debug_level('e')>2) e_printf("(G) %-12s %s %s %08x %08x %08x [%s]\n",\ (s),showreg(r1),showreg(r2),(int)(a),(int)(b),(int)(c),showmode(mode)) extern void FlagSync_AP (void); extern void FlagSync_O (void); extern void FlagSync_All (void); ///////////////////////////////////////////////////////////////////////////// // returns 1(16 bit), 0(32 bit) #define BTA(bpos, mode) ({ register int temp; \ __asm__ ("bt %1,%2\n \ rcrl $1,%0\n \ shrl $31,%0" \ : "=&r"(temp) \ : "i"(bpos), "g"(mode) ); temp; }) // returns 2(16 bit), 4(32 bit) #define BT24(bpos, mode) ({ register int temp; \ __asm__ ("movb $4,%b0\n \ bt %1,%2\n \ sbbb $0,%b0\n \ andl $6,%0" \ : "=&q"(temp) \ : "i"(bpos), "g"(mode) ); temp; }) static __inline__ int FastLog2(register int v) { register int temp; __asm__ ("bsr %1,%0\n \ jnz 1f\n \ xor %0,%0\n \ 1: " \ : "=a"(temp) : "g"(v) ); return temp; } ///////////////////////////////////////////////////////////////////////////// static __inline__ void PUSH(int m, void *w) { unsigned long sp; caddr_t addr; int v; sp = (TheCPU.esp-BT24(BitDATA16, m)) & TheCPU.StackMask; addr = (caddr_t)(LONG_SS + sp); v = e_munprotect(addr, 0); if (m&DATA16) *((short *)addr) = *((short *)w); else *((int *)addr) = *((int *)w); if (v) e_mprotect(addr, 0); #ifdef KEEP_ESP TheCPU.esp = (sp&TheCPU.StackMask) | (TheCPU.esp&~TheCPU.StackMask); #else TheCPU.esp = sp; #endif } ///////////////////////////////////////////////////////////////////////////// #define FWJ_OFFS 5 ///////////////////////////////////////////////////////////////////////////// #endif