I\'ve ported my library x86Lib to mbed. It fully emulates the 8086 processor, but a few things I\'m still working on. Notable missing things are interrupts. Previously I used exceptions for interrupts, but exceptions aren\'t supported with the mbed compiler. It is also quite slow

Dependents:   x86Lib_Tester

Files at this revision

API Documentation at this revision

Comitter:
earlz
Date:
Sun Mar 04 08:15:47 2012 +0000
Commit message:

Changed in this revision

device_manager.cpp Show annotated file Show diff for this revision Revisions of this file
include/config.h Show annotated file Show diff for this revision Revisions of this file
include/opcode_def.h Show annotated file Show diff for this revision Revisions of this file
include/x86Lib.h Show annotated file Show diff for this revision Revisions of this file
include/x86Lib_internal.h Show annotated file Show diff for this revision Revisions of this file
ops/etc.cpp Show annotated file Show diff for this revision Revisions of this file
ops/flags.cpp Show annotated file Show diff for this revision Revisions of this file
ops/flow.cpp Show annotated file Show diff for this revision Revisions of this file
ops/groups.cpp Show annotated file Show diff for this revision Revisions of this file
ops/maths.cpp Show annotated file Show diff for this revision Revisions of this file
ops/store.cpp Show annotated file Show diff for this revision Revisions of this file
ops/strings.cpp Show annotated file Show diff for this revision Revisions of this file
x86Lib.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 217a7931b41f device_manager.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/device_manager.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,252 @@
+/**
+Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <iostream>
+#include <list>
+#include <stdlib.h>
+#include <stdio.h>
+#include <cstring>
+#include <x86Lib.h>
+
+
+namespace x86Lib{
+//The lack of indentation for namespaces is intentional...
+using namespace std;
+
+MemorySystem::MemorySystem()
+{
+    locked=0;
+}
+/**Because we must resize the list with realloc, we use malloc through out this for safety.**/
+void MemorySystem::Add(uint32_t low,uint32_t high,MemoryDevice *memdev){
+    DeviceRange_t device;
+    
+    /* Check For Overlapping Addresses */
+    Serial pc(USBTX, USBRX); // tx, rx
+    pc.printf("memorysystem add\n");
+    for(unsigned int i = 0; i < memorySystemVector.size(); i++)
+    {
+        device = memorySystemVector[i];
+        
+        if( device.high <= high && 
+            device.low >= low )
+        {
+            pc.printf("System_excp\n");
+            exit(1);
+        }
+    }
+    pc.printf("high: 0x%x low: 0x%x\n",high,low);
+    device.high = high;
+    device.low = low;
+    device.memdev = memdev;
+    
+    /* Place Device in Memory System Vector */
+    memorySystemVector.push_back( device );
+}
+
+void MemorySystem::Remove(uint32_t low,uint32_t high)
+{
+    
+}
+    
+void MemorySystem::Remove(MemoryDevice *memdev)
+{
+}
+void MemorySystem::Read(uint32_t address,int size,void *b)
+{
+    uint32_t* buffer=(uint32_t*)b;
+    DeviceRange_t device;
+    
+    if(size == 0)
+    {
+        return;
+    }
+        
+    size--;
+        
+    for(unsigned int i = 0; i < memorySystemVector.size(); i++)
+    {
+        device = memorySystemVector[i];
+        if(device.low <= address && 
+           device.high >= address)
+        {
+            //we found a region matching.
+            if( (address + size) > device.high )
+            {
+                //One device range will not cover the whole request.
+                device.memdev->Read(address, device.high - address + 1, buffer);
+                size -= device.high - address;
+                
+                buffer += device.high - address + 1; //bug?
+                
+                address += device.high - address + 1;
+                Read( address, size+1 , buffer );
+            }
+            else
+            {
+                //correct absolute address to a relative one
+                address-=device.low;
+                device.memdev->Read(address, size + 1, buffer);
+            }
+            return;
+        }
+    }
+    Onx86LibError();
+    //throw Mem_excp(address);
+}
+
+
+
+void MemorySystem::Write(uint32_t address,int size,void *b)
+{
+    uint32_t *buffer=(uint32_t*)b;
+    DeviceRange_t device;
+        
+    if( size==0 )
+    {
+        return;
+    }
+        
+    size--;
+        
+    for( unsigned int i = 0; i < memorySystemVector.size(); i++ )
+    {
+        device = memorySystemVector[i];
+        
+        if(device.low <= address && 
+           device.high >= address)
+        {
+            //we found a region matching.
+            if( (address + size) > device.high)
+            {
+                //One device range will not cover the whole request.
+                device.memdev->Write(address, device.high - address + 1, buffer);
+                
+                size -= device.high - address;
+                
+                buffer += device.high - address;
+
+                address += device.high - address + 1;
+                
+                Write(address , size + 1, buffer);            
+            }
+            else
+            {
+                //correct absolute address to a relative one
+                address-=device.low;
+                device.memdev->Write(address,size+1,buffer);
+            }
+            return;
+        }
+    }
+    Onx86LibError();
+    //throw Mem_excp(address);
+}
+
+int  MemorySystem::RangeFree(uint32_t low,uint32_t high)
+{
+    return 1;
+}
+
+
+
+PortSystem::PortSystem(){
+    count=0;
+    //list=NULL;
+}
+void PortSystem::Add(uint16_t low,uint16_t high,PortDevice *portdev){
+    int i;
+    for(i=0;i<count;i++){
+        if(list[i].high<=high && list[i].low>=low){
+            Onx86LibError();
+            //throw new System_excp();
+        }
+    }
+    if(count==0){
+        list=(DeviceRange_t*)malloc(sizeof(DeviceRange_t)*1);
+        //count++;
+    }else{
+        void *t=list;
+        list=(DeviceRange_t*)realloc(list,sizeof(DeviceRange_t)*count+1);
+        if(list==NULL){
+            list=(DeviceRange_t*)t; //restore old pointer so we can free it
+            Onx86LibError();
+            //throw Default_excp(__FILE__,__FUNCTION__,__LINE__);
+        }
+        //count++;
+    }
+    list[count].high=high;
+    list[count].low=low;
+    list[count].portdev=portdev;
+    count++;
+}
+
+
+
+void PortSystem::Read(uint16_t address,int size,void *buffer){
+    int i;
+    if(size==0){return;}
+    size=size-1;
+    for(i=0;i<count;i++){
+        if(list[i].low<=address && list[i].high>=address){
+            //we found a region matching.
+            list[i].portdev->Read(address,size+1,buffer);
+            return;
+        }
+    }
+    Onx86LibError();
+    //throw Mem_excp(address);
+}
+
+
+
+void PortSystem::Write(uint16_t address,int size,void *buffer){
+    int i;
+    if(size==0){return;}
+    size=size-1;
+    for(i=0;i<count;i++){
+        if(list[i].low<=address && list[i].high>=address){
+                list[i].portdev->Write(address,size+1,buffer);
+            return;
+        }
+    }
+    Onx86LibError();
+    //throw Mem_excp(address);
+}
+
+void Remove(uint16_t low,uint16_t high){}
+void Remove(PortDevice *portdev){}
+int RangeFree(uint32_t low,uint32_t high){return 1;}
+
+
+
+
+};
+
diff -r 000000000000 -r 217a7931b41f include/config.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/config.h	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,85 @@
+/**
+Copyright (c) 2007 - 2010 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#ifndef CONFIG_H
+#define CONFIG_H
+
+//#define SAFE_MODE //This should be set if debugging, or if there are
+//mysterious errors... This should be disabled in release builds so that it is faster
+//static const bool Default_A20=1;
+
+//#define ENABLE_OPCODE_CALLBACK //warning! Bug when this is enabled and a callback is not assigned! 
+/**Define this for a callback to be available for EachOpcode. This callback will be called
+   after every opcode executed. This slows down the main loop so only enable if needed!**/
+
+#ifdef __i386__
+//#define USE_NATIVE //This means to optimize by using native assembly when available...
+#endif
+
+//#define STRICT_OPCODES //This should be defined if strict opcode errors should be used...this may slow down the CPU however
+
+//#define X86_MULTITHREADING //This should be defined to enable multi-threading optimizations(note, these will break most single thread implementations)
+
+//#define ENABLE_OPCODE_CALLBACK //provide a callback for each time an opcode is executed. Useful for debugging 8086 programs
+
+#define NEW_API_11
+/**This is the option to use the "new" API for version 1.1.x
+   This is for using the MemorySystem and MemoryDevice classes**/
+
+
+
+#endif
+
+/**Locked Memory Access Description
+Ok, for this new multi CPU capable branch, memory locking has been added.
+The PhysMemory now has Lock, Unlock, and IsLocked member functions, and it has
+a new variable in it called locked (of type uint32_t)
+Also, at the end of Readxxxx and Writexxxx functions, there is now a new variable
+named locked_access (with a default value of 0) If this value is 1, then memory
+access should be granted, even though the memory is locked. This basically means
+that the memory request is coming from the current CPU which holds the lock.
+
+In most implementations, (unless the X86_MULTITHREADING define is used) the CPU
+will check IsLocked and if the memory is already locked(which in most cases, it
+actually shouldn't be) then it will break from the currently executing instruction
+so that if another CPU holds the lock, it will be able to get to the next CPU in
+single threaded implementations.
+
+For PhysMemory preaccess lock checks, basically, what should be attached at the first of all
+Readxxxx and Writexxxx functions is
+	if(locked_access==0){
+		while(locked>0){}
+	}
+so that if the busmaster is no trying to access memory, and the memory is locked,
+then it will halt access until the lock is repelled. (note the infinite loop should never
+be got to in single-threaded implementations
+**/
+
+
+
diff -r 000000000000 -r 217a7931b41f include/opcode_def.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/opcode_def.h	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,567 @@
+/**
+Copyright (c) 2007 - 2010 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+
+/**This file contains the opcode function definitions and prototypes for x86CPU**/
+
+/**NOTE! this is included INSIDE of a class, so this file is somewhat limited...**/
+uint8_t Add8(uint8_t,uint8_t);
+uint16_t Add16(uint16_t,uint16_t);
+uint8_t Sub8(uint8_t,uint8_t);
+uint16_t Sub16(uint16_t,uint16_t);
+uint8_t And8(uint8_t,uint8_t);
+uint16_t And16(uint16_t,uint16_t);
+uint8_t Or8(uint8_t,uint8_t);
+uint16_t Or16(uint16_t,uint16_t);
+uint8_t Xor8(uint8_t,uint8_t);
+uint16_t Xor16(uint16_t,uint16_t);
+uint8_t ShiftLogicalRight8(uint8_t,uint8_t);
+uint16_t ShiftLogicalRight16(uint16_t,uint8_t);
+uint8_t ShiftArithmeticRight8(uint8_t,uint8_t);
+uint16_t ShiftArithmeticRight16(uint16_t,uint8_t);
+uint8_t ShiftLogicalLeft8(uint8_t,uint8_t);
+uint16_t ShiftLogicalLeft16(uint16_t,uint8_t);
+uint8_t RotateRight8(uint8_t,uint8_t);
+uint16_t RotateRight16(uint16_t,uint8_t);
+uint8_t RotateLeft8(uint8_t,uint8_t);
+uint16_t RotateLeft16(uint16_t,uint8_t);
+uint8_t RotateCarryRight8(uint8_t,uint8_t);
+uint16_t RotateCarryRight16(uint16_t,uint8_t);
+uint8_t RotateCarryLeft8(uint8_t,uint8_t);
+uint16_t RotateCarryLeft16(uint16_t,uint8_t);
+
+
+void InstallOp(uint8_t,opcode,uint32_t=CPU086);
+void InitOpcodes();
+/*
+uint8_t ReadByte(uint8_t seg,uint32_t offset);
+uint16_t ReadWord(uint8_t seg,uint32_t offset);
+uint32_t ReadDword(uint8_t seg,uint32_t offset);
+
+void WriteByte(uint8_t seg,uint32_t offset,uint8_t data);
+void WriteWord(uint8_t seg,uint32_t offset,uint16_t data);
+void WriteDword(uint8_t seg,uint32_t offset,uint32_t data);
+*/
+
+
+
+
+
+void op16_unknown();
+void op16_mov_r8_imm8(); //Tested, pass #1;
+void op16_hlt(); //Tested, pass #1;
+void op16_nop(); //Tested, pass #1;
+void op16_mov_r16_imm16(); //Tested, pass #1;
+void op16_jmp_rel8(); //Tested, pass #1;
+void op16_sub_al_imm8(); //Tested, pass #1;
+void op16_sub_ax_imm16(); //Tested, pass #1;
+void op16_ja_rel8();
+void op16_jnc_rel8();
+void op16_jbe_rel8();
+void op16_jc_rel8(); //Tested, pass #1;
+void op16_jz_rel8(); //Tested, pass #1;
+void op16_jnz_rel8(); //Tested, pass #1;
+void op16_jp_rel8(); //Tested, pass #1;
+void op16_jnp_rel8(); //Tested, pass #1;
+void op16_jg_rel8(); //Tested, pass #1;
+void op16_jge_rel8();
+void op16_jle_rel8();
+void op16_jl_rel8(); //Tested, pass #1;
+void op16_jo_rel8();
+void op16_jno_rel8();
+void op16_js_rel8();
+void op16_jns_rel8();
+void op16_mov_sr_rm16(); //Tested, pass #1;
+void op16_mov_rm16_sr(); //Tested, pass #1;
+void op16_pop_r16(); //Tested, pass #1;
+void op16_push_imm16(); //Tested, pass #1;
+void op16_push_r16(); //Tested, pass #1;
+void op16_push_es(); //Tested, pass #1;
+void op16_push_cs(); //Tested, pass #1;
+void op16_push_ss(); //Tested, pass #1;
+void op16_push_ds(); //Tested, pass #1;
+void op16_pop_es(); //Tested, pass #1;
+void op16_pop_ss(); //Tested, pass #1;
+void op16_pop_ds(); //Tested, pass #1;
+void op16_mov_r16_rm16(); //Tested, pass #1;
+void op16_mov_rm16_r16(); //Tested, pass #1;
+void op16_call_rel16(); //Tested, pass #1;
+void op16_retn(); //Tested, pass #1;
+void op16_loop_rel8(); //Tested, pass #1;
+void op16_pre_cs_override(); //Tested, pass #1;
+void op16_pre_ds_override(); //Tested, pass #1;
+void op16_pre_es_override(); //Tested, pass #1;
+void op16_pre_ss_override(); //Tested, pass #1;
+void op16_movsw(); //Tested, pass #1;
+void op16_movsb(); //Tested, pass #1;
+void op16_clc();
+void op16_cld(); //Tested, pass #1;
+void op16_cli(); //Tested, pass #1;
+void op16_stc();
+void op16_std(); //Tested, pass #1;
+void op16_sti(); //Tested, pass #1;
+void op16_rep(); //Tested, pass #1;(only rep, not conditionals)
+void op16_out_imm8_al(); //Tested, pass #1;
+void op16_out_imm8_ax(); //Tested, pass #1;
+void op16_call_imm16_imm16(); //Tested, pass #1;
+void op16_retf(); //Tested, pass #1;
+void op16_int_imm8(); //Tested, pass #1;
+void op16_iret(); //Tested, pass #1;
+void op16_into();
+void op16_int3();
+void op16_in_al_imm8();
+void op16_in_ax_imm8();
+void op16_add_al_imm8(); //Tested, pass #1;
+void op16_add_ax_imm8(); //Tested, pass #1;
+void op16_sub_rm8_r8(); //Tested, pass #1;
+void op16_group_80(); //Tested, pass #1;
+void op16_sub_r8_rm8();
+void op16_sub_rm16_r16();
+void op16_sub_r16_rm16();
+void op16_group_81(); //Tested, pass #1;
+void op16_add_rm8_r8();
+void op16_add_rm16_r16();
+void op16_add_r8_rm8();
+void op16_add_r16_rm16();
+void op16_mov_al_off8();
+void op16_mov_ax_off16();
+void op16_mov_rm8_r8();
+void op16_mov_r8_rm8();
+void op16_mov_off8_al(); //Tested, pass #1;
+void op16_mov_off16_ax(); //Tested, pass #1;
+void op16_mov_m8_imm8(); //Tested, pass #1;
+void op16_mov_m16_imm16();  //Tested, pass #1;//currently have 85 instructions or prefixes implemented(actually more, not counting group instructions)
+void op16_cmp_rm8_r8();
+void op16_cmp_rm16_r16();
+void op16_cmp_r8_rm8();
+void op16_cmp_r16_rm16();
+void op16_cmp_al_imm8(); //Tested, pass #1;
+void op16_cmp_ax_imm16(); //Tested, pass #1;
+void op16_group_83(); //Tested, pass #1;
+void op16_jmp_rel16(); //Tested, pass #1
+void op16_jmp_imm16_imm16(); //Tested, pass #1
+void op16_group_FF();
+void op16_push_imm8();
+void op16_group_8F();
+void op16_salc(); //Undocumented -- Set AL on Carry
+void op16_cmc();
+void op16_cbw();
+void op16_aaa();
+void op16_daa();
+void op16_das();
+void op16_aas();
+void op16_aad();
+void op16_aam();
+void op16_inc_r16();
+void op16_dec_r16();
+void op16_group_FE();
+void op16_group_F6();
+void op16_group_F7();
+void op16_cwd();
+void op16_and_rm8_r8();
+void op16_and_rm16_r16();
+void op16_and_r8_rm8();
+void op16_and_r16_rm16();
+void op16_and_al_imm8();
+void op16_and_ax_imm16();
+void op16_or_rm8_r8();
+void op16_or_rm16_r16();
+void op16_or_r8_rm8();
+void op16_or_r16_rm16();
+void op16_or_al_imm8();
+void op16_or_ax_imm16();
+void op16_escape();
+void op16_cmpsb(); //Tested, pass #1, full
+void op16_cmpsw(); //tested, pass #1, full
+void op16_jcxz_rel8();
+void op16_adc_al_imm8();
+void op16_adc_ax_imm8();
+void op16_adc_rm8_r8();
+void op16_adc_rm16_r16();
+void op16_adc_r8_rm8();
+void op16_adc_r16_rm16();
+void op16_lahf();
+void op16_sahf();
+void op16_loope_rel8();
+void op16_loopne_rel8();
+void op16_lds();
+void op16_les();
+void op16_lea();
+void op16_lock(); //funcitonally does nothing...
+void op16_xor_rm8_r8();
+void op16_xor_rm16_r16();
+void op16_xor_r8_rm8();
+void op16_xor_r16_rm16();
+void op16_xor_al_imm8();
+void op16_xor_ax_imm16();
+void op16_sbb_rm8_r8();
+void op16_sbb_rm16_r16();
+void op16_sbb_r8_rm8();
+void op16_sbb_r16_rm16();
+void op16_sbb_al_imm8();
+void op16_sbb_ax_imm16();
+void op16_test_al_imm8();
+void op16_test_ax_imm16();
+void op16_test_rm8_r8();
+void op16_test_rm16_r16();
+void op16_xchg_rm8_r8();
+void op16_xchg_rm16_r16();
+void op16_xchg_ax_r16();
+void op16_group_D2();
+void op16_group_D3();
+void op16_group_D0();
+void op16_group_D1();
+void op16_lodsb();
+void op16_lodsw();
+void op16_scasb();
+void op16_scasw();
+void op16_stosb();
+void op16_stosw();
+void op16_wait();
+void op16_xlatb();
+
+void op16_in_al_dx();
+void op16_in_ax_dx();
+void op16_out_dx_al();
+void op16_out_dx_ax();
+
+
+
+
+//Oh God how I hate prototyping and adding the opcodes to the master InstallOp list...
+
+
+
+
+/**Group Include Functions(not direct opcodes)**/
+void op16_sub_rm8_imm8(ModRM16&); //group 0x80 /5
+void op16_sub_rm16_imm16(ModRM16&);
+void op16_add_rm8_imm8(ModRM16&);
+void op16_add_rm16_imm16(ModRM16&);
+void op16_cmp_rm8_imm8(ModRM16&); //Tested, pass #1
+void op16_cmp_rm16_imm16(ModRM16&);
+void op16_sub_rm16_imm8(ModRM16&);
+void op16_add_rm16_imm8(ModRM16&);
+void op16_cmp_rm16_imm8(ModRM16&); //Tested, pass #1
+void op16_jmp_rm16(ModRM16&); //Tested, pass #1
+void op16_jmp_m16_m16(ModRM16&); //Tested, pass #1
+void op16_push_m16(ModRM16&);
+void op16_pop_m16(ModRM16&);
+void op16_inc_rm8(ModRM16&);
+void op16_inc_rm16(ModRM16&);
+void op16_dec_rm8(ModRM16&);
+void op16_dec_rm16(ModRM16&);
+void op16_div_rm8(ModRM16 &rm);//Tested, pass #1
+void op16_div_rm16(ModRM16 &rm);//Tested, pass #1
+void op16_idiv_rm8(ModRM16 &rm);//Tested, pass #1
+void op16_idiv_rm16(ModRM16 &rm);//Tested, pass #1
+void op16_mul_rm8(ModRM16 &rm);//Tested, pass #1
+void op16_mul_rm16(ModRM16 &rm);//Tested, pass #1
+void op16_imul_rm8(ModRM16 &rm);
+void op16_imul_rm16(ModRM16 &rm);
+void op16_and_rm8_imm8(ModRM16 &rm);
+void op16_and_rm16_imm16(ModRM16 &rm);
+void op16_and_rm16_imm8(ModRM16 &rm);
+void op16_or_rm8_imm8(ModRM16& rm);
+void op16_or_rm16_imm16(ModRM16 &rm);
+void op16_or_rm16_imm8(ModRM16 &rm);
+void op16_adc_rm8_imm8(ModRM16&);
+void op16_adc_rm16_imm16(ModRM16&);
+void op16_adc_rm16_imm8(ModRM16&);
+void op16_neg_rm16(ModRM16&);
+void op16_neg_rm8(ModRM16&);
+void op16_xor_rm8_imm8(ModRM16& rm);
+void op16_xor_rm16_imm16(ModRM16 &rm);
+void op16_xor_rm16_imm8(ModRM16 &rm);
+void op16_sbb_rm8_imm8(ModRM16 &rm);
+void op16_sbb_rm16_imm16(ModRM16 &rm);
+void op16_sbb_rm16_imm8(ModRM16 &rm);
+void op16_test_rm8_imm8(ModRM16 &rm);
+void op16_test_rm16_imm16(ModRM16 &rm);
+void op16_test_rm16_imm8(ModRM16 &rm); /**This needs to be added**/
+void op16_shr_rm8_cl(ModRM16 &rm);
+void op16_shr_rm16_cl(ModRM16 &rm);
+void op16_sar_rm8_cl(ModRM16 &rm);
+void op16_sar_rm16_cl(ModRM16 &rm);
+void op16_shl_rm8_cl(ModRM16 &rm);
+void op16_shl_rm16_cl(ModRM16 &rm);
+void op16_rol_rm8_cl(ModRM16 &rm);
+void op16_rol_rm16_cl(ModRM16 &rm);
+void op16_ror_rm8_cl(ModRM16 &rm);
+void op16_ror_rm16_cl(ModRM16 &rm);
+void op16_rcl_rm8_cl(ModRM16 &rm);
+void op16_rcl_rm16_cl(ModRM16 &rm);
+void op16_rcr_rm8_cl(ModRM16 &rm);
+void op16_rcr_rm16_cl(ModRM16 &rm);
+void op16_shr_rm8_1(ModRM16 &rm);
+void op16_shr_rm16_1(ModRM16 &rm);
+void op16_sar_rm8_1(ModRM16 &rm);
+void op16_sar_rm16_1(ModRM16 &rm);
+void op16_shl_rm8_1(ModRM16 &rm);
+void op16_shl_rm16_1(ModRM16 &rm);
+void op16_rol_rm8_1(ModRM16 &rm);
+void op16_rol_rm16_1(ModRM16 &rm);
+void op16_ror_rm8_1(ModRM16 &rm);
+void op16_ror_rm16_1(ModRM16 &rm);
+void op16_rcl_rm8_1(ModRM16 &rm);
+void op16_rcl_rm16_1(ModRM16 &rm);
+void op16_rcr_rm8_1(ModRM16 &rm);
+void op16_rcr_rm16_1(ModRM16 &rm);
+void op16_not_rm8(ModRM16 &rm);
+void op16_not_rm16(ModRM16 &rm);
+void op16_call_rm16(ModRM16 &rm);
+void op16_call_rm16_rm16(ModRM16 &rm);
+
+
+
+void Push16(uint16_t val){
+    *regs16[SP]-=2;
+    WriteWord(cSS,*regs16[SP],val);
+}
+uint16_t Pop16(){
+    uint16_t register tmp;
+    tmp=ReadWord(cSS,*regs16[SP]);
+    *regs16[SP]+=2;
+    return tmp;
+}
+
+
+inline void SetIndex8(){ //this just makes my code look better...
+    if(freg.df==0){
+        (*regs16[SI])++;
+        (*regs16[DI])++;
+    }else{
+        (*regs16[SI])--;
+        (*regs16[DI])--;
+    }
+}
+
+inline void SetIndex16(){
+    if(freg.df==0){
+        (*regs16[SI])+=2;
+        (*regs16[DI])+=2;
+    }else{
+        (*regs16[SI])-=2;
+        (*regs16[DI])-=2;
+    }
+}
+
+inline void CalculatePF8(uint8_t val){
+    unsigned int i;
+    unsigned int count=0;
+    for(i=0;i<=7;i++){
+        if((val&((1<<i)))!=0){count++;}
+    }
+    if((count%2)==0){freg.pf=1;}else{freg.pf=0;}
+
+
+
+
+}
+
+inline void CalculatePF16(uint16_t val){
+    #ifndef USE_NATIVE
+    unsigned int i;
+    unsigned int count=0;
+    for(i=0;i<=15;i++){
+        /* TODO (Jordan#4#): speed this up! */
+        if((val&((1<<i)))!=0){count++;}
+    }
+    if((count%2)==0){freg.pf=1;}else{freg.pf=0;}
+    #else
+    //x86 ASM optimization..
+    __asm(".intel_syntax noprefix\n"
+    "cmp WORD PTR [ebp-10],0\n"
+    "jp .yes__\n"
+    ".att_syntax\n");
+    val=0;
+    __asm(".intel_syntax noprefix\n"
+    "jmp .end__\n"
+    ".local .yes__:\n"
+    ".att_syntax\n");
+    val=1;
+    __asm(".intel_syntax noprefix\n"
+    ".local .end__:\n"
+    ".att_syntax\n");
+    freg.pf=val;
+    return;
+    #endif
+}
+
+//these calculate SF for the given operand size
+inline void CalculateSF8(uint8_t val){
+    if((val&0x80)==0){freg.sf=0;}else{freg.sf=1;}
+}
+
+inline void CalculateSF16(uint16_t val){
+    if((val&0x8000)==0){freg.sf=0;}else{freg.sf=1;}
+}
+
+
+
+
+void Jmp16_near16(uint16_t off){
+
+    //I thought there would be a good way to do this, but I suppose this works..
+    if((off&0x8000)==0){ //if unsigned
+        eip=eip+off;
+    }else{
+        eip=eip-((uint16_t)-off);
+    }
+
+}
+
+void Jmp16_near8(uint8_t off){
+    //I thought there would be a good way to do this, but I suppose this works..
+    if((off&0x80)==0){ //if unsigned
+        eip=eip+off;
+    }else{
+        eip=eip-((uint8_t)-off);
+    }
+    //eip++;
+
+}
+
+void Int16(uint8_t num){
+    Push16(*(uint16_t*)&freg);
+    freg._if=0;
+    Push16(seg[cCS]);
+    Push16(eip);
+    seg[cIS]=0;
+    eip=ReadWord(cIS,num*4);
+    seg[cCS]=ReadWord(cIS,num*4+2);
+    
+//    cout << "0x" << hex << eip << "0x" << seg[cCS] << endl;
+    eip--;
+}
+
+inline void ResetSegments(){
+    ES=cES;
+    CS=cCS;
+    SS=cSS;
+    DS=cDS;
+    FS=cFS;
+    GS=cGS;
+}
+
+inline void SetSegments(uint8_t segm){
+    ES=segm;
+    CS=segm;
+    SS=segm;
+    DS=segm;
+    FS=segm;
+    GS=segm;
+}
+
+
+
+inline uint8_t ReadByte(uint8_t segm,uint32_t off){
+    Memory->WaitLock(busmaster);
+    uint8_t res=0;
+    Memory->Read((seg[segm]<<4)|off,1,&res);
+    return res;
+}
+
+inline uint16_t ReadWord(uint8_t segm,uint32_t off){
+    Memory->WaitLock(busmaster);
+    uint16_t res=0;
+    if(Opcodes==opcodes_16bit && off>=0xFFFE){
+
+        uint16_t offset=off; //for ease of rounding
+        uint32_t tmp=0;
+        Memory->Read((seg[segm]<<4)|offset,1,&tmp);
+        res=tmp;
+        Memory->Read((seg[segm]<<4)|(uint16_t)(offset+1),1,&tmp);
+        res|=tmp<<8;
+        return res;
+    }else{
+        Memory->Read((seg[segm]<<4)|off,2,&res);
+        return res;
+    }
+}
+
+inline uint32_t ReadDword(uint8_t segm,uint32_t off){
+    Memory->WaitLock(busmaster);
+    uint32_t res=0;
+    if(Opcodes==opcodes_16bit && off>=0xFFFC){
+        uint16_t offset=off; //for ease of rounding
+        uint32_t tmp=0;
+        Memory->Read((seg[segm]<<4)|offset,1,&tmp);
+        res=tmp;
+        Memory->Read((seg[segm]<<4)|(uint16_t)(offset+1),1,&tmp);
+        res|=tmp<<8;
+        Memory->Read((seg[segm]<<4)|(uint16_t)(offset+2),1,&tmp);
+        res|=tmp<<16;
+        Memory->Read((seg[segm]<<4)|(uint16_t)(offset+3),1,&tmp);
+        res|=tmp<<24;
+        return res;
+    }else{
+        Memory->Read((seg[segm]<<4)|off,4,&res);
+        return res;
+    }
+}
+
+inline void WriteByte(uint8_t segm,uint32_t off,uint8_t val){
+        Memory->WaitLock(busmaster);
+        Memory->Write((seg[segm]<<4)|off,1,&val);
+}
+
+inline void WriteWord(uint8_t segm,uint32_t off,uint16_t val){
+    Memory->WaitLock(busmaster);
+    if(Opcodes==opcodes_16bit && off>=0xFFFE){
+        uint16_t offset=off; //for ease of rounding
+        uint16_t tmp=val&0x00FF;
+        Memory->Write((seg[segm]<<4)|offset,1,&tmp);
+        tmp=(val&0xFF00)>>8;
+        Memory->Write((seg[segm]<<4)|(uint16_t)(offset+1),1,&tmp);
+    }else{
+        Memory->Write((seg[segm]<<4)|off,2,&val);
+    }
+}
+
+inline void WriteDword(uint8_t segm,uint32_t off,uint32_t val){
+    Memory->WaitLock(busmaster);
+    if(Opcodes==opcodes_16bit && off>=0xFFFC){
+        uint16_t offset=off; //for ease of rounding
+        uint32_t tmp=val&0x00FF;
+        Memory->Write((seg[segm]<<4)|offset,1,&tmp);
+        tmp=(val&0xFF00)>>8;
+        Memory->Write((seg[segm]<<4)|(uint16_t)(offset+1),1,&tmp);
+        tmp=(val&0xFF0000)>>16;
+        Memory->Write((seg[segm]<<4)|(uint16_t)(offset+2),1,&tmp);
+        tmp=(val&0xFF000000)>>24;
+        Memory->Write((seg[segm]<<4)|(uint16_t)(offset+3),1,&tmp);
+    }else{
+        Memory->Write((seg[segm]<<4)|off,4,&val);
+    }
+}
+
+
+
+
diff -r 000000000000 -r 217a7931b41f include/x86Lib.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/x86Lib.h	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,452 @@
+/**
+Copyright (c) 2007 - 2010 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+
+#ifndef X86LIB
+#define X86LIB
+#include <iostream>
+#include <vector>
+#include <stdint.h>
+#include <string>
+#include "mbed.h"
+
+//! The main namespace of x86Lib
+namespace x86Lib{
+
+#ifdef X86LIB_BUILD
+#include <config.h>
+#endif
+
+//!    8086 CPU level
+static const uint32_t CPU086=1;
+//!    186 CPU level
+static const uint32_t CPU186=2|CPU086;
+//!    286 real mode only CPU level
+static const uint32_t CPU286_REAL=4|CPU186; //Only support real mode instructions
+//!    286 CPU level
+static const uint32_t CPU286=8|CPU286_REAL;
+//!    386 real mode only CPU level
+static const uint32_t CPU386_REAL=16|CPU286_REAL; //Only Support real mode instructions
+//!    386 CPU level
+static const uint32_t CPU386=32|CPU386_REAL|CPU286;
+//!    486 CPU level
+static const uint32_t CPU486=64|CPU386;
+//!    Pentium(586) CPU level
+static const uint32_t CPU_PENTIUM=128|CPU486;
+//!    Pentium Pro CPU level
+static const uint32_t CPU_PPRO=256|CPU_PENTIUM;
+//!    Default CPU level
+/*!    CPU_DEFAULT will use the CPU with the most complete emulation
+*/
+static const uint32_t CPU_DEFAULT=0; //this is actually changed internally..
+
+
+
+
+
+
+/**Exceptions...**/
+//!    Exception code for an infinite halt
+static const uint32_t CLIHLT_EXCP=1; //cli/hlt...nothing to do
+//!    Exception code for memory access exception
+static const uint32_t MEM_ACCESS_EXCP=3; //Memory Access Error...(can actually be page fault, or GPF, or stack fault...
+//!    Exception code for triple fault
+/*!    This code is always OR'd with another code
+    so that you can tell what caused the triple fault.
+*/
+static const uint32_t TRIPLE_FAULT_EXCP=0x10000; //Triple fault...This should be ORd with the last exception
+
+
+
+//!    A debug exception
+/*!    This exception should really only be used when debugging.
+    It should be used as throw(Default_excp(__FILE__,__FUNCTION__,__LINE__));
+*/
+class Default_excp{ //Internal only...these should never happen when released...
+
+    public:
+    /*!
+    \param file_ The file name in which the exception occured(use __FILE__)
+    \param func_ The function in which the exception occured(use __FUNCTION__)
+    \param line_ The line number which the excption occured on(use __LINE__)
+    */
+    Default_excp(std::string file_,std::string func_,int line_){
+        file=file_;
+        func=func_;
+        line=line_;
+    }
+    //! The file which the exception was thrown from
+    std::string file;
+    //! The function which the exception was thrown from
+    std::string func;
+    //! The line which the exception was thrown from
+    int line;
+};
+
+//! CPU Panic exception
+/*!    This exception is thrown out of x86CPU if a fatal CPU error occurs,
+    such as a triple fault.
+*/
+class CpuPanic_excp{ //used for fatal CPU errors, such as triple fault..
+
+    public:
+    /*!
+    \param desc_ A text description of the error
+    \param code_ An exception code
+    */
+    CpuPanic_excp(std::string desc_,uint32_t code_){
+        desc=desc_;
+        code=code_;
+    }
+    //!A text description of the error
+    std::string desc;
+    //!An exception code
+    uint32_t code;
+};
+
+//!    Memory error exception
+/*!    This should only be thrown out of the PhysMemory class
+    It is thrown out to tell x86CPU a memory exception has occured.
+    This does not always result in a triple fault.
+    /sa PhysMemory
+*/
+class Mem_excp{ //Exclusively for the Memory Classes, these are caught and then a more appropriate excp is thrown
+    public:
+    /*!
+    \param address_ The address at which had problems being read or written
+    */
+    Mem_excp(uint32_t address_){
+        address=address_;
+    }
+    uint32_t address;
+};
+
+class System_excp{
+    public:
+    System_excp(){}
+};
+
+class x86CPU;
+/**This will be used for memory mapped devices(including memory itself)**/
+class MemoryDevice{
+    public:
+    virtual void Read(uint32_t address,int count,void *buffer)=0;
+    virtual void Write(uint32_t address,int count,void *data)=0;
+    virtual int Readable(uint32_t address,int count){
+        return 1;
+        //This is optional. It is currently not used in the CPU code
+    }
+    virtual int Writeable(uint32_t address,int count){
+        return 1;
+        //This is optional. It is currently not used in the CPU code
+    }
+    virtual inline ~MemoryDevice()=0;
+};
+
+inline MemoryDevice::~MemoryDevice(){}
+void Onx86LibError();
+
+class PortDevice{
+    public:
+    virtual void Read(uint16_t address,int count,void *buffer)=0;
+    virtual void Write(uint16_t address,int count,void *data)=0;
+    virtual inline ~PortDevice()=0;
+};
+
+inline PortDevice::~PortDevice(){}
+
+typedef struct DeviceRange
+{
+    union
+    {
+        class MemoryDevice *memdev;
+        class PortDevice *portdev;
+    };
+    uint32_t high;
+    uint32_t low;
+}DeviceRange_t;
+/*Myk I hate you. This is going to be harder to implement than I thought. lol */
+class MemorySystem{
+    std::vector<DeviceRange_t> memorySystemVector;
+    protected:
+    //! Intended to be used to mark if the address space is locked.
+    volatile uint32_t locked; 
+    public:
+    MemorySystem();
+    void Add(uint32_t low,uint32_t high,MemoryDevice *memdev);
+    void Remove(uint32_t low,uint32_t high);
+    void Remove(MemoryDevice *memdev);
+    int RangeFree(uint32_t low,uint32_t high);
+    void Read(uint32_t address,int count,void *buffer);
+    void Write(uint32_t address,int count,void *data);
+    //! Tells if memory is locked
+    /*!
+    \return 1 if memory is locked, 0 if not locked.
+    */
+    bool IsLocked(){return locked;}
+    //!    Locks the address space
+    void Lock(){
+        while(locked==1){}
+        locked=1;
+    }
+    //! Unlocks the address space
+    void Unlock(){
+        locked=0;
+    }
+    void WaitLock(int haslock){
+        if(haslock==0){
+            while(locked>0){}
+        }
+    }
+};
+
+class PortSystem{
+    DeviceRange_t *list;
+    int count;
+    public:
+    PortSystem();
+
+    void Add(uint16_t low,uint16_t high,PortDevice *portdev);
+    void Remove(uint16_t low,uint16_t high);
+    void Remove(PortDevice *portdev);
+    int RangeFree(uint32_t low,uint32_t high);
+    void Read(uint16_t address,int count,void *buffer);
+    void Write(uint16_t address,int count,void *data);
+};
+
+
+
+//! The struct used to save the current state of x86CPU
+struct x86SaveData{
+    //! General registers
+    uint32_t reg32[8];
+    //! Segment registers
+    uint16_t seg[7];
+    //! Segment register routing(in case of segment overrides)
+    uint8_t seg_route[7];
+    //! Instruction pointer
+    uint32_t eip;
+    //! Which opcode map is currently in use
+    uint32_t opcode_mode;
+    //! Flags register
+    uint16_t freg;
+    //! CPU level
+    uint32_t cpu_level;
+};
+
+};
+
+#ifdef X86LIB_BUILD
+
+#include <x86Lib_internal.h>
+#endif
+
+
+
+namespace x86Lib{
+
+typedef void (x86Lib::x86CPU::*opcode)();
+typedef struct{
+     unsigned char rm:3;
+     unsigned char extra:3;
+     unsigned char mod:2;
+}
+__attribute__((packed))mod_rm16; //this struct is a described mod r/m byte..
+
+//Note, this will re-cache op_cache, so do not use op_cache afterward
+//Also, eip should be on the modrm byte!
+//On return, it is on the last byte of the modrm block, so no advancement needed unelss there is an immediate
+//Also, this will advance EIP upon exiting the opcode(deconstruction)
+class ModRM16{ //This is the best thing I have ever done...
+    //I love this class so much...am I cheating on her? lol
+    protected:
+    bool use_ss;
+    bool op_specific;
+    x86CPU *this_cpu;
+    private:
+    mod_rm16 modrm;
+    inline uint16_t GetRegD(); //This returns the register displacement value
+    inline uint16_t GetDisp();
+    public:
+    inline ModRM16(x86CPU* this_cpu_);
+    inline ~ModRM16();
+    //The r suffix means /r, which means for op_specific=1, use general registers
+    inline uint8_t ReadByter();
+    inline uint16_t ReadWordr();
+    inline uint32_t ReadDword();
+    inline void WriteByter(uint8_t byte);
+    inline void WriteWordr(uint16_t word);
+    inline void WriteDword(uint32_t dword);
+    inline uint8_t GetLength(); //This returns how many total bytes the modrm block consumes
+    inline uint8_t GetExtra(); //Get the extra fied from mod_rm
+    inline uint16_t ReadOffset(); //This is only used by LEA. It will obtain the offset and not dereference it...
+
+}; //I hope that SIB and ModR/M32 will be this good!
+//!    The main CPU control class
+/*!    This class is the complete CPU. That being said, it is quite big
+    and has many functions. It completely emulates the x86 line of CPUs
+*/
+class x86CPU{
+    friend class ModRM16;
+    volatile uint32_t reg32[8];
+    volatile uint16_t *regs16[8];
+    volatile uint8_t *regs8[8];
+    volatile uint16_t seg[7];
+    volatile uint32_t eip;
+    #ifdef X86LIB_BUILD
+    volatile FLAGS freg;
+    #else
+    volatile uint16_t freg;
+    #endif
+    volatile uint8_t op_cache[4];
+    volatile uint8_t ES;
+    volatile uint8_t CS;
+    volatile uint8_t SS;
+    volatile uint8_t DS;
+    volatile uint8_t FS;
+    volatile uint8_t GS;
+    volatile bool string_compares;
+    volatile uint8_t cli_count; //Whenever this is 1, an STI is done.
+    volatile bool int_pending;
+    volatile uint8_t int_number;
+    uint32_t cpu_level;
+    volatile bool busmaster;
+    void Init();
+    protected:
+    //! Do one CPU opcode
+    /*! This should be put in the main loop, as this is what makes the CPU work.
+    */
+    void Cycle();
+    opcode opcodes_16bit[256];
+    opcode *Opcodes;
+    
+    /*!
+    \return 0 if no interrupts are pending
+     */
+    int CheckInterrupts();
+    public:
+#ifdef ENABLE_OPCODE_CALLBACK
+    void (*EachOpcodeCallback)(x86CPU *thiscpu);
+#endif
+    MemorySystem *Memory;
+    PortSystem *Ports;
+    /*!
+    \param cpu_level The CPU level to use(default argument is default level)
+    \param flags special flags to control CPU (currently, there is none)
+    */
+    x86CPU(uint32_t cpu_level=0 ,uint32_t flags=0);
+    /*!
+    \param save The x86SaveData class to restore the cpu to
+    \param flags special flags to control CPU (currently, there is none)
+    */
+    x86CPU(x86SaveData &save,uint32_t flags=0);
+
+    //!Runs the CPU for the specified cyclecount.
+    void Exec(int cyclecount);
+    
+    //! Dump CPU state
+    /*! This will dump cpu state to output. This is mainly used for debugging, as it is not flexible.
+    \param output output stream which to use.
+    */
+    void DumpState(std::ostream &output);
+    //! Cause a CPU interrupt
+    /*! This will cause a CPU interrupt(unless interrupt flag is cleared)
+        Note! This does not resolve IRQs! This takes normal interrupt numbers(0-255)
+    \param num Interrupt number
+    */
+    void Int(uint8_t num);
+    //! Saves CPU state
+    /*! This will completely save the CPU state of the current x86CPU class
+    \param save_data_buffer This should be a free memory area the size of x86SaveData
+    */
+    void SaveState(x86SaveData *save_data_buffer);
+    //!Loads CPU state
+    /*! This will completely reset and reload the cpu state.
+    \param load_data where the x86SaveData is located
+    */
+    void LoadState(x86SaveData &load_data);
+
+    //!Completely resets the CPU
+    void Reset();
+    //~x86CPU();
+    //!Locks the PhysMemory in use, and declares this CPU as busmaster
+    void Lock();
+    //!Unlocks the PhysMemory in use
+    void Unlock();
+    //! Tells if PhysMemory in use is locked
+    /*!
+    \return 1 if PhysMemory in use is locked, otherwise returns 0
+    */
+    bool IsLocked();
+    /*Added after inital multi-branch switch over*/
+    //!Checks if an interrupt is on the stack waiting to be answered.
+    /*!
+    \return 1 if an interrupt is waiting to be answered by the CPU, else, 0.
+    */
+    bool IntPending();
+    
+    /*End public interface*/
+    #ifdef X86LIB_BUILD
+    private:
+    #include <opcode_def.h>
+    #endif
+
+};
+
+
+
+#ifdef X86LIB_BUILD
+#define X86_POST_CPU
+#include "x86Lib_internal.h"
+#undef X86_POST_CPU
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+
+#endif
+
diff -r 000000000000 -r 217a7931b41f include/x86Lib_internal.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/x86Lib_internal.h	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,452 @@
+/**
+Copyright (c) 2007 - 2010 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+
+
+#ifndef X86LIB_INTERNAL_H
+#define X86LIB_INTERNAL_H
+
+
+namespace x86Lib{
+    //32 bit register macros
+static const int EAX=0;
+static const int ECX=1;
+static const int EDX=2;
+static const int EBX=3;
+static const int ESP=4;
+static const int EBP=5;
+static const int ESI=6;
+static const int EDI=7;
+
+
+//16 bit register macros
+static const int AX=0;
+static const int CX=1;
+static const int DX=2;
+static const int BX=3;
+static const int SP=4;
+static const int BP=5;
+static const int SI=6;
+static const int DI=7;
+
+//8 bit register macros
+static const int AL=0;
+static const int CL=1;
+static const int DL=2;
+static const int BL=3;
+static const int AH=4;
+static const int CH=5;
+static const int DH=6;
+static const int BH=7;
+
+
+//segment registers constants(the defaults)
+static const int cES=0;
+static const int cCS=1;
+static const int cSS=2;
+static const int cDS=3;
+static const int cFS=4;
+static const int cGS=5;
+static const int cIS=6; //this is an imaginary segment only used for direct segment overrides
+//for instance it would be used in mov [1000:bx],ax
+
+
+
+typedef struct{
+    unsigned char cf:1;
+    unsigned char r0:1;
+    unsigned char pf:1;
+    unsigned char r1:1;
+    unsigned char af:1;
+    unsigned char r2:1;
+    unsigned char zf:1;
+    unsigned char sf:1;
+    unsigned char tf:1;
+    unsigned char _if:1;
+    unsigned char df:1;
+    unsigned char of:1;
+    unsigned char iopl:2; //not yet used
+    unsigned char nt:1;
+    unsigned char r3:1;
+}__attribute__((packed))FLAGS; //this is a better representation of flags(much easier to use)
+
+
+
+
+
+typedef void (x86Lib::x86CPU::*opcode)(); /**You have no idea how hard it was to figure out how to do that!**/
+
+
+static const uint32_t OPCODE_REAL_16=1;
+
+
+//CPU Exceptions(interrupt handled)
+static const uint32_t DIV0_IEXCP=0xF000; //Divide by zero exception
+static const uint32_t DEBUG_IEXCP=0xF001; //Debug exception
+static const uint32_t NMI_IEXCP=0xF002; //NMI
+static const uint32_t BREAK_IEXCP=0xF003; //Breakpoint/int 3
+static const uint32_t OVERFLOW_IEXCP=0xF004; //Overflow/into
+static const uint32_t BOUNDS_IEXCP=0xF005; //Bounds Check
+static const uint32_t UNK_IEXCP=0xF006; //unknown opcode
+static const uint32_t UNDEV_IEXCP=0xF007; //Unknown device
+static const uint32_t DOUBLE_FAULT_IEXCP=0xF008;
+static const uint32_t SEG_OVERRUN_IEXCP=0xF009; //Co-processor segment overrun..(not used after i486
+static const uint32_t ITSS_IEXCP=0xF00A; //Invalid TSS
+static const uint32_t ISEG_IEXCP=0xF00B; //Invalid/non-existent segment
+static const uint32_t STACK_IEXCP=0xF00C; //Stack Exception
+static const uint32_t GPF_IEXCP=0xF00D; //GPF
+static const uint32_t PAGE_FAULT_IEXCP=0xF00E;
+static const uint32_t RESERVED_IEXCP=0xF00F; //Reserved by intel, so internal use?
+static const uint32_t FLOAT_ERROR_IEXCP=0xF010; //Floating Point Error..
+static const uint32_t ALIGN_IEXCP=0xF011; //Alignment Check...
+
+class CpuInt_excp{ //Used internally for handling interrupt exceptions...
+    public:
+    CpuInt_excp(uint32_t code_){
+        code=code_;
+    }
+    uint32_t code;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**Random support functions that are static inline'd**/
+
+static inline uint16_t SignExtend8(uint8_t val){ //sign extend a byte to a word
+    if((val&0x80)!=0){
+        return 0xFF00|val;
+    }else{
+        return val;
+    }
+}
+
+//convert signed integer into unsigned, and store top bit in store
+static inline uint32_t Unsign32(uint32_t val,bool &store){
+
+    if(val>=0x80000000){
+        store=1;
+        //cout << hex << "0x" << (int) ~(-2) << endl;
+        return (~(val))+1;
+    }else{
+        store=0;
+        return val;
+    }
+
+}
+
+static inline uint16_t Unsign16(uint16_t val,bool &store){
+    if(val>=0x8000){
+        store=1;
+        //cout << hex << "0x" << (int) ~(-2) << endl;
+        return (~(val))+1;
+    }else{
+        store=0;
+        return val;
+    }
+
+}
+
+static inline uint8_t Unsign8(uint8_t val,bool &store){
+    if(val>=0x80){
+        store=1;
+        return (~(val))+1;
+    }else{
+        store=0;
+        return val;
+    }
+
+}
+
+/**Resign an unsigned integer using the store as the sign bit.
+--Note, in order to combine two sign bits, just bitwise XOR(^) them!*/
+static inline uint32_t Resign32(uint32_t val,bool store1){
+    if((store1)==1){
+        return (~(val))+1;
+    }else{
+        return val;
+    }
+}
+
+static inline uint16_t Resign16(uint16_t val,bool store1){
+    if((store1)==1){
+        return (~(val))+1;
+    }else{
+        return val;
+    }
+}
+
+static inline uint8_t Resign8(uint8_t val,bool store1){
+    if((store1)==1){
+        return (~(val))+1;
+    }else{
+        return val;
+    }
+}
+
+
+};
+
+
+#endif
+
+
+#ifdef X86_POST_CPU
+
+#ifndef X86LIB_INTERNAL_H_POST_CPU
+#define X86LIB_INTERNAL_H_POST_CPU
+//namespace x86Lib{
+
+    
+
+
+
+    
+inline uint16_t ModRM16::GetRegD(){ //This returns the register displacement value
+    switch(modrm.rm){
+        case 0:
+        return *this_cpu->regs16[BX]+*this_cpu->regs16[SI];
+        case 1:
+        return *this_cpu->regs16[BX]+*this_cpu->regs16[DI];
+        case 2:
+        use_ss=1;
+        return *this_cpu->regs16[BP]+*this_cpu->regs16[SI];
+        case 3:
+        use_ss=1;
+        return *this_cpu->regs16[BP]+*this_cpu->regs16[DI];
+        case 4:
+        return *this_cpu->regs16[SI];
+        case 5:
+        return *this_cpu->regs16[DI];
+        case 6: //immediate Displacement only, so no register displace..
+        return 0;
+        case 7:
+        return *this_cpu->regs16[BX];
+    }
+    return 0;
+}
+
+inline uint16_t ModRM16::GetDisp(){
+    uint16_t reg;
+    reg=GetRegD();
+    if(modrm.rm==6){ //Don't worry, it's safe...
+        use_ss=1;
+        reg=*this_cpu->regs16[BP];
+    }
+    switch(modrm.mod){
+        case 0: //no displacement
+
+        if(modrm.rm==6){ //if only word displacement...
+            use_ss=0;
+            //eip++;
+            //eip++;
+            return *(uint16_t*)&this_cpu->op_cache[1];
+        }else{
+            return reg;
+        }
+        case 1: //byte displacement(signed)
+        //eip++;
+        return (signed)reg+(signed)this_cpu->op_cache[1];
+        case 2: //word displacement(signed)
+        return (signed)reg+(signed)(*(uint16_t*)&this_cpu->op_cache[1]);
+        case 3: //opcode specific...
+        op_specific=1;
+        return 0;
+    }
+    return 0;
+}
+
+
+inline ModRM16::ModRM16(x86CPU *this_cpu_){
+    use_ss=0;
+    op_specific=0;
+    this_cpu=this_cpu_;
+    *(uint32_t*)&this_cpu->op_cache=this_cpu->ReadDword(cCS,this_cpu->eip);
+    *(uint8_t*)&modrm=this_cpu->op_cache[0];
+    //cout << hex << (int)modrm.rm << endl;
+    //knowing how to do type casting owns!
+}
+
+inline ModRM16::~ModRM16(){
+    this_cpu->eip+=GetLength()-1;
+    //eip--;
+}
+
+//The r suffix means /r, which means for op_specific=1, use general registers
+inline uint8_t ModRM16::ReadByter(){
+    use_ss=0;
+    op_specific=0;
+    uint16_t disp=GetDisp();
+    if(op_specific==1){
+        return *this_cpu->regs8[modrm.rm];
+    }else{
+        if(use_ss==1){
+            return this_cpu->ReadByte(this_cpu->SS,disp);
+        }else{
+            return this_cpu->ReadByte(this_cpu->DS,disp);
+        }
+    }
+}
+
+inline uint16_t ModRM16::ReadWordr(){
+    use_ss=0;
+    op_specific=0;
+    uint16_t disp=GetDisp();
+    if(op_specific==1){
+        //cout << "h" << endl;
+        return *this_cpu->regs16[modrm.rm];
+    }else{
+
+        if(use_ss==1){
+            return this_cpu->ReadWord(this_cpu->SS,disp);
+        }else{
+            return this_cpu->ReadWord(this_cpu->DS,disp);
+        }
+    }
+}
+inline uint32_t ModRM16::ReadDword(){
+    use_ss=0;
+    op_specific=0;
+    uint16_t disp=GetDisp();
+    if(op_specific==1){
+        //cout << "h" << endl;
+        Onx86LibError();
+        //throw CpuInt_excp(UNK_IEXCP);
+        //We can't return regs16 because it needs 32bits!
+        //return *regs16[modrm.rm];
+    }else{
+
+        if(use_ss==1){
+            return this_cpu->ReadDword(this_cpu->SS,disp);
+        }else{
+            return this_cpu->ReadDword(this_cpu->DS,disp);
+        }
+    }
+    return 0;
+}
+
+inline void ModRM16::WriteByter(uint8_t byte){
+    use_ss=0;
+    op_specific=0;
+    uint16_t disp=GetDisp();
+    if(op_specific==1){
+        *this_cpu->regs8[modrm.rm]=byte;
+    }else{
+
+        if(use_ss==1){
+            this_cpu->WriteByte(this_cpu->SS,disp,byte);
+        }else{
+            this_cpu->WriteByte(this_cpu->DS,disp,byte);
+        }
+    }
+}
+inline void ModRM16::WriteWordr(uint16_t word){
+    use_ss=0;
+    op_specific=0;
+    uint16_t disp=GetDisp();
+    if(op_specific==1){
+        *this_cpu->regs16[modrm.rm]=word;
+    }else{
+
+        if(use_ss==1){
+            this_cpu->WriteWord(this_cpu->SS,disp,word);
+        }else{
+            this_cpu->WriteWord(this_cpu->DS,disp,word);
+        }
+    }
+}
+inline void ModRM16::WriteDword(uint32_t dword){
+    use_ss=0;
+    op_specific=0;
+    uint16_t disp=GetDisp();
+    if(op_specific==1){
+        //*regs16[modrm.rm]=word;
+        Onx86LibError();
+        //throw CpuInt_excp(UNK_IEXCP);
+    }else{
+
+        if(use_ss==1){
+            this_cpu->WriteDword(this_cpu->SS,disp,dword);
+        }else{
+            this_cpu->WriteDword(this_cpu->DS,disp,dword);
+        }
+    }
+}
+
+inline uint8_t ModRM16::GetLength(){ //This returns how many total bytes the modrm block consumes
+    if((modrm.mod==0) && (modrm.rm==6)){
+        return 3;
+    }
+    switch(modrm.mod){
+        case 0:
+        return 1;
+        case 1:
+        return 2;
+        case 2:
+        return 3;
+        case 3:
+        return 1;
+    }
+    return 1; //should never reach here, but to avoid warnings...
+} //that was easier than I first thought it would be...
+inline uint8_t ModRM16::GetExtra(){ //Get the extra fied from mod_rm
+    return modrm.extra;
+}
+
+inline uint16_t ModRM16::ReadOffset(){ //This is only used by LEA. It will obtain the offset and not dereference it...
+    use_ss=0;
+    op_specific=0;
+    uint16_t disp=GetDisp();
+    if(op_specific==1){
+        Onx86LibError();
+        //throw CpuInt_excp(UNK_IEXCP);
+        //We can't return regs16 because it can't get address of a register!
+        //return *regs16[modrm.rm];
+    }else{
+        return disp;
+    }
+    return 0;
+}
+//}
+
+
+#endif
+#endif
diff -r 000000000000 -r 217a7931b41f ops/etc.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ops/etc.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,214 @@
+/**
+Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <x86Lib.h>
+
+
+namespace x86Lib{
+
+void x86CPU::op16_nop(){ //0x90
+    //do nothing
+}
+
+void x86CPU::op16_hlt(){ //0xF4
+    if(freg._if==0){
+        Onx86LibError();
+        //throw CpuPanic_excp("HLT With IF=0; Nothing to do",CLIHLT_EXCP);
+    }
+}
+
+void x86CPU::op16_unknown(){
+    Onx86LibError();
+    //throw CpuInt_excp(UNK_IEXCP);
+}
+
+
+
+
+//Segment overrides...
+void x86CPU::op16_pre_es_override(){ //0x26
+    SetSegments(cES);
+    eip++;
+    *(uint32_t*)&op_cache=ReadDword(cCS,eip);
+    (this->*Opcodes[op_cache[0]])();
+
+    ResetSegments();
+}
+
+void x86CPU::op16_pre_ds_override(){ //0x3E
+    SetSegments(cDS);
+    eip++;
+    *(uint32_t*)&op_cache=ReadDword(cCS,eip);
+    (this->*Opcodes[op_cache[0]])();
+
+    ResetSegments();
+}
+
+void x86CPU::op16_pre_ss_override(){ //0x36
+    SetSegments(cSS);
+    eip++;
+    *(uint32_t*)&op_cache=ReadDword(cCS,eip);
+    (this->*Opcodes[op_cache[0]])();
+
+    ResetSegments();
+}
+
+void x86CPU::op16_pre_cs_override(){ //0x2E
+    SetSegments(cCS);
+    eip++;
+    *(uint32_t*)&op_cache=ReadDword(cCS,eip);
+    (this->*Opcodes[op_cache[0]])();
+
+    ResetSegments();
+}
+
+void x86CPU::op16_rep(){ //repe and repne..(different opcodes, but I make them possible to use the same function)
+    //use a string_compares variable...
+    if(*regs16[CX]==0){ //for this, not executing the instruction is almost as expensive...
+        *(uint16_t*)&op_cache=ReadWord(cCS,eip+1);
+        int i=0;
+        //get size of opcode and prefixes....
+        for(i=0;i<4;i++){
+            switch(op_cache[i]){
+                case 0x67:
+                case 0x66:
+                case 0x2E:
+                case 0x36:
+                case 0x3E:
+                case 0x26:
+                case 0x64:
+                case 0x65:
+                eip++;
+                break;
+                default:
+                eip++;
+                return;
+            }
+        }
+        return;
+    }else{
+        uint32_t tmp=eip;
+        uint8_t t2=op_cache[0];
+        eip++;
+        *(uint32_t*)&op_cache=ReadDword(cCS,eip);
+        (this->*Opcodes[op_cache[0]])();
+        (*regs16[CX])--;
+        eip=tmp-1;
+        if(string_compares==1){
+            string_compares=0;
+            if(t2==0xF2){ //repNE
+                if(freg.zf==1){ //exit...
+                    eip+=2;
+                    return;
+                }
+            }else{
+                if((volatile uint8_t)freg.zf==0){ //exit...
+                    eip+=2;
+                    return;
+                }
+            }
+        }
+    }
+}
+
+void x86CPU::op16_lock(){ //0xF0 prefix
+    #ifndef X86_MULTITHREADING
+    if(IsLocked()==1){
+        eip--;
+        return;
+    }
+    #endif
+    Lock();
+    eip++;
+    *(uint32_t*)&op_cache=ReadDword(cCS,eip);
+    //Add strict opcode testing for 386+
+    (this->*Opcodes[op_cache[0]])();
+    Unlock();
+}
+
+
+
+void x86CPU::op16_cbw(){
+    if((*regs8[AL]&0x80)==0){
+        *regs8[AH]=0;
+    }else{
+        *regs8[AH]=0xFF;
+    }
+}
+
+
+
+void x86CPU::op16_cwd(){
+    if(*regs16[AX]>=0x8000){
+        *regs16[DX]=0xFFFF;
+    }else{
+        *regs16[DX]=0;
+    }
+}
+
+void x86CPU::op16_escape(){
+    /**This is for FPU escape opcodes
+    this uses 0xD8 to 0xDF
+    **/
+    Onx86LibError();
+    //throw CpuInt_excp(UNDEV_IEXCP); //throw unknown device exception
+}
+void x86CPU::op16_wait(){
+    /**Does nothing...**/
+    Onx86LibError();
+    //throw CpuInt_excp(UNDEV_IEXCP);
+}
+
+
+
+/**so-called undocumented opcodes:**/
+
+/**salc -0xD6- this is will set al on carry -no arguments
+log:  if cf=0 then al=0 else al=FF
+**/
+void x86CPU::op16_salc(){ //set al on carry
+    if(freg.cf==0){*regs8[AL]=0;
+    }else{*regs8[AL]=0xFF;
+    }
+
+}
+
+
+
+
+
+
+
+
+};
+
+
+
+
diff -r 000000000000 -r 217a7931b41f ops/flags.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ops/flags.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,205 @@
+/**
+Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <x86Lib.h>
+namespace x86Lib{
+using namespace std;
+
+//jmp rel8 jcc stuff
+void x86CPU::op16_ja_rel8(){ //is also jnbe
+	eip++;
+    if(freg.cf==0 && freg.zf==0){
+		Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jnc_rel8(){ //is also jae and jnb
+	eip++;
+    if(freg.cf==0){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+
+void x86CPU::op16_jbe_rel8(){ //is also jna
+	eip++;
+    if(freg.cf==1 || freg.zf==1){
+        Jmp16_near8(op_cache[1]);
+    }else{
+    	eip++;
+    }
+}
+
+void x86CPU::op16_jc_rel8(){ //is also jb and jnae
+	eip++;
+    if(freg.cf==1){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jz_rel8(){ //is also je
+	eip++;
+    if(freg.zf==1){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jnz_rel8(){ //is also jne
+	eip++;
+    if(freg.zf==0){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+
+void x86CPU::op16_jp_rel8(){ //also jpe
+	eip++;
+    if(freg.pf==1){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jnp_rel8(){ //is also jpo
+	eip++;
+    if(freg.pf==0){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jg_rel8(){ //is also jnle
+	eip++;
+    if(freg.sf==freg.of && freg.zf==0){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+
+void x86CPU::op16_jge_rel8(){ //is also jnl
+	eip++;
+    if(freg.sf==freg.of){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jle_rel8(){ //is also jng
+	eip++;
+    if(freg.sf!=freg.of || freg.zf==1){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jl_rel8(){ //is also jnge
+	eip++;
+    if(freg.sf!=freg.of){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+
+void x86CPU::op16_jo_rel8(){
+    eip++;
+	if(freg.of==1){
+       Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jno_rel8(){
+	eip++;
+    if(freg.of==0){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_js_rel8(){ //is negative
+	eip++;
+    if(freg.sf==1){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+void x86CPU::op16_jns_rel8(){ //is  positive
+	eip++;
+    if(freg.sf==0){
+        Jmp16_near8(op_cache[1]);
+    }
+}
+
+
+
+void x86CPU::op16_clc(){
+	freg.cf=0;
+}
+
+void x86CPU::op16_cld(){
+	freg.df=0;
+}
+
+void x86CPU::op16_cli(){
+	freg._if=0;
+}
+
+void x86CPU::op16_stc(){
+	freg.cf=1;
+}
+
+void x86CPU::op16_std(){
+	freg.df=1;
+}
+
+void x86CPU::op16_sti(){
+	freg._if=1;
+}
+
+
+void x86CPU::op16_cmc(){
+    freg.cf=freg.cf^1;
+}
+
+void x86CPU::op16_lahf(){
+	*regs8[AL]=*(uint8_t*)&freg;
+}
+void x86CPU::op16_sahf(){
+	*(uint8_t*)&freg=*regs8[AL];
+}
+
+
+
+
+
+
+
+
+
+
+
+};
+
+
+
diff -r 000000000000 -r 217a7931b41f ops/flow.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ops/flow.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,178 @@
+/**
+Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <x86Lib.h>
+namespace x86Lib{
+using namespace std;
+
+
+
+
+
+
+
+
+
+
+void x86CPU::op16_jmp_rel8(){
+	eip++;
+	Jmp16_near8(op_cache[1]);
+}
+
+void x86CPU::op16_jmp_rel16(){
+	eip+=2; //get to last byte of address so jmp works right
+	Jmp16_near16(*(uint16_t*)&op_cache[1]);
+}
+
+void x86CPU::op16_jmp_imm16_imm16(){ //far jmp
+	*(uint32_t*)&op_cache=ReadDword(cCS,eip+1);
+	seg[cCS]=*(uint16_t*)&op_cache[2]; //I always forget that they are reversed...
+	eip=*(uint16_t*)&op_cache[0];
+	eip--; //eip will be incremented in Cycle
+}
+
+void x86CPU::op16_jmp_rm16(ModRM16 &rm){
+	eip=rm.ReadWordr(); //absolute address...
+	eip--;
+}
+
+void x86CPU::op16_jmp_m16_m16(ModRM16 &rm){
+	*(uint32_t*)&op_cache=rm.ReadDword(); //quicker to use op_cache, than dynamic variables...
+	seg[cCS]=*(uint16_t*)&op_cache[2];
+	eip=*(uint16_t*)&op_cache[0];
+	eip--;
+}
+
+
+
+void x86CPU::op16_jcxz_rel8(){
+	if(*regs16[CX]==0){
+		Jmp16_near8(op_cache[1]);
+	}
+}
+
+
+
+
+
+
+void x86CPU::op16_call_rel16(){
+
+	Push16(eip+2);
+	if(*(uint16_t*)&op_cache[1]<0x8000){
+		//eip++;
+	}
+	eip+=2;
+	Jmp16_near16(*(uint16_t*)&op_cache[1]);
+}
+void x86CPU::op16_retn(){
+	eip=Pop16();
+	//eip--; //because in Cycle, we increment..
+}
+
+void x86CPU::op16_loop_rel8(){
+	(*regs16[CX])--;
+	eip++;
+	if(*regs16[CX]!=0){
+		Jmp16_near8(op_cache[1]);
+	}
+}
+
+void x86CPU::op16_loope_rel8(){
+	(*regs16[CX])--;
+	eip++;
+	if((*regs16[CX]!=0) && (freg.zf==1)){
+		Jmp16_near8(op_cache[1]);
+	}
+}
+
+void x86CPU::op16_loopne_rel8(){
+	(*regs16[CX])--;
+	eip++;
+	if((*regs16[CX]!=0) && (freg.zf==0)){
+		Jmp16_near8(op_cache[1]);
+	}
+}
+
+
+void x86CPU::op16_call_imm16_imm16(){ //far call
+	Push16(seg[cCS]);
+	Push16(eip+4);
+	*(uint32_t*)&op_cache=ReadDword(cCS,eip+1);
+	seg[cCS]=*(uint16_t*)&op_cache[2]; //I always forget that they are reversed...
+	eip=*(uint16_t*)&op_cache[0];
+	eip--; //eip will be incremented in Cycle
+}
+
+void x86CPU::op16_retf(){
+	eip=Pop16();
+	seg[cCS]=Pop16();
+}
+
+void x86CPU::op16_int_imm8(){
+	eip++;
+	Int16(op_cache[1]);
+}
+
+void x86CPU::op16_iret(){
+	eip=Pop16();
+	seg[cCS]=Pop16();
+	*(uint16_t*)&freg=Pop16();
+}
+
+void x86CPU::op16_int3(){
+	Int16(3);
+}
+
+void x86CPU::op16_into(){
+	if(freg.of==1){
+		Int16(4);
+	}
+}
+void x86CPU::op16_call_rm16(ModRM16 &rm){ //far call
+	Push16(eip+rm.GetLength()+1);
+	eip=rm.ReadWordr();
+	eip--; //eip will be incremented in Cycle
+}
+
+void x86CPU::op16_call_rm16_rm16(ModRM16 &rm){ //far call
+	Push16(seg[cCS]);
+	Push16(eip+rm.GetLength()+1);
+	*(uint32_t*)&op_cache=ReadDword(DS,rm.ReadDword());
+	seg[cCS]=*(uint16_t*)&op_cache[2]; //I always forget that they are reversed...
+	eip=*(uint16_t*)&op_cache[0];
+	eip--; //eip will be incremented in Cycle
+}
+
+
+
+};
+
+
diff -r 000000000000 -r 217a7931b41f ops/groups.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ops/groups.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,437 @@
+/**
+Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <x86Lib.h>
+namespace x86Lib{
+using namespace std;
+
+
+void x86CPU::op16_group_80(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 5:
+		op16_sub_rm8_imm8(rm);
+		break;
+		case 0:
+		op16_add_rm8_imm8(rm);
+		break;
+		case 2:
+		op16_adc_rm8_imm8(rm);
+		break;
+		case 7:
+		op16_cmp_rm8_imm8(rm);
+		break;
+		case 1:
+		op16_or_rm8_imm8(rm);
+		break;
+		case 6:
+		op16_xor_rm8_imm8(rm);
+		break;
+		case 3:
+		op16_sbb_rm8_imm8(rm);
+		break;
+		case 4:
+		op16_and_rm8_imm8(rm);
+		break;
+
+		default:
+		eip--; //to get actual opcode
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+	eip++; //for imm8
+
+}
+
+void x86CPU::op16_group_81(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 5:
+		op16_sub_rm16_imm16(rm);
+		break;
+		case 0:
+		op16_add_rm16_imm16(rm);
+		break;
+		case 2:
+		op16_adc_rm16_imm16(rm);
+		break;
+		case 7:
+		op16_cmp_rm16_imm16(rm);
+		break;
+		case 1:
+		op16_or_rm16_imm16(rm);
+		break;
+		case 6:
+		op16_xor_rm16_imm16(rm);
+		break;
+		case 3:
+		op16_sbb_rm16_imm16(rm);
+		break;
+		case 4:
+		op16_and_rm16_imm16(rm);
+		break;
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+	eip+=2; //these each have imm16
+}
+
+void x86CPU::op16_group_83(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 0:
+		op16_add_rm16_imm8(rm);
+		break;
+		case 2:
+		op16_adc_rm16_imm8(rm);
+		break;
+		case 5:
+		op16_sub_rm16_imm8(rm);
+		break;
+		case 7:
+		op16_cmp_rm16_imm8(rm);
+		break;
+		case 1:
+		op16_or_rm16_imm8(rm);
+		break;
+		case 6:
+		op16_xor_rm16_imm8(rm);
+		break;
+		case 3:
+		op16_sbb_rm16_imm8(rm);
+		break;
+		case 4:
+		op16_and_rm16_imm8(rm);
+		break;
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+	eip++;
+}
+
+void x86CPU::op16_group_8F(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 0:
+		op16_pop_m16(rm);
+		break;
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+void x86CPU::op16_group_F6(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 6:
+		op16_div_rm8(rm);
+		break;
+		case 7:
+		op16_idiv_rm8(rm);
+		break;
+		case 4:
+		op16_mul_rm8(rm);
+		break;
+		case 5:
+		op16_imul_rm8(rm);
+		break;
+		case 3:
+		op16_neg_rm8(rm);
+		break;
+		case 0:
+		op16_test_rm8_imm8(rm);
+		eip++;
+		break;
+		case 2:
+		op16_not_rm8(rm);
+		break;
+		
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+void x86CPU::op16_group_F7(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 6:
+		op16_div_rm16(rm);
+		break;
+		case 7:
+		op16_idiv_rm16(rm);
+		break;
+		case 4:
+		op16_mul_rm16(rm);
+		break;
+		case 5:
+		op16_imul_rm16(rm);
+		break;
+		case 3:
+		op16_neg_rm16(rm);
+		break;
+		case 0:
+		op16_test_rm16_imm16(rm);
+		eip+=2;
+		break;
+		case 2:
+		op16_not_rm16(rm);
+		break;
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+
+void x86CPU::op16_group_FF(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 4:
+		op16_jmp_rm16(rm);
+		break;
+		case 5:
+		op16_jmp_m16_m16(rm);
+		break;
+		case 6:
+		op16_push_m16(rm);
+		break;
+		case 0:
+		op16_inc_rm16(rm);
+		break;
+		case 1:
+		op16_dec_rm16(rm);
+		break;
+		case 2:
+		op16_call_rm16(rm);
+		break;
+		case 3:
+		op16_call_rm16_rm16(rm);
+		break;
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+void x86CPU::op16_group_FE(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 0:
+		op16_inc_rm8(rm);
+		break;
+		case 1:
+		op16_dec_rm8(rm);
+		break;
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+void x86CPU::op16_group_D0(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 7:
+		op16_sar_rm8_1(rm);
+		break;
+		case 4:
+		op16_shl_rm8_1(rm);
+		break;
+		case 5:
+		op16_shr_rm8_1(rm);
+		break;
+		case 0:
+		op16_rol_rm8_1(rm);
+		break;
+		case 1:
+		op16_ror_rm8_1(rm);
+		break;
+		case 3:
+		op16_rcr_rm8_1(rm);
+		break;
+		case 2:
+		op16_rcl_rm8_1(rm);
+		break;
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+void x86CPU::op16_group_D1(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 7:
+		op16_sar_rm16_1(rm);
+		break;
+		case 4:
+		op16_shl_rm16_1(rm);
+		break;
+		case 5:
+		op16_shr_rm16_1(rm);
+		break;
+		case 0:
+		op16_rol_rm16_1(rm);
+		break;
+		case 1:
+		op16_ror_rm16_1(rm);
+		break;
+		case 3:
+		op16_rcr_rm16_1(rm);
+		break;
+		case 2:
+		op16_rcl_rm16_1(rm);
+		break;
+
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+void x86CPU::op16_group_D2(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 7:
+		op16_sar_rm8_cl(rm);
+		break;
+		case 4:
+		op16_shl_rm8_cl(rm);
+		break;
+		case 5:
+		op16_shr_rm8_cl(rm);
+		break;
+		case 0:
+		op16_rol_rm8_cl(rm);
+		break;
+		case 1:
+		op16_ror_rm8_cl(rm);
+		break;
+		case 3:
+		op16_rcr_rm8_cl(rm);
+		break;
+		case 2:
+		op16_rcl_rm8_cl(rm);
+		break;
+
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+void x86CPU::op16_group_D3(){
+	eip++;
+	ModRM16 rm(this);
+	switch(rm.GetExtra()){
+		case 7:
+		op16_sar_rm16_cl(rm);
+		break;
+		case 4:
+		op16_shl_rm16_cl(rm);
+		break;
+		case 5:
+		op16_shr_rm16_cl(rm);
+		break;
+		case 0:
+		op16_rol_rm16_cl(rm);
+		break;
+		case 1:
+		op16_ror_rm16_cl(rm);
+		break;
+		case 3:
+		op16_rcr_rm16_cl(rm);
+		break;
+		case 2:
+		op16_rcl_rm16_cl(rm);
+		break;
+
+
+		default:
+		eip--;
+		Onx86LibError();
+		//throw CpuInt_excp(UNK_IEXCP);
+		break;
+	}
+}
+
+
+
+
+
+
+};
+
+
+
diff -r 000000000000 -r 217a7931b41f ops/maths.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ops/maths.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,1287 @@
+/**
+Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <x86Lib.h>
+namespace x86Lib{
+using namespace std;
+
+
+
+
+// TODO (Jordan#4#): Get AF stuff working in this!!
+uint8_t x86CPU::Sub8(uint8_t base,uint8_t subt){
+    int8_t result;
+    if(subt>base){freg.cf=1;}else{freg.cf=0;}
+    if((int16_t)base-subt>127 || (int16_t)base-subt<-127){
+            freg.of=1;
+        }else{
+            freg.of=0;
+        }
+    result=base-subt;
+    if(result==0){freg.zf=1;}else{freg.zf=0;}
+    CalculatePF8(result); //do pf
+    CalculateSF8(result); //do sf
+	base&=0xF;
+	subt&=0xF; 
+    freg.af = (((base-subt) & ~0xf) != 0); //thank you http://stackoverflow.com/questions/4513746/explain-how-the-af-flag-works-in-an-x86-instructions
+    return result;
+}
+
+uint16_t x86CPU::Sub16(uint16_t base,uint16_t subt){
+    int16_t result;
+    uint16_t mirror;
+    if(subt>base){freg.cf=1;}else{freg.cf=0;}
+    if((int32_t)base-subt>32767 || (int32_t)base-subt<-32767){
+            freg.of=1;
+        }else{
+            freg.of=0;
+        }
+    mirror=base-subt;
+    result=mirror;
+    if(result==0){freg.zf=1;}else{freg.zf=0;}
+    CalculatePF16(result); //do pf
+    CalculateSF16(result); //do sf
+	base&=0xF;
+	subt&=0xF; 
+    freg.af = (((base-subt) & ~0xf) != 0); 
+    return mirror;
+}
+
+uint8_t x86CPU::Add8(uint8_t base,uint8_t adder){
+    int8_t result;
+    if(adder+base>255){freg.cf=1;}else{freg.cf=0;}
+    if((int16_t)base+adder>127 || (int16_t)base+adder<-127){
+            freg.of=1;
+        }else{
+            freg.of=0;
+        }
+    result=base+adder;
+    if(result==0){freg.zf=1;}else{freg.zf=0;}
+    CalculatePF8(result); //do pf
+    CalculateSF8(result); //do sf
+	base&=0x0F;
+	adder&=0x0F;
+    freg.af = ((int16_t)base+adder > 15);
+    return result;
+}
+
+uint16_t x86CPU::Add16(uint16_t base,uint16_t adder){
+    int16_t result;
+    if((uint32_t)adder+base>(uint32_t)65535){freg.cf=1;}else{freg.cf=0;}
+    if((int32_t)base+adder>32767 || (int32_t)base+adder<-32767){
+            freg.of=1;
+        }else{
+            freg.of=0;
+        }
+    result=base+adder;
+    if(result==0){freg.zf=1;}else{freg.zf=0;}
+    CalculatePF16(result); //do pf
+    CalculateSF16(result); //do sf
+	base&=0x0F;
+	adder&=0x0F;
+    freg.af = ((int16_t)base+adder > 15);
+    return result;
+}
+
+
+
+
+uint8_t x86CPU::And8(uint8_t base,uint8_t mask){
+	freg.of=0;
+	freg.cf=0;
+	base=base&mask;
+	CalculatePF8(base);
+	CalculateSF8(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	return base;
+}
+
+uint16_t x86CPU::And16(uint16_t base,uint16_t mask){
+	freg.of=0;
+	freg.cf=0;
+	base=base&mask;
+	CalculatePF16(base);
+	CalculateSF16(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	return base;
+}
+
+//Not affects no flags, so just use ~
+
+
+uint8_t x86CPU::Or8(uint8_t base,uint8_t mask){
+	freg.of=0;
+	freg.cf=0;
+	base=base|mask;
+	CalculatePF8(base);
+	CalculateSF8(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	return base;
+}
+
+uint16_t x86CPU::Or16(uint16_t base,uint16_t mask){
+	freg.of=0;
+	freg.cf=0;
+	base=base|mask;
+	CalculatePF16(base);
+	CalculateSF16(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	return base;
+}
+
+uint8_t x86CPU::Xor8(uint8_t base,uint8_t mask){
+	freg.of=0;
+	freg.cf=0;
+	base=base^mask;
+	CalculatePF8(base);
+	CalculateSF8(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	return base;
+}
+
+uint16_t x86CPU::Xor16(uint16_t base,uint16_t mask){
+	freg.of=0;
+	freg.cf=0;
+	base=base^mask;
+	CalculatePF16(base);
+	CalculateSF16(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	return base;
+}
+
+uint8_t x86CPU::ShiftLogicalRight8(uint8_t base,uint8_t count){
+	count&=0x1F; //only use bottom 5 bits
+	if(count==0){
+		CalculatePF8(base);
+		CalculateSF8(base);
+		freg.zf=1;
+		return base;
+	}
+	freg.of=(base&0x80)>>7;
+	freg.cf=(base>>(count-1))&1;
+	base=base>>count;
+	freg.of=freg.of^((base&0x80)>>7); //if the sign bit changed, then set it to 1
+	CalculatePF8(base);
+	CalculateSF8(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	freg.of=0;
+	return base;
+}
+
+uint16_t x86CPU::ShiftLogicalRight16(uint16_t base,uint8_t count){
+	count&=0x1F; //only use bottom 5 bits
+	if(count==0){
+		CalculatePF16(base);
+		CalculateSF16(base);
+		freg.zf=1;
+		return base;
+	}
+	freg.of=(base&0x8000)>>15;
+	freg.cf=(base>>(count-1))&1;
+	base=base>>count;
+	freg.of=freg.of^((base&0x8000)>>15); //if the sign bit changed, then set it to 1
+	CalculatePF16(base);
+	CalculateSF16(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	freg.of=0;
+	return base;
+}
+uint8_t x86CPU::ShiftArithmeticRight8(uint8_t base,uint8_t count){
+	count&=0x1F; //only use bottom 5 bits
+	if(count==0){
+		CalculatePF8(base);
+		CalculateSF8(base);
+		freg.zf=1;
+		return base;
+	}
+	freg.cf=(base>>(count-1))&1;
+	if((base&0x80)!=0){
+		base=(base>>count)|(~(0xFF>>count)); //this replaces displaced zero bits with the sign bit
+	}else{
+		base=(base>>count);
+	}
+	freg.of=0;
+	CalculatePF8(base);
+	CalculateSF8(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	freg.of=0;
+	return base;
+}
+uint16_t x86CPU::ShiftArithmeticRight16(uint16_t base,uint8_t count){
+	count&=0x1F; //only use bottom 5 bits
+	if(count==0){
+		CalculatePF16(base);
+		CalculateSF16(base);
+		freg.zf=1;
+		return base;
+	}
+	freg.cf=(base>>(count-1))&1;
+	if((base&0x8000)!=0){
+		base=(base>>count)|(~(0xFFFF>>count)); //this replaces displaced zero bits with the sign bit
+	}else{
+		base=(base>>count);
+	}
+	freg.of=0;
+	CalculatePF16(base);
+	CalculateSF16(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	freg.of=0;
+	return base;
+}
+
+uint8_t x86CPU::ShiftLogicalLeft8(uint8_t base,uint8_t count){
+	count&=0x1F; //only use bottom 5 bits
+	if(count==0){
+		CalculatePF8(base);
+		CalculateSF8(base);
+		freg.zf=1;
+		return base;
+	}
+	freg.of=(base&0x80)>>7;
+	freg.cf=((base<<(count-1))&0x80)>>7;
+	base=base<<count;
+	freg.of=freg.of^((base&0x80)>>7); //if the sign bit changed, then set it to 1
+	CalculatePF8(base);
+	CalculateSF8(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	freg.of=0;
+	return base;
+}
+
+uint16_t x86CPU::ShiftLogicalLeft16(uint16_t base,uint8_t count){
+	count&=0x1F; //only use bottom 5 bits
+	if(count==0){
+		CalculatePF16(base);
+		CalculateSF16(base);
+		freg.zf=1;
+		return base;
+	}
+	freg.of=(base&0x8000)>>15;
+	freg.cf=((base<<(count-1))&0x8000)>>15;
+	base=base<<count;
+	freg.of=freg.of^((base&0x8000)>>15); //if the sign bit changed, then set it to 1
+	CalculatePF16(base);
+	CalculateSF16(base);
+	if(base==0){
+		freg.zf=1;
+	}else{
+		freg.zf=0;
+	}
+	return base;
+}
+
+/**ToDo: Possibly adapt BOCHS source so that we avoid this loop crap...**/
+uint8_t x86CPU::RotateRight8(uint8_t base,uint8_t count){
+	freg.of=(base&0x80)>>7;
+	while(count>0){
+		freg.cf=(base&0x01);
+		base=(freg.cf<<7)|(base>>1);
+		count--;
+	}
+	freg.of=freg.of^((base&0x80)>>7);
+	return base;
+}
+
+uint16_t x86CPU::RotateRight16(uint16_t base,uint8_t count){
+	freg.of=(base&0x8000)>>15;
+	while(count>0){
+		freg.cf=(base&0x01);
+		base=(freg.cf<<15)|(base>>1);
+		count--;
+	}
+	freg.of=freg.of^((base&0x80)>>15);
+	return base;
+}
+
+uint8_t x86CPU::RotateLeft8(uint8_t base,uint8_t count){
+	freg.of=(base&0x80)>>7;
+	while(count>0){
+		freg.cf=(base&0x80)>>7;
+		base=(freg.cf)|(base<<1);
+		count--;
+	}
+	freg.of=freg.of^((base&0x80)>>7);
+	return base;
+}
+
+uint16_t x86CPU::RotateLeft16(uint16_t base,uint8_t count){
+	freg.of=(base&0x8000)>>15;
+	while(count>0){
+		freg.cf=(base&0x8000)>>15;
+		base=(freg.cf)|(base<<1);
+		count--;
+	}
+	freg.of=freg.of^((base&0x8000)>>15);
+	return base;
+}
+
+uint8_t x86CPU::RotateCarryLeft8(uint8_t base,uint8_t count){
+   freg.of=(base&0x80)>>7;
+   while(count>0){
+      freg.r0=freg.cf; //reserved bit as a temp variable...
+      freg.cf=(base&0x80)>>7;
+      base=(base<<1);
+      base|=freg.r0; //puts (old)CF in it's place
+      count--;
+   }
+   freg.of=freg.of^((base&0x80)>>7);
+   return base;
+}
+
+uint16_t x86CPU::RotateCarryLeft16(uint16_t base,uint8_t count){
+	freg.of=(base&0x8000)>>15;
+	while(count>0){
+		freg.r0=freg.cf; //reserved bit as a temp variable...
+		freg.cf=(base&0x8000)>>15;
+		base=(base<<1);
+		base=(base&0xFFFE)|freg.r0; //zeros the 0 bit and puts (old)CF in it's place
+		count--;
+	}
+	freg.of=freg.of^((base&0x8000)>>15);
+	return base;
+}
+
+uint8_t x86CPU::RotateCarryRight8(uint8_t base,uint8_t count){
+	freg.of=(base&0x80)>>7;
+	while(count>0){
+		freg.r0=freg.cf;
+		freg.cf=(base&0x01);
+		base=(freg.r0<<7)|(base>>1);
+		count--;
+	}
+	freg.of=freg.of^((base&0x80)>>7);
+	return base;
+}
+
+uint16_t x86CPU::RotateCarryRight16(uint16_t base,uint8_t count){
+	freg.of=(base&0x8000)>>15;
+	while(count>0){
+		freg.r0=freg.cf;
+		freg.cf=(base&0x01);
+		base=(freg.r0<<15)|(base>>1);
+		count--;
+	}
+	freg.of=freg.of^((base&0x8000)>>15);
+	return base;
+}
+
+
+
+
+
+
+
+
+
+void x86CPU::op16_sub_al_imm8(){ //0x2C
+	*regs8[AL]=Sub8(*regs8[AL],op_cache[1]);
+	eip++;
+}
+
+void x86CPU::op16_sub_ax_imm16(){ //0x2D..yay! 2D and not 3!
+	*regs16[AX]=Sub16(*regs16[AX],*(uint16_t*)&op_cache[1]);
+	eip+=2;
+}
+
+void x86CPU::op16_sub_rm8_r8(){
+	eip++;
+	ModRM16 rm8(this);
+	rm8.WriteByter(Sub8(rm8.ReadByter(),*regs8[rm8.GetExtra()]));
+	//finally learning the power of deconstructors!
+}
+
+void x86CPU::op16_sub_rm16_r16(){
+	eip++;
+	ModRM16 rm16(this);
+	rm16.WriteWordr(Sub16(rm16.ReadWordr(),*regs16[rm16.GetExtra()]));
+}
+void x86CPU::op16_sub_r8_rm8(){
+	eip++;
+	ModRM16 rm8(this);
+	*regs8[rm8.GetExtra()]=Sub8(*regs8[rm8.GetExtra()],rm8.ReadByter());
+}
+
+void x86CPU::op16_sub_r16_rm16(){
+	eip++;
+	ModRM16 rm16(this);
+	*regs16[rm16.GetExtra()]=Sub16(*regs16[rm16.GetExtra()],rm16.ReadWordr());
+}
+
+void x86CPU::op16_sub_rm8_imm8(ModRM16 &rm8){ //group 0x80 /5
+	rm8.WriteByter(Sub8(rm8.ReadByter(),ReadByte(cCS,eip+rm8.GetLength())));
+}
+
+void x86CPU::op16_sub_rm16_imm16(ModRM16 &rm){ //Group 0x81 /5
+	rm.WriteWordr(Sub16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_sub_rm16_imm8(ModRM16 &rm){ //group 0x83 /5
+	rm.WriteWordr(Sub16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))));
+}
+
+/****/
+void x86CPU::op16_sbb_al_imm8(){
+	*regs8[AL]=Sub8(*regs8[AL],op_cache[1]-freg.cf);
+	eip++;
+}
+
+void x86CPU::op16_sbb_ax_imm16(){
+	*regs16[AX]=Sub16(*regs16[AX],*(uint16_t*)&op_cache[1]-freg.cf);
+	eip++;
+	eip++;
+}
+
+void x86CPU::op16_sbb_rm8_r8(){
+	eip++;
+	ModRM16 rm8(this);
+	rm8.WriteByter(Sub8(rm8.ReadByter(),*regs8[rm8.GetExtra()]-freg.cf));
+}
+
+void x86CPU::op16_sbb_rm16_r16(){
+	eip++;
+	ModRM16 rm16(this);
+	rm16.WriteWordr(Sub16(rm16.ReadWordr(),*regs16[rm16.GetExtra()]-freg.cf));
+}
+void x86CPU::op16_sbb_r8_rm8(){
+	eip++;
+	ModRM16 rm8(this);
+	*regs8[rm8.GetExtra()]=Sub8(*regs8[rm8.GetExtra()],rm8.ReadByter()-freg.cf);
+}
+
+void x86CPU::op16_sbb_r16_rm16(){
+	eip++;
+	ModRM16 rm16(this);
+	*regs16[rm16.GetExtra()]=Sub16(*regs16[rm16.GetExtra()],rm16.ReadWordr()-freg.cf);
+}
+
+void x86CPU::op16_sbb_rm8_imm8(ModRM16 &rm8){ //group 0x80
+	rm8.WriteByter(Sub8(rm8.ReadByter(),ReadByte(cCS,eip+rm8.GetLength())-freg.cf));
+}
+
+void x86CPU::op16_sbb_rm16_imm16(ModRM16 &rm){ //Group 0x81
+	rm.WriteWordr(Sub16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())-freg.cf));
+}
+
+void x86CPU::op16_sbb_rm16_imm8(ModRM16 &rm){ //group 0x83
+	rm.WriteWordr(Sub16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())-freg.cf)));
+}
+
+
+void x86CPU::op16_dec_r16(){ //0x48+r
+	freg.r0=freg.cf;
+	*regs16[(op_cache[0]-0x48)]=Sub16(*regs16[(op_cache[0]-0x48)],1);
+	freg.cf=freg.r0;
+}
+
+void x86CPU::op16_dec_rm8(ModRM16& rm){
+	freg.r0=freg.cf;
+	rm.WriteByter(Sub8(rm.ReadByter(),1));
+	freg.cf=freg.r0;
+}
+
+void x86CPU::op16_dec_rm16(ModRM16& rm){
+	freg.r0=freg.cf;
+	rm.WriteWordr(Sub16(rm.ReadWordr(),1));
+	freg.cf=freg.r0;
+}
+
+
+
+
+
+
+//cmp and sub are so similar, that they are both going in here...
+void x86CPU::op16_cmp_al_imm8(){
+	Sub8(*regs8[AL],op_cache[1]);
+	eip++;
+}
+
+void x86CPU::op16_cmp_ax_imm16(){
+	Sub16(*regs16[AX],*(uint16_t*)&op_cache[1]);
+	eip+=2;
+}
+
+void x86CPU::op16_cmp_rm8_r8(){
+	eip++;
+	ModRM16 rm(this);
+	Sub8(rm.ReadByter(),*regs8[rm.GetExtra()]);
+}
+
+void x86CPU::op16_cmp_rm16_r16(){
+	eip++;
+	ModRM16 rm(this);
+	Sub16(rm.ReadWordr(),*regs16[rm.GetExtra()]);
+}
+
+void x86CPU::op16_cmp_r8_rm8(){
+	eip++;
+	ModRM16 rm(this);
+	Sub8(*regs16[rm.GetExtra()],rm.ReadByter());
+}
+
+void x86CPU::op16_cmp_r16_rm16(){
+	eip++;
+	ModRM16 rm(this);
+	Sub16(*regs16[rm.GetExtra()],rm.ReadWordr());
+}
+
+void x86CPU::op16_cmp_rm8_imm8(ModRM16 &rm){ //group 80 /7
+	Sub8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength()));
+}
+
+void x86CPU::op16_cmp_rm16_imm16(ModRM16 &rm){ //group 81 /7
+	Sub16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength()));
+}
+
+void x86CPU::op16_cmp_rm16_imm8(ModRM16 &rm){ //group 83 /7
+	Sub16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())));
+}
+
+
+
+
+
+
+void x86CPU::op16_add_al_imm8(){
+	*regs8[AL]=Add8(*regs8[AL],op_cache[1]);
+	eip++;
+}
+
+void x86CPU::op16_add_ax_imm8(){
+	*regs16[AX]=Add16(*regs16[AX],*(uint16_t*)&op_cache[1]);
+	eip++;
+	eip++;
+}
+
+void x86CPU::op16_add_rm8_r8(){
+	eip++;
+	ModRM16 rm8(this);
+	rm8.WriteByter(Add8(rm8.ReadByter(),*regs8[rm8.GetExtra()]));
+}
+
+void x86CPU::op16_add_rm16_r16(){
+	eip++;
+	ModRM16 rm16(this);
+	rm16.WriteWordr(Add16(rm16.ReadWordr(),*regs16[rm16.GetExtra()]));
+}
+
+void x86CPU::op16_add_r8_rm8(){
+	eip++;
+	ModRM16 rm(this);
+	*regs8[rm.GetExtra()]=Add8(*regs8[rm.GetExtra()],rm.ReadByter());
+}
+
+void x86CPU::op16_add_r16_rm16(){
+	eip++;
+	ModRM16 rm(this);
+	*regs16[rm.GetExtra()]=Add16(*regs16[rm.GetExtra()],rm.ReadWordr());
+}
+
+void x86CPU::op16_add_rm8_imm8(ModRM16 &rm){ //Group 0x80 /0
+	rm.WriteByter(Add8(rm.ReadWordr(),ReadByte(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_add_rm16_imm16(ModRM16 &rm){ //Group 0x81 /0
+	rm.WriteWordr(Add16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_add_rm16_imm8(ModRM16 &rm){ //group 0x83 /0
+	rm.WriteWordr(Add16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))));
+}
+
+
+/****/
+void x86CPU::op16_adc_al_imm8(){
+	*regs8[AL]=Add8(*regs8[AL],op_cache[1]+freg.cf);
+	eip++;
+}
+
+void x86CPU::op16_adc_ax_imm8(){
+	*regs16[AX]=Add16(*regs16[AX],*(uint16_t*)&op_cache[1]+freg.cf);
+	eip++;
+	eip++;
+}
+
+void x86CPU::op16_adc_rm8_r8(){
+	eip++;
+	ModRM16 rm8(this);
+	rm8.WriteByter(Add8(rm8.ReadByter(),*regs8[rm8.GetExtra()]+freg.cf));
+}
+
+void x86CPU::op16_adc_rm16_r16(){
+	eip++;
+	ModRM16 rm16(this);
+	rm16.WriteWordr(Add16(rm16.ReadWordr(),*regs16[rm16.GetExtra()]+freg.cf));
+}
+
+void x86CPU::op16_adc_r8_rm8(){
+	eip++;
+	ModRM16 rm(this);
+	*regs8[rm.GetExtra()]=Add8(*regs8[rm.GetExtra()],rm.ReadByter()+freg.cf);
+}
+
+void x86CPU::op16_adc_r16_rm16(){
+	eip++;
+	ModRM16 rm(this);
+	*regs16[rm.GetExtra()]=Add16(*regs16[rm.GetExtra()],rm.ReadWordr()+freg.cf);
+}
+
+void x86CPU::op16_adc_rm8_imm8(ModRM16 &rm){ //Group 0x80 /2
+	rm.WriteByter(Add8(rm.ReadWordr(),ReadByte(cCS,eip+rm.GetLength())+freg.cf));
+}
+
+void x86CPU::op16_adc_rm16_imm16(ModRM16 &rm){ //Group 0x81 /2
+	rm.WriteWordr(Add16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())+freg.cf));
+}
+
+void x86CPU::op16_adc_rm16_imm8(ModRM16 &rm){ //group 0x83 /2
+	rm.WriteWordr(Add16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))+freg.cf));
+}
+
+
+
+void x86CPU::op16_inc_r16(){ //0x40+r
+	freg.r0=freg.cf;
+	*regs16[(op_cache[0]-0x40)]=Add16(*regs16[(op_cache[0]-0x40)],1);
+	freg.cf=freg.r0;
+}
+
+void x86CPU::op16_inc_rm8(ModRM16 &rm){
+	freg.r0=freg.cf; //yay for reserved flags!
+	rm.WriteByter(Add8(rm.ReadByter(),1));
+	freg.cf=freg.r0;
+}
+
+void x86CPU::op16_inc_rm16(ModRM16 &rm){
+	freg.r0=freg.cf;
+	rm.WriteWordr(Add16(rm.ReadWordr(),1));
+	freg.cf=freg.r0;
+}
+
+void x86CPU::op16_neg_rm8(ModRM16 &rm){
+	uint8_t tmp=rm.ReadByter();
+	if(tmp==0xFF){
+		freg.of=1;
+		return;
+	}
+	rm.WriteByter(Sub8(0,tmp));
+	if(tmp==0){
+		freg.cf=0;
+	}else{
+		freg.cf=1;
+	}
+}
+void x86CPU::op16_neg_rm16(ModRM16 &rm){
+	uint16_t tmp=rm.ReadWordr();
+	if(tmp==0xFFFF){
+		freg.of=1;
+		return;
+	}
+	rm.WriteWordr(Sub16(0,tmp));
+	if(tmp==0){
+		freg.cf=0;
+	}else{
+		freg.cf=1;
+	}
+}
+
+
+
+void x86CPU::op16_div_rm8(ModRM16 &rm){
+	if(rm.ReadByter()==0){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+	if(((*regs16[AX])/rm.ReadByter())>0xFF){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP); 
+	}
+	*regs8[AL]=(*regs16[AX])/rm.ReadByter();
+	*regs8[AH]=(*regs16[AX])%rm.ReadByter();
+}
+
+void x86CPU::op16_div_rm16(ModRM16 &rm){
+	if(rm.ReadWordr()==0){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+	if((((*regs16[DX]<<16)|(*regs16[AX]))/rm.ReadWordr())>0xFFFF){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+	*regs8[AX]=((*regs16[DX]<<16)|(*regs16[AX]))/rm.ReadWordr();
+	*regs8[DX]=((*regs16[DX]<<16)|(*regs16[AX]))%rm.ReadWordr();
+}
+
+
+void x86CPU::op16_idiv_rm8(ModRM16 &rm){ //This WORKS! both signed, and unsigned!
+	//grrr...who the crap does signed division anyway!?
+	if(rm.ReadByter()==0){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+	uint8_t tmp=rm.ReadByter();
+	bool store1,store2;
+
+	tmp=Unsign8(tmp,store1);
+	*regs16[AX]=Unsign16(*regs16[AX],store2);
+	if(((*regs16[AX])/tmp)>0xFF){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+
+	*regs8[AL]=(*regs16[AX])/tmp;
+	*regs8[AH]=(*regs16[AX])%tmp;
+
+	*regs8[AL]=Resign8(*regs8[AL],store1^store2);
+}
+
+void x86CPU::op16_idiv_rm16(ModRM16 &rm){
+	if(rm.ReadWordr()==0){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+	uint16_t tmp=rm.ReadWordr();
+	bool store1,store2;
+	tmp=Unsign16(tmp,store1);
+	static uint32_t tmp2=Unsign32(((*regs16[DX])<<16)|(*regs16[AX]),store2);
+
+	if((tmp2/tmp)>0xFFFF){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+	*regs16[AX]=tmp2/tmp;
+	*regs16[DX]=tmp2%tmp;
+
+	*regs16[AX]=Resign16(*regs16[AX],store1^store2);
+}
+
+
+
+void x86CPU::op16_mul_rm8(ModRM16 &rm){
+    *regs16[AX]=(*regs8[AL])*rm.ReadByter();
+    if((*regs8[AH])>0){ //if tophalf of result has anything in it
+        freg.cf=1;
+        freg.of=1;
+    }else{
+        freg.cf=0;
+        freg.of=0;
+    }
+}
+
+
+void x86CPU::op16_mul_rm16(ModRM16 &rm){
+	uint32_t result;
+    result=(*regs16[AX])*rm.ReadWordr();
+    *regs16[AX]=result&0x0000FFFF;
+    *regs16[DX]=(result&0xFFFF0000)>>16;
+    if((*regs16[DX])>0){ //if tophalf of result has anything in it
+        freg.cf=1;
+        freg.of=1;
+    }else{
+        freg.cf=0;
+        freg.of=0;
+    }
+}
+
+void x86CPU::op16_imul_rm8(ModRM16 &rm){
+	bool store1,store2;
+	*regs16[AX]=Unsign8(*regs8[AL],store1)*Unsign8(rm.ReadByter(),store2);
+	if(*regs8[AX]>0){
+		freg.of=1;
+		freg.cf=1;
+	}else{
+		freg.of=0;
+		freg.cf=0;
+	}
+	*regs16[AX]=Resign16(*regs16[AX],store1^store2);
+}
+
+void x86CPU::op16_imul_rm16(ModRM16 &rm){
+	bool store1,store2;
+	uint32_t result=Unsign16(*regs16[AX],store1)*Unsign16(rm.ReadWordr(),store2);
+	if((result&0xFFFF0000)>0){
+		freg.of=1;
+		freg.cf=1;
+	}else{
+		freg.of=0;
+		freg.cf=0;
+	}
+	result=Resign32(result,store1^store2);
+	*regs16[DX]=(result&0xFFFF0000)>>16;
+	*regs16[AX]=(result&0xFFFF);
+}
+
+
+
+void x86CPU::op16_and_rm8_r8(){
+	eip++;
+	ModRM16 rm(this);
+	rm.WriteByter(And8(rm.ReadByter(),*regs8[rm.GetExtra()]));
+}
+
+void x86CPU::op16_and_rm16_r16(){
+	eip++;
+	ModRM16 rm(this);
+	rm.WriteWordr(And16(rm.ReadWordr(),*regs16[rm.GetExtra()]));
+}
+
+void x86CPU::op16_and_r8_rm8(){
+	eip++;
+	ModRM16 rm(this);
+	*regs8[rm.GetExtra()]=And8(*regs8[rm.GetExtra()],rm.ReadByter());
+}
+
+void x86CPU::op16_and_r16_rm16(){
+	eip++;
+	ModRM16 rm(this);
+	*regs16[rm.GetExtra()]=And16(*regs16[rm.GetExtra()],rm.ReadWordr());
+}
+
+void x86CPU::op16_and_al_imm8(){
+	eip++;
+	*regs8[AL]=And8(*regs8[AL],op_cache[1]);
+}
+
+void x86CPU::op16_and_ax_imm16(){
+	eip++;
+	eip++;
+	*regs16[AX]=And16(*regs16[AX],*(uint16_t*)&op_cache[1]);
+}
+
+void x86CPU::op16_and_rm8_imm8(ModRM16& rm){
+	rm.WriteByter(And8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_and_rm16_imm16(ModRM16& rm){
+	rm.WriteWordr(And16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_and_rm16_imm8(ModRM16& rm){
+	rm.WriteWordr(And16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))));
+	//gotta love parentheses...
+}
+
+void x86CPU::op16_or_rm8_r8(){
+	eip++;
+	ModRM16 rm(this);
+	rm.WriteByter(Or8(rm.ReadByter(),*regs8[rm.GetExtra()]));
+}
+
+void x86CPU::op16_or_rm16_r16(){
+	eip++;
+	ModRM16 rm(this);
+	rm.WriteWordr(Or16(rm.ReadWordr(),*regs16[rm.GetExtra()]));
+}
+
+void x86CPU::op16_or_r8_rm8(){
+	eip++;
+	ModRM16 rm(this);
+	*regs8[rm.GetExtra()]=Or8(*regs8[rm.GetExtra()],rm.ReadByter());
+}
+
+void x86CPU::op16_or_r16_rm16(){
+	eip++;
+	ModRM16 rm(this);
+	*regs16[rm.GetExtra()]=Or16(*regs16[rm.GetExtra()],rm.ReadWordr());
+}
+
+void x86CPU::op16_or_al_imm8(){
+	eip++;
+	*regs8[AL]=Or8(*regs8[AL],op_cache[1]);
+}
+
+void x86CPU::op16_or_ax_imm16(){
+	eip++;
+	eip++;
+	*regs16[AX]=Or16(*regs16[AX],*(uint16_t*)&op_cache[1]);
+}
+
+void x86CPU::op16_or_rm8_imm8(ModRM16& rm){
+	rm.WriteByter(Or8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_or_rm16_imm16(ModRM16& rm){
+	rm.WriteWordr(Or16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_or_rm16_imm8(ModRM16& rm){
+	rm.WriteWordr(Or16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))));
+	//gotta love parentheses...
+}
+
+
+
+void x86CPU::op16_xor_rm8_r8(){
+	eip++;
+	ModRM16 rm(this);
+	rm.WriteByter(Xor8(rm.ReadByter(),*regs8[rm.GetExtra()]));
+}
+
+void x86CPU::op16_xor_rm16_r16(){
+	eip++;
+	ModRM16 rm(this);
+	rm.WriteWordr(Xor16(rm.ReadWordr(),*regs16[rm.GetExtra()]));
+}
+
+void x86CPU::op16_xor_r8_rm8(){
+	eip++;
+	ModRM16 rm(this);
+	*regs8[rm.GetExtra()]=Xor8(*regs8[rm.GetExtra()],rm.ReadByter());
+}
+
+void x86CPU::op16_xor_r16_rm16(){
+	eip++;
+	ModRM16 rm(this);
+	*regs16[rm.GetExtra()]=Xor16(*regs16[rm.GetExtra()],rm.ReadWordr());
+}
+
+void x86CPU::op16_xor_al_imm8(){
+	eip++;
+	*regs8[AL]=Xor8(*regs8[AL],op_cache[1]);
+}
+
+void x86CPU::op16_xor_ax_imm16(){
+	eip++;
+	eip++;
+	*regs16[AX]=Xor16(*regs16[AX],*(uint16_t*)&op_cache[1]);
+}
+
+void x86CPU::op16_xor_rm8_imm8(ModRM16& rm){
+	rm.WriteByter(Xor8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_xor_rm16_imm16(ModRM16& rm){
+	rm.WriteWordr(Xor16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength())));
+}
+
+void x86CPU::op16_xor_rm16_imm8(ModRM16& rm){
+	rm.WriteWordr(Xor16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength()))));
+	//gotta love parentheses...
+}
+
+void x86CPU::op16_test_rm8_r8(){
+	eip++;
+	ModRM16 rm(this);
+	And8(rm.ReadByter(),*regs8[rm.GetExtra()]);
+}
+
+void x86CPU::op16_test_rm16_r16(){
+	eip++;
+	ModRM16 rm(this);
+	And16(rm.ReadWordr(),*regs16[rm.GetExtra()]);
+}
+void x86CPU::op16_test_al_imm8(){
+	eip++;
+	And8(*regs8[AL],op_cache[1]);
+}
+void x86CPU::op16_test_ax_imm16(){
+	eip++;
+	eip++;
+	And16(*regs16[AX],*(uint16_t*)&op_cache[1]);
+}
+
+void x86CPU::op16_test_rm8_imm8(ModRM16& rm){
+	And8(rm.ReadByter(),ReadByte(cCS,eip+rm.GetLength()));
+}
+
+void x86CPU::op16_test_rm16_imm16(ModRM16& rm){
+	And16(rm.ReadWordr(),ReadWord(cCS,eip+rm.GetLength()));
+}
+
+void x86CPU::op16_test_rm16_imm8(ModRM16& rm){
+	And16(rm.ReadWordr(),SignExtend8(ReadByte(cCS,eip+rm.GetLength())));
+	//gotta love parentheses...
+}
+
+
+void x86CPU::op16_shr_rm8_cl(ModRM16 &rm){
+	rm.WriteByter(ShiftLogicalRight8(rm.ReadByter(),*regs8[CL]));
+}
+void x86CPU::op16_shr_rm16_cl(ModRM16 &rm){
+	rm.WriteWordr(ShiftLogicalRight16(rm.ReadWordr(),*regs8[CL]));
+}
+
+void x86CPU::op16_shl_rm8_cl(ModRM16 &rm){
+	rm.WriteByter(ShiftLogicalLeft8(rm.ReadByter(),*regs8[CL]));
+}
+void x86CPU::op16_shl_rm16_cl(ModRM16 &rm){
+	rm.WriteWordr(ShiftLogicalLeft16(rm.ReadWordr(),*regs8[CL]));
+}
+
+void x86CPU::op16_sar_rm8_cl(ModRM16 &rm){
+	rm.WriteByter(ShiftArithmeticRight8(rm.ReadByter(),*regs8[CL]));
+}
+void x86CPU::op16_sar_rm16_cl(ModRM16 &rm){
+	rm.WriteWordr(ShiftArithmeticRight16(rm.ReadWordr(),*regs8[CL]));
+}
+
+void x86CPU::op16_rol_rm8_cl(ModRM16 &rm){
+	rm.WriteByter(RotateLeft8(rm.ReadByter(),*regs8[CL]));
+}
+void x86CPU::op16_rol_rm16_cl(ModRM16 &rm){
+	rm.WriteWordr(RotateLeft16(rm.ReadWordr(),*regs8[CL]));
+}
+
+void x86CPU::op16_ror_rm8_cl(ModRM16 &rm){
+	rm.WriteByter(RotateRight8(rm.ReadByter(),*regs8[CL]));
+}
+void x86CPU::op16_ror_rm16_cl(ModRM16 &rm){
+	rm.WriteWordr(RotateRight16(rm.ReadWordr(),*regs8[CL]));
+}
+
+
+void x86CPU::op16_rcl_rm8_cl(ModRM16 &rm){
+	rm.WriteByter(RotateCarryLeft8(rm.ReadByter(),*regs8[CL]));
+}
+void x86CPU::op16_rcl_rm16_cl(ModRM16 &rm){
+	rm.WriteWordr(RotateCarryLeft16(rm.ReadWordr(),*regs8[CL]));
+}
+
+void x86CPU::op16_rcr_rm8_cl(ModRM16 &rm){
+	rm.WriteByter(RotateCarryRight8(rm.ReadByter(),*regs8[CL]));
+}
+void x86CPU::op16_rcr_rm16_cl(ModRM16 &rm){
+	rm.WriteWordr(RotateCarryRight16(rm.ReadWordr(),*regs8[CL]));
+}
+
+
+/****/
+void x86CPU::op16_shr_rm8_1(ModRM16 &rm){
+	rm.WriteByter(ShiftLogicalRight8(rm.ReadByter(),1));
+}
+void x86CPU::op16_shr_rm16_1(ModRM16 &rm){
+	rm.WriteWordr(ShiftLogicalRight16(rm.ReadWordr(),1));
+}
+
+void x86CPU::op16_shl_rm8_1(ModRM16 &rm){
+	rm.WriteByter(ShiftLogicalLeft8(rm.ReadByter(),1));
+}
+void x86CPU::op16_shl_rm16_1(ModRM16 &rm){
+	rm.WriteWordr(ShiftLogicalLeft16(rm.ReadWordr(),1));
+}
+
+void x86CPU::op16_sar_rm8_1(ModRM16 &rm){
+	rm.WriteByter(ShiftArithmeticRight8(rm.ReadByter(),1));
+}
+void x86CPU::op16_sar_rm16_1(ModRM16 &rm){
+	rm.WriteWordr(ShiftArithmeticRight16(rm.ReadWordr(),1));
+}
+
+void x86CPU::op16_rol_rm8_1(ModRM16 &rm){
+	rm.WriteByter(RotateLeft8(rm.ReadByter(),1));
+}
+void x86CPU::op16_rol_rm16_1(ModRM16 &rm){
+	rm.WriteWordr(RotateLeft16(rm.ReadWordr(),1));
+}
+
+void x86CPU::op16_ror_rm8_1(ModRM16 &rm){
+	rm.WriteByter(RotateRight8(rm.ReadByter(),1));
+}
+void x86CPU::op16_ror_rm16_1(ModRM16 &rm){
+	rm.WriteWordr(RotateRight16(rm.ReadWordr(),1));
+}
+
+
+void x86CPU::op16_rcl_rm8_1(ModRM16 &rm){
+	rm.WriteByter(RotateCarryLeft8(rm.ReadByter(),1));
+}
+void x86CPU::op16_rcl_rm16_1(ModRM16 &rm){
+	rm.WriteWordr(RotateCarryLeft16(rm.ReadWordr(),1));
+}
+
+void x86CPU::op16_rcr_rm8_1(ModRM16 &rm){
+	rm.WriteByter(RotateCarryRight8(rm.ReadByter(),1));
+}
+void x86CPU::op16_rcr_rm16_1(ModRM16 &rm){
+	rm.WriteWordr(RotateCarryRight16(rm.ReadWordr(),1));
+}
+
+void x86CPU::op16_not_rm8(ModRM16 &rm){
+	rm.WriteByter(~(rm.ReadByter()));
+}
+
+void x86CPU::op16_not_rm16(ModRM16 &rm){
+	rm.WriteWordr(~(rm.ReadWordr()));
+}
+
+
+
+
+/**
+BCD Opcodes for Open86
+By: Alboin, 3-16-07
+Modified to work with x86Lib by Jordan(hckr83)
+**/
+
+
+/* Opcode: 0x37 */
+void x86CPU::op16_aaa() {
+	if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) {
+		*regs8[AL] += 6;
+		*regs8[AH]++;
+		freg.af = 1;
+		freg.cf = 1;
+	}
+	else {
+		freg.af = 0;
+		freg.cf = 0;
+	}
+	*regs8[AL] = *regs8[AL] & 0x0f;
+}
+
+
+/* Opcode: 0x27 */
+void x86CPU::op16_daa() {
+	if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) {
+		*regs8[AL] += 6;
+		*regs8[AH]++;
+	}
+	else
+		freg.af = 0;
+
+	if(*regs8[AL] > 0x9f || freg.cf == 1) {
+			*regs8[AL] = *regs8[AL] + 0x60;
+			freg.cf = 1;
+	}
+	else
+		freg.cf = 0;
+}
+
+/* Opcode: 0x2F */
+void x86CPU::op16_das() {
+	if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) {
+		*regs8[AL] -= 6;
+		freg.af = 1;
+	}
+	else
+		freg.af = 0;
+
+	if(*regs8[AL] > 0x9f || freg.cf == 1) {
+			*regs8[AL] -= 0x60;
+			freg.cf = 1;
+	}
+	else
+		freg.cf = 0;
+}
+
+/* Opcode: 0x3F */
+void x86CPU::op16_aas() {
+	if((*regs8[AL] & 0x0f) > 9 || freg.af == 1) {
+		*regs8[AL] -= 6;
+		*regs8[AH]--;
+		freg.af = 1;
+		freg.cf = 1;
+	}
+	else {
+		freg.af = 0;
+		freg.cf = 0;
+	}
+	*regs8[AL] = *regs8[AL] & 0x0f;
+}
+
+
+
+void x86CPU::op16_aad(){
+	//AAD is a weird opcode because it is two bytes
+	//for "apparently" no reason. But really, it is just
+	//undocumented... the 0x0A in the second byte is for
+	//multiplecation...but it can be changed...
+	*regs8[AL]=(*regs8[AH])*(op_cache[1])+*regs8[AL];
+	*regs8[AH]=0;
+}
+
+void x86CPU::op16_aam(){
+	//same wiht the 0x0A operand as above..
+	if(op_cache[1]==0){
+	    Onx86LibError();
+		//throw CpuInt_excp(DIV0_IEXCP);
+	}
+	*regs8[AH]=(*regs8[AL])/op_cache[1];
+	*regs8[AL]=(*regs8[AL])%op_cache[1];
+}
+
+
+
+
+
+
+
+
+
+
+};
+
+
+
diff -r 000000000000 -r 217a7931b41f ops/store.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ops/store.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,307 @@
+/**
+Copyright (c) 2007 - 2010 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <x86Lib.h>
+namespace x86Lib{
+using namespace std;
+
+
+
+
+
+
+void x86CPU::op16_mov_r8_imm8(){ //0xB0+r
+    //I suppose the first real instruction is the hardest...
+    *regs8[op_cache[0]-0xB0]=op_cache[1];
+    eip++;
+}
+
+void x86CPU::op16_mov_r16_imm16(){ //0xB8+r
+    *regs16[op_cache[0]-0xB8]=*(uint16_t*)&op_cache[1];
+    eip+=2;
+}
+
+void x86CPU::op16_mov_sr_rm16(){ //0x8E
+    eip++;
+    ModRM16 rm16(this);
+    if(rm16.GetExtra()==cSS){ //if a mov into SS, then disable interrupts for 1 instruction.
+        cli_count=2;
+        freg._if=0;
+    }
+    seg[rm16.GetExtra()]=rm16.ReadWordr();
+}
+
+void x86CPU::op16_mov_rm16_sr(){ //0x8C
+    eip++;
+    ModRM16 rm16(this);
+    rm16.WriteWordr(seg[rm16.GetExtra()]);
+}
+
+
+
+void x86CPU::op16_mov_r16_rm16(){
+    eip++;
+    ModRM16 rm16(this);
+    *regs16[rm16.GetExtra()]=rm16.ReadWordr();
+}
+
+void x86CPU::op16_mov_rm16_r16(){
+    eip++;
+    ModRM16 rm16(this);
+    rm16.WriteWordr(*regs16[rm16.GetExtra()]);
+}
+
+void x86CPU::op16_mov_al_off8(){
+    *regs8[AL]=ReadByte(DS,*(uint16_t*)&op_cache[1]);
+    eip++;
+    eip++;
+}
+void x86CPU::op16_mov_ax_off16(){
+    *regs16[AX]=ReadWord(DS,*(uint16_t*)&op_cache[1]);
+    eip++;
+    eip++;
+}
+
+void x86CPU::op16_mov_rm8_r8(){
+    eip++;
+    ModRM16 rm(this);
+    rm.WriteByter(*regs8[rm.GetExtra()]);
+}
+
+void x86CPU::op16_mov_r8_rm8(){
+    eip++;
+    ModRM16 rm(this);
+    *regs8[rm.GetExtra()]=rm.ReadByter();
+}
+void x86CPU::op16_mov_off8_al(){
+    WriteByte(DS,*(uint16_t*)&op_cache[1],*regs8[AL]);
+    eip++;
+    eip++;
+}
+
+void x86CPU::op16_mov_off16_ax(){
+    WriteWord(DS,*(uint16_t*)&op_cache[1],*regs16[AX]);
+    eip++;eip++;
+}
+
+void x86CPU::op16_mov_m8_imm8(){
+    eip++;
+    ModRM16 rm(this);
+    
+    //eventually fix this so that if r is used, then invalid opcode...
+    rm.WriteByter(ReadByte(cCS,eip+rm.GetLength()));
+    eip++;
+}
+
+void x86CPU::op16_mov_m16_imm16(){
+    eip++;
+    ModRM16 rm(this);
+    rm.WriteWordr(ReadWord(cCS,eip+rm.GetLength()));
+    eip++;
+    eip++;
+}
+
+void x86CPU::op16_lds(){
+    eip++;
+    ModRM16 rm(this);
+    uint32_t tmp=rm.ReadDword();
+    seg[cDS]=(tmp&0xFFFF0000)>>16;
+    *regs16[rm.GetExtra()]=(tmp&0xFFFF);
+}
+
+void x86CPU::op16_les(){
+    eip++;
+    ModRM16 rm(this);
+    uint32_t tmp=rm.ReadDword();
+    seg[cES]=(tmp&0xFFFF0000)>>16;
+    *regs16[rm.GetExtra()]=(tmp&0xFFFF);
+}
+
+void x86CPU::op16_lea(){ //wtf is the point of this instruction! why not just mov reg,immediate! seriously frikkin crazy designers of x86
+    eip++;
+    ModRM16 rm(this);
+    *regs16[rm.GetExtra()]=rm.ReadOffset();
+}
+
+
+
+void x86CPU::op16_push_imm8(){
+    eip++;
+    Push16(op_cache[1]);
+}
+void x86CPU::op16_push_m16(ModRM16 &rm){
+    Push16(rm.ReadWordr());
+}
+
+void x86CPU::op16_push_imm16(){ //0x68
+    eip++;
+    Push16(*(uint16_t*)&op_cache[1]);
+    eip++;
+}
+
+
+void x86CPU::op16_push_r16(){ //0x50+reg
+    Push16(*regs16[op_cache[0]-0x50]);
+}
+
+void x86CPU::op16_push_es(){
+    Push16(seg[ES]);
+}
+
+void x86CPU::op16_push_cs(){
+    Push16(seg[CS]);
+}
+
+void x86CPU::op16_push_ds(){
+    Push16(seg[DS]);
+}
+
+
+void x86CPU::op16_push_ss(){
+    Push16(seg[SS]);
+}
+
+
+
+void x86CPU::op16_pop_m16(ModRM16 &rm){
+    rm.WriteWordr(Pop16());
+}
+
+void x86CPU::op16_pop_r16(){ //0x58+reg
+    *regs16[op_cache[0]-0x58]=Pop16();
+}
+
+
+void x86CPU::op16_pop_es(){
+    seg[ES]=Pop16();
+}
+
+void x86CPU::op16_pop_ss(){
+    cli_count=2;
+    freg._if=0;
+    seg[SS]=Pop16();
+}
+
+void x86CPU::op16_pop_ds(){
+    seg[DS]=Pop16();
+}
+
+
+
+void x86CPU::op16_out_imm8_al(){
+    Ports->Write(op_cache[1],1,(void*)regs8[AL]);
+    eip++;
+}
+
+void x86CPU::op16_out_imm8_ax(){
+    Ports->Write(op_cache[1],2,(void*)regs16[AX]);
+    eip++;
+}
+
+void x86CPU::op16_out_dx_al(){
+    Ports->Write(*regs16[DX],1,(void*)regs8[AL]);
+}
+
+void x86CPU::op16_out_dx_ax(){
+    Ports->Write(*regs16[DX],2,(void*)regs16[AX]);
+}
+
+
+void x86CPU::op16_in_al_imm8(){
+    Ports->Read(op_cache[1],1,(void*)regs8[AL]);
+    eip++;
+}
+
+void x86CPU::op16_in_ax_imm8(){
+    Ports->Read(op_cache[1],2,(void*)regs16[AX]);
+    eip++;
+}
+
+void x86CPU::op16_in_al_dx(){
+    Ports->Read(*regs16[DX],1,(void*)regs8[AL]);
+}
+
+void x86CPU::op16_in_ax_dx(){
+    Ports->Read(*regs16[DX],2,(void*)regs16[AX]);
+}
+
+
+
+void x86CPU::op16_xchg_rm8_r8(){
+    #ifndef X86_MULTITHREADING
+    if(IsLocked()==1){
+        eip--;
+        return;
+    }
+    #endif
+    Lock();
+    eip++;
+    ModRM16 rm(this);
+    uint8_t tmp=*regs8[rm.GetExtra()];
+    *regs8[rm.GetExtra()]=rm.ReadByter();
+    rm.WriteByter(tmp);
+    Unlock();
+}
+void x86CPU::op16_xchg_rm16_r16(){
+    #ifndef X86_MULTITHREADING
+    if(IsLocked()==1){
+        eip--;
+        return;
+    }
+    #endif
+    Lock();
+    eip++;
+    ModRM16 rm(this);
+    uint16_t tmp=*regs16[rm.GetExtra()];
+    *regs16[rm.GetExtra()]=rm.ReadWordr();
+    rm.WriteWordr(tmp);
+    Unlock();
+}
+
+void x86CPU::op16_xchg_ax_r16(){ //0x90+r
+    uint16_t tmp=*regs16[AX];
+    *regs16[AX]=*regs16[op_cache[0]-0x90];
+    *regs16[op_cache[0]-0x90]=tmp;
+}
+
+
+void x86CPU::op16_xlatb(){
+    *regs8[AL]=ReadByte(DS,(*regs16[BX])+(*regs8[AL]));
+}
+
+
+
+
+
+
+};
+
+
+
diff -r 000000000000 -r 217a7931b41f ops/strings.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ops/strings.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,92 @@
+/**
+Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <x86Lib.h>
+namespace x86Lib{
+using namespace std;
+
+
+
+void x86CPU::op16_movsb(){
+	WriteByte(cES,*regs16[DI],ReadByte(DS,*regs16[SI]));
+	SetIndex8();
+}
+
+void x86CPU::op16_movsw(){
+	WriteWord(cES,*regs16[DI],ReadWord(DS,*regs16[SI]));
+	SetIndex16();
+}
+
+void x86CPU::op16_cmpsb(){
+	string_compares=1;
+	Sub8(ReadByte(DS,*regs16[SI]),ReadByte(cES,*regs16[DI]));
+	SetIndex8();
+}
+
+void x86CPU::op16_cmpsw(){
+	string_compares=1;
+	Sub16(ReadWord(DS,*regs16[SI]),ReadWord(cES,*regs16[DI]));
+	SetIndex16();
+}
+
+void x86CPU::op16_lodsb(){
+	*regs8[AL]=ReadByte(DS,*regs16[SI]);
+	SetIndex8();
+}
+void x86CPU::op16_lodsw(){
+	*regs16[AX]=ReadWord(DS,*regs16[SI]);
+	SetIndex16();
+}
+
+void x86CPU::op16_scasb(){
+	string_compares=1;
+	Sub8(*regs8[AL],ReadByte(cES,*regs16[DI]));
+	SetIndex8();
+}
+void x86CPU::op16_scasw(){
+	string_compares=1;
+	Sub16(*regs16[AX],ReadWord(cES,*regs16[DI]));
+	SetIndex16();
+}
+void x86CPU::op16_stosb(){
+	WriteByte(ES,*regs16[DI],*regs8[AL]);
+	SetIndex8();
+}
+void x86CPU::op16_stosw(){
+	WriteWord(ES,*regs16[DI],*regs16[AX]);
+	SetIndex16();
+}
+
+
+
+};
+
+
+
diff -r 000000000000 -r 217a7931b41f x86Lib.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/x86Lib.cpp	Sun Mar 04 08:15:47 2012 +0000
@@ -0,0 +1,542 @@
+/**
+Copyright (c) 2007 - 2010 Jordan "Earlz/hckr83" Earls  <http://www.Earlz.biz.tm>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+   
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+This file is part of the x86Lib project.
+**/
+#define X86LIB_BUILD
+#include <iostream>
+#include "include/x86Lib.h"
+
+
+namespace x86Lib{
+//The lack of indentation for namespaces is intentional...
+using namespace std;
+
+
+x86CPU::x86CPU(uint32_t cpu_level_,uint32_t flags){
+    if(cpu_level_==0){
+        cpu_level=CPU286_REAL; //The default CPU right now..
+    }else{
+        cpu_level=cpu_level_;
+    }
+    Init();
+}
+x86CPU::x86CPU(x86SaveData &load_data,uint32_t flags){
+    Init();
+    LoadState(load_data);
+}
+
+void x86CPU::Init(){
+    //ports=new x86Ports();
+#ifdef ENABLE_OPCODE_CALLBACK
+    EachOpcodeCallback=NULL;
+#endif
+    Reset();
+}
+
+void Onx86LibError()
+{
+    Serial pc(USBTX, USBRX); // tx, rx
+    pc.printf("x86lib error\n");
+    exit(1);
+}
+
+void x86CPU::Reset(){
+    /**Initialize register pointers**/
+    regs16[0]=&((volatile uint16_t*)reg32)[0];
+    regs16[1]=&((volatile uint16_t*)reg32)[2];
+    regs16[2]=&((volatile uint16_t*)reg32)[4];
+    regs16[3]=&((volatile uint16_t*)reg32)[6];
+    regs16[4]=&((volatile uint16_t*)reg32)[8];
+    regs16[5]=&((volatile uint16_t*)reg32)[10];
+    regs16[6]=&((volatile uint16_t*)reg32)[12];
+    regs16[7]=&((volatile uint16_t*)reg32)[14];
+    regs8[0]=&((volatile uint8_t*)reg32)[0];
+    regs8[1]=&((volatile uint8_t*)reg32)[4];
+    regs8[2]=&((volatile uint8_t*)reg32)[8];
+    regs8[3]=&((volatile uint8_t*)reg32)[12], //now do all the highs
+    regs8[4]=&((volatile uint8_t*)reg32)[1];
+    regs8[5]=&((volatile uint8_t*)reg32)[5];
+    regs8[6]=&((volatile uint8_t*)reg32)[9];
+    regs8[7]=&((volatile uint8_t*)reg32)[13];
+    busmaster=0;
+    //assumes pmem and ports are still the same...
+    InitOpcodes();
+    uint32_t i;
+    for(i=0;i<8;i++){
+        reg32[i]=0;
+    }
+    for(i=0;i<7;i++){
+        seg[i]=0;
+    }
+    ResetSegments();
+    //eip=0xFFFE;
+    eip=0x0;
+    seg[cCS]=0xF000;
+    *(uint16_t*)&freg=0;
+    string_compares=0;
+    int_pending=0;
+    cli_count=0;
+}
+
+
+void x86CPU::SaveState(x86SaveData *save){
+    uint32_t i;
+    for(i=0;i<8;i++){
+        save->reg32[i]=reg32[i];
+    }
+    for(i=0;i<7;i++){
+        save->seg[i]=seg[i];
+    }
+    save->freg=*(uint16_t*)&freg;
+    save->eip=eip;
+    save->seg_route[cES]=ES;
+    save->seg_route[cCS]=CS;
+    save->seg_route[cDS]=DS;
+    save->seg_route[cSS]=SS;
+    save->seg_route[cFS]=FS;
+    save->seg_route[cGS]=GS;
+    save->cpu_level=cpu_level;
+    if(Opcodes==opcodes_16bit){
+        save->opcode_mode=OPCODE_REAL_16;
+    }else{
+        Onx86LibError();
+        //throw Default_excp(__FILE__,__FUNCTION__,__LINE__);
+    }
+}
+
+void x86CPU::LoadState(x86SaveData &load){
+    uint32_t i;
+    cpu_level=load.cpu_level;
+    Reset();
+    for(i=0;i<8;i++){
+        reg32[i]=load.reg32[i];
+    }
+    for(i=0;i<7;i++){
+        seg[i]=load.seg[i];
+    }
+    *(uint16_t*)&freg=load.freg;
+    eip=load.eip;
+    ES=load.seg_route[cES];
+    CS=load.seg_route[cCS];
+    DS=load.seg_route[cDS];
+    SS=load.seg_route[cSS];
+    GS=load.seg_route[cGS];
+    FS=load.seg_route[cFS];
+    if(load.opcode_mode==OPCODE_REAL_16){
+        Opcodes=opcodes_16bit;
+    }else{
+        Onx86LibError();
+        //throw Default_excp(__FILE__,__FUNCTION__,__LINE__);
+    }
+}
+
+
+
+
+void x86CPU::DumpState(ostream &output){
+    output << "EAX: "<< hex << reg32[EAX] <<endl;
+    output << "ECX: "<< hex << reg32[ECX] <<endl;
+    output << "EDX: "<< hex << reg32[EDX] <<endl;
+    output << "EBX: "<< hex << reg32[EBX] <<endl;
+    output << "ESP: "<< hex << reg32[ESP] <<endl;
+    output << "EBP: "<< hex << reg32[EBP] <<endl;
+    output << "ESI: "<< hex << reg32[ESI] <<endl;
+    output << "EDI: "<< hex << reg32[EDI] <<endl;
+
+    output << "CS: " << hex << seg[cCS] << endl;
+    output << "SS: " << hex << seg[cSS] << endl;
+    output << "DS: " << hex << seg[cDS] << endl;
+    output << "ES: " << hex << seg[cES] << endl;
+    output << "FS: " << hex << seg[cFS] << endl;
+    output << "GS: " << hex << seg[cGS] << endl;
+    output << "EIP: " << hex << eip << endl;
+
+    output << "--Flags:" <<hex << *(uint16_t*)&freg<< endl;
+    output << "CF: " << (int)freg.cf << endl;
+    output << "PF: " << (int)freg.pf << endl;
+    output << "AF: " << (int)freg.af << endl;
+    output << "ZF: " << (int)freg.zf << endl;
+    output << "SF: " << (int)freg.sf << endl;
+    output << "TF: " << (int)freg.tf << endl;
+    output << "IF: " << (int)freg._if << endl;
+    output << "DF: " << (int)freg.df << endl;
+    output << "OF: " << (int)freg.of << endl;
+}
+
+void x86CPU::Int(uint8_t num){ //external interrupt
+    int_pending=1;
+    int_number=num;
+}
+
+bool x86CPU::IntPending(){
+    return int_pending;
+}
+
+
+
+int x86CPU::CheckInterrupts(){
+    //possible bug here. What if we have a pop SS without an interrupt waiting? Won't interrupts be forever ignored?
+    if(int_pending==0){return 0;} //quickly get out of this, this is in the main Cycle loop, so needs to be very speedy...
+    if((int_pending==1) && (int_number==2)){ //NMI
+        eip--;
+        Int16(2);
+        eip++;
+        int_pending=0;
+        return 1;
+    }
+    if(freg._if==0){
+        if(cli_count>1){
+            cli_count--;
+        }else{
+            if(cli_count!=0){
+                freg._if=1;
+            }
+        }
+    }else{
+        if(int_pending==1){
+            eip--;
+            Int16(int_number);
+            eip++;
+            int_pending=0;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+void x86CPU::Exec(int cyclecount){
+    int i=0;
+    bool done=false;
+    while(!done){
+        //try{
+            for(;i<cyclecount;i++){
+                Cycle();
+            }
+        //}
+        /*catch(CpuInt_excp err){
+            err.code&=0x00FF;
+            switch(err.code){
+                case 0: //division by zero
+                case 1: //debug exception
+                case 2: //NMI
+                case 3: //breakpoint
+                case 4: //overflow
+                
+                case 7: //device unavailable
+                Int16(err.code);
+                eip++; //undo the decrement by Int
+                break;
+                case 5: //(186+ bounds check)
+                if(cpu_level >= CPU186){
+                    Int16(err.code);
+                    eip++;
+                    break;
+                }
+                default:
+                throw CpuPanic_excp("16bit Faults",(err.code|0xF000)|TRIPLE_FAULT_EXCP);
+                break;
+            }
+        }
+        catch(Mem_excp err){
+            throw CpuPanic_excp("Mem Error--16bit Faults",TRIPLE_FAULT_EXCP);
+        }
+        */
+        if(i>=cyclecount){
+            done=true;
+        }
+    }
+}
+
+
+void x86CPU::Cycle(){
+#ifdef ENABLE_OPCODE_CALLBACK
+    if(EachOpcodeCallback!=NULL){
+        (*EachOpcodeCallback)(this);
+    }
+#endif
+    CheckInterrupts();
+    *(uint32_t*)&op_cache=ReadDword(cCS,eip);
+    (this->*Opcodes[op_cache[0]])();
+    //operate on the this class with the opcode functions in this class
+    eip=(uint16_t)eip+1;
+}
+
+
+
+
+
+
+
+void x86CPU::InstallOp(uint8_t num,opcode func,uint32_t level){
+    if((cpu_level&level)>0){
+        Opcodes[num]=func;
+    }
+}
+
+
+void x86CPU::InitOpcodes(){
+    Opcodes=opcodes_16bit;
+    int i;
+    for(i=0;i<256;i++){
+        InstallOp(i,&x86CPU::op16_unknown);
+    }
+    for(i=0;i<=7;i++){
+        InstallOp(0xB0+i,&x86CPU::op16_mov_r8_imm8);
+        InstallOp(0x58+i,&x86CPU::op16_pop_r16);
+        InstallOp(0x50+i,&x86CPU::op16_push_r16);
+        InstallOp(0x40+i,&x86CPU::op16_inc_r16);
+        InstallOp(0x48+i,&x86CPU::op16_dec_r16);
+        InstallOp(0xD8+i,&x86CPU::op16_escape);
+        InstallOp(0x90+i,&x86CPU::op16_xchg_ax_r16);
+        InstallOp(0xB8+i,&x86CPU::op16_mov_r16_imm16);
+    }
+    InstallOp(0xF4,&x86CPU::op16_hlt);
+    InstallOp(0x90,&x86CPU::op16_nop);
+    InstallOp(0xEB,&x86CPU::op16_jmp_rel8);
+    InstallOp(0x2C,&x86CPU::op16_sub_al_imm8);
+    InstallOp(0x2D,&x86CPU::op16_sub_ax_imm16);
+    InstallOp(0x77,&x86CPU::op16_ja_rel8);
+    InstallOp(0x70,&x86CPU::op16_jo_rel8);
+    InstallOp(0x71,&x86CPU::op16_jno_rel8);
+    InstallOp(0x72,&x86CPU::op16_jc_rel8);
+    InstallOp(0x73,&x86CPU::op16_jnc_rel8);
+    InstallOp(0x74,&x86CPU::op16_jz_rel8);
+    InstallOp(0x75,&x86CPU::op16_jnz_rel8);
+    InstallOp(0x77,&x86CPU::op16_jbe_rel8);
+    InstallOp(0x78,&x86CPU::op16_js_rel8);
+    InstallOp(0x79,&x86CPU::op16_jns_rel8);
+    InstallOp(0x7A,&x86CPU::op16_jp_rel8);
+    InstallOp(0x7B,&x86CPU::op16_jnp_rel8);
+    InstallOp(0x7C,&x86CPU::op16_jl_rel8);
+    InstallOp(0x7D,&x86CPU::op16_jge_rel8);
+    InstallOp(0x7E,&x86CPU::op16_jle_rel8);
+    InstallOp(0x7F,&x86CPU::op16_jg_rel8);
+    InstallOp(0x8E,&x86CPU::op16_mov_sr_rm16);
+    InstallOp(0x8C,&x86CPU::op16_mov_rm16_sr);
+    InstallOp(0x68,&x86CPU::op16_push_imm16,CPU286_REAL);
+    InstallOp(0x07,&x86CPU::op16_pop_es);
+    InstallOp(0x17,&x86CPU::op16_pop_ss);
+    InstallOp(0x1F,&x86CPU::op16_pop_ds);
+    InstallOp(0x06,&x86CPU::op16_push_es);
+    InstallOp(0x0E,&x86CPU::op16_push_cs);
+    InstallOp(0x16,&x86CPU::op16_push_ss);
+    InstallOp(0x1E,&x86CPU::op16_push_ds);
+    InstallOp(0x89,&x86CPU::op16_mov_rm16_r16);
+    InstallOp(0x8B,&x86CPU::op16_mov_r16_rm16);
+    InstallOp(0xE8,&x86CPU::op16_call_rel16);
+    InstallOp(0xC3,&x86CPU::op16_retn);
+    InstallOp(0xE2,&x86CPU::op16_loop_rel8);
+    InstallOp(0x26,&x86CPU::op16_pre_es_override);
+    InstallOp(0x3E,&x86CPU::op16_pre_ds_override);
+    InstallOp(0x36,&x86CPU::op16_pre_ss_override);
+    InstallOp(0x2E,&x86CPU::op16_pre_cs_override);
+    InstallOp(0xA5,&x86CPU::op16_movsw);
+    InstallOp(0xA4,&x86CPU::op16_movsb);
+    InstallOp(0xF8,&x86CPU::op16_clc);
+    InstallOp(0xFC,&x86CPU::op16_cld);
+    InstallOp(0xFA,&x86CPU::op16_cli);
+    InstallOp(0xF9,&x86CPU::op16_stc);
+    InstallOp(0xFD,&x86CPU::op16_std);
+    InstallOp(0xFB,&x86CPU::op16_sti);
+    InstallOp(0xF2,&x86CPU::op16_rep);
+    InstallOp(0xF3,&x86CPU::op16_rep); //different, but handled by the same function...
+    InstallOp(0xE6,&x86CPU::op16_out_imm8_al);
+    InstallOp(0xE7,&x86CPU::op16_out_imm8_ax);
+    InstallOp(0x9A,&x86CPU::op16_call_imm16_imm16);
+    InstallOp(0xCB,&x86CPU::op16_retf); //lol...CB...<inside joke>
+    InstallOp(0xCD,&x86CPU::op16_int_imm8);
+    InstallOp(0xCF,&x86CPU::op16_iret);
+    InstallOp(0xCC,&x86CPU::op16_int3);
+    InstallOp(0xCE,&x86CPU::op16_into);
+    InstallOp(0xE4,&x86CPU::op16_in_al_imm8);
+    InstallOp(0xE5,&x86CPU::op16_in_ax_imm8);
+    InstallOp(0x04,&x86CPU::op16_add_al_imm8);
+    InstallOp(0x05,&x86CPU::op16_add_ax_imm8);
+    InstallOp(0x28,&x86CPU::op16_sub_rm8_r8);
+    InstallOp(0x80,&x86CPU::op16_group_80);
+    InstallOp(0x29,&x86CPU::op16_sub_rm16_r16);
+    InstallOp(0x2A,&x86CPU::op16_sub_r8_rm8);
+    InstallOp(0x2B,&x86CPU::op16_sub_r16_rm16);
+    InstallOp(0x81,&x86CPU::op16_group_81);
+    InstallOp(0x00,&x86CPU::op16_add_rm8_r8);
+    InstallOp(0x01,&x86CPU::op16_add_rm16_r16);
+    InstallOp(0x02,&x86CPU::op16_add_r8_rm8);
+    InstallOp(0x03,&x86CPU::op16_add_r16_rm16);
+    InstallOp(0xA0,&x86CPU::op16_mov_al_off8);
+    InstallOp(0xA1,&x86CPU::op16_mov_ax_off16);
+    InstallOp(0x88,&x86CPU::op16_mov_rm8_r8);
+    InstallOp(0x8A,&x86CPU::op16_mov_r8_rm8);
+    InstallOp(0xA2,&x86CPU::op16_mov_off8_al);
+    InstallOp(0xA3,&x86CPU::op16_mov_off16_ax);
+    InstallOp(0xC6,&x86CPU::op16_mov_m8_imm8);
+    InstallOp(0xC7,&x86CPU::op16_mov_m16_imm16);
+    InstallOp(0x38,&x86CPU::op16_cmp_rm8_r8);
+    InstallOp(0x39,&x86CPU::op16_cmp_rm16_r16);
+    InstallOp(0x3A,&x86CPU::op16_cmp_r8_rm8);
+    InstallOp(0x3B,&x86CPU::op16_cmp_r16_rm16);
+    InstallOp(0x3C,&x86CPU::op16_cmp_al_imm8);
+    InstallOp(0x3D,&x86CPU::op16_cmp_ax_imm16); //3D TimD Tim Vision TV!!! Yay!!!
+    InstallOp(0x83,&x86CPU::op16_group_83); //83 is my lucky number btw...
+    InstallOp(0xFF,&x86CPU::op16_group_FF);
+    InstallOp(0xE9,&x86CPU::op16_jmp_rel16);
+    InstallOp(0xEA,&x86CPU::op16_jmp_imm16_imm16);
+    InstallOp(0x6A,&x86CPU::op16_push_imm8);
+    InstallOp(0x8F,&x86CPU::op16_group_8F);
+    InstallOp(0xD6,&x86CPU::op16_salc);
+    InstallOp(0xF5,&x86CPU::op16_cmc);
+    InstallOp(0x98,&x86CPU::op16_cbw);
+    InstallOp(0x37,&x86CPU::op16_aaa);
+    InstallOp(0x27,&x86CPU::op16_daa);
+    InstallOp(0x2F,&x86CPU::op16_das);
+    InstallOp(0x3F,&x86CPU::op16_aas);
+    InstallOp(0xD5,&x86CPU::op16_aad);
+    InstallOp(0xD4,&x86CPU::op16_aam);
+    InstallOp(0xFE,&x86CPU::op16_group_FE);
+    InstallOp(0xF6,&x86CPU::op16_group_F6);
+    InstallOp(0xF7,&x86CPU::op16_group_F7);
+    InstallOp(0x99,&x86CPU::op16_cwd);
+    InstallOp(0x20,&x86CPU::op16_and_rm8_r8);
+    InstallOp(0x21,&x86CPU::op16_and_rm16_r16);
+    InstallOp(0x22,&x86CPU::op16_and_r8_rm8);
+    InstallOp(0x23,&x86CPU::op16_and_r16_rm16);
+    InstallOp(0x24,&x86CPU::op16_and_al_imm8);
+    InstallOp(0x25,&x86CPU::op16_and_ax_imm16);
+    InstallOp(0x08,&x86CPU::op16_or_rm8_r8);
+    InstallOp(0x09,&x86CPU::op16_or_rm16_r16);
+    InstallOp(0x0A,&x86CPU::op16_or_r8_rm8);
+    InstallOp(0x0B,&x86CPU::op16_or_r16_rm16);
+    InstallOp(0x0C,&x86CPU::op16_or_al_imm8);
+    InstallOp(0x0D,&x86CPU::op16_or_ax_imm16);
+    InstallOp(0xA6,&x86CPU::op16_cmpsb);
+    InstallOp(0xA7,&x86CPU::op16_cmpsw);
+    InstallOp(0xE3,&x86CPU::op16_jcxz_rel8);
+    InstallOp(0x14,&x86CPU::op16_adc_al_imm8);
+    InstallOp(0x15,&x86CPU::op16_adc_ax_imm8);
+    InstallOp(0x10,&x86CPU::op16_adc_rm8_r8);
+    InstallOp(0x11,&x86CPU::op16_adc_rm16_r16);
+    InstallOp(0x12,&x86CPU::op16_adc_r8_rm8);
+    InstallOp(0x13,&x86CPU::op16_adc_r16_rm16);
+    InstallOp(0x9E,&x86CPU::op16_sahf);
+    InstallOp(0x9F,&x86CPU::op16_lahf);
+    InstallOp(0xE1,&x86CPU::op16_loope_rel8);
+    InstallOp(0xE0,&x86CPU::op16_loopne_rel8);
+    InstallOp(0xC5,&x86CPU::op16_lds);
+    InstallOp(0xC4,&x86CPU::op16_les);
+    InstallOp(0x8D,&x86CPU::op16_lea);
+    InstallOp(0xF0,&x86CPU::op16_lock);
+    InstallOp(0x30,&x86CPU::op16_xor_rm8_r8);
+    InstallOp(0x31,&x86CPU::op16_xor_rm16_r16);
+    InstallOp(0x32,&x86CPU::op16_xor_r8_rm8);
+    InstallOp(0x33,&x86CPU::op16_xor_r16_rm16);
+    InstallOp(0x34,&x86CPU::op16_xor_al_imm8);
+    InstallOp(0x35,&x86CPU::op16_xor_ax_imm16);
+    InstallOp(0x1C,&x86CPU::op16_sbb_al_imm8);
+    InstallOp(0x1D,&x86CPU::op16_sbb_ax_imm16);
+    InstallOp(0x19,&x86CPU::op16_sbb_rm16_r16);
+    InstallOp(0x1A,&x86CPU::op16_sbb_r8_rm8);
+    InstallOp(0x1B,&x86CPU::op16_sbb_r16_rm16);
+    InstallOp(0x18,&x86CPU::op16_sub_rm8_r8);
+    InstallOp(0x84,&x86CPU::op16_test_rm8_r8);
+    InstallOp(0x85,&x86CPU::op16_test_rm16_r16);
+    InstallOp(0xA8,&x86CPU::op16_test_al_imm8);
+    InstallOp(0xA9,&x86CPU::op16_test_ax_imm16);
+    InstallOp(0x86,&x86CPU::op16_xchg_rm8_r8);
+    InstallOp(0x87,&x86CPU::op16_xchg_rm16_r16);
+    InstallOp(0xD2,&x86CPU::op16_group_D2);
+    InstallOp(0xD3,&x86CPU::op16_group_D3);
+    InstallOp(0xD0,&x86CPU::op16_group_D0);
+    InstallOp(0xD1,&x86CPU::op16_group_D1);
+    InstallOp(0xAC,&x86CPU::op16_lodsb);
+    InstallOp(0xAD,&x86CPU::op16_lodsw);
+    InstallOp(0xAE,&x86CPU::op16_scasb);
+    InstallOp(0xAF,&x86CPU::op16_scasw);
+    InstallOp(0x9B,&x86CPU::op16_wait);
+    InstallOp(0xD7,&x86CPU::op16_xlatb);
+    InstallOp(0xEC,&x86CPU::op16_in_al_dx);
+    InstallOp(0xED,&x86CPU::op16_in_ax_dx);
+    InstallOp(0xEE,&x86CPU::op16_out_dx_al);
+    InstallOp(0xEF,&x86CPU::op16_out_dx_ax);
+    InstallOp(0xAA,&x86CPU::op16_stosb);
+    InstallOp(0xAB,&x86CPU::op16_stosw);
+
+
+
+}
+
+
+
+//void unknown();
+
+bool x86CPU::IsLocked(){
+    return Memory->IsLocked();
+}
+
+void x86CPU::Lock(){
+    //nothing...
+    Memory->Lock();
+    busmaster=1;
+}
+
+void x86CPU::Unlock(){
+    //still nothing...
+    Memory->Unlock();
+    busmaster=0;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+};
+
+
+
+
+
+