added PCI expansion ROM support,
works for some ATI and Nvidia AGP cards now. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1851 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
		@@ -1,4 +1,6 @@
 | 
				
			|||||||
uses CONFIG_CONSOLE_SERIAL8250 CONFIG_CONSOLE_VGA CONFIG_CONSOLE_BTEXT
 | 
					uses CONFIG_CONSOLE_SERIAL8250
 | 
				
			||||||
 | 
					uses CONFIG_CONSOLE_VGA
 | 
				
			||||||
 | 
					uses CONFIG_CONSOLE_BTEXT
 | 
				
			||||||
uses CONFIG_CONSOLE_LOGBUF
 | 
					uses CONFIG_CONSOLE_LOGBUF
 | 
				
			||||||
uses CONFIG_USE_INIT
 | 
					uses CONFIG_USE_INIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,4 +26,3 @@ object vsprintf.o
 | 
				
			|||||||
if CONFIG_USE_INIT
 | 
					if CONFIG_USE_INIT
 | 
				
			||||||
	initobject vtxprintf.o
 | 
						initobject vtxprintf.o
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +1,2 @@
 | 
				
			|||||||
dir /cpu/x86/mtrr
 | 
					dir /cpu/x86/mtrr
 | 
				
			||||||
object amd_mtrr.c
 | 
					object amd_mtrr.o
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,3 +6,6 @@ object pnp_device.o
 | 
				
			|||||||
object hypertransport.o
 | 
					object hypertransport.o
 | 
				
			||||||
object pci_ops.o
 | 
					object pci_ops.o
 | 
				
			||||||
object smbus_ops.o
 | 
					object smbus_ops.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object pci_rom.o
 | 
				
			||||||
 | 
					dir emulator
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								src/devices/emulator/Config.lb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/devices/emulator/Config.lb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					object biosemu.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dir pcbios
 | 
				
			||||||
 | 
					dir x86emu
 | 
				
			||||||
							
								
								
									
										335
									
								
								src/devices/emulator/biosemu.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										335
									
								
								src/devices/emulator/biosemu.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,335 @@
 | 
				
			|||||||
 | 
					#include <arch/io.h>
 | 
				
			||||||
 | 
					#include <console/console.h>
 | 
				
			||||||
 | 
					#include <device/device.h>
 | 
				
			||||||
 | 
					#include <device/pci.h>
 | 
				
			||||||
 | 
					#include <device/pci_ids.h>
 | 
				
			||||||
 | 
					#include <device/pci_ops.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <x86emu/x86emu.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MEM_WB(where, what) wrb(where, what)
 | 
				
			||||||
 | 
					#define MEM_WW(where, what) wrw(where, what)
 | 
				
			||||||
 | 
					#define MEM_WL(where, what) wrl(where, what)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MEM_RB(where) rdb(where)
 | 
				
			||||||
 | 
					#define MEM_RW(where) rdw(where)
 | 
				
			||||||
 | 
					#define MEM_RL(where) rdl(where)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8 x_inb(u16 port);
 | 
				
			||||||
 | 
					u16 x_inw(u16 port);
 | 
				
			||||||
 | 
					void x_outb(u16 port, u8 val);
 | 
				
			||||||
 | 
					void x_outw(u16 port, u16 val);
 | 
				
			||||||
 | 
					u32 x_inl(u16 port);
 | 
				
			||||||
 | 
					void x_outl(u16 port, u32 val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* general software interrupt handler */
 | 
				
			||||||
 | 
					u32 getIntVect(int num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return MEM_RW(num << 2) + (MEM_RW((num << 2) + 2) << 4);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* FixME: There is already a push_word() in the emulator */
 | 
				
			||||||
 | 
					void pushw(u16 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						X86_ESP -= 2;
 | 
				
			||||||
 | 
						MEM_WW(((u32) X86_SS << 4) + X86_SP, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int run_bios_int(int num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 eflags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						eflags = X86_EFLAGS;
 | 
				
			||||||
 | 
						pushw(eflags);
 | 
				
			||||||
 | 
						pushw(X86_CS);
 | 
				
			||||||
 | 
						pushw(X86_IP);
 | 
				
			||||||
 | 
						X86_CS = MEM_RW((num << 2) + 2);
 | 
				
			||||||
 | 
						X86_IP = MEM_RW(num << 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("%s: INT %x CS:IP = %x:%x\n", __FUNCTION__,
 | 
				
			||||||
 | 
							     num, MEM_RW((num << 2) + 2), MEM_RW(num << 2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8 x_inb(u16 port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = inb(port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (port != 0x40)
 | 
				
			||||||
 | 
						    printk_debug("inb(0x%04x) = 0x%02x\n", port, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16 x_inw(u16 port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u16 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = inw(port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("inw(0x%04x) = 0x%04x\n", port, val);
 | 
				
			||||||
 | 
						return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32 x_inl(u16 port)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = inl(port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("inl(0x%04x) = 0x%08x\n", port, val);
 | 
				
			||||||
 | 
						return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x_outb(u16 port, u8 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (port != 0x43)
 | 
				
			||||||
 | 
							printk_debug("outb(0x%02x, 0x%04x)\n", val, port);
 | 
				
			||||||
 | 
						outb(val, port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x_outw(u16 port, u16 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printk_debug("outw(0x%04x, 0x%04x)\n", val, port);
 | 
				
			||||||
 | 
						outw(val, port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x_outl(u16 port, u32 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						printk_debug("outl(0x%08x, 0x%04x)\n", val, port);
 | 
				
			||||||
 | 
						outl(val, port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					X86EMU_pioFuncs myfuncs = {
 | 
				
			||||||
 | 
						x_inb, x_inw, x_inl,
 | 
				
			||||||
 | 
						x_outb, x_outw, x_outl
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Interrupt multiplexer */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void do_int(int num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("int%x vector at %x\n", num, getIntVect(num));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (num) {
 | 
				
			||||||
 | 
					#ifndef _PC
 | 
				
			||||||
 | 
						case 0x10:
 | 
				
			||||||
 | 
						case 0x42:
 | 
				
			||||||
 | 
						case 0x6D:
 | 
				
			||||||
 | 
							if (getIntVect(num) == 0x0000) {
 | 
				
			||||||
 | 
								printk_debug("un-inited int vector\n");
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (getIntVect(num) == 0xFF065) {
 | 
				
			||||||
 | 
								//ret = int42_handler();
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						case 0x15:
 | 
				
			||||||
 | 
							//ret = int15_handler();
 | 
				
			||||||
 | 
							ret = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 0x16:
 | 
				
			||||||
 | 
							//ret = int16_handler();
 | 
				
			||||||
 | 
							ret = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 0x1A:
 | 
				
			||||||
 | 
							ret = pcibios_handler();
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 0xe6:
 | 
				
			||||||
 | 
							//ret = intE6_handler();
 | 
				
			||||||
 | 
							ret = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ret)
 | 
				
			||||||
 | 
							ret = run_bios_int(num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ret) {
 | 
				
			||||||
 | 
							printk_debug("\nint%x: not implemented\n", num);
 | 
				
			||||||
 | 
							x86emu_dump_xregs();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#define SYS_BIOS 0xf0000
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * here we are really paranoid about faking a "real"
 | 
				
			||||||
 | 
					 * BIOS. Most of this information was pulled from
 | 
				
			||||||
 | 
					 * dosemu.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					void setup_int_vect(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* let the int vects point to the SYS_BIOS seg */
 | 
				
			||||||
 | 
						for (i = 0; i < 0x80; i++) {
 | 
				
			||||||
 | 
							MEM_WW(i << 2, 0);
 | 
				
			||||||
 | 
							MEM_WW((i << 2) + 2, SYS_BIOS >> 4);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reset_int_vect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* font tables default location (int 1F) */
 | 
				
			||||||
 | 
						MEM_WW(0x1f << 2, 0xfa6e);
 | 
				
			||||||
 | 
						/* int 11 default location (Get Equipment Configuration) */
 | 
				
			||||||
 | 
						MEM_WW(0x11 << 2, 0xf84d);
 | 
				
			||||||
 | 
						/* int 12 default location (Get Conventional Memory Size) */
 | 
				
			||||||
 | 
						MEM_WW(0x12 << 2, 0xf841);
 | 
				
			||||||
 | 
						/* int 15 default location (I/O System Extensions) */
 | 
				
			||||||
 | 
						MEM_WW(0x15 << 2, 0xf859);
 | 
				
			||||||
 | 
						/* int 1A default location (RTC, PCI and others) */
 | 
				
			||||||
 | 
						MEM_WW(0x1a << 2, 0xff6e);
 | 
				
			||||||
 | 
						/* int 05 default location (Bound Exceeded) */
 | 
				
			||||||
 | 
						MEM_WW(0x05 << 2, 0xff54);
 | 
				
			||||||
 | 
						/* int 08 default location (Double Fault) */
 | 
				
			||||||
 | 
						MEM_WW(0x08 << 2, 0xfea5);
 | 
				
			||||||
 | 
						/* int 13 default location (Disk) */
 | 
				
			||||||
 | 
						MEM_WW(0x13 << 2, 0xec59);
 | 
				
			||||||
 | 
						/* int 0E default location (Page Fault) */
 | 
				
			||||||
 | 
						MEM_WW(0x0e << 2, 0xef57);
 | 
				
			||||||
 | 
						/* int 17 default location (Parallel Port) */
 | 
				
			||||||
 | 
						MEM_WW(0x17 << 2, 0xefd2);
 | 
				
			||||||
 | 
						/* fdd table default location (int 1e) */
 | 
				
			||||||
 | 
						MEM_WW(0x1e << 2, 0xefc7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Set Equipment flag to VGA */
 | 
				
			||||||
 | 
						i = MEM_RB(0x0410) & 0xCF;
 | 
				
			||||||
 | 
						MEM_WB(0x0410, i);
 | 
				
			||||||
 | 
						/* XXX Perhaps setup more of the BDA here.  See also int42(0x00). */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int setup_system_bios(void *base_addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char *base = (char *) base_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * we trap the "industry standard entry points" to the BIOS
 | 
				
			||||||
 | 
						 * and all other locations by filling them with "hlt"
 | 
				
			||||||
 | 
						 * TODO: implement hlt-handler for these
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						memset(base, 0xf4, 0x10000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* set bios date */
 | 
				
			||||||
 | 
						//strcpy(base + 0x0FFF5, "06/11/99");
 | 
				
			||||||
 | 
						/* set up eisa ident string */
 | 
				
			||||||
 | 
						//strcpy(base + 0x0FFD9, "PCI_ISA");
 | 
				
			||||||
 | 
						/* write system model id for IBM-AT */
 | 
				
			||||||
 | 
						//*((unsigned char *) (base + 0x0FFFE)) = 0xfc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void reset_int_vect(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * This table is normally located at 0xF000:0xF0A4.  However, int 0x42,
 | 
				
			||||||
 | 
						 * function 0 (Mode Set) expects it (or a copy) somewhere in the bottom
 | 
				
			||||||
 | 
						 * 64kB.  Note that because this data doesn't survive POST, int 0x42 should
 | 
				
			||||||
 | 
						 * only be used during EGA/VGA BIOS initialisation.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						static const u8 VideoParms[] = {
 | 
				
			||||||
 | 
							/* Timing for modes 0x00 & 0x01 */
 | 
				
			||||||
 | 
							0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
 | 
				
			||||||
 | 
							0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
 | 
				
			||||||
 | 
							/* Timing for modes 0x02 & 0x03 */
 | 
				
			||||||
 | 
							0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
 | 
				
			||||||
 | 
							0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
 | 
				
			||||||
 | 
							/* Timing for modes 0x04, 0x05 & 0x06 */
 | 
				
			||||||
 | 
							0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70,
 | 
				
			||||||
 | 
							0x02, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
 | 
				
			||||||
 | 
							/* Timing for mode 0x07 */
 | 
				
			||||||
 | 
							0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19,
 | 
				
			||||||
 | 
							0x02, 0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
 | 
				
			||||||
 | 
							/* Display page lengths in little endian order */
 | 
				
			||||||
 | 
							0x00, 0x08,	/* Modes 0x00 and 0x01 */
 | 
				
			||||||
 | 
							0x00, 0x10,	/* Modes 0x02 and 0x03 */
 | 
				
			||||||
 | 
							0x00, 0x40,	/* Modes 0x04 and 0x05 */
 | 
				
			||||||
 | 
							0x00, 0x40,	/* Modes 0x06 and 0x07 */
 | 
				
			||||||
 | 
							/* Number of columns for each mode */
 | 
				
			||||||
 | 
							40, 40, 80, 80, 40, 40, 80, 80,
 | 
				
			||||||
 | 
							/* CGA Mode register value for each mode */
 | 
				
			||||||
 | 
							0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29,
 | 
				
			||||||
 | 
							/* Padding */
 | 
				
			||||||
 | 
							0x00, 0x00, 0x00, 0x00
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < sizeof(VideoParms); i++)
 | 
				
			||||||
 | 
							MEM_WB(i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
 | 
				
			||||||
 | 
						MEM_WW(0x1d << 2, 0x1000 - sizeof(VideoParms));
 | 
				
			||||||
 | 
						MEM_WW((0x1d << 2) + 2, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("SETUP INT\n");
 | 
				
			||||||
 | 
						MEM_WW(0x10 << 2, 0xf065);
 | 
				
			||||||
 | 
						MEM_WW((0x10 << 2) + 2, SYS_BIOS >> 4);
 | 
				
			||||||
 | 
						MEM_WW(0x42 << 2, 0xf065);
 | 
				
			||||||
 | 
						MEM_WW((0x42 << 2) + 2, SYS_BIOS >> 4);
 | 
				
			||||||
 | 
						MEM_WW(0x6D << 2, 0xf065);
 | 
				
			||||||
 | 
						MEM_WW((0x6D << 2) + 2, SYS_BIOS >> 4);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run_bios(struct device * dev, unsigned long addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if 1
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
						unsigned short initialcs = (addr & 0xF0000) >> 4;
 | 
				
			||||||
 | 
						unsigned short initialip = (addr + 3) & 0xFFFF;
 | 
				
			||||||
 | 
						unsigned short devfn = dev->bus->secondary << 8 | dev->path.u.pci.devfn;
 | 
				
			||||||
 | 
						X86EMU_intrFuncs intFuncs[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						X86EMU_setMemBase(0, 0x100000);
 | 
				
			||||||
 | 
						X86EMU_setupPioFuncs(&myfuncs);
 | 
				
			||||||
 | 
						for (i = 0; i < 256; i++)
 | 
				
			||||||
 | 
							intFuncs[i] = do_int;
 | 
				
			||||||
 | 
						X86EMU_setupIntrFuncs(intFuncs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							char *date = "01/01/99";
 | 
				
			||||||
 | 
							for (i = 0; date[i]; i++)
 | 
				
			||||||
 | 
								wrb(0xffff5 + i, date[i]);
 | 
				
			||||||
 | 
							wrb(0xffff7, '/');
 | 
				
			||||||
 | 
							wrb(0xffffa, '/');
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						    /* FixME: move PIT init to its own file */
 | 
				
			||||||
 | 
						    outb(0x36, 0x43);
 | 
				
			||||||
 | 
						    outb(0x00, 0x40);
 | 
				
			||||||
 | 
						    outb(0x00, 0x40);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						//setup_int_vect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* cpu setup */
 | 
				
			||||||
 | 
						X86_AX = devfn ? devfn : 0xff;
 | 
				
			||||||
 | 
						X86_DX = 0x80;
 | 
				
			||||||
 | 
						X86_EIP = initialip;
 | 
				
			||||||
 | 
						X86_CS = initialcs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Initialize stack and data segment */
 | 
				
			||||||
 | 
						X86_SS = initialcs;
 | 
				
			||||||
 | 
						X86_SP = 0xfffe;
 | 
				
			||||||
 | 
						X86_DS = 0x0040;
 | 
				
			||||||
 | 
						X86_ES = 0x0000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We need a sane way to return from bios
 | 
				
			||||||
 | 
						 * execution. A hlt instruction and a pointer
 | 
				
			||||||
 | 
						 * to it, both kept on the stack, will do.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						pushw(0xf4f4);		/* hlt; hlt */
 | 
				
			||||||
 | 
						pushw(X86_SS);
 | 
				
			||||||
 | 
						pushw(X86_SP + 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//X86EMU_trace_on();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						X86EMU_exec();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								src/devices/emulator/pcbios/Config.lb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/devices/emulator/pcbios/Config.lb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					object pcibios.o
 | 
				
			||||||
							
								
								
									
										142
									
								
								src/devices/emulator/pcbios/pcibios.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								src/devices/emulator/pcbios/pcibios.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
				
			|||||||
 | 
					#include <console/console.h>
 | 
				
			||||||
 | 
					#include <device/device.h>
 | 
				
			||||||
 | 
					#include <device/pci.h>
 | 
				
			||||||
 | 
					#include <device/pci_ids.h>
 | 
				
			||||||
 | 
					#include <device/pci_ops.h>
 | 
				
			||||||
 | 
					#include <x86emu/x86emu.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "pcibios.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int pcibios_handler()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i, ret = 0;
 | 
				
			||||||
 | 
						struct device *dev = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("%s AX = %x\n", __func__, X86_AX);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (X86_AX) {
 | 
				
			||||||
 | 
						case PCI_BIOS_PRESENT:
 | 
				
			||||||
 | 
							X86_AH	= 0x00;		/* no config space/special cycle support */
 | 
				
			||||||
 | 
							X86_AL	= 0x01;		/* config mechanism 1 */
 | 
				
			||||||
 | 
							X86_EDX = 'P' | 'C' << 8 | 'I' | ' ' << 24;
 | 
				
			||||||
 | 
							X86_EBX = 0x0210;	/* Version 2.10 */
 | 
				
			||||||
 | 
							X86_ECX = 0xFF00;	/* FixME: Max bus number */
 | 
				
			||||||
 | 
							X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
							ret = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case FIND_PCI_DEVICE:
 | 
				
			||||||
 | 
							/* FixME: support SI != 0 */
 | 
				
			||||||
 | 
							dev = dev_find_device(X86_DX, X86_CX, dev);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								X86_BH = dev->bus->secondary;
 | 
				
			||||||
 | 
								X86_BL = dev->path.u.pci.devfn;
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case FIND_PCI_CLASS_CODE:
 | 
				
			||||||
 | 
							/* FixME: support SI != 0 */
 | 
				
			||||||
 | 
							dev = dev_find_class(X86_ECX, dev);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								X86_BH = dev->bus->secondary;
 | 
				
			||||||
 | 
								X86_BL = dev->path.u.pci.devfn;
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case READ_CONFIG_BYTE:
 | 
				
			||||||
 | 
							dev = dev_find_slot(X86_BH, X86_BL);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								X86_CL = pci_read_config8(dev, X86_DI);
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */	
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case READ_CONFIG_WORD:
 | 
				
			||||||
 | 
							dev = dev_find_slot(X86_BH, X86_BL);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								X86_CX = pci_read_config16(dev, X86_DI);
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */	
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case READ_CONFIG_DWORD:
 | 
				
			||||||
 | 
							dev = dev_find_slot(X86_BH, X86_BL);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								X86_ECX = pci_read_config32(dev, X86_DI);
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */	
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WRITE_CONFIG_BYTE:
 | 
				
			||||||
 | 
							dev = dev_find_slot(X86_BH, X86_BL);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								pci_write_config8(dev, X86_DI, X86_CL);
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */	
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WRITE_CONFIG_WORD:
 | 
				
			||||||
 | 
							dev = dev_find_slot(X86_BH, X86_BL);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								pci_write_config16(dev, X86_DI, X86_CX);
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */	
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case WRITE_CONFIG_DWORD:
 | 
				
			||||||
 | 
							dev = dev_find_slot(X86_BH, X86_BL);
 | 
				
			||||||
 | 
							if (dev != 0) {
 | 
				
			||||||
 | 
								pci_write_config16(dev, X86_DI, X86_ECX);
 | 
				
			||||||
 | 
								X86_AH = SUCCESSFUL;
 | 
				
			||||||
 | 
								X86_EFLAGS &= ~FB_CF;	/* clear carry flag */
 | 
				
			||||||
 | 
								ret = 1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								X86_AH = DEVICE_NOT_FOUND;
 | 
				
			||||||
 | 
								X86_EFLAGS |= FB_CF;	/* set carry flag */	
 | 
				
			||||||
 | 
								ret = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							X86_AH = FUNC_NOT_SUPPORTED;
 | 
				
			||||||
 | 
							X86_EFLAGS |= FB_CF; 
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								src/devices/emulator/pcbios/pcibios.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/devices/emulator/pcbios/pcibios.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					enum {
 | 
				
			||||||
 | 
						PCI_BIOS_PRESENT	= 0xB101,
 | 
				
			||||||
 | 
						FIND_PCI_DEVICE		= 0xB102,
 | 
				
			||||||
 | 
						FIND_PCI_CLASS_CODE	= 0xB103,
 | 
				
			||||||
 | 
						GENERATE_SPECIAL_CYCLE	= 0xB106,
 | 
				
			||||||
 | 
						READ_CONFIG_BYTE	= 0xB108,
 | 
				
			||||||
 | 
						READ_CONFIG_WORD	= 0xB109,
 | 
				
			||||||
 | 
						READ_CONFIG_DWORD	= 0xB10A,
 | 
				
			||||||
 | 
						WRITE_CONFIG_BYTE	= 0xB10B,
 | 
				
			||||||
 | 
						WRITE_CONFIG_WORD	= 0xB10C,
 | 
				
			||||||
 | 
						WRITE_CONFIG_DWORD	= 0xB10D,
 | 
				
			||||||
 | 
						GET_IRQ_ROUTING_OPTIONS	= 0xB10E,
 | 
				
			||||||
 | 
						SET_PCI_IRQ		= 0xB10F
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						SUCCESSFUL		= 0x00,
 | 
				
			||||||
 | 
						FUNC_NOT_SUPPORTED	= 0x81,
 | 
				
			||||||
 | 
						BAD_VENDOR_ID		= 0x83,
 | 
				
			||||||
 | 
						DEVICE_NOT_FOUND	= 0x86,
 | 
				
			||||||
 | 
						BAD_REGISTER_NUMBER	= 0x87,
 | 
				
			||||||
 | 
						SET_FAILED		= 0x88,
 | 
				
			||||||
 | 
						BUFFER_TOO_SMALL	= 0x89
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										7
									
								
								src/devices/emulator/x86emu/Config.lb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/devices/emulator/x86emu/Config.lb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					object debug.o
 | 
				
			||||||
 | 
					object decode.o
 | 
				
			||||||
 | 
					object fpu.o
 | 
				
			||||||
 | 
					object ops.o
 | 
				
			||||||
 | 
					object ops2.o
 | 
				
			||||||
 | 
					object prim_ops.o
 | 
				
			||||||
 | 
					object sys.o
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/devices/emulator/x86emu/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/devices/emulator/x86emu/LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					                         License information
 | 
				
			||||||
 | 
					                         -------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The x86emu library is under a BSD style license, comaptible
 | 
				
			||||||
 | 
					with the XFree86 and X licenses used by XFree86. The
 | 
				
			||||||
 | 
					original x86emu libraries were under the GNU General Public
 | 
				
			||||||
 | 
					License. Due to license incompatibilities between the GPL
 | 
				
			||||||
 | 
					and the XFree86 license, the original authors of the code
 | 
				
			||||||
 | 
					decided to allow a license change. If you have submitted
 | 
				
			||||||
 | 
					code to the original x86emu project, and you don't agree
 | 
				
			||||||
 | 
					with the license change, please contact us and let you
 | 
				
			||||||
 | 
					know. Your code will be removed to comply with your wishes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have any questions about this, please send email to
 | 
				
			||||||
 | 
					x86emu@linuxlabs.com or KendallB@scitechsoft.com for
 | 
				
			||||||
 | 
					clarification.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										425
									
								
								src/devices/emulator/x86emu/debug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										425
									
								
								src/devices/emulator/x86emu/debug.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,425 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*                       Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*               Copyright (C) 1991-2004 SciTech Software, Inc.
 | 
				
			||||||
 | 
					*                    Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					*                      Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:     ANSI C
 | 
				
			||||||
 | 
					* Environment:  Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  This file contains the code to handle debugging of the
 | 
				
			||||||
 | 
					*               emulator.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "x86emui.h"
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*----------------------------- Implementation ----------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void     print_encoded_bytes (u16 s, u16 o);
 | 
				
			||||||
 | 
					static void     print_decoded_instruction (void);
 | 
				
			||||||
 | 
					static int      parse_line (char *s, int *ps, int *n);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* should look something like debug's output. */
 | 
				
			||||||
 | 
					void X86EMU_trace_regs (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (DEBUG_TRACE()) {
 | 
				
			||||||
 | 
					        x86emu_dump_regs();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) {
 | 
				
			||||||
 | 
					        printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
 | 
				
			||||||
 | 
					        print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
 | 
				
			||||||
 | 
					        print_decoded_instruction();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void X86EMU_trace_xregs (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (DEBUG_TRACE()) {
 | 
				
			||||||
 | 
					        x86emu_dump_xregs();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_just_disassemble (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * This routine called if the flag DEBUG_DISASSEMBLE is set kind
 | 
				
			||||||
 | 
					     * of a hack!
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
 | 
				
			||||||
 | 
					    print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
 | 
				
			||||||
 | 
					    print_decoded_instruction();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void disassemble_forward (u16 seg, u16 off, int n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    X86EMU_sysEnv tregs;
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    u8 op1;
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * hack, hack, hack.  What we do is use the exact machinery set up
 | 
				
			||||||
 | 
					     * for execution, except that now there is an additional state
 | 
				
			||||||
 | 
					     * flag associated with the "execution", and we are using a copy
 | 
				
			||||||
 | 
					     * of the register struct.  All the major opcodes, once fully
 | 
				
			||||||
 | 
					     * decoded, have the following two steps: TRACE_REGS(r,m);
 | 
				
			||||||
 | 
					     * SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
 | 
				
			||||||
 | 
					     * the preprocessor.  The TRACE_REGS macro expands to:
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * if (debug&DEBUG_DISASSEMBLE)
 | 
				
			||||||
 | 
					     *     {just_disassemble(); goto EndOfInstruction;}
 | 
				
			||||||
 | 
					     *     if (debug&DEBUG_TRACE) trace_regs(r,m);
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * ......  and at the last line of the routine.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * EndOfInstruction: end_instr();
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * Up to the point where TRACE_REG is expanded, NO modifications
 | 
				
			||||||
 | 
					     * are done to any register EXCEPT the IP register, for fetch and
 | 
				
			||||||
 | 
					     * decoding purposes.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * This was done for an entirely different reason, but makes a
 | 
				
			||||||
 | 
					     * nice way to get the system to help debug codes.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    tregs = M;
 | 
				
			||||||
 | 
					    tregs.x86.R_IP = off;
 | 
				
			||||||
 | 
					    tregs.x86.R_CS = seg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* reset the decoding buffers */
 | 
				
			||||||
 | 
					    tregs.x86.enc_str_pos = 0;
 | 
				
			||||||
 | 
					    tregs.x86.enc_pos = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* turn on the "disassemble only, no execute" flag */
 | 
				
			||||||
 | 
					    tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* DUMP NEXT n instructions to screen in straight_line fashion */
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * This looks like the regular instruction fetch stream, except
 | 
				
			||||||
 | 
					     * that when this occurs, each fetched opcode, upon seeing the
 | 
				
			||||||
 | 
					     * DEBUG_DISASSEMBLE flag set, exits immediately after decoding
 | 
				
			||||||
 | 
					     * the instruction.  XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
 | 
				
			||||||
 | 
					     * Note the use of a copy of the register structure...
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    for (i=0; i<n; i++) {
 | 
				
			||||||
 | 
					        op1 = (*sys_rdb)(((u32)M.x86.R_CS<<4) + (M.x86.R_IP++));
 | 
				
			||||||
 | 
					        (x86emu_optab[op1])(op1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /* end major hack mode. */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_check_ip_access (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /* NULL as of now */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_check_sp_access (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_check_mem_access (u32 dummy)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*  check bounds, etc */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_check_data_access (uint dummy1, uint dummy2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    /*  check bounds, etc */
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_inc_decoded_inst_len (int x)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    M.x86.enc_pos += x;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_decode_printf (char *x)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",x);
 | 
				
			||||||
 | 
					    M.x86.enc_str_pos += strlen(x);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_decode_printf2 (char *x, int y)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char temp[100];
 | 
				
			||||||
 | 
					    sprintf(temp,x,y);
 | 
				
			||||||
 | 
					    sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",temp);
 | 
				
			||||||
 | 
					    M.x86.enc_str_pos += strlen(temp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_end_instr (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    M.x86.enc_str_pos = 0;
 | 
				
			||||||
 | 
					    M.x86.enc_pos = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_encoded_bytes (u16 s, u16 o)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    char buf1[64];
 | 
				
			||||||
 | 
					    for (i=0; i< M.x86.enc_pos; i++) {
 | 
				
			||||||
 | 
					        sprintf(buf1+2*i,"%02x", fetch_data_byte_abs(s,o+i));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    printk("%-20s",buf1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_decoded_instruction (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    printk("%s", M.x86.decoded_buf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_print_int_vect (u16 iv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    u16 seg,off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (iv > 256) return;
 | 
				
			||||||
 | 
					    seg   = fetch_data_word_abs(0,iv*4);
 | 
				
			||||||
 | 
					    off   = fetch_data_word_abs(0,iv*4+2);
 | 
				
			||||||
 | 
					    printk("%04x:%04x ", seg, off);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void X86EMU_dump_memory (u16 seg, u16 off, u32 amt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    u32 start = off & 0xfffffff0;
 | 
				
			||||||
 | 
					    u32 end  = (off+16) & 0xfffffff0;
 | 
				
			||||||
 | 
					    u32 i;
 | 
				
			||||||
 | 
					    u32 current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    current = start;
 | 
				
			||||||
 | 
					    while (end <= off + amt) {
 | 
				
			||||||
 | 
					        printk("%04x:%04x ", seg, start);
 | 
				
			||||||
 | 
					        for (i=start; i< off; i++)
 | 
				
			||||||
 | 
					          printk("   ");
 | 
				
			||||||
 | 
					        for (       ; i< end; i++)
 | 
				
			||||||
 | 
					          printk("%02x ", fetch_data_byte_abs(seg,i));
 | 
				
			||||||
 | 
					        printk("\n");
 | 
				
			||||||
 | 
					        start = end;
 | 
				
			||||||
 | 
					        end = start + 16;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_single_step (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char s[1024];
 | 
				
			||||||
 | 
					    int ps[10];
 | 
				
			||||||
 | 
					    int ntok;
 | 
				
			||||||
 | 
					    int cmd;
 | 
				
			||||||
 | 
					    int done;
 | 
				
			||||||
 | 
					        int segment;
 | 
				
			||||||
 | 
					    int offset;
 | 
				
			||||||
 | 
					    static int breakpoint;
 | 
				
			||||||
 | 
					    static int noDecode = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (DEBUG_BREAK()) {
 | 
				
			||||||
 | 
					                if (M.x86.saved_ip != breakpoint) {
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					              M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
 | 
				
			||||||
 | 
					                        M.x86.debug |= DEBUG_TRACE_F;
 | 
				
			||||||
 | 
					                        M.x86.debug &= ~DEBUG_BREAK_F;
 | 
				
			||||||
 | 
					                        print_decoded_instruction ();
 | 
				
			||||||
 | 
					                        X86EMU_trace_regs();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    done=0;
 | 
				
			||||||
 | 
					    offset = M.x86.saved_ip;
 | 
				
			||||||
 | 
					    while (!done) {
 | 
				
			||||||
 | 
					        printk("-");
 | 
				
			||||||
 | 
					        p = fgets(s, 1023, stdin);
 | 
				
			||||||
 | 
					        cmd = parse_line(s, ps, &ntok);
 | 
				
			||||||
 | 
					        switch(cmd) {
 | 
				
			||||||
 | 
					          case 'u':
 | 
				
			||||||
 | 
					            disassemble_forward(M.x86.saved_cs,(u16)offset,10);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'd':
 | 
				
			||||||
 | 
					                            if (ntok == 2) {
 | 
				
			||||||
 | 
					                                    segment = M.x86.saved_cs;
 | 
				
			||||||
 | 
					                                    offset = ps[1];
 | 
				
			||||||
 | 
					                                    X86EMU_dump_memory(segment,(u16)offset,16);
 | 
				
			||||||
 | 
					                                    offset += 16;
 | 
				
			||||||
 | 
					                            } else if (ntok == 3) {
 | 
				
			||||||
 | 
					                                    segment = ps[1];
 | 
				
			||||||
 | 
					                                    offset = ps[2];
 | 
				
			||||||
 | 
					                                    X86EMU_dump_memory(segment,(u16)offset,16);
 | 
				
			||||||
 | 
					                                    offset += 16;
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                    segment = M.x86.saved_cs;
 | 
				
			||||||
 | 
					                                    X86EMU_dump_memory(segment,(u16)offset,16);
 | 
				
			||||||
 | 
					                                    offset += 16;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'c':
 | 
				
			||||||
 | 
					            M.x86.debug ^= DEBUG_TRACECALL_F;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 's':
 | 
				
			||||||
 | 
					            M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'r':
 | 
				
			||||||
 | 
					            X86EMU_trace_regs();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'x':
 | 
				
			||||||
 | 
					            X86EMU_trace_xregs();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'g':
 | 
				
			||||||
 | 
					            if (ntok == 2) {
 | 
				
			||||||
 | 
					                breakpoint = ps[1];
 | 
				
			||||||
 | 
					        if (noDecode) {
 | 
				
			||||||
 | 
					                        M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					                        M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        M.x86.debug &= ~DEBUG_TRACE_F;
 | 
				
			||||||
 | 
					        M.x86.debug |= DEBUG_BREAK_F;
 | 
				
			||||||
 | 
					        done = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 'q':
 | 
				
			||||||
 | 
					          M.x86.debug |= DEBUG_EXIT;
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					      case 'P':
 | 
				
			||||||
 | 
					          noDecode = (noDecode)?0:1;
 | 
				
			||||||
 | 
					          printk("Toggled decoding to %s\n",(noDecode)?"FALSE":"TRUE");
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					          case 't':
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					            done = 1;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int X86EMU_trace_on(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return M.x86.debug |= DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int X86EMU_trace_off(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int parse_line (char *s, int *ps, int *n)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *n = 0;
 | 
				
			||||||
 | 
					    while(*s == ' ' || *s == '\t') s++;
 | 
				
			||||||
 | 
					    ps[*n] = *s;
 | 
				
			||||||
 | 
					    switch (*s) {
 | 
				
			||||||
 | 
					      case '\n':
 | 
				
			||||||
 | 
					        *n += 1;
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        cmd = *s;
 | 
				
			||||||
 | 
					        *n += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (1) {
 | 
				
			||||||
 | 
					        while (*s != ' ' && *s != '\t' && *s != '\n')  s++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (*s == '\n')
 | 
				
			||||||
 | 
					            return cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while(*s == ' ' || *s == '\t') s++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sscanf(s,"%x",&ps[*n]);
 | 
				
			||||||
 | 
					        *n += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_dump_regs (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    printk("\tAX=%04x  ", M.x86.R_AX );
 | 
				
			||||||
 | 
					    printk("BX=%04x  ", M.x86.R_BX );
 | 
				
			||||||
 | 
					    printk("CX=%04x  ", M.x86.R_CX );
 | 
				
			||||||
 | 
					    printk("DX=%04x  ", M.x86.R_DX );
 | 
				
			||||||
 | 
					    printk("SP=%04x  ", M.x86.R_SP );
 | 
				
			||||||
 | 
					    printk("BP=%04x  ", M.x86.R_BP );
 | 
				
			||||||
 | 
					    printk("SI=%04x  ", M.x86.R_SI );
 | 
				
			||||||
 | 
					    printk("DI=%04x\n", M.x86.R_DI );
 | 
				
			||||||
 | 
					    printk("\tDS=%04x  ", M.x86.R_DS );
 | 
				
			||||||
 | 
					    printk("ES=%04x  ", M.x86.R_ES );
 | 
				
			||||||
 | 
					    printk("SS=%04x  ", M.x86.R_SS );
 | 
				
			||||||
 | 
					    printk("CS=%04x  ", M.x86.R_CS );
 | 
				
			||||||
 | 
					    printk("IP=%04x   ", M.x86.R_IP );
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_OF))    printk("OV ");     /* CHECKED... */
 | 
				
			||||||
 | 
					    else                        printk("NV ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_DF))    printk("DN ");
 | 
				
			||||||
 | 
					    else                        printk("UP ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_IF))    printk("EI ");
 | 
				
			||||||
 | 
					    else                        printk("DI ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_SF))    printk("NG ");
 | 
				
			||||||
 | 
					    else                        printk("PL ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_ZF))    printk("ZR ");
 | 
				
			||||||
 | 
					    else                        printk("NZ ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_AF))    printk("AC ");
 | 
				
			||||||
 | 
					    else                        printk("NA ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_PF))    printk("PE ");
 | 
				
			||||||
 | 
					    else                        printk("PO ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_CF))    printk("CY ");
 | 
				
			||||||
 | 
					    else                        printk("NC ");
 | 
				
			||||||
 | 
					    printk("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void x86emu_dump_xregs (void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    printk("\tEAX=%08x  ", M.x86.R_EAX );
 | 
				
			||||||
 | 
					    printk("EBX=%08x  ", M.x86.R_EBX );
 | 
				
			||||||
 | 
					    printk("ECX=%08x  ", M.x86.R_ECX );
 | 
				
			||||||
 | 
					    printk("EDX=%08x  \n", M.x86.R_EDX );
 | 
				
			||||||
 | 
					    printk("\tESP=%08x  ", M.x86.R_ESP );
 | 
				
			||||||
 | 
					    printk("EBP=%08x  ", M.x86.R_EBP );
 | 
				
			||||||
 | 
					    printk("ESI=%08x  ", M.x86.R_ESI );
 | 
				
			||||||
 | 
					    printk("EDI=%08x\n", M.x86.R_EDI );
 | 
				
			||||||
 | 
					    printk("\tDS=%04x  ", M.x86.R_DS );
 | 
				
			||||||
 | 
					    printk("ES=%04x  ", M.x86.R_ES );
 | 
				
			||||||
 | 
					    printk("SS=%04x  ", M.x86.R_SS );
 | 
				
			||||||
 | 
					    printk("CS=%04x  ", M.x86.R_CS );
 | 
				
			||||||
 | 
					    printk("EIP=%08x\n\t", M.x86.R_EIP );
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_OF))    printk("OV ");     /* CHECKED... */
 | 
				
			||||||
 | 
					    else                        printk("NV ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_DF))    printk("DN ");
 | 
				
			||||||
 | 
					    else                        printk("UP ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_IF))    printk("EI ");
 | 
				
			||||||
 | 
					    else                        printk("DI ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_SF))    printk("NG ");
 | 
				
			||||||
 | 
					    else                        printk("PL ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_ZF))    printk("ZR ");
 | 
				
			||||||
 | 
					    else                        printk("NZ ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_AF))    printk("AC ");
 | 
				
			||||||
 | 
					    else                        printk("NA ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_PF))    printk("PE ");
 | 
				
			||||||
 | 
					    else                        printk("PO ");
 | 
				
			||||||
 | 
					    if (ACCESS_FLAG(F_CF))    printk("CY ");
 | 
				
			||||||
 | 
					    else                        printk("NC ");
 | 
				
			||||||
 | 
					    printk("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										213
									
								
								src/devices/emulator/x86emu/debug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								src/devices/emulator/x86emu/debug.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,213 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for debug definitions.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/debug.h,v 1.4 2000/11/21 23:10:27 tsi Exp $ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_DEBUG_H
 | 
				
			||||||
 | 
					#define __X86EMU_DEBUG_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#define DEBUG 0
 | 
				
			||||||
 | 
					#undef DEBUG
 | 
				
			||||||
 | 
					/*---------------------- Macros and type definitions ----------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* checks to be enabled for "runtime" */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHECK_IP_FETCH_F                0x1
 | 
				
			||||||
 | 
					#define CHECK_SP_ACCESS_F               0x2
 | 
				
			||||||
 | 
					#define CHECK_MEM_ACCESS_F              0x4 /*using regular linear pointer */
 | 
				
			||||||
 | 
					#define CHECK_DATA_ACCESS_F             0x8 /*using segment:offset*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					# define CHECK_IP_FETCH()              	(M.x86.check & CHECK_IP_FETCH_F)
 | 
				
			||||||
 | 
					# define CHECK_SP_ACCESS()             	(M.x86.check & CHECK_SP_ACCESS_F)
 | 
				
			||||||
 | 
					# define CHECK_MEM_ACCESS()            	(M.x86.check & CHECK_MEM_ACCESS_F)
 | 
				
			||||||
 | 
					# define CHECK_DATA_ACCESS()           	(M.x86.check & CHECK_DATA_ACCESS_F)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define CHECK_IP_FETCH()
 | 
				
			||||||
 | 
					# define CHECK_SP_ACCESS()
 | 
				
			||||||
 | 
					# define CHECK_MEM_ACCESS()
 | 
				
			||||||
 | 
					# define CHECK_DATA_ACCESS()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					# define DEBUG_INSTRUMENT()    	(M.x86.debug & DEBUG_INSTRUMENT_F)
 | 
				
			||||||
 | 
					# define DEBUG_DECODE()        	(M.x86.debug & DEBUG_DECODE_F)
 | 
				
			||||||
 | 
					# define DEBUG_TRACE()         	(M.x86.debug & DEBUG_TRACE_F)
 | 
				
			||||||
 | 
					# define DEBUG_STEP()          	(M.x86.debug & DEBUG_STEP_F)
 | 
				
			||||||
 | 
					# define DEBUG_DISASSEMBLE()   	(M.x86.debug & DEBUG_DISASSEMBLE_F)
 | 
				
			||||||
 | 
					# define DEBUG_BREAK()         	(M.x86.debug & DEBUG_BREAK_F)
 | 
				
			||||||
 | 
					# define DEBUG_SVC()           	(M.x86.debug & DEBUG_SVC_F)
 | 
				
			||||||
 | 
					# define DEBUG_SAVE_IP_CS()     (M.x86.debug & DEBUG_SAVE_IP_CS_F)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# define DEBUG_FS()            	(M.x86.debug & DEBUG_FS_F)
 | 
				
			||||||
 | 
					# define DEBUG_PROC()          	(M.x86.debug & DEBUG_PROC_F)
 | 
				
			||||||
 | 
					# define DEBUG_SYSINT()        	(M.x86.debug & DEBUG_SYSINT_F)
 | 
				
			||||||
 | 
					# define DEBUG_TRACECALL()     	(M.x86.debug & DEBUG_TRACECALL_F)
 | 
				
			||||||
 | 
					# define DEBUG_TRACECALLREGS() 	(M.x86.debug & DEBUG_TRACECALL_REGS_F)
 | 
				
			||||||
 | 
					# define DEBUG_SYS()           	(M.x86.debug & DEBUG_SYS_F)
 | 
				
			||||||
 | 
					# define DEBUG_MEM_TRACE()     	(M.x86.debug & DEBUG_MEM_TRACE_F)
 | 
				
			||||||
 | 
					# define DEBUG_IO_TRACE()      	(M.x86.debug & DEBUG_IO_TRACE_F)
 | 
				
			||||||
 | 
					# define DEBUG_DECODE_NOPRINT() (M.x86.debug & DEBUG_DECODE_NOPRINT_F)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define DEBUG_INSTRUMENT()    	0
 | 
				
			||||||
 | 
					# define DEBUG_DECODE()        	0
 | 
				
			||||||
 | 
					# define DEBUG_TRACE()         	0
 | 
				
			||||||
 | 
					# define DEBUG_STEP()          	0
 | 
				
			||||||
 | 
					# define DEBUG_DISASSEMBLE()   	0
 | 
				
			||||||
 | 
					# define DEBUG_BREAK()         	0
 | 
				
			||||||
 | 
					# define DEBUG_SVC()           	0
 | 
				
			||||||
 | 
					# define DEBUG_SAVE_IP_CS()     0
 | 
				
			||||||
 | 
					# define DEBUG_FS()            	0
 | 
				
			||||||
 | 
					# define DEBUG_PROC()          	0
 | 
				
			||||||
 | 
					# define DEBUG_SYSINT()        	0
 | 
				
			||||||
 | 
					# define DEBUG_TRACECALL()     	0
 | 
				
			||||||
 | 
					# define DEBUG_TRACECALLREGS() 	0
 | 
				
			||||||
 | 
					# define DEBUG_SYS()           	0
 | 
				
			||||||
 | 
					# define DEBUG_MEM_TRACE()     	0
 | 
				
			||||||
 | 
					# define DEBUG_IO_TRACE()      	0
 | 
				
			||||||
 | 
					# define DEBUG_DECODE_NOPRINT() 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# define DECODE_PRINTF(x)     	if (DEBUG_DECODE()) \
 | 
				
			||||||
 | 
														x86emu_decode_printf(x)
 | 
				
			||||||
 | 
					# define DECODE_PRINTF2(x,y)  	if (DEBUG_DECODE()) \
 | 
				
			||||||
 | 
														x86emu_decode_printf2(x,y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The following allow us to look at the bytes of an instruction.  The
 | 
				
			||||||
 | 
					 * first INCR_INSTRN_LEN, is called everytime bytes are consumed in
 | 
				
			||||||
 | 
					 * the decoding process.  The SAVE_IP_CS is called initially when the
 | 
				
			||||||
 | 
					 * major opcode of the instruction is accessed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define INC_DECODED_INST_LEN(x)                    	\
 | 
				
			||||||
 | 
						if (DEBUG_DECODE())  	                       	\
 | 
				
			||||||
 | 
							x86emu_inc_decoded_inst_len(x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SAVE_IP_CS(x,y)                               			\
 | 
				
			||||||
 | 
						if (DEBUG_DECODE() | DEBUG_TRACECALL() | DEBUG_BREAK() \
 | 
				
			||||||
 | 
					              | DEBUG_IO_TRACE() | DEBUG_SAVE_IP_CS()) { \
 | 
				
			||||||
 | 
							M.x86.saved_cs = x;                          			\
 | 
				
			||||||
 | 
							M.x86.saved_ip = y;                          			\
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define INC_DECODED_INST_LEN(x)
 | 
				
			||||||
 | 
					# define DECODE_PRINTF(x)
 | 
				
			||||||
 | 
					# define DECODE_PRINTF2(x,y)
 | 
				
			||||||
 | 
					# define SAVE_IP_CS(x,y)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					#define TRACE_REGS()                                   		\
 | 
				
			||||||
 | 
						if (DEBUG_DISASSEMBLE()) {                         		\
 | 
				
			||||||
 | 
							x86emu_just_disassemble();                        	\
 | 
				
			||||||
 | 
							goto EndOfTheInstructionProcedure;             		\
 | 
				
			||||||
 | 
						}                                                   	\
 | 
				
			||||||
 | 
						if (DEBUG_TRACE() || DEBUG_DECODE()) X86EMU_trace_regs()
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define TRACE_REGS()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					# define SINGLE_STEP()		if (DEBUG_STEP()) x86emu_single_step()
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define SINGLE_STEP()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TRACE_AND_STEP()	\
 | 
				
			||||||
 | 
						TRACE_REGS();			\
 | 
				
			||||||
 | 
						SINGLE_STEP()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					# define START_OF_INSTR()
 | 
				
			||||||
 | 
					# define END_OF_INSTR()		EndOfTheInstructionProcedure: x86emu_end_instr();
 | 
				
			||||||
 | 
					# define END_OF_INSTR_NO_TRACE()	x86emu_end_instr();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define START_OF_INSTR()
 | 
				
			||||||
 | 
					# define END_OF_INSTR()
 | 
				
			||||||
 | 
					# define END_OF_INSTR_NO_TRACE()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					# define  CALL_TRACE(u,v,w,x,s)                                 \
 | 
				
			||||||
 | 
						if (DEBUG_TRACECALLREGS())									\
 | 
				
			||||||
 | 
							x86emu_dump_regs();                                     \
 | 
				
			||||||
 | 
						if (DEBUG_TRACECALL())                                     	\
 | 
				
			||||||
 | 
							printk("%04x:%04x: CALL %s%04x:%04x\n", u , v, s, w, x);
 | 
				
			||||||
 | 
					# define RETURN_TRACE(n,u,v)                                    \
 | 
				
			||||||
 | 
						if (DEBUG_TRACECALLREGS())									\
 | 
				
			||||||
 | 
							x86emu_dump_regs();                                     \
 | 
				
			||||||
 | 
						if (DEBUG_TRACECALL())                                     	\
 | 
				
			||||||
 | 
							printk("%04x:%04x: %s\n",u,v,n);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define CALL_TRACE(u,v,w,x,s)
 | 
				
			||||||
 | 
					# define RETURN_TRACE(n,u,v)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					#define	DB(x)	x
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define	DB(x)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*-------------------------- Function Prototypes --------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					extern "C" {            			/* Use "C" linkage when in C++ mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void x86emu_inc_decoded_inst_len (int x);
 | 
				
			||||||
 | 
					extern void x86emu_decode_printf (char *x);
 | 
				
			||||||
 | 
					extern void x86emu_decode_printf2 (char *x, int y);
 | 
				
			||||||
 | 
					extern void x86emu_just_disassemble (void);
 | 
				
			||||||
 | 
					extern void x86emu_single_step (void);
 | 
				
			||||||
 | 
					extern void x86emu_end_instr (void);
 | 
				
			||||||
 | 
					extern void x86emu_dump_regs (void);
 | 
				
			||||||
 | 
					extern void x86emu_dump_xregs (void);
 | 
				
			||||||
 | 
					extern void x86emu_print_int_vect (u16 iv);
 | 
				
			||||||
 | 
					extern void x86emu_instrument_instruction (void);
 | 
				
			||||||
 | 
					extern void x86emu_check_ip_access (void);
 | 
				
			||||||
 | 
					extern void x86emu_check_sp_access (void);
 | 
				
			||||||
 | 
					extern void x86emu_check_mem_access (u32 p);
 | 
				
			||||||
 | 
					extern void x86emu_check_data_access (uint s, uint o);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					}                       			/* End of "C" linkage for C++   	*/
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_DEBUG_H */
 | 
				
			||||||
							
								
								
									
										1147
									
								
								src/devices/emulator/x86emu/decode.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1147
									
								
								src/devices/emulator/x86emu/decode.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										87
									
								
								src/devices/emulator/x86emu/decode.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								src/devices/emulator/x86emu/decode.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,87 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for instruction decoding logic.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_DECODE_H
 | 
				
			||||||
 | 
					#define __X86EMU_DECODE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*---------------------- Macros and type definitions ----------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Instruction Decoding Stuff */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FETCH_DECODE_MODRM(mod,rh,rl) 	fetch_decode_modrm(&mod,&rh,&rl)
 | 
				
			||||||
 | 
					#define DECODE_RM_BYTE_REGISTER(r)    	decode_rm_byte_register(r)
 | 
				
			||||||
 | 
					#define DECODE_RM_WORD_REGISTER(r)    	decode_rm_word_register(r)
 | 
				
			||||||
 | 
					#define DECODE_RM_LONG_REGISTER(r)    	decode_rm_long_register(r)
 | 
				
			||||||
 | 
					#define DECODE_CLEAR_SEGOVR()         	M.x86.mode &= ~SYSMODE_CLRMASK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*-------------------------- Function Prototypes --------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					extern "C" {            			/* Use "C" linkage when in C++ mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void 	x86emu_intr_raise (u8 type);
 | 
				
			||||||
 | 
					void    fetch_decode_modrm (int *mod,int *regh,int *regl);
 | 
				
			||||||
 | 
					u8      fetch_byte_imm (void);
 | 
				
			||||||
 | 
					u16     fetch_word_imm (void);
 | 
				
			||||||
 | 
					u32     fetch_long_imm (void);
 | 
				
			||||||
 | 
					u8      fetch_data_byte (uint offset);
 | 
				
			||||||
 | 
					u8      fetch_data_byte_abs (uint segment, uint offset);
 | 
				
			||||||
 | 
					u16     fetch_data_word (uint offset);
 | 
				
			||||||
 | 
					u16     fetch_data_word_abs (uint segment, uint offset);
 | 
				
			||||||
 | 
					u32     fetch_data_long (uint offset);
 | 
				
			||||||
 | 
					u32     fetch_data_long_abs (uint segment, uint offset);
 | 
				
			||||||
 | 
					void    store_data_byte (uint offset, u8 val);
 | 
				
			||||||
 | 
					void    store_data_byte_abs (uint segment, uint offset, u8 val);
 | 
				
			||||||
 | 
					void    store_data_word (uint offset, u16 val);
 | 
				
			||||||
 | 
					void    store_data_word_abs (uint segment, uint offset, u16 val);
 | 
				
			||||||
 | 
					void    store_data_long (uint offset, u32 val);
 | 
				
			||||||
 | 
					void    store_data_long_abs (uint segment, uint offset, u32 val);
 | 
				
			||||||
 | 
					u8* 	decode_rm_byte_register(int reg);
 | 
				
			||||||
 | 
					u16* 	decode_rm_word_register(int reg);
 | 
				
			||||||
 | 
					u32* 	decode_rm_long_register(int reg);
 | 
				
			||||||
 | 
					u16* 	decode_rm_seg_register(int reg);
 | 
				
			||||||
 | 
					unsigned decode_rm00_address(int rm);
 | 
				
			||||||
 | 
					unsigned decode_rm01_address(int rm);
 | 
				
			||||||
 | 
					unsigned decode_rm10_address(int rm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					}                       			/* End of "C" linkage for C++   	*/
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_DECODE_H */
 | 
				
			||||||
							
								
								
									
										945
									
								
								src/devices/emulator/x86emu/fpu.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										945
									
								
								src/devices/emulator/x86emu/fpu.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,945 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*                       Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*               Copyright (C) 1991-2004 SciTech Software, Inc.
 | 
				
			||||||
 | 
					*                    Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					*                      Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:     ANSI C
 | 
				
			||||||
 | 
					* Environment:  Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  This file contains the code to implement the decoding and
 | 
				
			||||||
 | 
					*               emulation of the FPU instructions.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "x86emui.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*----------------------------- Implementation ----------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xd8 */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    DECODE_PRINTF("ESC D8\n");
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *x86emu_fpu_op_d9_tab[] = {
 | 
				
			||||||
 | 
					    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *x86emu_fpu_op_d9_tab1[] = {
 | 
				
			||||||
 | 
					    "FLD\t", "FLD\t", "FLD\t", "FLD\t",
 | 
				
			||||||
 | 
					    "FLD\t", "FLD\t", "FLD\t", "FLD\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
 | 
				
			||||||
 | 
					    "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
 | 
				
			||||||
 | 
					    "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
 | 
				
			||||||
 | 
					    "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FCHS", "FABS", "ESC_D9", "ESC_D9",
 | 
				
			||||||
 | 
					    "FTST", "FXAM", "ESC_D9", "ESC_D9",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
 | 
				
			||||||
 | 
					    "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "F2XM1", "FYL2X", "FPTAN", "FPATAN",
 | 
				
			||||||
 | 
					    "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
 | 
				
			||||||
 | 
					    "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xd9 */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int mod, rl, rh;
 | 
				
			||||||
 | 
					    uint destoffset;
 | 
				
			||||||
 | 
					    u8 stkelem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    FETCH_DECODE_MODRM(mod, rh, rl);
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					    if (mod != 3) {
 | 
				
			||||||
 | 
					        DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        destoffset = decode_rm00_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        destoffset = decode_rm01_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        destoffset = decode_rm10_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:                   /* register to register */
 | 
				
			||||||
 | 
					        stkelem = (u8)rl;
 | 
				
			||||||
 | 
					        if (rh < 4) {
 | 
				
			||||||
 | 
					                DECODE_PRINTF2("ST(%d)\n", stkelem);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					                DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#ifdef X86EMU_FPU_PRESENT
 | 
				
			||||||
 | 
					    /* execute */
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            switch (rl) {
 | 
				
			||||||
 | 
					              case 0:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_nop();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              default:
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            switch (rl) {
 | 
				
			||||||
 | 
					            case 0:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 1:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 4:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case 5:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                /* 2,3,6,7 */
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            switch (rl) {
 | 
				
			||||||
 | 
					              case 0:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 1:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 2:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 3:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 4:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 5:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 6:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              default:
 | 
				
			||||||
 | 
					                /* 7 */
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            switch (rl) {
 | 
				
			||||||
 | 
					              case 0:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 1:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 2:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 3:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 4:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 5:
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 6:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_decstp();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 7:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_incstp();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            switch (rl) {
 | 
				
			||||||
 | 
					              case 0:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 1:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 2:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 3:
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 4:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 5:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 6:
 | 
				
			||||||
 | 
					              case 7:
 | 
				
			||||||
 | 
					              default:
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          default:
 | 
				
			||||||
 | 
					            switch (rh) {
 | 
				
			||||||
 | 
					              case 0:
 | 
				
			||||||
 | 
					                x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 1:
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 2:
 | 
				
			||||||
 | 
					                x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 3:
 | 
				
			||||||
 | 
					                x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 4:
 | 
				
			||||||
 | 
					                x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 5:
 | 
				
			||||||
 | 
					                x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 6:
 | 
				
			||||||
 | 
					                x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 7:
 | 
				
			||||||
 | 
					                x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif /* X86EMU_FPU_PRESENT */
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *x86emu_fpu_op_da_tab[] = {
 | 
				
			||||||
 | 
					    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FICOMP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FIDIVR\tDWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FICOMP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FIDIVR\tDWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FICOMP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "FIDIVR\tDWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
 | 
				
			||||||
 | 
					    "ESC_DA     ", "ESC_DA ", "ESC_DA   ", "ESC_DA ",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xda */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int mod, rl, rh;
 | 
				
			||||||
 | 
					    uint destoffset;
 | 
				
			||||||
 | 
					    u8 stkelem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    FETCH_DECODE_MODRM(mod, rh, rl);
 | 
				
			||||||
 | 
					    DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        destoffset = decode_rm00_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        destoffset = decode_rm01_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        destoffset = decode_rm10_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:           /* register to register */
 | 
				
			||||||
 | 
					        stkelem = (u8)rl;
 | 
				
			||||||
 | 
					        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#ifdef X86EMU_FPU_PRESENT
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *x86emu_fpu_op_db_tab[] = {
 | 
				
			||||||
 | 
					    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
 | 
				
			||||||
 | 
					    "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xdb */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int mod, rl, rh;
 | 
				
			||||||
 | 
					    uint destoffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    FETCH_DECODE_MODRM(mod, rh, rl);
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					    if (mod != 3) {
 | 
				
			||||||
 | 
					        DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
 | 
				
			||||||
 | 
					    } else if (rh == 4) {       /* === 11 10 0 nnn */
 | 
				
			||||||
 | 
					        switch (rl) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            DECODE_PRINTF("FENI\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            DECODE_PRINTF("FDISI\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            DECODE_PRINTF("FCLEX\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            DECODE_PRINTF("FINIT\n");
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        destoffset = decode_rm00_address(rl);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        destoffset = decode_rm01_address(rl);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        destoffset = decode_rm10_address(rl);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:                   /* register to register */
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#ifdef X86EMU_FPU_PRESENT
 | 
				
			||||||
 | 
					    /* execute */
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            switch (rl) {
 | 
				
			||||||
 | 
					              case 0:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_feni();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 1:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fdisi();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 2:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_fclex();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              case 3:
 | 
				
			||||||
 | 
					                x86emu_fpu_R_finit();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					              default:
 | 
				
			||||||
 | 
					                x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          default:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					                      case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					char *x86emu_fpu_op_dc_tab[] = {
 | 
				
			||||||
 | 
					    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FCOMP\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FDIVR\tQWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FCOMP\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FDIVR\tQWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FCOMP\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FDIVR\tQWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
 | 
				
			||||||
 | 
					    "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xdc */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int mod, rl, rh;
 | 
				
			||||||
 | 
					    uint destoffset;
 | 
				
			||||||
 | 
					    u8 stkelem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    FETCH_DECODE_MODRM(mod, rh, rl);
 | 
				
			||||||
 | 
					    DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        destoffset = decode_rm00_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        destoffset = decode_rm01_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        destoffset = decode_rm10_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:                   /* register to register */
 | 
				
			||||||
 | 
					        stkelem = (u8)rl;
 | 
				
			||||||
 | 
					        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#ifdef X86EMU_FPU_PRESENT
 | 
				
			||||||
 | 
					    /* execute */
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *x86emu_fpu_op_dd_tab[] = {
 | 
				
			||||||
 | 
					    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
 | 
				
			||||||
 | 
					    "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
 | 
				
			||||||
 | 
					    "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xdd */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int mod, rl, rh;
 | 
				
			||||||
 | 
					    uint destoffset;
 | 
				
			||||||
 | 
					    u8 stkelem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    FETCH_DECODE_MODRM(mod, rh, rl);
 | 
				
			||||||
 | 
					    DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        destoffset = decode_rm00_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        destoffset = decode_rm01_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        destoffset = decode_rm10_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:                   /* register to register */
 | 
				
			||||||
 | 
					        stkelem = (u8)rl;
 | 
				
			||||||
 | 
					        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#ifdef X86EMU_FPU_PRESENT
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_ffree(stkelem);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fxch(stkelem);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fst(stkelem);  /* register version */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fstp(stkelem); /* register version */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          default:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *x86emu_fpu_op_de_tab[] =
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FICOMP\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FIDIVR\tWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FICOMP\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FIDIVR\tWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FICOMP\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FIDIVR\tWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
 | 
				
			||||||
 | 
					    "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xde */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int mod, rl, rh;
 | 
				
			||||||
 | 
					    uint destoffset;
 | 
				
			||||||
 | 
					    u8 stkelem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    FETCH_DECODE_MODRM(mod, rh, rl);
 | 
				
			||||||
 | 
					    DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        destoffset = decode_rm00_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        destoffset = decode_rm01_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        destoffset = decode_rm10_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:                   /* register to register */
 | 
				
			||||||
 | 
					        stkelem = (u8)rl;
 | 
				
			||||||
 | 
					        DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#ifdef X86EMU_FPU_PRESENT
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            if (stkelem == 1)
 | 
				
			||||||
 | 
					              x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static char *x86emu_fpu_op_df_tab[] = {
 | 
				
			||||||
 | 
					    /* mod == 00 */
 | 
				
			||||||
 | 
					    "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
 | 
				
			||||||
 | 
					    "FISTP\tQWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* mod == 01 */
 | 
				
			||||||
 | 
					    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
 | 
				
			||||||
 | 
					    "FISTP\tQWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* mod == 10 */
 | 
				
			||||||
 | 
					    "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
 | 
				
			||||||
 | 
					    "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
 | 
				
			||||||
 | 
					    "FISTP\tQWORD PTR ",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* mod == 11 */
 | 
				
			||||||
 | 
					    "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
 | 
				
			||||||
 | 
					    "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* DEBUG */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* opcode=0xdf */
 | 
				
			||||||
 | 
					void x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int mod, rl, rh;
 | 
				
			||||||
 | 
					    uint destoffset;
 | 
				
			||||||
 | 
					    u8 stkelem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    START_OF_INSTR();
 | 
				
			||||||
 | 
					    FETCH_DECODE_MODRM(mod, rh, rl);
 | 
				
			||||||
 | 
					    DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 0:
 | 
				
			||||||
 | 
					        destoffset = decode_rm00_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 1:
 | 
				
			||||||
 | 
					        destoffset = decode_rm01_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 2:
 | 
				
			||||||
 | 
					        destoffset = decode_rm10_address(rl);
 | 
				
			||||||
 | 
					        DECODE_PRINTF("\n");
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      case 3:                   /* register to register */
 | 
				
			||||||
 | 
					        stkelem = (u8)rl;
 | 
				
			||||||
 | 
					        DECODE_PRINTF2("\tST(%d)\n", stkelem);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#ifdef X86EMU_FPU_PRESENT
 | 
				
			||||||
 | 
					    switch (mod) {
 | 
				
			||||||
 | 
					      case 3:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_ffree(stkelem);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fxch(stkelem);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fst(stkelem);  /* register version */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_R_fstp(stkelem); /* register version */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          default:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      default:
 | 
				
			||||||
 | 
					        switch (rh) {
 | 
				
			||||||
 | 
					          case 0:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 1:
 | 
				
			||||||
 | 
					            x86emu_fpu_illegal();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 2:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 3:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 4:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 5:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 6:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					          case 7:
 | 
				
			||||||
 | 
					            x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    DECODE_CLEAR_SEGOVR();
 | 
				
			||||||
 | 
					    END_OF_INSTR_NO_TRACE();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										61
									
								
								src/devices/emulator/x86emu/fpu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/devices/emulator/x86emu/fpu.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for FPU instruction decoding.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_FPU_H
 | 
				
			||||||
 | 
					#define __X86EMU_FPU_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					extern "C" {            			/* Use "C" linkage when in C++ mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* these have to be defined, whether 8087 support compiled in or not. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_d8 (u8 op1);
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_d9 (u8 op1);
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_da (u8 op1);
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_db (u8 op1);
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_dc (u8 op1);
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_dd (u8 op1);
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_de (u8 op1);
 | 
				
			||||||
 | 
					extern void x86emuOp_esc_coprocess_df (u8 op1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					}                       			/* End of "C" linkage for C++   	*/
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_FPU_H */
 | 
				
			||||||
							
								
								
									
										5427
									
								
								src/devices/emulator/x86emu/ops.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5427
									
								
								src/devices/emulator/x86emu/ops.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										45
									
								
								src/devices/emulator/x86emu/ops.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/devices/emulator/x86emu/ops.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for operand decoding functions.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_OPS_H
 | 
				
			||||||
 | 
					#define __X86EMU_OPS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern void (*x86emu_optab[0x100])(u8 op1);
 | 
				
			||||||
 | 
					extern void (*x86emu_optab2[0x100])(u8 op2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_OPS_H */
 | 
				
			||||||
							
								
								
									
										1764
									
								
								src/devices/emulator/x86emu/ops2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1764
									
								
								src/devices/emulator/x86emu/ops2.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										971
									
								
								src/devices/emulator/x86emu/prim_asm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										971
									
								
								src/devices/emulator/x86emu/prim_asm.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,971 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		Watcom C++ 10.6 or later
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Inline assembler versions of the primitive operand
 | 
				
			||||||
 | 
					*				functions for faster performance. At the moment this is
 | 
				
			||||||
 | 
					*				x86 inline assembler, but these functions could be replaced
 | 
				
			||||||
 | 
					*				with native inline assembler for each supported processor
 | 
				
			||||||
 | 
					*				platform.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/prim_asm.h,v 1.3 2000/04/19 15:48:15 tsi Exp $ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef	__X86EMU_PRIM_ASM_H
 | 
				
			||||||
 | 
					#define	__X86EMU_PRIM_ASM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef	__WATCOMC__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef	VALIDATE
 | 
				
			||||||
 | 
					#define	__HAVE_INLINE_ASSEMBLER__
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32		get_flags_asm(void);
 | 
				
			||||||
 | 
					#pragma aux get_flags_asm =			\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	eax"                  	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     aaa_word_asm(u32 *flags,u16 d);
 | 
				
			||||||
 | 
					#pragma aux aaa_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"aaa"                  			\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] 				\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     aas_word_asm(u32 *flags,u16 d);
 | 
				
			||||||
 | 
					#pragma aux aas_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"aas"                  			\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] 				\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     aad_word_asm(u32 *flags,u16 d);
 | 
				
			||||||
 | 
					#pragma aux aad_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"aad"                  			\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] 				\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     aam_word_asm(u32 *flags,u8 d);
 | 
				
			||||||
 | 
					#pragma aux aam_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"aam"                  			\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] 				\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      adc_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux adc_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"adc	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     adc_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux adc_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"adc	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     adc_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux adc_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"adc	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      add_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux add_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"add	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     add_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux add_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"add	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     add_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux add_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"add	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      and_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux and_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"and	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     and_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux and_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"and	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     and_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux and_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"and	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      cmp_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux cmp_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"cmp	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     cmp_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux cmp_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"cmp	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     cmp_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux cmp_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"cmp	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      daa_byte_asm(u32 *flags,u8 d);
 | 
				
			||||||
 | 
					#pragma aux daa_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"daa"                  			\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al]            		\
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      das_byte_asm(u32 *flags,u8 d);
 | 
				
			||||||
 | 
					#pragma aux das_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"das"                  			\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al]            		\
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      dec_byte_asm(u32 *flags,u8 d);
 | 
				
			||||||
 | 
					#pragma aux dec_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"dec	al"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al]            		\
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     dec_word_asm(u32 *flags,u16 d);
 | 
				
			||||||
 | 
					#pragma aux dec_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"dec	ax"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax]            		\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     dec_long_asm(u32 *flags,u32 d);
 | 
				
			||||||
 | 
					#pragma aux dec_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"dec	eax"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax]          		\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      inc_byte_asm(u32 *flags,u8 d);
 | 
				
			||||||
 | 
					#pragma aux inc_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"inc	al"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al]            		\
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     inc_word_asm(u32 *flags,u16 d);
 | 
				
			||||||
 | 
					#pragma aux inc_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"inc	ax"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax]            		\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     inc_long_asm(u32 *flags,u32 d);
 | 
				
			||||||
 | 
					#pragma aux inc_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"inc	eax"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax]          		\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      or_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux or_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"or	al,bl"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     or_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux or_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"or	ax,bx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     or_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux or_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"or	eax,ebx"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      neg_byte_asm(u32 *flags,u8 d);
 | 
				
			||||||
 | 
					#pragma aux neg_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"neg	al"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al]            		\
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     neg_word_asm(u32 *flags,u16 d);
 | 
				
			||||||
 | 
					#pragma aux neg_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"neg	ax"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax]            		\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     neg_long_asm(u32 *flags,u32 d);
 | 
				
			||||||
 | 
					#pragma aux neg_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"neg	eax"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax]          		\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      not_byte_asm(u32 *flags,u8 d);
 | 
				
			||||||
 | 
					#pragma aux not_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"not	al"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al]            		\
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     not_word_asm(u32 *flags,u16 d);
 | 
				
			||||||
 | 
					#pragma aux not_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"not	ax"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax]            		\
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     not_long_asm(u32 *flags,u32 d);
 | 
				
			||||||
 | 
					#pragma aux not_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"not	eax"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax]          		\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      rcl_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rcl_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rcl	al,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [cl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     rcl_word_asm(u32 *flags,u16 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rcl_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rcl	ax,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [cl]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     rcl_long_asm(u32 *flags,u32 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rcl_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rcl	eax,cl"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [cl]          	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      rcr_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rcr_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rcr	al,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [cl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     rcr_word_asm(u32 *flags,u16 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rcr_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rcr	ax,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [cl]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     rcr_long_asm(u32 *flags,u32 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rcr_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rcr	eax,cl"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [cl]          	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      rol_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rol_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rol	al,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [cl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     rol_word_asm(u32 *flags,u16 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rol_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rol	ax,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [cl]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     rol_long_asm(u32 *flags,u32 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux rol_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"rol	eax,cl"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [cl]          	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      ror_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux ror_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"ror	al,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [cl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     ror_word_asm(u32 *flags,u16 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux ror_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"ror	ax,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [cl]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     ror_long_asm(u32 *flags,u32 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux ror_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"ror	eax,cl"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [cl]          	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      shl_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shl_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shl	al,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [cl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     shl_word_asm(u32 *flags,u16 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shl_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shl	ax,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [cl]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     shl_long_asm(u32 *flags,u32 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shl_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shl	eax,cl"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [cl]          	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      shr_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shr_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shr	al,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [cl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     shr_word_asm(u32 *flags,u16 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shr_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shr	ax,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [cl]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     shr_long_asm(u32 *flags,u32 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shr_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shr	eax,cl"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [cl]          	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      sar_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux sar_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sar	al,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [cl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     sar_word_asm(u32 *flags,u16 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux sar_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sar	ax,cl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [cl]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     sar_long_asm(u32 *flags,u32 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux sar_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sar	eax,cl"                	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [cl]          	\
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16		shld_word_asm(u32 *flags,u16 d, u16 fill, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shld_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shld	ax,dx,cl"               \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [dx] [cl]       \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax dx cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     shld_long_asm(u32 *flags,u32 d, u32 fill, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shld_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shld	eax,edx,cl"             \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [edx] [cl]     \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax edx cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16		shrd_word_asm(u32 *flags,u16 d, u16 fill, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shrd_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shrd	ax,dx,cl"               \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [dx] [cl]       \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax dx cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     shrd_long_asm(u32 *flags,u32 d, u32 fill, u8 s);
 | 
				
			||||||
 | 
					#pragma aux shrd_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"shrd	eax,edx,cl"             \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [edx] [cl]     \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax edx cl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      sbb_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux sbb_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sbb	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     sbb_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux sbb_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sbb	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     sbb_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux sbb_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sbb	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      sub_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux sub_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sub	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     sub_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux sub_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sub	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     sub_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux sub_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"sub	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	test_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux test_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"test	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	test_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux test_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"test	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	test_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux test_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"test	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8      xor_byte_asm(u32 *flags,u8 d, u8 s);
 | 
				
			||||||
 | 
					#pragma aux xor_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"xor	al,bl"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [al] [bl]            \
 | 
				
			||||||
 | 
						value [al]                      \
 | 
				
			||||||
 | 
						modify exact [al bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     xor_word_asm(u32 *flags,u16 d, u16 s);
 | 
				
			||||||
 | 
					#pragma aux xor_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"xor	ax,bx"                  \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [ax] [bx]            \
 | 
				
			||||||
 | 
						value [ax]                      \
 | 
				
			||||||
 | 
						modify exact [ax bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32     xor_long_asm(u32 *flags,u32 d, u32 s);
 | 
				
			||||||
 | 
					#pragma aux xor_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"xor	eax,ebx"                \
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						parm [edi] [eax] [ebx]          \
 | 
				
			||||||
 | 
						value [eax]                     \
 | 
				
			||||||
 | 
						modify exact [eax ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void    imul_byte_asm(u32 *flags,u16 *ax,u8 d,u8 s);
 | 
				
			||||||
 | 
					#pragma aux imul_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"imul	bl"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],ax"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [al] [bl]      \
 | 
				
			||||||
 | 
						modify exact [esi ax bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void    imul_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 d,u16 s);
 | 
				
			||||||
 | 
					#pragma aux imul_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"imul	bx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],ax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],dx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [ax] [bx]\
 | 
				
			||||||
 | 
						modify exact [esi edi ax bx dx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void    imul_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 d,u32 s);
 | 
				
			||||||
 | 
					#pragma aux imul_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"imul	ebx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],eax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],edx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [eax] [ebx] \
 | 
				
			||||||
 | 
						modify exact [esi edi eax ebx edx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void    mul_byte_asm(u32 *flags,u16 *ax,u8 d,u8 s);
 | 
				
			||||||
 | 
					#pragma aux mul_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"mul	bl"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],ax"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [al] [bl]      \
 | 
				
			||||||
 | 
						modify exact [esi ax bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void    mul_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 d,u16 s);
 | 
				
			||||||
 | 
					#pragma aux mul_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"mul	bx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],ax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],dx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [ax] [bx]\
 | 
				
			||||||
 | 
						modify exact [esi edi ax bx dx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void    mul_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 d,u32 s);
 | 
				
			||||||
 | 
					#pragma aux mul_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"mul	ebx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],eax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],edx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [eax] [ebx] \
 | 
				
			||||||
 | 
						modify exact [esi edi eax ebx edx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	idiv_byte_asm(u32 *flags,u8 *al,u8 *ah,u16 d,u8 s);
 | 
				
			||||||
 | 
					#pragma aux idiv_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"idiv	bl"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],al"				\
 | 
				
			||||||
 | 
						"mov	[ecx],ah"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [ax] [bl]\
 | 
				
			||||||
 | 
						modify exact [esi edi ax bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	idiv_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 dlo,u16 dhi,u16 s);
 | 
				
			||||||
 | 
					#pragma aux idiv_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"idiv	bx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],ax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],dx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [ax] [dx] [bx]\
 | 
				
			||||||
 | 
						modify exact [esi edi ax dx bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	idiv_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 dlo,u32 dhi,u32 s);
 | 
				
			||||||
 | 
					#pragma aux idiv_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"idiv	ebx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],eax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],edx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
 | 
				
			||||||
 | 
						modify exact [esi edi eax edx ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	div_byte_asm(u32 *flags,u8 *al,u8 *ah,u16 d,u8 s);
 | 
				
			||||||
 | 
					#pragma aux div_byte_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"div	bl"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],al"				\
 | 
				
			||||||
 | 
						"mov	[ecx],ah"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [ax] [bl]\
 | 
				
			||||||
 | 
						modify exact [esi edi ax bl];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	div_word_asm(u32 *flags,u16 *ax,u16 *dx,u16 dlo,u16 dhi,u16 s);
 | 
				
			||||||
 | 
					#pragma aux div_word_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"div	bx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],ax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],dx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [ax] [dx] [bx]\
 | 
				
			||||||
 | 
						modify exact [esi edi ax dx bx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void	div_long_asm(u32 *flags,u32 *eax,u32 *edx,u32 dlo,u32 dhi,u32 s);
 | 
				
			||||||
 | 
					#pragma aux div_long_asm =			\
 | 
				
			||||||
 | 
						"push	[edi]"            		\
 | 
				
			||||||
 | 
						"popf"                         	\
 | 
				
			||||||
 | 
						"div	ebx"                  	\
 | 
				
			||||||
 | 
						"pushf"                         \
 | 
				
			||||||
 | 
						"pop	[edi]"            		\
 | 
				
			||||||
 | 
						"mov	[esi],eax"				\
 | 
				
			||||||
 | 
						"mov	[ecx],edx"				\
 | 
				
			||||||
 | 
						parm [edi] [esi] [ecx] [eax] [edx] [ebx]\
 | 
				
			||||||
 | 
						modify exact [esi edi eax edx ebx];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_PRIM_ASM_H */
 | 
				
			||||||
							
								
								
									
										2442
									
								
								src/devices/emulator/x86emu/prim_ops.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2442
									
								
								src/devices/emulator/x86emu/prim_ops.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										231
									
								
								src/devices/emulator/x86emu/prim_ops.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								src/devices/emulator/x86emu/prim_ops.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,231 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for primitive operation functions.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_PRIM_OPS_H
 | 
				
			||||||
 | 
					#define __X86EMU_PRIM_OPS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "prim_asm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					extern "C" {            			/* Use "C" linkage when in C++ mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u16     aaa_word (u16 d);
 | 
				
			||||||
 | 
					u16     aas_word (u16 d);
 | 
				
			||||||
 | 
					u16     aad_word (u16 d);
 | 
				
			||||||
 | 
					u16     aam_word (u8 d);
 | 
				
			||||||
 | 
					u8      adc_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     adc_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     adc_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					u8      add_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     add_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     add_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					u8      and_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     and_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     and_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					u8      cmp_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     cmp_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     cmp_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					u8      daa_byte (u8 d);
 | 
				
			||||||
 | 
					u8      das_byte (u8 d);
 | 
				
			||||||
 | 
					u8      dec_byte (u8 d);
 | 
				
			||||||
 | 
					u16     dec_word (u16 d);
 | 
				
			||||||
 | 
					u32     dec_long (u32 d);
 | 
				
			||||||
 | 
					u8      inc_byte (u8 d);
 | 
				
			||||||
 | 
					u16     inc_word (u16 d);
 | 
				
			||||||
 | 
					u32     inc_long (u32 d);
 | 
				
			||||||
 | 
					u8      or_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     or_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     or_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					u8      neg_byte (u8 s);
 | 
				
			||||||
 | 
					u16     neg_word (u16 s);
 | 
				
			||||||
 | 
					u32     neg_long (u32 s);
 | 
				
			||||||
 | 
					u8      not_byte (u8 s);
 | 
				
			||||||
 | 
					u16     not_word (u16 s);
 | 
				
			||||||
 | 
					u32     not_long (u32 s);
 | 
				
			||||||
 | 
					u8      rcl_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     rcl_word (u16 d, u8 s);
 | 
				
			||||||
 | 
					u32     rcl_long (u32 d, u8 s);
 | 
				
			||||||
 | 
					u8      rcr_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     rcr_word (u16 d, u8 s);
 | 
				
			||||||
 | 
					u32     rcr_long (u32 d, u8 s);
 | 
				
			||||||
 | 
					u8      rol_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     rol_word (u16 d, u8 s);
 | 
				
			||||||
 | 
					u32     rol_long (u32 d, u8 s);
 | 
				
			||||||
 | 
					u8      ror_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     ror_word (u16 d, u8 s);
 | 
				
			||||||
 | 
					u32     ror_long (u32 d, u8 s);
 | 
				
			||||||
 | 
					u8      shl_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     shl_word (u16 d, u8 s);
 | 
				
			||||||
 | 
					u32     shl_long (u32 d, u8 s);
 | 
				
			||||||
 | 
					u8      shr_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     shr_word (u16 d, u8 s);
 | 
				
			||||||
 | 
					u32     shr_long (u32 d, u8 s);
 | 
				
			||||||
 | 
					u8      sar_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     sar_word (u16 d, u8 s);
 | 
				
			||||||
 | 
					u32     sar_long (u32 d, u8 s);
 | 
				
			||||||
 | 
					u16     shld_word (u16 d, u16 fill, u8 s);
 | 
				
			||||||
 | 
					u32     shld_long (u32 d, u32 fill, u8 s);
 | 
				
			||||||
 | 
					u16     shrd_word (u16 d, u16 fill, u8 s);
 | 
				
			||||||
 | 
					u32     shrd_long (u32 d, u32 fill, u8 s);
 | 
				
			||||||
 | 
					u8      sbb_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     sbb_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     sbb_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					u8      sub_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     sub_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     sub_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					void    test_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					void    test_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					void    test_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					u8      xor_byte (u8 d, u8 s);
 | 
				
			||||||
 | 
					u16     xor_word (u16 d, u16 s);
 | 
				
			||||||
 | 
					u32     xor_long (u32 d, u32 s);
 | 
				
			||||||
 | 
					void    imul_byte (u8 s);
 | 
				
			||||||
 | 
					void    imul_word (u16 s);
 | 
				
			||||||
 | 
					void    imul_long (u32 s);
 | 
				
			||||||
 | 
					void 	imul_long_direct(u32 *res_lo, u32* res_hi,u32 d, u32 s);
 | 
				
			||||||
 | 
					void    mul_byte (u8 s);
 | 
				
			||||||
 | 
					void    mul_word (u16 s);
 | 
				
			||||||
 | 
					void    mul_long (u32 s);
 | 
				
			||||||
 | 
					void    idiv_byte (u8 s);
 | 
				
			||||||
 | 
					void    idiv_word (u16 s);
 | 
				
			||||||
 | 
					void    idiv_long (u32 s);
 | 
				
			||||||
 | 
					void    div_byte (u8 s);
 | 
				
			||||||
 | 
					void    div_word (u16 s);
 | 
				
			||||||
 | 
					void    div_long (u32 s);
 | 
				
			||||||
 | 
					void    ins (int size);
 | 
				
			||||||
 | 
					void    outs (int size);
 | 
				
			||||||
 | 
					u16     mem_access_word (int addr);
 | 
				
			||||||
 | 
					void    push_word (u16 w);
 | 
				
			||||||
 | 
					void    push_long (u32 w);
 | 
				
			||||||
 | 
					u16     pop_word (void);
 | 
				
			||||||
 | 
					u32		pop_long (void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if  defined(__HAVE_INLINE_ASSEMBLER__) && !defined(PRIM_OPS_NO_REDEFINE_ASM)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define	aaa_word(d)		aaa_word_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define aas_word(d)		aas_word_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define aad_word(d)		aad_word_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define aam_word(d)		aam_word_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define adc_byte(d,s)	adc_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define adc_word(d,s)	adc_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define adc_long(d,s)	adc_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define add_byte(d,s) 	add_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define add_word(d,s)	add_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define add_long(d,s)	add_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define and_byte(d,s)	and_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define and_word(d,s)	and_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define and_long(d,s)	and_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define cmp_byte(d,s)	cmp_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define cmp_word(d,s)	cmp_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define cmp_long(d,s)	cmp_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define daa_byte(d)		daa_byte_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define das_byte(d)		das_byte_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define dec_byte(d)		dec_byte_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define dec_word(d)		dec_word_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define dec_long(d)		dec_long_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define inc_byte(d)		inc_byte_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define inc_word(d)		inc_word_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define inc_long(d)		inc_long_asm(&M.x86.R_EFLG,d)
 | 
				
			||||||
 | 
					#define or_byte(d,s)	or_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define or_word(d,s)	or_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define or_long(d,s)	or_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define neg_byte(s)		neg_byte_asm(&M.x86.R_EFLG,s)
 | 
				
			||||||
 | 
					#define neg_word(s)		neg_word_asm(&M.x86.R_EFLG,s)
 | 
				
			||||||
 | 
					#define neg_long(s)		neg_long_asm(&M.x86.R_EFLG,s)
 | 
				
			||||||
 | 
					#define not_byte(s)		not_byte_asm(&M.x86.R_EFLG,s)
 | 
				
			||||||
 | 
					#define not_word(s)		not_word_asm(&M.x86.R_EFLG,s)
 | 
				
			||||||
 | 
					#define not_long(s)		not_long_asm(&M.x86.R_EFLG,s)
 | 
				
			||||||
 | 
					#define rcl_byte(d,s)	rcl_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rcl_word(d,s)	rcl_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rcl_long(d,s)	rcl_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rcr_byte(d,s)	rcr_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rcr_word(d,s)	rcr_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rcr_long(d,s)	rcr_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rol_byte(d,s)	rol_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rol_word(d,s)	rol_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define rol_long(d,s)	rol_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define ror_byte(d,s)	ror_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define ror_word(d,s)	ror_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define ror_long(d,s)	ror_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define shl_byte(d,s)	shl_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define shl_word(d,s)	shl_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define shl_long(d,s)	shl_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define shr_byte(d,s)	shr_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define shr_word(d,s)	shr_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define shr_long(d,s)	shr_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sar_byte(d,s)	sar_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sar_word(d,s)	sar_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sar_long(d,s)	sar_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define shld_word(d,fill,s)	shld_word_asm(&M.x86.R_EFLG,d,fill,s)
 | 
				
			||||||
 | 
					#define shld_long(d,fill,s)	shld_long_asm(&M.x86.R_EFLG,d,fill,s)
 | 
				
			||||||
 | 
					#define shrd_word(d,fill,s)	shrd_word_asm(&M.x86.R_EFLG,d,fill,s)
 | 
				
			||||||
 | 
					#define shrd_long(d,fill,s)	shrd_long_asm(&M.x86.R_EFLG,d,fill,s)
 | 
				
			||||||
 | 
					#define sbb_byte(d,s)	sbb_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sbb_word(d,s)	sbb_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sbb_long(d,s)	sbb_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sub_byte(d,s)	sub_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sub_word(d,s)	sub_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define sub_long(d,s)	sub_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define test_byte(d,s)	test_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define test_word(d,s)	test_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define test_long(d,s)	test_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define xor_byte(d,s)	xor_byte_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define xor_word(d,s)	xor_word_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define xor_long(d,s)	xor_long_asm(&M.x86.R_EFLG,d,s)
 | 
				
			||||||
 | 
					#define imul_byte(s)	imul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s)
 | 
				
			||||||
 | 
					#define imul_word(s)	imul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s)
 | 
				
			||||||
 | 
					#define imul_long(s)	imul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s)
 | 
				
			||||||
 | 
					#define imul_long_direct(res_lo,res_hi,d,s)	imul_long_asm(&M.x86.R_EFLG,res_lo,res_hi,d,s)
 | 
				
			||||||
 | 
					#define mul_byte(s)		mul_byte_asm(&M.x86.R_EFLG,&M.x86.R_AX,M.x86.R_AL,s)
 | 
				
			||||||
 | 
					#define mul_word(s)		mul_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,s)
 | 
				
			||||||
 | 
					#define mul_long(s)		mul_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,s)
 | 
				
			||||||
 | 
					#define idiv_byte(s)	idiv_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s)
 | 
				
			||||||
 | 
					#define idiv_word(s)	idiv_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s)
 | 
				
			||||||
 | 
					#define idiv_long(s)	idiv_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s)
 | 
				
			||||||
 | 
					#define div_byte(s)		div_byte_asm(&M.x86.R_EFLG,&M.x86.R_AL,&M.x86.R_AH,M.x86.R_AX,s)
 | 
				
			||||||
 | 
					#define div_word(s)		div_word_asm(&M.x86.R_EFLG,&M.x86.R_AX,&M.x86.R_DX,M.x86.R_AX,M.x86.R_DX,s)
 | 
				
			||||||
 | 
					#define div_long(s)		div_long_asm(&M.x86.R_EFLG,&M.x86.R_EAX,&M.x86.R_EDX,M.x86.R_EAX,M.x86.R_EDX,s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					}                       			/* End of "C" linkage for C++   	*/
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_PRIM_OPS_H */
 | 
				
			||||||
							
								
								
									
										595
									
								
								src/devices/emulator/x86emu/sys.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										595
									
								
								src/devices/emulator/x86emu/sys.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,595 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  This file includes subroutines which are related to
 | 
				
			||||||
 | 
					*				programmed I/O and memory access. Included in this module
 | 
				
			||||||
 | 
					*				are default functions with limited usefulness. For real
 | 
				
			||||||
 | 
					*				uses these functions will most likely be overriden by the
 | 
				
			||||||
 | 
					*				user library.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					/* $XFree86: xc/extras/x86emu/src/x86emu/sys.c,v 1.5 2000/08/23 22:10:01 tsi Exp $ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <x86emu/x86emu.h>
 | 
				
			||||||
 | 
					#include <x86emu/regs.h>
 | 
				
			||||||
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "prim_ops.h"
 | 
				
			||||||
 | 
					#ifdef LINUXBIOS_VERSION
 | 
				
			||||||
 | 
					#include "arch/io.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <sys/io.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef IN_MODULE
 | 
				
			||||||
 | 
					#include "xf86_ansic.h"
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					/*------------------------- Global Variables ------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					X86EMU_sysEnv _X86EMU_env;	/* Global emulator machine state */
 | 
				
			||||||
 | 
					X86EMU_intrFuncs _X86EMU_intrTab[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*----------------------------- Implementation ----------------------------*/
 | 
				
			||||||
 | 
					#if defined(__alpha__) || defined(__alpha)
 | 
				
			||||||
 | 
					/* to cope with broken egcs-1.1.2 :-(((( */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * inline functions to do unaligned accesses
 | 
				
			||||||
 | 
					 * from linux/include/asm-alpha/unaligned.h
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * EGCS 1.1 knows about arbitrary unaligned loads.  Define some
 | 
				
			||||||
 | 
					 * packed structures to talk about such things with.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 | 
				
			||||||
 | 
					struct __una_u64 {
 | 
				
			||||||
 | 
						unsigned long x __attribute__ ((packed));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					struct __una_u32 {
 | 
				
			||||||
 | 
						unsigned int x __attribute__ ((packed));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					struct __una_u16 {
 | 
				
			||||||
 | 
						unsigned short x __attribute__ ((packed));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __inline__ unsigned long ldq_u(unsigned long *r11)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 | 
				
			||||||
 | 
						const struct __una_u64 *ptr = (const struct __una_u64 *) r11;
 | 
				
			||||||
 | 
						return ptr->x;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						unsigned long r1, r2;
 | 
				
			||||||
 | 
					      __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extql %0,%2,%0\n\t" "extqh %1,%2,%1":"=&r"(r1),
 | 
				
			||||||
 | 
							"=&r"
 | 
				
			||||||
 | 
							(r2)
 | 
				
			||||||
 | 
					      :	"r"(r11), "m"(*r11),
 | 
				
			||||||
 | 
							"m"(*(const unsigned long *) (7 + (char *) r11)));
 | 
				
			||||||
 | 
						return r1 | r2;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __inline__ unsigned long ldl_u(unsigned int *r11)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 | 
				
			||||||
 | 
						const struct __una_u32 *ptr = (const struct __una_u32 *) r11;
 | 
				
			||||||
 | 
						return ptr->x;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						unsigned long r1, r2;
 | 
				
			||||||
 | 
					      __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extll %0,%2,%0\n\t" "extlh %1,%2,%1":"=&r"(r1),
 | 
				
			||||||
 | 
							"=&r"
 | 
				
			||||||
 | 
							(r2)
 | 
				
			||||||
 | 
					      :	"r"(r11), "m"(*r11),
 | 
				
			||||||
 | 
							"m"(*(const unsigned long *) (3 + (char *) r11)));
 | 
				
			||||||
 | 
						return r1 | r2;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __inline__ unsigned long ldw_u(unsigned short *r11)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 | 
				
			||||||
 | 
						const struct __una_u16 *ptr = (const struct __una_u16 *) r11;
 | 
				
			||||||
 | 
						return ptr->x;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						unsigned long r1, r2;
 | 
				
			||||||
 | 
					      __asm__("ldq_u %0,%3\n\t" "ldq_u %1,%4\n\t" "extwl %0,%2,%0\n\t" "extwh %1,%2,%1":"=&r"(r1),
 | 
				
			||||||
 | 
							"=&r"
 | 
				
			||||||
 | 
							(r2)
 | 
				
			||||||
 | 
					      :	"r"(r11), "m"(*r11),
 | 
				
			||||||
 | 
							"m"(*(const unsigned long *) (1 + (char *) r11)));
 | 
				
			||||||
 | 
						return r1 | r2;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Elemental unaligned stores 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __inline__ void stq_u(unsigned long r5, unsigned long *r11)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 | 
				
			||||||
 | 
						struct __una_u64 *ptr = (struct __una_u64 *) r11;
 | 
				
			||||||
 | 
						ptr->x = r5;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						unsigned long r1, r2, r3, r4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      __asm__("ldq_u %3,%1\n\t" "ldq_u %2,%0\n\t" "insqh %6,%7,%5\n\t" "insql %6,%7,%4\n\t" "mskqh %3,%7,%3\n\t" "mskql %2,%7,%2\n\t" "bis %3,%5,%3\n\t" "bis %2,%4,%2\n\t" "stq_u %3,%1\n\t" "stq_u %2,%0":"=m"(*r11),
 | 
				
			||||||
 | 
							"=m"(*(unsigned long *) (7 + (char *) r11)),
 | 
				
			||||||
 | 
							"=&r"(r1), "=&r"(r2), "=&r"(r3), "=&r"(r4)
 | 
				
			||||||
 | 
					      :	"r"(r5), "r"(r11));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __inline__ void stl_u(unsigned long r5, unsigned int *r11)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 | 
				
			||||||
 | 
						struct __una_u32 *ptr = (struct __una_u32 *) r11;
 | 
				
			||||||
 | 
						ptr->x = r5;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						unsigned long r1, r2, r3, r4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      __asm__("ldq_u %3,%1\n\t" "ldq_u %2,%0\n\t" "inslh %6,%7,%5\n\t" "insll %6,%7,%4\n\t" "msklh %3,%7,%3\n\t" "mskll %2,%7,%2\n\t" "bis %3,%5,%3\n\t" "bis %2,%4,%2\n\t" "stq_u %3,%1\n\t" "stq_u %2,%0":"=m"(*r11),
 | 
				
			||||||
 | 
							"=m"(*(unsigned long *) (3 + (char *) r11)),
 | 
				
			||||||
 | 
							"=&r"(r1), "=&r"(r2), "=&r"(r3), "=&r"(r4)
 | 
				
			||||||
 | 
					      :	"r"(r5), "r"(r11));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static __inline__ void stw_u(unsigned long r5, unsigned short *r11)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if __GNUC__ > 2 || __GNUC_MINOR__ >= 91
 | 
				
			||||||
 | 
						struct __una_u16 *ptr = (struct __una_u16 *) r11;
 | 
				
			||||||
 | 
						ptr->x = r5;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						unsigned long r1, r2, r3, r4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      __asm__("ldq_u %3,%1\n\t" "ldq_u %2,%0\n\t" "inswh %6,%7,%5\n\t" "inswl %6,%7,%4\n\t" "mskwh %3,%7,%3\n\t" "mskwl %2,%7,%2\n\t" "bis %3,%5,%3\n\t" "bis %2,%4,%2\n\t" "stq_u %3,%1\n\t" "stq_u %2,%0":"=m"(*r11),
 | 
				
			||||||
 | 
							"=m"(*(unsigned long *) (1 + (char *) r11)),
 | 
				
			||||||
 | 
							"=&r"(r1), "=&r"(r2), "=&r"(r3), "=&r"(r4)
 | 
				
			||||||
 | 
					      :	"r"(r5), "r"(r11));
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* compute a pointer. This replaces code scattered all over the place! */
 | 
				
			||||||
 | 
					u8 *mem_ptr(u32 addr, int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 *retaddr = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (addr > M.mem_size - size) {
 | 
				
			||||||
 | 
							DB(printk("mem_ptr: address %#lx out of range!\n", addr);)
 | 
				
			||||||
 | 
							    HALT_SYS();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						/* a or b segment? */
 | 
				
			||||||
 | 
						/* & with e to clear low-order bit, if it is a or b it will be a */
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
						if (((addr & 0xfffe0000) == 0xa0000) && M.abseg) {
 | 
				
			||||||
 | 
							//printk("It's a0000\n");
 | 
				
			||||||
 | 
							//addr &= ~0xfffe0000;
 | 
				
			||||||
 | 
							retaddr = (u8 *) (M.mem_base + addr);
 | 
				
			||||||
 | 
							//printk("retaddr now 0x%p\n", retaddr);
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						if (addr < 0x200) {
 | 
				
			||||||
 | 
							printk("%x:%x updating int vector 0x%x\n",
 | 
				
			||||||
 | 
							       M.x86.R_CS, M.x86.R_IP, addr >> 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							retaddr = (u8 *) (M.mem_base + addr);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							retaddr = (u8 *) (M.mem_base + addr);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//printk_debug("%s, %x:%x ask address %x return address %x\n",
 | 
				
			||||||
 | 
						//	     __func__,  M.x86.R_CS, M.x86.R_IP, addr, retaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return retaddr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- Emulator memory address to read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RETURNS:
 | 
				
			||||||
 | 
					Byte value read from emulator memory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Reads a byte value from the emulator memory. 
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					u8 X86API rdb(u32 addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 val;
 | 
				
			||||||
 | 
						u8 *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = mem_ptr(addr, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = *ptr;
 | 
				
			||||||
 | 
						DB(if (DEBUG_MEM_TRACE())
 | 
				
			||||||
 | 
						   printk("%#08x 1 -> %#x\n", addr, val);)
 | 
				
			||||||
 | 
							return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- Emulator memory address to read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RETURNS:
 | 
				
			||||||
 | 
					Word value read from emulator memory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Reads a word value from the emulator memory.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					u16 X86API rdw(u32 addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u16 val = 0;
 | 
				
			||||||
 | 
						u8 *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = mem_ptr(addr, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (addr > M.mem_size - 2) {
 | 
				
			||||||
 | 
							DB(printk("mem_read: address %#lx out of range!\n", (unsigned long) addr);
 | 
				
			||||||
 | 
							    )
 | 
				
			||||||
 | 
							    HALT_SYS();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#ifdef __BIG_ENDIAN__
 | 
				
			||||||
 | 
						if (addr & 0x1) {
 | 
				
			||||||
 | 
							val = (*ptr | (*(ptr + 1) << 8));
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(__alpha__) || defined(__alpha)
 | 
				
			||||||
 | 
							val = ldw_u((u16 *) (ptr));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							val = *(u16 *) (ptr);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						DB(if (DEBUG_MEM_TRACE())
 | 
				
			||||||
 | 
						   printk("%#08x 2 -> %#x\n", addr, val);)
 | 
				
			||||||
 | 
							return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- Emulator memory address to read
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RETURNS:
 | 
				
			||||||
 | 
					Long value read from emulator memory.
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Reads a long value from the emulator memory. 
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					u32 X86API rdl(u32 addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 val = 0;
 | 
				
			||||||
 | 
						u8 *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = mem_ptr(addr, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __BIG_ENDIAN__
 | 
				
			||||||
 | 
						if (addr & 0x3) {
 | 
				
			||||||
 | 
							val = (*(u8 *) (ptr + 0) |
 | 
				
			||||||
 | 
							       (*(u8 *) (ptr + 1) << 8) |
 | 
				
			||||||
 | 
							       (*(u8 *) (ptr + 2) << 16) | (*(u8 *) (ptr + 3) << 24));
 | 
				
			||||||
 | 
						} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(__alpha__) || defined(__alpha)
 | 
				
			||||||
 | 
							val = ldl_u((u32 *) (ptr));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							val = *(u32 *) (ptr);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						DB(if (DEBUG_MEM_TRACE())
 | 
				
			||||||
 | 
						   printk("%#08x 4 -> %#x\n", addr, val);)
 | 
				
			||||||
 | 
							return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- Emulator memory address to read
 | 
				
			||||||
 | 
					val		- Value to store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Writes a byte value to emulator memory.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					void X86API wrb(u32 addr, u8 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = mem_ptr(addr, 1);
 | 
				
			||||||
 | 
						DB(if (DEBUG_MEM_TRACE())
 | 
				
			||||||
 | 
						   printk("%#08x 1 <- %#x\n", addr, val);)
 | 
				
			||||||
 | 
							*(u8 *) (ptr) = val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- Emulator memory address to read
 | 
				
			||||||
 | 
					val		- Value to store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Writes a word value to emulator memory.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					void X86API wrw(u32 addr, u16 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = mem_ptr(addr, 2);
 | 
				
			||||||
 | 
						DB(if (DEBUG_MEM_TRACE())
 | 
				
			||||||
 | 
						   printk("%#08x 2 <- %#x\n", addr, val);)
 | 
				
			||||||
 | 
					#ifdef __BIG_ENDIAN__
 | 
				
			||||||
 | 
							if (addr & 0x1) {
 | 
				
			||||||
 | 
								*(u8 *) (ptr + 0) = (val >> 0) & 0xff;
 | 
				
			||||||
 | 
								*(u8 *) (ptr + 1) = (val >> 8) & 0xff;
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(__alpha__) || defined(__alpha)
 | 
				
			||||||
 | 
								stw_u(val, (u16 *) (ptr));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
								*(u16 *) (ptr) = val;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- Emulator memory address to read
 | 
				
			||||||
 | 
					val		- Value to store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Writes a long value to emulator memory. 
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					void X86API wrl(u32 addr, u32 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u8 *ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ptr = mem_ptr(addr, 4);
 | 
				
			||||||
 | 
						DB(if (DEBUG_MEM_TRACE())
 | 
				
			||||||
 | 
						   printk("%#08x 4 <- %#x\n", addr, val);)
 | 
				
			||||||
 | 
					#ifdef __BIG_ENDIAN__
 | 
				
			||||||
 | 
							if (addr & 0x1) {
 | 
				
			||||||
 | 
								*(u8 *) (ptr + 0) = (val >> 0) & 0xff;
 | 
				
			||||||
 | 
								*(u8 *) (ptr + 1) = (val >> 8) & 0xff;
 | 
				
			||||||
 | 
								*(u8 *) (ptr + 2) = (val >> 16) & 0xff;
 | 
				
			||||||
 | 
								*(u8 *) (ptr + 3) = (val >> 24) & 0xff;
 | 
				
			||||||
 | 
							} else
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#if defined(__alpha__) || defined(__alpha)
 | 
				
			||||||
 | 
								stl_u(val, (u32 *) (ptr));
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
								*(u32 *) (ptr) = val;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- PIO address to read
 | 
				
			||||||
 | 
					RETURN:
 | 
				
			||||||
 | 
					0
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Default PIO byte read function. Doesn't perform real inb.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					static u8 X86API p_inb(X86EMU_pioAddr addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DB(if (DEBUG_IO_TRACE())
 | 
				
			||||||
 | 
							printk("inb %#04x \n", addr);)
 | 
				
			||||||
 | 
						return inb(addr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- PIO address to read
 | 
				
			||||||
 | 
					RETURN:
 | 
				
			||||||
 | 
					0
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Default PIO word read function. Doesn't perform real inw.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					static u16 X86API p_inw(X86EMU_pioAddr addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DB(if (DEBUG_IO_TRACE())
 | 
				
			||||||
 | 
							printk("inw %#04x \n", addr);)
 | 
				
			||||||
 | 
						return inw(addr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- PIO address to read
 | 
				
			||||||
 | 
					RETURN:
 | 
				
			||||||
 | 
					0
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Default PIO long read function. Doesn't perform real inl.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					static u32 X86API p_inl(X86EMU_pioAddr addr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DB(if (DEBUG_IO_TRACE())
 | 
				
			||||||
 | 
							printk("inl %#04x \n", addr);)
 | 
				
			||||||
 | 
						return inl(addr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- PIO address to write
 | 
				
			||||||
 | 
					val     - Value to store
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Default PIO byte write function. Doesn't perform real outb.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					static void X86API p_outb(X86EMU_pioAddr addr, u8 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DB(if (DEBUG_IO_TRACE())
 | 
				
			||||||
 | 
							printk("outb %#02x -> %#04x \n", val, addr);)
 | 
				
			||||||
 | 
						outb(val, addr);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- PIO address to write
 | 
				
			||||||
 | 
					val     - Value to store
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Default PIO word write function. Doesn't perform real outw.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					static void X86API p_outw(X86EMU_pioAddr addr, u16 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DB(if (DEBUG_IO_TRACE())
 | 
				
			||||||
 | 
							printk("outw %#04x -> %#04x \n", val, addr);)
 | 
				
			||||||
 | 
						outw(val, addr);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					addr	- PIO address to write
 | 
				
			||||||
 | 
					val     - Value to store
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Default PIO ;ong write function. Doesn't perform real outl.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					static void X86API p_outl(X86EMU_pioAddr addr, u32 val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DB(if (DEBUG_IO_TRACE())
 | 
				
			||||||
 | 
						       printk("outl %#08x -> %#04x \n", val, addr);)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						outl(val, addr);
 | 
				
			||||||
 | 
						return;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*------------------------- Global Variables ------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u8(X86APIP sys_rdb) (u32 addr) = rdb;
 | 
				
			||||||
 | 
					u16(X86APIP sys_rdw) (u32 addr) = rdw;
 | 
				
			||||||
 | 
					u32(X86APIP sys_rdl) (u32 addr) = rdl;
 | 
				
			||||||
 | 
					void (X86APIP sys_wrb) (u32 addr, u8 val) = wrb;
 | 
				
			||||||
 | 
					void (X86APIP sys_wrw) (u32 addr, u16 val) = wrw;
 | 
				
			||||||
 | 
					void (X86APIP sys_wrl) (u32 addr, u32 val) = wrl;
 | 
				
			||||||
 | 
					u8(X86APIP sys_inb) (X86EMU_pioAddr addr) = p_inb;
 | 
				
			||||||
 | 
					u16(X86APIP sys_inw) (X86EMU_pioAddr addr) = p_inw;
 | 
				
			||||||
 | 
					u32(X86APIP sys_inl) (X86EMU_pioAddr addr) = p_inl;
 | 
				
			||||||
 | 
					void (X86APIP sys_outb) (X86EMU_pioAddr addr, u8 val) = p_outb;
 | 
				
			||||||
 | 
					void (X86APIP sys_outw) (X86EMU_pioAddr addr, u16 val) = p_outw;
 | 
				
			||||||
 | 
					void (X86APIP sys_outl) (X86EMU_pioAddr addr, u32 val) = p_outl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*----------------------------- Setup -------------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					funcs	- New memory function pointers to make active
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					This function is used to set the pointers to functions which access
 | 
				
			||||||
 | 
					memory space, allowing the user application to override these functions
 | 
				
			||||||
 | 
					and hook them out as necessary for their application.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					void X86EMU_setupMemFuncs(X86EMU_memFuncs * funcs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sys_rdb = funcs->rdb;
 | 
				
			||||||
 | 
						sys_rdw = funcs->rdw;
 | 
				
			||||||
 | 
						sys_rdl = funcs->rdl;
 | 
				
			||||||
 | 
						sys_wrb = funcs->wrb;
 | 
				
			||||||
 | 
						sys_wrw = funcs->wrw;
 | 
				
			||||||
 | 
						sys_wrl = funcs->wrl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					funcs	- New programmed I/O function pointers to make active
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					This function is used to set the pointers to functions which access
 | 
				
			||||||
 | 
					I/O space, allowing the user application to override these functions
 | 
				
			||||||
 | 
					and hook them out as necessary for their application.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					void X86EMU_setupPioFuncs(X86EMU_pioFuncs * funcs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						sys_inb = funcs->inb;
 | 
				
			||||||
 | 
						sys_inw = funcs->inw;
 | 
				
			||||||
 | 
						sys_inl = funcs->inl;
 | 
				
			||||||
 | 
						sys_outb = funcs->outb;
 | 
				
			||||||
 | 
						sys_outw = funcs->outw;
 | 
				
			||||||
 | 
						sys_outl = funcs->outl;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					funcs	- New interrupt vector table to make active
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					This function is used to set the pointers to functions which handle
 | 
				
			||||||
 | 
					interrupt processing in the emulator, allowing the user application to
 | 
				
			||||||
 | 
					hook interrupts as necessary for their application. Any interrupts that
 | 
				
			||||||
 | 
					are not hooked by the user application, and reflected and handled internally
 | 
				
			||||||
 | 
					in the emulator via the interrupt vector table. This allows the application
 | 
				
			||||||
 | 
					to get control when the code being emulated executes specific software
 | 
				
			||||||
 | 
					interrupts.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					void X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0; i < 256; i++)
 | 
				
			||||||
 | 
							_X86EMU_intrTab[i] = NULL;
 | 
				
			||||||
 | 
						if (funcs) {
 | 
				
			||||||
 | 
							for (i = 0; i < 256; i++)
 | 
				
			||||||
 | 
								_X86EMU_intrTab[i] = funcs[i];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					PARAMETERS:
 | 
				
			||||||
 | 
					int	- New software interrupt to prepare for
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					This function is used to set up the emulator state to exceute a software
 | 
				
			||||||
 | 
					interrupt. This can be used by the user application code to allow an
 | 
				
			||||||
 | 
					interrupt to be hooked, examined and then reflected back to the emulator
 | 
				
			||||||
 | 
					so that the code in the emulator will continue processing the software
 | 
				
			||||||
 | 
					interrupt as per normal. This essentially allows system code to actively
 | 
				
			||||||
 | 
					hook and handle certain software interrupts as necessary.
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					void X86EMU_prepareForInt(int num)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						push_word((u16) M.x86.R_FLG);
 | 
				
			||||||
 | 
						CLEAR_FLAG(F_IF);
 | 
				
			||||||
 | 
						CLEAR_FLAG(F_TF);
 | 
				
			||||||
 | 
						push_word(M.x86.R_CS);
 | 
				
			||||||
 | 
						M.x86.R_CS = mem_access_word(num * 4 + 2);
 | 
				
			||||||
 | 
						push_word(M.x86.R_IP);
 | 
				
			||||||
 | 
						M.x86.R_IP = mem_access_word(num * 4);
 | 
				
			||||||
 | 
						M.x86.intr = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void X86EMU_setMemBase(void *base, size_t size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						M.mem_base = (int) base;
 | 
				
			||||||
 | 
						M.mem_size = size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void X86EMU_setabseg(void *abseg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						M.abseg = (unsigned long) abseg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										789
									
								
								src/devices/emulator/x86emu/validate.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										789
									
								
								src/devices/emulator/x86emu/validate.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,789 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*                       Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*               Copyright (C) 1991-2004 SciTech Software, Inc.
 | 
				
			||||||
 | 
					*                    Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					*                      Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:     Watcom C 10.6 or later
 | 
				
			||||||
 | 
					* Environment:  32-bit DOS
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Program to validate the x86 emulator library for
 | 
				
			||||||
 | 
					*               correctness. We run the emulator primitive operations
 | 
				
			||||||
 | 
					*               functions against the real x86 CPU, and compare the result
 | 
				
			||||||
 | 
					*               and flags to ensure correctness.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*               We use inline assembler to compile and build this program.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					#include "x86emu.h"
 | 
				
			||||||
 | 
					#include "x86emu/prim_asm.h"
 | 
				
			||||||
 | 
					#include "x86emu/prim_ops.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*-------------------------- Implementation -------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define true 1
 | 
				
			||||||
 | 
					#define false 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					u32 cur_flags_mask = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int flags_are_different(u32 flags1, u32 flags2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return (flags1&cur_flags_mask) != (flags2&cur_flags_mask);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ALL_FLAGS   (F_CF | F_PF | F_AF | F_ZF | F_SF | F_OF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_START_BINARY(parm_type,res_type,dmax,smax,dincr,sincr)  \
 | 
				
			||||||
 | 
					{                                                                   \
 | 
				
			||||||
 | 
					    parm_type   d,s;                                                \
 | 
				
			||||||
 | 
					    res_type    r,r_asm;                                            \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                      \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                   \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                  \
 | 
				
			||||||
 | 
					    for (d = 0; d < dmax; d += dincr) {                             \
 | 
				
			||||||
 | 
					        for (s = 0; s < smax; s += sincr) {                         \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags;             \
 | 
				
			||||||
 | 
					            for (f = 0; f < 2; f++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_TEST_BINARY(name)                                           \
 | 
				
			||||||
 | 
					                r_asm = name##_asm(&flags,d,s);                         \
 | 
				
			||||||
 | 
					                r = name(d,s);                                  \
 | 
				
			||||||
 | 
					                if (r != r_asm || flags_are_different(M.x86.R_EFLG, flags))                \
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_TEST_BINARY_VOID(name)                                      \
 | 
				
			||||||
 | 
					                name##_asm(&flags,d,s);                                 \
 | 
				
			||||||
 | 
					                name(d,s);                                      \
 | 
				
			||||||
 | 
					                r = r_asm = 0;                                          \
 | 
				
			||||||
 | 
					                if (flags_are_different(M.x86.R_EFLG, flags))                              \
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_BYTE_BYTE_BINARY(name)                                                                 \
 | 
				
			||||||
 | 
					                    if (failed)                                                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                    printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
 | 
				
			||||||
 | 
					                    printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_WORD_WORD_BINARY(name)                                                                 \
 | 
				
			||||||
 | 
					                    if (failed)                                                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                    printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));   \
 | 
				
			||||||
 | 
					                    printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_LONG_LONG_BINARY(name)                                                                 \
 | 
				
			||||||
 | 
					                    if (failed)                                                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                    printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \
 | 
				
			||||||
 | 
					                    printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_END_BINARY()                                                    \
 | 
				
			||||||
 | 
					                    }                                                       \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                if (failed)                                                 \
 | 
				
			||||||
 | 
					                    break;                                                  \
 | 
				
			||||||
 | 
					                }                                                           \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_BYTE_BYTE_BINARY(name)          \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);    \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1)   \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY(name)                   \
 | 
				
			||||||
 | 
					    VAL_FAIL_BYTE_BYTE_BINARY(name)         \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_WORD_WORD_BINARY(name)                      \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY(name)                               \
 | 
				
			||||||
 | 
					    VAL_FAIL_WORD_WORD_BINARY(name)                     \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_LONG_LONG_BINARY(name)                                      \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY(name)                                               \
 | 
				
			||||||
 | 
					    VAL_FAIL_LONG_LONG_BINARY(name)                                     \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_VOID_BYTE_BINARY(name)          \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);    \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1)   \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY_VOID(name)              \
 | 
				
			||||||
 | 
					    VAL_FAIL_BYTE_BYTE_BINARY(name)         \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_VOID_WORD_BINARY(name)                      \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY_VOID(name)                          \
 | 
				
			||||||
 | 
					    VAL_FAIL_WORD_WORD_BINARY(name)                     \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_VOID_LONG_BINARY(name)                                      \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY_VOID(name)                                          \
 | 
				
			||||||
 | 
					    VAL_FAIL_LONG_LONG_BINARY(name)                                     \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_BYTE_ROTATE(name)               \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);    \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u8,u8,0xFF,8,1,1)      \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY(name)                   \
 | 
				
			||||||
 | 
					    VAL_FAIL_BYTE_BYTE_BINARY(name)         \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_WORD_ROTATE(name)                           \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u16,u16,0xFF00,16,0x100,1)         \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY(name)                               \
 | 
				
			||||||
 | 
					    VAL_FAIL_WORD_WORD_BINARY(name)                     \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_LONG_ROTATE(name)                                           \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					    VAL_START_BINARY(u32,u32,0xFF000000,32,0x1000000,1)                 \
 | 
				
			||||||
 | 
					    VAL_TEST_BINARY(name)                                               \
 | 
				
			||||||
 | 
					    VAL_FAIL_LONG_LONG_BINARY(name)                                     \
 | 
				
			||||||
 | 
					    VAL_END_BINARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_START_TERNARY(parm_type,res_type,dmax,smax,dincr,sincr,maxshift)\
 | 
				
			||||||
 | 
					{                                                                   \
 | 
				
			||||||
 | 
					    parm_type   d,s;                                                \
 | 
				
			||||||
 | 
					    res_type    r,r_asm;                                            \
 | 
				
			||||||
 | 
					    u8          shift;                                              \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                      \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                   \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                  \
 | 
				
			||||||
 | 
					    for (d = 0; d < dmax; d += dincr) {                             \
 | 
				
			||||||
 | 
					        for (s = 0; s < smax; s += sincr) {                         \
 | 
				
			||||||
 | 
					            for (shift = 0; shift < maxshift; shift += 1) {        \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags;         \
 | 
				
			||||||
 | 
					                for (f = 0; f < 2; f++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_TEST_TERNARY(name)                                          \
 | 
				
			||||||
 | 
					                    r_asm = name##_asm(&flags,d,s,shift);               \
 | 
				
			||||||
 | 
					                    r = name(d,s,shift);                           \
 | 
				
			||||||
 | 
					                    if (r != r_asm || flags_are_different(M.x86.R_EFLG, flags))            \
 | 
				
			||||||
 | 
					                        failed = true;                                  \
 | 
				
			||||||
 | 
					                    if (failed || trace) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_WORD_WORD_TERNARY(name)                                                                \
 | 
				
			||||||
 | 
					                        if (failed)                                                                         \
 | 
				
			||||||
 | 
					                            printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                        printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                            r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));   \
 | 
				
			||||||
 | 
					                        printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                            r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_LONG_LONG_TERNARY(name)                                                                \
 | 
				
			||||||
 | 
					                        if (failed)                                                                         \
 | 
				
			||||||
 | 
					                            printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                        printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                            r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
 | 
				
			||||||
 | 
					                        printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                            r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_END_TERNARY()                                                   \
 | 
				
			||||||
 | 
					                        }                                                       \
 | 
				
			||||||
 | 
					                    M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                    if (failed)                                                 \
 | 
				
			||||||
 | 
					                        break;                                                  \
 | 
				
			||||||
 | 
					                    }                                                           \
 | 
				
			||||||
 | 
					                if (failed)                                                     \
 | 
				
			||||||
 | 
					                    break;                                                      \
 | 
				
			||||||
 | 
					                }                                                               \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_WORD_ROTATE_DBL(name)                           \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                    \
 | 
				
			||||||
 | 
					    VAL_START_TERNARY(u16,u16,0xFF00,0xFF00,0x100,0x100,16) \
 | 
				
			||||||
 | 
					    VAL_TEST_TERNARY(name)                                  \
 | 
				
			||||||
 | 
					    VAL_FAIL_WORD_WORD_TERNARY(name)                        \
 | 
				
			||||||
 | 
					    VAL_END_TERNARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_LONG_ROTATE_DBL(name)                                           \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                    \
 | 
				
			||||||
 | 
					    VAL_START_TERNARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000,32) \
 | 
				
			||||||
 | 
					    VAL_TEST_TERNARY(name)                                                  \
 | 
				
			||||||
 | 
					    VAL_FAIL_LONG_LONG_TERNARY(name)                                        \
 | 
				
			||||||
 | 
					    VAL_END_TERNARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_START_UNARY(parm_type,max,incr)                 \
 | 
				
			||||||
 | 
					{                                                           \
 | 
				
			||||||
 | 
					    parm_type   d,r,r_asm;                                  \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                              \
 | 
				
			||||||
 | 
					    int         f,failed = false;                           \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                          \
 | 
				
			||||||
 | 
					    for (d = 0; d < max; d += incr) {                       \
 | 
				
			||||||
 | 
					        M.x86.R_EFLG = inflags = flags = def_flags;         \
 | 
				
			||||||
 | 
					        for (f = 0; f < 2; f++) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_TEST_UNARY(name)                                \
 | 
				
			||||||
 | 
					            r_asm = name##_asm(&flags,d);                   \
 | 
				
			||||||
 | 
					            r = name(d);                                \
 | 
				
			||||||
 | 
					            if (r != r_asm || flags_are_different(M.x86.R_EFLG, flags)) {      \
 | 
				
			||||||
 | 
					                failed = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_BYTE_UNARY(name)                                                               \
 | 
				
			||||||
 | 
					                printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n",                            \
 | 
				
			||||||
 | 
					                    r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));    \
 | 
				
			||||||
 | 
					                printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n",                            \
 | 
				
			||||||
 | 
					                    r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_WORD_UNARY(name)                                                               \
 | 
				
			||||||
 | 
					                printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n",                            \
 | 
				
			||||||
 | 
					                    r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
 | 
				
			||||||
 | 
					                printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n",                            \
 | 
				
			||||||
 | 
					                    r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_FAIL_LONG_UNARY(name)                                                               \
 | 
				
			||||||
 | 
					                printk("fail\n");                                                               \
 | 
				
			||||||
 | 
					                printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n",                            \
 | 
				
			||||||
 | 
					                    r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));    \
 | 
				
			||||||
 | 
					                printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n",                            \
 | 
				
			||||||
 | 
					                    r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_END_UNARY()                                                 \
 | 
				
			||||||
 | 
					                }                                                       \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags | ALL_FLAGS;     \
 | 
				
			||||||
 | 
					            if (failed)                                                 \
 | 
				
			||||||
 | 
					                break;                                                  \
 | 
				
			||||||
 | 
					            }                                                           \
 | 
				
			||||||
 | 
					        if (failed)                                                     \
 | 
				
			||||||
 | 
					            break;                                                      \
 | 
				
			||||||
 | 
					        }                                                               \
 | 
				
			||||||
 | 
					    if (!failed)                                                        \
 | 
				
			||||||
 | 
					        printk("passed\n");                                             \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_BYTE_UNARY(name)                \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);    \
 | 
				
			||||||
 | 
					    VAL_START_UNARY(u8,0xFF,0x1)            \
 | 
				
			||||||
 | 
					    VAL_TEST_UNARY(name)                    \
 | 
				
			||||||
 | 
					    VAL_FAIL_BYTE_UNARY(name)               \
 | 
				
			||||||
 | 
					    VAL_END_UNARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_WORD_UNARY(name)                \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);    \
 | 
				
			||||||
 | 
					    VAL_START_UNARY(u16,0xFF00,0x100)       \
 | 
				
			||||||
 | 
					    VAL_TEST_UNARY(name)                    \
 | 
				
			||||||
 | 
					    VAL_FAIL_WORD_UNARY(name)               \
 | 
				
			||||||
 | 
					    VAL_END_UNARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_WORD_BYTE_UNARY(name)           \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);    \
 | 
				
			||||||
 | 
					    VAL_START_UNARY(u16,0xFF,0x1)           \
 | 
				
			||||||
 | 
					    VAL_TEST_UNARY(name)                    \
 | 
				
			||||||
 | 
					    VAL_FAIL_WORD_UNARY(name)               \
 | 
				
			||||||
 | 
					    VAL_END_UNARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_LONG_UNARY(name)                \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);    \
 | 
				
			||||||
 | 
					    VAL_START_UNARY(u32,0xFF000000,0x1000000) \
 | 
				
			||||||
 | 
					    VAL_TEST_UNARY(name)                    \
 | 
				
			||||||
 | 
					    VAL_FAIL_LONG_UNARY(name)               \
 | 
				
			||||||
 | 
					    VAL_END_UNARY()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_BYTE_MUL(name)                                              \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					{                                                                       \
 | 
				
			||||||
 | 
					    u8          d,s;                                                    \
 | 
				
			||||||
 | 
					    u16         r,r_asm;                                                \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                          \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                       \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                      \
 | 
				
			||||||
 | 
					    for (d = 0; d < 0xFF; d += 1) {                                     \
 | 
				
			||||||
 | 
					        for (s = 0; s < 0xFF; s += 1) {                                 \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags;                 \
 | 
				
			||||||
 | 
					            for (f = 0; f < 2; f++) {                                   \
 | 
				
			||||||
 | 
					                name##_asm(&flags,&r_asm,d,s);                          \
 | 
				
			||||||
 | 
					                M.x86.R_AL = d;                                         \
 | 
				
			||||||
 | 
					                name(s);                                            \
 | 
				
			||||||
 | 
					                r = M.x86.R_AX;                                         \
 | 
				
			||||||
 | 
					                if (r != r_asm || flags_are_different(M.x86.R_EFLG, flags))                \
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {                                  \
 | 
				
			||||||
 | 
					                    if (failed)                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                               \
 | 
				
			||||||
 | 
					                    printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
 | 
				
			||||||
 | 
					                    printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n",                         \
 | 
				
			||||||
 | 
					                        r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
 | 
				
			||||||
 | 
					                    }                                                       \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                if (failed)                                                 \
 | 
				
			||||||
 | 
					                    break;                                                  \
 | 
				
			||||||
 | 
					                }                                                           \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_WORD_MUL(name)                                              \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					{                                                                       \
 | 
				
			||||||
 | 
					    u16         d,s;                                                    \
 | 
				
			||||||
 | 
					    u16         r_lo,r_asm_lo;                                          \
 | 
				
			||||||
 | 
					    u16         r_hi,r_asm_hi;                                          \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                          \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                       \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                      \
 | 
				
			||||||
 | 
					    for (d = 0; d < 0xFF00; d += 0x100) {                               \
 | 
				
			||||||
 | 
					        for (s = 0; s < 0xFF00; s += 0x100) {                           \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags;                 \
 | 
				
			||||||
 | 
					            for (f = 0; f < 2; f++) {                                   \
 | 
				
			||||||
 | 
					                name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s);             \
 | 
				
			||||||
 | 
					                M.x86.R_AX = d;                                         \
 | 
				
			||||||
 | 
					                name(s);                                            \
 | 
				
			||||||
 | 
					                r_lo = M.x86.R_AX;                                      \
 | 
				
			||||||
 | 
					                r_hi = M.x86.R_DX;                                      \
 | 
				
			||||||
 | 
					                if (r_lo != r_asm_lo || r_hi != r_asm_hi || flags_are_different(M.x86.R_EFLG, flags))\
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {                                  \
 | 
				
			||||||
 | 
					                    if (failed)                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                               \
 | 
				
			||||||
 | 
					                    printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                              \
 | 
				
			||||||
 | 
					                        r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));       \
 | 
				
			||||||
 | 
					                    printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n",                              \
 | 
				
			||||||
 | 
					                        r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
 | 
				
			||||||
 | 
					                    }                                                                                               \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                if (failed)                                                 \
 | 
				
			||||||
 | 
					                    break;                                                  \
 | 
				
			||||||
 | 
					                }                                                           \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_LONG_MUL(name)                                              \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					{                                                                       \
 | 
				
			||||||
 | 
					    u32         d,s;                                                    \
 | 
				
			||||||
 | 
					    u32         r_lo,r_asm_lo;                                          \
 | 
				
			||||||
 | 
					    u32         r_hi,r_asm_hi;                                          \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                          \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                       \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                      \
 | 
				
			||||||
 | 
					    for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
 | 
				
			||||||
 | 
					        for (s = 0; s < 0xFF000000; s += 0x1000000) {                   \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags;                 \
 | 
				
			||||||
 | 
					            for (f = 0; f < 2; f++) {                                   \
 | 
				
			||||||
 | 
					                name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s);             \
 | 
				
			||||||
 | 
					                M.x86.R_EAX = d;                                        \
 | 
				
			||||||
 | 
					                name(s);                                            \
 | 
				
			||||||
 | 
					                r_lo = M.x86.R_EAX;                                     \
 | 
				
			||||||
 | 
					                r_hi = M.x86.R_EDX;                                     \
 | 
				
			||||||
 | 
					                if (r_lo != r_asm_lo || r_hi != r_asm_hi || flags_are_different(M.x86.R_EFLG, flags))\
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {                                  \
 | 
				
			||||||
 | 
					                    if (failed)                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                               \
 | 
				
			||||||
 | 
					                    printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                              \
 | 
				
			||||||
 | 
					                        r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));       \
 | 
				
			||||||
 | 
					                    printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n",                              \
 | 
				
			||||||
 | 
					                        r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
 | 
				
			||||||
 | 
					                    }                                                                                               \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                if (failed)                                                 \
 | 
				
			||||||
 | 
					                    break;                                                  \
 | 
				
			||||||
 | 
					                }                                                           \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_BYTE_DIV(name)                                              \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					{                                                                       \
 | 
				
			||||||
 | 
					    u16         d,s;                                                    \
 | 
				
			||||||
 | 
					    u8          r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                          \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                       \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                      \
 | 
				
			||||||
 | 
					    for (d = 0; d < 0xFF00; d += 0x100) {                               \
 | 
				
			||||||
 | 
					        for (s = 1; s < 0xFF; s += 1) {                                 \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags;                 \
 | 
				
			||||||
 | 
					            for (f = 0; f < 2; f++) {                                   \
 | 
				
			||||||
 | 
					                M.x86.intr = 0;                                         \
 | 
				
			||||||
 | 
					                M.x86.R_AX = d;                                         \
 | 
				
			||||||
 | 
					                name(s);                                            \
 | 
				
			||||||
 | 
					                r_quot = M.x86.R_AL;                                    \
 | 
				
			||||||
 | 
					                r_rem = M.x86.R_AH;                                     \
 | 
				
			||||||
 | 
					                if (M.x86.intr & INTR_SYNCH)                            \
 | 
				
			||||||
 | 
					                    continue;                                           \
 | 
				
			||||||
 | 
					                name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,s);          \
 | 
				
			||||||
 | 
					                if (r_quot != r_asm_quot || r_rem != r_asm_rem || flags_are_different(M.x86.R_EFLG, flags)) \
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {                                  \
 | 
				
			||||||
 | 
					                    if (failed)                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                               \
 | 
				
			||||||
 | 
					                    printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                        r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
 | 
				
			||||||
 | 
					                    printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                        r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
 | 
				
			||||||
 | 
					                    }                                                       \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                if (failed)                                                 \
 | 
				
			||||||
 | 
					                    break;                                                  \
 | 
				
			||||||
 | 
					                }                                                           \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_WORD_DIV(name)                                              \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					{                                                                       \
 | 
				
			||||||
 | 
					    u32         d,s;                                                    \
 | 
				
			||||||
 | 
					    u16         r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                          \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                       \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                      \
 | 
				
			||||||
 | 
					    for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
 | 
				
			||||||
 | 
					        for (s = 0x100; s < 0xFF00; s += 0x100) {                       \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags;                 \
 | 
				
			||||||
 | 
					            for (f = 0; f < 2; f++) {                                   \
 | 
				
			||||||
 | 
					                M.x86.intr = 0;                                         \
 | 
				
			||||||
 | 
					                M.x86.R_AX = d & 0xFFFF;                                \
 | 
				
			||||||
 | 
					                M.x86.R_DX = d >> 16;                                   \
 | 
				
			||||||
 | 
					                name(s);                                            \
 | 
				
			||||||
 | 
					                r_quot = M.x86.R_AX;                                    \
 | 
				
			||||||
 | 
					                r_rem = M.x86.R_DX;                                     \
 | 
				
			||||||
 | 
					                if (M.x86.intr & INTR_SYNCH)                            \
 | 
				
			||||||
 | 
					                    continue;                                           \
 | 
				
			||||||
 | 
					                name##_asm(&flags,&r_asm_quot,&r_asm_rem,d & 0xFFFF,d >> 16,s);\
 | 
				
			||||||
 | 
					                if (r_quot != r_asm_quot || r_rem != r_asm_rem || flags_are_different(M.x86.R_EFLG, flags)) \
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {                                  \
 | 
				
			||||||
 | 
					                    if (failed)                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                               \
 | 
				
			||||||
 | 
					                    printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                        r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));     \
 | 
				
			||||||
 | 
					                    printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n",                      \
 | 
				
			||||||
 | 
					                        r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags));  \
 | 
				
			||||||
 | 
					                    }                                                       \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                if (failed)                                                 \
 | 
				
			||||||
 | 
					                    break;                                                  \
 | 
				
			||||||
 | 
					                }                                                           \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define VAL_LONG_DIV(name)                                              \
 | 
				
			||||||
 | 
					    printk("Validating %s ... ", #name);                                \
 | 
				
			||||||
 | 
					{                                                                       \
 | 
				
			||||||
 | 
					    u32         d,s;                                                    \
 | 
				
			||||||
 | 
					    u32         r_quot,r_rem,r_asm_quot,r_asm_rem;                      \
 | 
				
			||||||
 | 
					    u32         flags,inflags;                                          \
 | 
				
			||||||
 | 
					    int         f,failed = false;                                       \
 | 
				
			||||||
 | 
					    char        buf1[80],buf2[80];                                      \
 | 
				
			||||||
 | 
					    for (d = 0; d < 0xFF000000; d += 0x1000000) {                       \
 | 
				
			||||||
 | 
					        for (s = 0x100; s < 0xFF00; s += 0x100) {                       \
 | 
				
			||||||
 | 
					            M.x86.R_EFLG = inflags = flags = def_flags;                 \
 | 
				
			||||||
 | 
					            for (f = 0; f < 2; f++) {                                   \
 | 
				
			||||||
 | 
					                M.x86.intr = 0;                                         \
 | 
				
			||||||
 | 
					                M.x86.R_EAX = d;                                        \
 | 
				
			||||||
 | 
					                M.x86.R_EDX = 0;                                        \
 | 
				
			||||||
 | 
					                name(s);                                            \
 | 
				
			||||||
 | 
					                r_quot = M.x86.R_EAX;                                   \
 | 
				
			||||||
 | 
					                r_rem = M.x86.R_EDX;                                    \
 | 
				
			||||||
 | 
					                if (M.x86.intr & INTR_SYNCH)                            \
 | 
				
			||||||
 | 
					                    continue;                                           \
 | 
				
			||||||
 | 
					                name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,0,s);        \
 | 
				
			||||||
 | 
					                if (r_quot != r_asm_quot || r_rem != r_asm_rem || flags_are_different(M.x86.R_EFLG, flags)) \
 | 
				
			||||||
 | 
					                    failed = true;                                      \
 | 
				
			||||||
 | 
					                if (failed || trace) {                                  \
 | 
				
			||||||
 | 
					                    if (failed)                                         \
 | 
				
			||||||
 | 
					                        printk("fail\n");                               \
 | 
				
			||||||
 | 
					                    printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n",                       \
 | 
				
			||||||
 | 
					                        r_quot, r_rem, #name, 0, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG));  \
 | 
				
			||||||
 | 
					                    printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n",                       \
 | 
				
			||||||
 | 
					                        r_asm_quot, r_asm_rem, #name"_asm", 0, d, s, print_flags(buf1,inflags), print_flags(buf2,flags));   \
 | 
				
			||||||
 | 
					                    }                                                       \
 | 
				
			||||||
 | 
					                M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF);   \
 | 
				
			||||||
 | 
					                if (failed)                                                 \
 | 
				
			||||||
 | 
					                    break;                                                  \
 | 
				
			||||||
 | 
					                }                                                           \
 | 
				
			||||||
 | 
					            if (failed)                                                     \
 | 
				
			||||||
 | 
					                break;                                                      \
 | 
				
			||||||
 | 
					            }                                                               \
 | 
				
			||||||
 | 
					        if (failed)                                                         \
 | 
				
			||||||
 | 
					            break;                                                          \
 | 
				
			||||||
 | 
					        }                                                                   \
 | 
				
			||||||
 | 
					    if (!failed)                                                            \
 | 
				
			||||||
 | 
					        printk("passed\n");                                                 \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void printk(const char *fmt, ...)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    va_list argptr;
 | 
				
			||||||
 | 
					    va_start(argptr, fmt);
 | 
				
			||||||
 | 
					    vfprintf(stdout, fmt, argptr);
 | 
				
			||||||
 | 
					    fflush(stdout);
 | 
				
			||||||
 | 
					    va_end(argptr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char * print_flags(char *buf,ulong flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *separator = "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buf[0] = 0;
 | 
				
			||||||
 | 
					    if (flags & F_CF) {
 | 
				
			||||||
 | 
					        strcat(buf,separator);
 | 
				
			||||||
 | 
					        strcat(buf,"CF");
 | 
				
			||||||
 | 
					        separator = ",";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    if (flags & F_PF) {
 | 
				
			||||||
 | 
					        strcat(buf,separator);
 | 
				
			||||||
 | 
					        strcat(buf,"PF");
 | 
				
			||||||
 | 
					        separator = ",";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    if (flags & F_AF) {
 | 
				
			||||||
 | 
					        strcat(buf,separator);
 | 
				
			||||||
 | 
					        strcat(buf,"AF");
 | 
				
			||||||
 | 
					        separator = ",";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    if (flags & F_ZF) {
 | 
				
			||||||
 | 
					        strcat(buf,separator);
 | 
				
			||||||
 | 
					        strcat(buf,"ZF");
 | 
				
			||||||
 | 
					        separator = ",";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    if (flags & F_SF) {
 | 
				
			||||||
 | 
					        strcat(buf,separator);
 | 
				
			||||||
 | 
					        strcat(buf,"SF");
 | 
				
			||||||
 | 
					        separator = ",";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    if (flags & F_OF) {
 | 
				
			||||||
 | 
					        strcat(buf,separator);
 | 
				
			||||||
 | 
					        strcat(buf,"OF");
 | 
				
			||||||
 | 
					        separator = ",";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    if (separator[0] == 0)
 | 
				
			||||||
 | 
					        strcpy(buf,"None");
 | 
				
			||||||
 | 
					    return buf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char *argv[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    u32  def_flags;
 | 
				
			||||||
 | 
					    int trace = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (argc > 1)
 | 
				
			||||||
 | 
					        trace = true;
 | 
				
			||||||
 | 
					    memset(&M, 0, sizeof(M));
 | 
				
			||||||
 | 
					    def_flags = get_flags_asm() & ~ALL_FLAGS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = F_AF | F_CF;
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(aaa_word);
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(aas_word);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = F_SF | F_ZF | F_PF;
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(aad_word);
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(aam_word);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS;
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(adc_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(adc_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(adc_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(add_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(add_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(add_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS & (~F_AF);
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(and_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(and_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(and_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS;
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(cmp_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(cmp_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(cmp_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS & (~F_OF);
 | 
				
			||||||
 | 
					    VAL_BYTE_UNARY(daa_byte);
 | 
				
			||||||
 | 
					    VAL_BYTE_UNARY(das_byte);   // Fails for 0x9A (out of range anyway)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS;
 | 
				
			||||||
 | 
					    VAL_BYTE_UNARY(dec_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(dec_word);
 | 
				
			||||||
 | 
					    VAL_LONG_UNARY(dec_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_UNARY(inc_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(inc_word);
 | 
				
			||||||
 | 
					    VAL_LONG_UNARY(inc_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS & (~F_AF);
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(or_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(or_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(or_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS;
 | 
				
			||||||
 | 
					    VAL_BYTE_UNARY(neg_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(neg_word);
 | 
				
			||||||
 | 
					    VAL_LONG_UNARY(neg_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_UNARY(not_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_UNARY(not_word);
 | 
				
			||||||
 | 
					    VAL_LONG_UNARY(not_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS & (~F_OF);
 | 
				
			||||||
 | 
					    VAL_BYTE_ROTATE(rcl_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE(rcl_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE(rcl_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_ROTATE(rcr_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE(rcr_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE(rcr_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_ROTATE(rol_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE(rol_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE(rol_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_ROTATE(ror_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE(ror_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE(ror_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS & (~(F_AF | F_OF));
 | 
				
			||||||
 | 
					    VAL_BYTE_ROTATE(shl_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE(shl_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE(shl_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_ROTATE(shr_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE(shr_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE(shr_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_ROTATE(sar_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE(sar_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE(sar_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS & (~(F_AF | F_OF));
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE_DBL(shld_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE_DBL(shld_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_WORD_ROTATE_DBL(shrd_word);
 | 
				
			||||||
 | 
					    VAL_LONG_ROTATE_DBL(shrd_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS;
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(sbb_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(sbb_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(sbb_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(sub_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(sub_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(sub_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = ALL_FLAGS & (~F_AF);
 | 
				
			||||||
 | 
					    VAL_BYTE_BYTE_BINARY(xor_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_WORD_BINARY(xor_word);
 | 
				
			||||||
 | 
					    VAL_LONG_LONG_BINARY(xor_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_VOID_BYTE_BINARY(test_byte);
 | 
				
			||||||
 | 
					    VAL_VOID_WORD_BINARY(test_word);
 | 
				
			||||||
 | 
					    VAL_VOID_LONG_BINARY(test_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = F_CF | F_OF;
 | 
				
			||||||
 | 
					    VAL_BYTE_MUL(imul_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_MUL(imul_word);
 | 
				
			||||||
 | 
					    VAL_LONG_MUL(imul_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_MUL(mul_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_MUL(mul_word);
 | 
				
			||||||
 | 
					    VAL_LONG_MUL(mul_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cur_flags_mask = 0;
 | 
				
			||||||
 | 
					    VAL_BYTE_DIV(idiv_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_DIV(idiv_word);
 | 
				
			||||||
 | 
					    VAL_LONG_DIV(idiv_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VAL_BYTE_DIV(div_byte);
 | 
				
			||||||
 | 
					    VAL_WORD_DIV(div_word);
 | 
				
			||||||
 | 
					    VAL_LONG_DIV(div_long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										105
									
								
								src/devices/emulator/x86emu/x86emui.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/devices/emulator/x86emu/x86emui.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for system specific functions. These functions
 | 
				
			||||||
 | 
					*				are always compiled and linked in the OS depedent libraries,
 | 
				
			||||||
 | 
					*				and never in a binary portable driver.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* $XFree86: xc/extras/x86emu/src/x86emu/x86emu/x86emui.h,v 1.4 2001/04/01 13:59:58 tsi Exp $ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_X86EMUI_H
 | 
				
			||||||
 | 
					#define __X86EMU_X86EMUI_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* If we are compiling in C++ mode, we can compile some functions as
 | 
				
			||||||
 | 
					 * inline to increase performance (however the code size increases quite
 | 
				
			||||||
 | 
					 * dramatically in this case).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if	defined(__cplusplus) && !defined(_NO_INLINE)
 | 
				
			||||||
 | 
					#define	_INLINE	inline
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define	_INLINE static
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Get rid of unused parameters in C++ compilation mode */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					#define	X86EMU_UNUSED(v)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define	X86EMU_UNUSED(v)	v
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "x86emu/x86emu.h"
 | 
				
			||||||
 | 
					#include "x86emu/regs.h"
 | 
				
			||||||
 | 
					#include "debug.h"
 | 
				
			||||||
 | 
					#include "decode.h"
 | 
				
			||||||
 | 
					#include "ops.h"
 | 
				
			||||||
 | 
					#include "prim_ops.h"
 | 
				
			||||||
 | 
					#include "fpu.h"
 | 
				
			||||||
 | 
					#include "x86emu/fpu_regs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef IN_MODULE
 | 
				
			||||||
 | 
					#include <xf86_ansic.h>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					//#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#endif                                                                                           
 | 
				
			||||||
 | 
					/*--------------------------- Inline Functions ----------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					extern "C" {            			/* Use "C" linkage when in C++ mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern u8  	(X86APIP sys_rdb)(u32 addr);
 | 
				
			||||||
 | 
					extern u16 	(X86APIP sys_rdw)(u32 addr);
 | 
				
			||||||
 | 
					extern u32 	(X86APIP sys_rdl)(u32 addr);
 | 
				
			||||||
 | 
					extern void (X86APIP sys_wrb)(u32 addr,u8 val);
 | 
				
			||||||
 | 
					extern void (X86APIP sys_wrw)(u32 addr,u16 val);
 | 
				
			||||||
 | 
					extern void (X86APIP sys_wrl)(u32 addr,u32 val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern u8  	(X86APIP sys_inb)(X86EMU_pioAddr addr);
 | 
				
			||||||
 | 
					extern u16 	(X86APIP sys_inw)(X86EMU_pioAddr addr);
 | 
				
			||||||
 | 
					extern u32 	(X86APIP sys_inl)(X86EMU_pioAddr addr);
 | 
				
			||||||
 | 
					extern void (X86APIP sys_outb)(X86EMU_pioAddr addr,u8 val);
 | 
				
			||||||
 | 
					extern void (X86APIP sys_outw)(X86EMU_pioAddr addr,u16 val);
 | 
				
			||||||
 | 
					extern void	(X86APIP sys_outl)(X86EMU_pioAddr addr,u32 val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					}                       			/* End of "C" linkage for C++   	*/
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_X86EMUI_H */
 | 
				
			||||||
@@ -548,13 +548,24 @@ void pci_bus_enable_resources(struct device *dev)
 | 
				
			|||||||
	enable_childrens_resources(dev);
 | 
						enable_childrens_resources(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
 | 
					void pci_dev_set_subsystem(device_t dev, unsigned vendor, unsigned device)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
 | 
						pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID, 
 | 
				
			||||||
		((device & 0xffff) << 16) | (vendor & 0xffff));
 | 
							((device & 0xffff) << 16) | (vendor & 0xffff));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void pci_dev_init(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct rom_header *rom, *ram;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rom = pci_rom_probe(dev);
 | 
				
			||||||
 | 
						if (rom == NULL)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						ram = pci_rom_load(dev, rom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						run_bios(dev, ram);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Default device operation for PCI devices */
 | 
					/** Default device operation for PCI devices */
 | 
				
			||||||
static struct pci_operations pci_dev_ops_pci = {
 | 
					static struct pci_operations pci_dev_ops_pci = {
 | 
				
			||||||
	.set_subsystem = pci_dev_set_subsystem,
 | 
						.set_subsystem = pci_dev_set_subsystem,
 | 
				
			||||||
@@ -564,7 +575,7 @@ struct device_operations default_pci_ops_dev = {
 | 
				
			|||||||
	.read_resources   = pci_dev_read_resources,
 | 
						.read_resources   = pci_dev_read_resources,
 | 
				
			||||||
	.set_resources    = pci_dev_set_resources,
 | 
						.set_resources    = pci_dev_set_resources,
 | 
				
			||||||
	.enable_resources = pci_dev_enable_resources,
 | 
						.enable_resources = pci_dev_enable_resources,
 | 
				
			||||||
	.init		  = 0,
 | 
						.init		  = pci_dev_init,
 | 
				
			||||||
	.scan_bus	  = 0,
 | 
						.scan_bus	  = 0,
 | 
				
			||||||
	.enable           = 0,
 | 
						.enable           = 0,
 | 
				
			||||||
	.ops_pci          = &pci_dev_ops_pci,
 | 
						.ops_pci          = &pci_dev_ops_pci,
 | 
				
			||||||
@@ -574,6 +585,7 @@ struct device_operations default_pci_ops_dev = {
 | 
				
			|||||||
static struct pci_operations pci_bus_ops_pci = {
 | 
					static struct pci_operations pci_bus_ops_pci = {
 | 
				
			||||||
	.set_subsystem = 0,
 | 
						.set_subsystem = 0,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct device_operations default_pci_ops_bus = {
 | 
					struct device_operations default_pci_ops_bus = {
 | 
				
			||||||
	.read_resources   = pci_bus_read_resources,
 | 
						.read_resources   = pci_bus_read_resources,
 | 
				
			||||||
	.set_resources    = pci_dev_set_resources,
 | 
						.set_resources    = pci_dev_set_resources,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										82
									
								
								src/devices/pci_rom.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/devices/pci_rom.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					#include <console/console.h>
 | 
				
			||||||
 | 
					#include <device/device.h>
 | 
				
			||||||
 | 
					#include <device/pci.h>
 | 
				
			||||||
 | 
					#include <device/pci_ids.h>
 | 
				
			||||||
 | 
					#include <device/pci_ops.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rom_header * pci_rom_probe(struct device *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned long rom_address;
 | 
				
			||||||
 | 
						struct rom_header *rom_header;
 | 
				
			||||||
 | 
						struct pci_data *rom_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rom_address = pci_read_config32(dev, PCI_ROM_ADDRESS);
 | 
				
			||||||
 | 
						if (rom_address == 0x00000000 || rom_address == 0xffffffff) {
 | 
				
			||||||
 | 
							/* FixME: search in the LinuxBIOS Image for integrated
 | 
				
			||||||
 | 
							 * devices? */
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("%s, rom address for %s = %x\n",
 | 
				
			||||||
 | 
							     __func__, dev_path(dev), rom_address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* enable expansion ROM address decoding */
 | 
				
			||||||
 | 
						pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address|PCI_ROM_ADDRESS_ENABLE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rom_header = rom_address;
 | 
				
			||||||
 | 
						printk_debug("%s, PCI Expansion ROM, signature 0x%04x, \n\t"
 | 
				
			||||||
 | 
							     "INIT size 0x%04x, data ptr 0x%04x\n",
 | 
				
			||||||
 | 
							     __func__, le32_to_cpu(rom_header->signature),
 | 
				
			||||||
 | 
							     rom_header->size * 512, le32_to_cpu(rom_header->data));
 | 
				
			||||||
 | 
						if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) {
 | 
				
			||||||
 | 
							printk_err("%s, Incorrect Expansion ROM Header Signature %04x\n",
 | 
				
			||||||
 | 
								   __func__, le32_to_cpu(rom_header->signature));
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rom_data = (unsigned char *) rom_header + le32_to_cpu(rom_header->data);
 | 
				
			||||||
 | 
						printk_debug("%s, PCI ROM Image,  Vendor %04x, Device %04x,\n",
 | 
				
			||||||
 | 
							     __func__, rom_data->vendor, rom_data->device);
 | 
				
			||||||
 | 
						if (dev->vendor != rom_data->vendor || dev->device != rom_data->device) {
 | 
				
			||||||
 | 
							printk_err("%s, Device or Vendor ID mismatch\n");
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printk_debug("%s, PCI ROM Image,  Class Code %02x%04x, Code Type %02x\n",
 | 
				
			||||||
 | 
							     __func__, rom_data->class_hi, rom_data->class_lo,
 | 
				
			||||||
 | 
							     rom_data->type);
 | 
				
			||||||
 | 
						if ((dev->class >> 8) != (rom_data->class_hi << 16 | rom_data->class_lo)) {
 | 
				
			||||||
 | 
							printk_err("%s, Class Code mismatch %x\n",
 | 
				
			||||||
 | 
								   __func__, dev->class);
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rom_header;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void *pci_ram_image_start = PCI_RAM_IMAGE_START;
 | 
				
			||||||
 | 
					struct rom_header *pci_rom_load(struct device *dev, struct rom_header *rom_header)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct pci_data * rom_data;
 | 
				
			||||||
 | 
						unsigned long rom_address;
 | 
				
			||||||
 | 
						unsigned int rom_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rom_address = pci_read_config32(dev, PCI_ROM_ADDRESS);
 | 
				
			||||||
 | 
						rom_data = (unsigned char *) rom_header + le32_to_cpu(rom_header->data);
 | 
				
			||||||
 | 
						rom_size = rom_header->size*512;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (PCI_CLASS_DISPLAY_VGA == (rom_data->class_hi << 16 | rom_data->class_lo)) {
 | 
				
			||||||
 | 
							printk_debug("%s, copying VGA ROM Image from %x to %x, %x bytes\n",
 | 
				
			||||||
 | 
								     __func__, rom_header, PCI_VGA_RAM_IMAGE_START, rom_size);
 | 
				
			||||||
 | 
							memcpy(PCI_VGA_RAM_IMAGE_START, rom_header, rom_size);
 | 
				
			||||||
 | 
							return (struct rom_header *) (PCI_VGA_RAM_IMAGE_START);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							printk_debug("%s, copying non-VGA ROM Image from %x to %x, %x bytes\n",
 | 
				
			||||||
 | 
								     __func__, rom_header, pci_ram_image_start, rom_size);
 | 
				
			||||||
 | 
							memcpy(pci_ram_image_start, rom_header, rom_size);
 | 
				
			||||||
 | 
							pci_ram_image_start += rom_size;
 | 
				
			||||||
 | 
							return (struct rom_header *) pci_ram_image_start;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						/* disable expansion ROM address decoding */
 | 
				
			||||||
 | 
						pci_write_config32(dev, PCI_ROM_ADDRESS, rom_address & ~PCI_ROM_ADDRESS_ENABLE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -19,7 +19,7 @@
 | 
				
			|||||||
#include <device/resource.h>
 | 
					#include <device/resource.h>
 | 
				
			||||||
#include <device/device.h>
 | 
					#include <device/device.h>
 | 
				
			||||||
#include <device/pci_ops.h>
 | 
					#include <device/pci_ops.h>
 | 
				
			||||||
 | 
					#include <device/pci_rom.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Common pci operations without a standard interface */
 | 
					/* Common pci operations without a standard interface */
 | 
				
			||||||
struct pci_operations {
 | 
					struct pci_operations {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										32
									
								
								src/include/device/pci_rom.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/include/device/pci_rom.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					#include <arch/byteorder.h>
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PCI_ROM_HDR 0xAA55
 | 
				
			||||||
 | 
					#define PCI_DATA_HDR (uint32_t) ( ('R' << 24) | ('I' << 16) | ('C' << 8) | 'P' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PCI_RAM_IMAGE_START 0xD0000
 | 
				
			||||||
 | 
					#define PCI_VGA_RAM_IMAGE_START 0xC0000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rom_header {
 | 
				
			||||||
 | 
						uint16_t	signature;
 | 
				
			||||||
 | 
						uint8_t		size;
 | 
				
			||||||
 | 
						uint8_t		init[3];
 | 
				
			||||||
 | 
						uint8_t		reserved[0x12];
 | 
				
			||||||
 | 
						uint16_t	data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct  pci_data {
 | 
				
			||||||
 | 
						uint32_t	signature;
 | 
				
			||||||
 | 
						uint16_t	vendor;
 | 
				
			||||||
 | 
						uint16_t	device;
 | 
				
			||||||
 | 
						uint16_t	reserved_1;
 | 
				
			||||||
 | 
						uint16_t	dlen;
 | 
				
			||||||
 | 
						uint8_t		drevision;
 | 
				
			||||||
 | 
						uint8_t		class_hi;
 | 
				
			||||||
 | 
						uint16_t	class_lo;
 | 
				
			||||||
 | 
						uint16_t	ilen;
 | 
				
			||||||
 | 
						uint16_t	irevision;
 | 
				
			||||||
 | 
						uint8_t		type;
 | 
				
			||||||
 | 
						uint8_t		indicator;
 | 
				
			||||||
 | 
						uint16_t	reserved_2;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										115
									
								
								src/include/x86emu/fpu_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/include/x86emu/fpu_regs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for FPU register definitions.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_FPU_REGS_H
 | 
				
			||||||
 | 
					#define __X86EMU_FPU_REGS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef X86_FPU_SUPPORT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma	pack(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Basic 8087 register can hold any of the following values: */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					union x86_fpu_reg_u {
 | 
				
			||||||
 | 
					    s8                  tenbytes[10];
 | 
				
			||||||
 | 
					    double              dval;
 | 
				
			||||||
 | 
					    float               fval;
 | 
				
			||||||
 | 
					    s16                 sval;
 | 
				
			||||||
 | 
					    s32                 lval;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct x86_fpu_reg {
 | 
				
			||||||
 | 
						union x86_fpu_reg_u reg;
 | 
				
			||||||
 | 
						char                tag;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Since we are not going to worry about the problems of aliasing
 | 
				
			||||||
 | 
					 * registers, every time a register is modified, its result type is
 | 
				
			||||||
 | 
					 * set in the tag fields for that register.  If some operation
 | 
				
			||||||
 | 
					 * attempts to access the type in a way inconsistent with its current
 | 
				
			||||||
 | 
					 * storage format, then we flag the operation.  If common, we'll
 | 
				
			||||||
 | 
					 * attempt the conversion.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define  X86_FPU_VALID          0x80
 | 
				
			||||||
 | 
					#define  X86_FPU_REGTYP(r)      ((r) & 0x7F)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define  X86_FPU_WORD           0x0
 | 
				
			||||||
 | 
					#define  X86_FPU_SHORT          0x1
 | 
				
			||||||
 | 
					#define  X86_FPU_LONG           0x2
 | 
				
			||||||
 | 
					#define  X86_FPU_FLOAT          0x3
 | 
				
			||||||
 | 
					#define  X86_FPU_DOUBLE         0x4
 | 
				
			||||||
 | 
					#define  X86_FPU_LDBL           0x5
 | 
				
			||||||
 | 
					#define  X86_FPU_BSD            0x6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define  X86_FPU_STKTOP  0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct x86_fpu_registers {
 | 
				
			||||||
 | 
					    struct x86_fpu_reg  x86_fpu_stack[8];
 | 
				
			||||||
 | 
					    int                 x86_fpu_flags;
 | 
				
			||||||
 | 
					    int                 x86_fpu_config;         /* rounding modes, etc. */
 | 
				
			||||||
 | 
					    short               x86_fpu_tos, x86_fpu_bos;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma	pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * There are two versions of the following macro.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * One version is for opcode D9, for which there are more than 32
 | 
				
			||||||
 | 
					 * instructions encoded in the second byte of the opcode.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The other version, deals with all the other 7 i87 opcodes, for
 | 
				
			||||||
 | 
					 * which there are only 32 strings needed to describe the
 | 
				
			||||||
 | 
					 * instructions.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* X86_FPU_SUPPORT */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
					# define DECODE_PRINTINSTR32(t,mod,rh,rl)     	\
 | 
				
			||||||
 | 
						DECODE_PRINTF(t[(mod<<3)+(rh)]);
 | 
				
			||||||
 | 
					# define DECODE_PRINTINSTR256(t,mod,rh,rl)    	\
 | 
				
			||||||
 | 
						DECODE_PRINTF(t[(mod<<6)+(rh<<3)+(rl)]);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					# define DECODE_PRINTINSTR32(t,mod,rh,rl)
 | 
				
			||||||
 | 
					# define DECODE_PRINTINSTR256(t,mod,rh,rl)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_FPU_REGS_H */
 | 
				
			||||||
							
								
								
									
										375
									
								
								src/include/x86emu/regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										375
									
								
								src/include/x86emu/regs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,375 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for x86 register definitions.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					/* $XFree86: xc/extras/x86emu/include/x86emu/regs.h,v 1.3 2001/10/28 03:32:25 tsi Exp $ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_REGS_H
 | 
				
			||||||
 | 
					#define __X86EMU_REGS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*---------------------- Macros and type definitions ----------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma pack(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * General EAX, EBX, ECX, EDX type registers.  Note that for
 | 
				
			||||||
 | 
					 * portability, and speed, the issue of byte swapping is not addressed
 | 
				
			||||||
 | 
					 * in the registers.  All registers are stored in the default format
 | 
				
			||||||
 | 
					 * available on the host machine.  The only critical issue is that the
 | 
				
			||||||
 | 
					 * registers should line up EXACTLY in the same manner as they do in
 | 
				
			||||||
 | 
					 * the 386.  That is:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * EAX & 0xff  === AL
 | 
				
			||||||
 | 
					 * EAX & 0xffff == AX
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * etc.  The result is that alot of the calculations can then be
 | 
				
			||||||
 | 
					 * done using the native instruction set fully.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef	__BIG_ENDIAN__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    u32 e_reg;
 | 
				
			||||||
 | 
						} I32_reg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						u16 filler0, x_reg;
 | 
				
			||||||
 | 
						} I16_reg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						u8 filler0, filler1, h_reg, l_reg;
 | 
				
			||||||
 | 
						} I8_reg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else /* !__BIG_ENDIAN__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    u32 e_reg;
 | 
				
			||||||
 | 
						} I32_reg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						u16 x_reg;
 | 
				
			||||||
 | 
						} I16_reg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						u8 l_reg, h_reg;
 | 
				
			||||||
 | 
						} I8_reg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* BIG_ENDIAN */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union {
 | 
				
			||||||
 | 
						I32_reg_t   I32_reg;
 | 
				
			||||||
 | 
						I16_reg_t   I16_reg;
 | 
				
			||||||
 | 
						I8_reg_t    I8_reg;
 | 
				
			||||||
 | 
						} i386_general_register;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct i386_general_regs {
 | 
				
			||||||
 | 
						i386_general_register A, B, C, D;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct i386_general_regs Gen_reg_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct i386_special_regs {
 | 
				
			||||||
 | 
						i386_general_register SP, BP, SI, DI, IP;
 | 
				
			||||||
 | 
						u32 FLAGS;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*  
 | 
				
			||||||
 | 
					 * Segment registers here represent the 16 bit quantities
 | 
				
			||||||
 | 
					 * CS, DS, ES, SS.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct i386_segment_regs {
 | 
				
			||||||
 | 
					    u16 CS, DS, SS, ES, FS, GS;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 8 bit registers */
 | 
				
			||||||
 | 
					#define R_AH  gen.A.I8_reg.h_reg
 | 
				
			||||||
 | 
					#define R_AL  gen.A.I8_reg.l_reg
 | 
				
			||||||
 | 
					#define R_BH  gen.B.I8_reg.h_reg
 | 
				
			||||||
 | 
					#define R_BL  gen.B.I8_reg.l_reg
 | 
				
			||||||
 | 
					#define R_CH  gen.C.I8_reg.h_reg
 | 
				
			||||||
 | 
					#define R_CL  gen.C.I8_reg.l_reg
 | 
				
			||||||
 | 
					#define R_DH  gen.D.I8_reg.h_reg
 | 
				
			||||||
 | 
					#define R_DL  gen.D.I8_reg.l_reg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 16 bit registers */
 | 
				
			||||||
 | 
					#define R_AX  gen.A.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_BX  gen.B.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_CX  gen.C.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_DX  gen.D.I16_reg.x_reg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 32 bit extended registers */
 | 
				
			||||||
 | 
					#define R_EAX  gen.A.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_EBX  gen.B.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_ECX  gen.C.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_EDX  gen.D.I32_reg.e_reg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* special registers */
 | 
				
			||||||
 | 
					#define R_SP  spc.SP.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_BP  spc.BP.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_SI  spc.SI.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_DI  spc.DI.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_IP  spc.IP.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_FLG spc.FLAGS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* special registers */
 | 
				
			||||||
 | 
					#define R_SP  spc.SP.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_BP  spc.BP.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_SI  spc.SI.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_DI  spc.DI.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_IP  spc.IP.I16_reg.x_reg
 | 
				
			||||||
 | 
					#define R_FLG spc.FLAGS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* special registers */
 | 
				
			||||||
 | 
					#define R_ESP  spc.SP.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_EBP  spc.BP.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_ESI  spc.SI.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_EDI  spc.DI.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_EIP  spc.IP.I32_reg.e_reg
 | 
				
			||||||
 | 
					#define R_EFLG spc.FLAGS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* segment registers */
 | 
				
			||||||
 | 
					#define R_CS  seg.CS
 | 
				
			||||||
 | 
					#define R_DS  seg.DS
 | 
				
			||||||
 | 
					#define R_SS  seg.SS
 | 
				
			||||||
 | 
					#define R_ES  seg.ES
 | 
				
			||||||
 | 
					#define R_FS  seg.FS
 | 
				
			||||||
 | 
					#define R_GS  seg.GS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* flag conditions   */
 | 
				
			||||||
 | 
					#define FB_CF 0x0001            /* CARRY flag  */
 | 
				
			||||||
 | 
					#define FB_PF 0x0004            /* PARITY flag */
 | 
				
			||||||
 | 
					#define FB_AF 0x0010            /* AUX  flag   */
 | 
				
			||||||
 | 
					#define FB_ZF 0x0040            /* ZERO flag   */
 | 
				
			||||||
 | 
					#define FB_SF 0x0080            /* SIGN flag   */
 | 
				
			||||||
 | 
					#define FB_TF 0x0100            /* TRAP flag   */
 | 
				
			||||||
 | 
					#define FB_IF 0x0200            /* INTERRUPT ENABLE flag */
 | 
				
			||||||
 | 
					#define FB_DF 0x0400            /* DIR flag    */
 | 
				
			||||||
 | 
					#define FB_OF 0x0800            /* OVERFLOW flag */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 80286 and above always have bit#1 set */
 | 
				
			||||||
 | 
					#define F_ALWAYS_ON  (0x0002)   /* flag bits always on */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Define a mask for only those flag bits we will ever pass back 
 | 
				
			||||||
 | 
					 * (via PUSHF) 
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* following bits masked in to a 16bit quantity */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define F_CF 0x0001             /* CARRY flag  */
 | 
				
			||||||
 | 
					#define F_PF 0x0004             /* PARITY flag */
 | 
				
			||||||
 | 
					#define F_AF 0x0010             /* AUX  flag   */
 | 
				
			||||||
 | 
					#define F_ZF 0x0040             /* ZERO flag   */
 | 
				
			||||||
 | 
					#define F_SF 0x0080             /* SIGN flag   */
 | 
				
			||||||
 | 
					#define F_TF 0x0100             /* TRAP flag   */
 | 
				
			||||||
 | 
					#define F_IF 0x0200             /* INTERRUPT ENABLE flag */
 | 
				
			||||||
 | 
					#define F_DF 0x0400             /* DIR flag    */
 | 
				
			||||||
 | 
					#define F_OF 0x0800             /* OVERFLOW flag */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TOGGLE_FLAG(flag)     	(M.x86.R_FLG ^= (flag))
 | 
				
			||||||
 | 
					#define SET_FLAG(flag)        	(M.x86.R_FLG |= (flag))
 | 
				
			||||||
 | 
					#define CLEAR_FLAG(flag)      	(M.x86.R_FLG &= ~(flag))
 | 
				
			||||||
 | 
					#define ACCESS_FLAG(flag)     	(M.x86.R_FLG & (flag))
 | 
				
			||||||
 | 
					#define CLEARALL_FLAG(m)    	(M.x86.R_FLG = 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CONDITIONAL_SET_FLAG(COND,FLAG) \
 | 
				
			||||||
 | 
					  if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define F_PF_CALC 0x010000      /* PARITY flag has been calced    */
 | 
				
			||||||
 | 
					#define F_ZF_CALC 0x020000      /* ZERO flag has been calced      */
 | 
				
			||||||
 | 
					#define F_SF_CALC 0x040000      /* SIGN flag has been calced      */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define F_ALL_CALC      0xff0000        /* All have been calced   */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Emulator machine state.
 | 
				
			||||||
 | 
					 * Segment usage control.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SYSMODE_SEG_DS_SS       0x00000001
 | 
				
			||||||
 | 
					#define SYSMODE_SEGOVR_CS       0x00000002
 | 
				
			||||||
 | 
					#define SYSMODE_SEGOVR_DS       0x00000004
 | 
				
			||||||
 | 
					#define SYSMODE_SEGOVR_ES       0x00000008
 | 
				
			||||||
 | 
					#define SYSMODE_SEGOVR_FS       0x00000010
 | 
				
			||||||
 | 
					#define SYSMODE_SEGOVR_GS       0x00000020
 | 
				
			||||||
 | 
					#define SYSMODE_SEGOVR_SS       0x00000040
 | 
				
			||||||
 | 
					#define SYSMODE_PREFIX_REPE     0x00000080
 | 
				
			||||||
 | 
					#define SYSMODE_PREFIX_REPNE    0x00000100
 | 
				
			||||||
 | 
					#define SYSMODE_PREFIX_DATA     0x00000200
 | 
				
			||||||
 | 
					#define SYSMODE_PREFIX_ADDR     0x00000400
 | 
				
			||||||
 | 
					#define SYSMODE_INTR_PENDING    0x10000000
 | 
				
			||||||
 | 
					#define SYSMODE_EXTRN_INTR      0x20000000
 | 
				
			||||||
 | 
					#define SYSMODE_HALTED          0x40000000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_CS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_DS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_ES      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_FS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_GS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_SS)
 | 
				
			||||||
 | 
					#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_CS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_DS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_ES      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_FS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_GS      | \
 | 
				
			||||||
 | 
											 SYSMODE_SEGOVR_SS      | \
 | 
				
			||||||
 | 
											 SYSMODE_PREFIX_DATA    | \
 | 
				
			||||||
 | 
											 SYSMODE_PREFIX_ADDR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define  INTR_SYNCH           0x1
 | 
				
			||||||
 | 
					#define  INTR_ASYNCH          0x2
 | 
				
			||||||
 | 
					#define  INTR_HALTED          0x4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    struct i386_general_regs    gen;
 | 
				
			||||||
 | 
					    struct i386_special_regs    spc;
 | 
				
			||||||
 | 
					    struct i386_segment_regs    seg;
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * MODE contains information on:
 | 
				
			||||||
 | 
					     *  REPE prefix             2 bits  repe,repne
 | 
				
			||||||
 | 
					     *  SEGMENT overrides       5 bits  normal,DS,SS,CS,ES
 | 
				
			||||||
 | 
					     *  Delayed flag set        3 bits  (zero, signed, parity)
 | 
				
			||||||
 | 
					     *  reserved                6 bits
 | 
				
			||||||
 | 
					     *  interrupt #             8 bits  instruction raised interrupt
 | 
				
			||||||
 | 
					     *  BIOS video segregs      4 bits  
 | 
				
			||||||
 | 
					     *  Interrupt Pending       1 bits  
 | 
				
			||||||
 | 
					     *  Extern interrupt        1 bits
 | 
				
			||||||
 | 
					     *  Halted                  1 bits
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    u32                         mode;
 | 
				
			||||||
 | 
					    volatile int                intr;   /* mask of pending interrupts */
 | 
				
			||||||
 | 
						int                         debug;
 | 
				
			||||||
 | 
					#ifdef DEBUG
 | 
				
			||||||
 | 
						int                         check;
 | 
				
			||||||
 | 
					    u16                         saved_ip;
 | 
				
			||||||
 | 
					    u16                         saved_cs;
 | 
				
			||||||
 | 
					    int                         enc_pos;
 | 
				
			||||||
 | 
					    int                         enc_str_pos;
 | 
				
			||||||
 | 
					    char                        decode_buf[32]; /* encoded byte stream  */
 | 
				
			||||||
 | 
					    char                        decoded_buf[256]; /* disassembled strings */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    u8                          intno;
 | 
				
			||||||
 | 
					    u8                          __pad[3];
 | 
				
			||||||
 | 
						} X86EMU_regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Structure maintaining the emulator machine state.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MEMBERS:
 | 
				
			||||||
 | 
					mem_base		- Base real mode memory for the emulator
 | 
				
			||||||
 | 
					abseg			- Base for the absegment
 | 
				
			||||||
 | 
					mem_size		- Size of the real mode memory block for the emulator
 | 
				
			||||||
 | 
					private			- private data pointer
 | 
				
			||||||
 | 
					x86			- X86 registers
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						unsigned long	mem_base;
 | 
				
			||||||
 | 
						unsigned long	mem_size;
 | 
				
			||||||
 | 
						unsigned long	abseg;
 | 
				
			||||||
 | 
						void*        	private;
 | 
				
			||||||
 | 
						X86EMU_regs		x86;
 | 
				
			||||||
 | 
						} X86EMU_sysEnv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*----------------------------- Global Variables --------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					extern "C" {            			/* Use "C" linkage when in C++ mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Global emulator machine state.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * We keep it global to avoid pointer dereferences in the code for speed.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern    X86EMU_sysEnv	_X86EMU_env;
 | 
				
			||||||
 | 
					#define   M             _X86EMU_env
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define X86_EAX M.x86.R_EAX
 | 
				
			||||||
 | 
					#define X86_EBX M.x86.R_EBX
 | 
				
			||||||
 | 
					#define X86_ECX M.x86.R_ECX
 | 
				
			||||||
 | 
					#define X86_EDX M.x86.R_EDX
 | 
				
			||||||
 | 
					#define X86_ESI M.x86.R_ESI
 | 
				
			||||||
 | 
					#define X86_EDI M.x86.R_EDI
 | 
				
			||||||
 | 
					#define X86_EBP M.x86.R_EBP
 | 
				
			||||||
 | 
					#define X86_EIP M.x86.R_EIP
 | 
				
			||||||
 | 
					#define X86_ESP M.x86.R_ESP
 | 
				
			||||||
 | 
					#define X86_EFLAGS M.x86.R_EFLG
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define X86_FLAGS M.x86.R_FLG
 | 
				
			||||||
 | 
					#define X86_AX M.x86.R_AX
 | 
				
			||||||
 | 
					#define X86_BX M.x86.R_BX
 | 
				
			||||||
 | 
					#define X86_CX M.x86.R_CX
 | 
				
			||||||
 | 
					#define X86_DX M.x86.R_DX
 | 
				
			||||||
 | 
					#define X86_SI M.x86.R_SI
 | 
				
			||||||
 | 
					#define X86_DI M.x86.R_DI
 | 
				
			||||||
 | 
					#define X86_BP M.x86.R_BP
 | 
				
			||||||
 | 
					#define X86_IP M.x86.R_IP
 | 
				
			||||||
 | 
					#define X86_SP M.x86.R_SP
 | 
				
			||||||
 | 
					#define X86_CS M.x86.R_CS
 | 
				
			||||||
 | 
					#define X86_DS M.x86.R_DS
 | 
				
			||||||
 | 
					#define X86_ES M.x86.R_ES
 | 
				
			||||||
 | 
					#define X86_SS M.x86.R_SS
 | 
				
			||||||
 | 
					#define X86_FS M.x86.R_FS
 | 
				
			||||||
 | 
					#define X86_GS M.x86.R_GS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define X86_AL M.x86.R_AL
 | 
				
			||||||
 | 
					#define X86_BL M.x86.R_BL
 | 
				
			||||||
 | 
					#define X86_CL M.x86.R_CL
 | 
				
			||||||
 | 
					#define X86_DL M.x86.R_DL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define X86_AH M.x86.R_AH
 | 
				
			||||||
 | 
					#define X86_BH M.x86.R_BH
 | 
				
			||||||
 | 
					#define X86_CH M.x86.R_CH
 | 
				
			||||||
 | 
					#define X86_DH M.x86.R_DH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					/*-------------------------- Function Prototypes --------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Function to log information at runtime */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//void	printk(const char *fmt, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					}                       			/* End of "C" linkage for C++   	*/
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_REGS_H */
 | 
				
			||||||
							
								
								
									
										89
									
								
								src/include/x86emu/types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/include/x86emu/types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for x86 emulator type definitions.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* $XFree86: xc/extras/x86emu/include/x86emu/types.h,v 1.4 2000/09/26 15:56:44 tsi Exp $ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_TYPES_H
 | 
				
			||||||
 | 
					#define __X86EMU_TYPES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//#ifndef IN_MODULE
 | 
				
			||||||
 | 
					//#include <sys/types.h>
 | 
				
			||||||
 | 
					//#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The following kludge is an attempt to work around typedef conflicts with
 | 
				
			||||||
 | 
					 * <sys/types.h>.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define u8   x86emuu8
 | 
				
			||||||
 | 
					#define u16  x86emuu16
 | 
				
			||||||
 | 
					#define u32  x86emuu32
 | 
				
			||||||
 | 
					#define u64  x86emuu64
 | 
				
			||||||
 | 
					#define s8   x86emus8
 | 
				
			||||||
 | 
					#define s16  x86emus16
 | 
				
			||||||
 | 
					#define s32  x86emus32
 | 
				
			||||||
 | 
					#define s64  x86emus64
 | 
				
			||||||
 | 
					#define uint x86emuuint
 | 
				
			||||||
 | 
					#define sint x86emusint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*---------------------- Macros and type definitions ----------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Currently only for Linux/32bit */
 | 
				
			||||||
 | 
					#if defined(__GNUC__) && !defined(NO_LONG_LONG)
 | 
				
			||||||
 | 
					#define __HAS_LONG_LONG__
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef unsigned char 		u8;
 | 
				
			||||||
 | 
					typedef unsigned short 		u16;
 | 
				
			||||||
 | 
					typedef unsigned int 		u32;
 | 
				
			||||||
 | 
					#ifdef __HAS_LONG_LONG__
 | 
				
			||||||
 | 
					typedef unsigned long long 	u64;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef char 				s8;
 | 
				
			||||||
 | 
					typedef short 				s16;
 | 
				
			||||||
 | 
					typedef int 				s32;
 | 
				
			||||||
 | 
					#ifdef __HAS_LONG_LONG__
 | 
				
			||||||
 | 
					typedef long long 			s64;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef unsigned int			uint;
 | 
				
			||||||
 | 
					typedef int 				sint;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef u16 X86EMU_pioAddr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif	/* __X86EMU_TYPES_H */
 | 
				
			||||||
							
								
								
									
										202
									
								
								src/include/x86emu/x86emu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								src/include/x86emu/x86emu.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,202 @@
 | 
				
			|||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*						Realmode X86 Emulator Library
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*            	Copyright (C) 1996-1999 SciTech Software, Inc.
 | 
				
			||||||
 | 
					* 				     Copyright (C) David Mosberger-Tang
 | 
				
			||||||
 | 
					* 					   Copyright (C) 1999 Egbert Eich
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  Permission to use, copy, modify, distribute, and sell this software and
 | 
				
			||||||
 | 
					*  its documentation for any purpose is hereby granted without fee,
 | 
				
			||||||
 | 
					*  provided that the above copyright notice appear in all copies and that
 | 
				
			||||||
 | 
					*  both that copyright notice and this permission notice appear in
 | 
				
			||||||
 | 
					*  supporting documentation, and that the name of the authors not be used
 | 
				
			||||||
 | 
					*  in advertising or publicity pertaining to distribution of the software
 | 
				
			||||||
 | 
					*  without specific, written prior permission.  The authors makes no
 | 
				
			||||||
 | 
					*  representations about the suitability of this software for any purpose.
 | 
				
			||||||
 | 
					*  It is provided "as is" without express or implied warranty.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
				
			||||||
 | 
					*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
				
			||||||
 | 
					*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
				
			||||||
 | 
					*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
 | 
				
			||||||
 | 
					*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
 | 
				
			||||||
 | 
					*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
				
			||||||
 | 
					*  PERFORMANCE OF THIS SOFTWARE.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					*  ========================================================================
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Language:		ANSI C
 | 
				
			||||||
 | 
					* Environment:	Any
 | 
				
			||||||
 | 
					* Developer:    Kendall Bennett
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Description:  Header file for public specific functions.
 | 
				
			||||||
 | 
					*               Any application linking against us should only
 | 
				
			||||||
 | 
					*               include this header
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					/* $XFree86: xc/extras/x86emu/include/x86emu.h,v 1.2 2000/11/21 23:10:25 tsi Exp $ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __X86EMU_X86EMU_H
 | 
				
			||||||
 | 
					#define __X86EMU_X86EMU_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* FIXME: undefine printk for the moment */
 | 
				
			||||||
 | 
					#ifdef LINUXBIOS_VERSION
 | 
				
			||||||
 | 
					#include "console/console.h"
 | 
				
			||||||
 | 
					#define printk printk_debug
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define printk printf
 | 
				
			||||||
 | 
					#endif 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef SCITECH
 | 
				
			||||||
 | 
					#include "scitech.h"
 | 
				
			||||||
 | 
					#define	X86API	_ASMAPI
 | 
				
			||||||
 | 
					#define	X86APIP	_ASMAPIP
 | 
				
			||||||
 | 
					typedef int X86EMU_pioAddr;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#include "types.h"
 | 
				
			||||||
 | 
					#define	X86API
 | 
				
			||||||
 | 
					#define	X86APIP	*
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#include "regs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*---------------------- Macros and type definitions ----------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma	pack(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Data structure containing ponters to programmed I/O functions used by the
 | 
				
			||||||
 | 
					emulator. This is used so that the user program can hook all programmed
 | 
				
			||||||
 | 
					I/O for the emulator to handled as necessary by the user program. By
 | 
				
			||||||
 | 
					default the emulator contains simple functions that do not do access the
 | 
				
			||||||
 | 
					hardware in any way. To allow the emualtor access the hardware, you will
 | 
				
			||||||
 | 
					need to override the programmed I/O functions using the X86EMU_setupPioFuncs
 | 
				
			||||||
 | 
					function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HEADER:
 | 
				
			||||||
 | 
					x86emu.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MEMBERS:
 | 
				
			||||||
 | 
					inb		- Function to read a byte from an I/O port
 | 
				
			||||||
 | 
					inw		- Function to read a word from an I/O port
 | 
				
			||||||
 | 
					inl     - Function to read a dword from an I/O port
 | 
				
			||||||
 | 
					outb	- Function to write a byte to an I/O port
 | 
				
			||||||
 | 
					outw    - Function to write a word to an I/O port
 | 
				
			||||||
 | 
					outl    - Function to write a dword to an I/O port
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						u8  	(X86APIP inb)(X86EMU_pioAddr addr);
 | 
				
			||||||
 | 
						u16 	(X86APIP inw)(X86EMU_pioAddr addr);
 | 
				
			||||||
 | 
						u32 	(X86APIP inl)(X86EMU_pioAddr addr);
 | 
				
			||||||
 | 
						void 	(X86APIP outb)(X86EMU_pioAddr addr, u8 val);
 | 
				
			||||||
 | 
						void 	(X86APIP outw)(X86EMU_pioAddr addr, u16 val);
 | 
				
			||||||
 | 
						void 	(X86APIP outl)(X86EMU_pioAddr addr, u32 val);
 | 
				
			||||||
 | 
						} X86EMU_pioFuncs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					REMARKS:
 | 
				
			||||||
 | 
					Data structure containing ponters to memory access functions used by the
 | 
				
			||||||
 | 
					emulator. This is used so that the user program can hook all memory
 | 
				
			||||||
 | 
					access functions as necessary for the emulator. By default the emulator
 | 
				
			||||||
 | 
					contains simple functions that only access the internal memory of the
 | 
				
			||||||
 | 
					emulator. If you need specialised functions to handle access to different
 | 
				
			||||||
 | 
					types of memory (ie: hardware framebuffer accesses and BIOS memory access
 | 
				
			||||||
 | 
					etc), you will need to override this using the X86EMU_setupMemFuncs
 | 
				
			||||||
 | 
					function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					HEADER:
 | 
				
			||||||
 | 
					x86emu.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MEMBERS:
 | 
				
			||||||
 | 
					rdb		- Function to read a byte from an address
 | 
				
			||||||
 | 
					rdw		- Function to read a word from an address
 | 
				
			||||||
 | 
					rdl     - Function to read a dword from an address
 | 
				
			||||||
 | 
					wrb		- Function to write a byte to an address
 | 
				
			||||||
 | 
					wrw    	- Function to write a word to an address
 | 
				
			||||||
 | 
					wrl    	- Function to write a dword to an address
 | 
				
			||||||
 | 
					****************************************************************************/
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
						u8  	(X86APIP rdb)(u32 addr);
 | 
				
			||||||
 | 
						u16 	(X86APIP rdw)(u32 addr);
 | 
				
			||||||
 | 
						u32 	(X86APIP rdl)(u32 addr);
 | 
				
			||||||
 | 
						void 	(X86APIP wrb)(u32 addr, u8 val);
 | 
				
			||||||
 | 
						void 	(X86APIP wrw)(u32 addr, u16 val);
 | 
				
			||||||
 | 
						void	(X86APIP wrl)(u32 addr, u32 val);
 | 
				
			||||||
 | 
						} X86EMU_memFuncs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/****************************************************************************
 | 
				
			||||||
 | 
					  Here are the default memory read and write
 | 
				
			||||||
 | 
					  function in case they are needed as fallbacks.
 | 
				
			||||||
 | 
					***************************************************************************/
 | 
				
			||||||
 | 
					extern u8 X86API rdb(u32 addr);
 | 
				
			||||||
 | 
					extern u16 X86API rdw(u32 addr);
 | 
				
			||||||
 | 
					extern u32 X86API rdl(u32 addr);
 | 
				
			||||||
 | 
					extern void X86API wrb(u32 addr, u8 val);
 | 
				
			||||||
 | 
					extern void X86API wrw(u32 addr, u16 val);
 | 
				
			||||||
 | 
					extern void X86API wrl(u32 addr, u32 val);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					#pragma	pack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*--------------------- type definitions -----------------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (X86APIP X86EMU_intrFuncs)(int num);
 | 
				
			||||||
 | 
					extern X86EMU_intrFuncs _X86EMU_intrTab[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*-------------------------- Function Prototypes --------------------------*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					extern "C" {            			/* Use "C" linkage when in C++ mode */
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void 	X86EMU_setupMemFuncs(X86EMU_memFuncs *funcs);
 | 
				
			||||||
 | 
					void 	X86EMU_setupPioFuncs(X86EMU_pioFuncs *funcs);
 | 
				
			||||||
 | 
					void 	X86EMU_setupIntrFuncs(X86EMU_intrFuncs funcs[]);
 | 
				
			||||||
 | 
					void 	X86EMU_prepareForInt(int num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* decode.c */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void 	X86EMU_exec(void);
 | 
				
			||||||
 | 
					void 	X86EMU_halt_sys(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef	DEBUG
 | 
				
			||||||
 | 
					#define	HALT_SYS()	\
 | 
				
			||||||
 | 
					    	printk("halt_sys: file %s, line %d\n", __FILE__, __LINE__);	\
 | 
				
			||||||
 | 
						X86EMU_halt_sys();
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define	HALT_SYS()	X86EMU_halt_sys()
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Debug options */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEBUG_DECODE_F          0x000001 /* print decoded instruction  */
 | 
				
			||||||
 | 
					#define DEBUG_TRACE_F           0x000002 /* dump regs before/after execution */
 | 
				
			||||||
 | 
					#define DEBUG_STEP_F            0x000004
 | 
				
			||||||
 | 
					#define DEBUG_DISASSEMBLE_F     0x000008
 | 
				
			||||||
 | 
					#define DEBUG_BREAK_F           0x000010
 | 
				
			||||||
 | 
					#define DEBUG_SVC_F             0x000020
 | 
				
			||||||
 | 
					#define DEBUG_FS_F              0x000080
 | 
				
			||||||
 | 
					#define DEBUG_PROC_F            0x000100
 | 
				
			||||||
 | 
					#define DEBUG_SYSINT_F          0x000200 /* bios system interrupts. */
 | 
				
			||||||
 | 
					#define DEBUG_TRACECALL_F       0x000400
 | 
				
			||||||
 | 
					#define DEBUG_INSTRUMENT_F      0x000800
 | 
				
			||||||
 | 
					#define DEBUG_MEM_TRACE_F       0x001000 
 | 
				
			||||||
 | 
					#define DEBUG_IO_TRACE_F        0x002000 
 | 
				
			||||||
 | 
					#define DEBUG_TRACECALL_REGS_F  0x004000
 | 
				
			||||||
 | 
					#define DEBUG_DECODE_NOPRINT_F  0x008000 
 | 
				
			||||||
 | 
					#define DEBUG_SAVE_IP_CS_F      0x010000
 | 
				
			||||||
 | 
					#define DEBUG_SYS_F             (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void 	X86EMU_trace_regs(void);
 | 
				
			||||||
 | 
					void 	X86EMU_trace_xregs(void);
 | 
				
			||||||
 | 
					void 	X86EMU_dump_memory(u16 seg, u16 off, u32 amt);
 | 
				
			||||||
 | 
					int 	X86EMU_trace_on(void);
 | 
				
			||||||
 | 
					int 	X86EMU_trace_off(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef  __cplusplus
 | 
				
			||||||
 | 
					}                       			/* End of "C" linkage for C++   	*/
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __X86EMU_X86EMU_H */
 | 
				
			||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
uses CONFIG_IDE
 | 
					uses CONFIG_IDE
 | 
				
			||||||
uses CONFIG_LEGACY_VGABIOS
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
object mc146818rtc.o
 | 
					object mc146818rtc.o
 | 
				
			||||||
object isa-dma.o
 | 
					object isa-dma.o
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user