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

Committer:
earlz
Date:
Sun Mar 04 08:15:47 2012 +0000
Revision:
0:217a7931b41f

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
earlz 0:217a7931b41f 1 /**
earlz 0:217a7931b41f 2 Copyright (c) 2007 - 2009 Jordan "Earlz/hckr83" Earls <http://www.Earlz.biz.tm>
earlz 0:217a7931b41f 3 All rights reserved.
earlz 0:217a7931b41f 4
earlz 0:217a7931b41f 5 Redistribution and use in source and binary forms, with or without
earlz 0:217a7931b41f 6 modification, are permitted provided that the following conditions
earlz 0:217a7931b41f 7 are met:
earlz 0:217a7931b41f 8
earlz 0:217a7931b41f 9 1. Redistributions of source code must retain the above copyright
earlz 0:217a7931b41f 10 notice, this list of conditions and the following disclaimer.
earlz 0:217a7931b41f 11 2. Redistributions in binary form must reproduce the above copyright
earlz 0:217a7931b41f 12 notice, this list of conditions and the following disclaimer in the
earlz 0:217a7931b41f 13 documentation and/or other materials provided with the distribution.
earlz 0:217a7931b41f 14 3. The name of the author may not be used to endorse or promote products
earlz 0:217a7931b41f 15 derived from this software without specific prior written permission.
earlz 0:217a7931b41f 16
earlz 0:217a7931b41f 17 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
earlz 0:217a7931b41f 18 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
earlz 0:217a7931b41f 19 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
earlz 0:217a7931b41f 20 THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
earlz 0:217a7931b41f 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
earlz 0:217a7931b41f 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
earlz 0:217a7931b41f 23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
earlz 0:217a7931b41f 24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
earlz 0:217a7931b41f 25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
earlz 0:217a7931b41f 26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
earlz 0:217a7931b41f 27
earlz 0:217a7931b41f 28 This file is part of the x86Lib project.
earlz 0:217a7931b41f 29 **/
earlz 0:217a7931b41f 30 #define X86LIB_BUILD
earlz 0:217a7931b41f 31 #include <x86Lib.h>
earlz 0:217a7931b41f 32
earlz 0:217a7931b41f 33
earlz 0:217a7931b41f 34 namespace x86Lib{
earlz 0:217a7931b41f 35
earlz 0:217a7931b41f 36 void x86CPU::op16_nop(){ //0x90
earlz 0:217a7931b41f 37 //do nothing
earlz 0:217a7931b41f 38 }
earlz 0:217a7931b41f 39
earlz 0:217a7931b41f 40 void x86CPU::op16_hlt(){ //0xF4
earlz 0:217a7931b41f 41 if(freg._if==0){
earlz 0:217a7931b41f 42 Onx86LibError();
earlz 0:217a7931b41f 43 //throw CpuPanic_excp("HLT With IF=0; Nothing to do",CLIHLT_EXCP);
earlz 0:217a7931b41f 44 }
earlz 0:217a7931b41f 45 }
earlz 0:217a7931b41f 46
earlz 0:217a7931b41f 47 void x86CPU::op16_unknown(){
earlz 0:217a7931b41f 48 Onx86LibError();
earlz 0:217a7931b41f 49 //throw CpuInt_excp(UNK_IEXCP);
earlz 0:217a7931b41f 50 }
earlz 0:217a7931b41f 51
earlz 0:217a7931b41f 52
earlz 0:217a7931b41f 53
earlz 0:217a7931b41f 54
earlz 0:217a7931b41f 55 //Segment overrides...
earlz 0:217a7931b41f 56 void x86CPU::op16_pre_es_override(){ //0x26
earlz 0:217a7931b41f 57 SetSegments(cES);
earlz 0:217a7931b41f 58 eip++;
earlz 0:217a7931b41f 59 *(uint32_t*)&op_cache=ReadDword(cCS,eip);
earlz 0:217a7931b41f 60 (this->*Opcodes[op_cache[0]])();
earlz 0:217a7931b41f 61
earlz 0:217a7931b41f 62 ResetSegments();
earlz 0:217a7931b41f 63 }
earlz 0:217a7931b41f 64
earlz 0:217a7931b41f 65 void x86CPU::op16_pre_ds_override(){ //0x3E
earlz 0:217a7931b41f 66 SetSegments(cDS);
earlz 0:217a7931b41f 67 eip++;
earlz 0:217a7931b41f 68 *(uint32_t*)&op_cache=ReadDword(cCS,eip);
earlz 0:217a7931b41f 69 (this->*Opcodes[op_cache[0]])();
earlz 0:217a7931b41f 70
earlz 0:217a7931b41f 71 ResetSegments();
earlz 0:217a7931b41f 72 }
earlz 0:217a7931b41f 73
earlz 0:217a7931b41f 74 void x86CPU::op16_pre_ss_override(){ //0x36
earlz 0:217a7931b41f 75 SetSegments(cSS);
earlz 0:217a7931b41f 76 eip++;
earlz 0:217a7931b41f 77 *(uint32_t*)&op_cache=ReadDword(cCS,eip);
earlz 0:217a7931b41f 78 (this->*Opcodes[op_cache[0]])();
earlz 0:217a7931b41f 79
earlz 0:217a7931b41f 80 ResetSegments();
earlz 0:217a7931b41f 81 }
earlz 0:217a7931b41f 82
earlz 0:217a7931b41f 83 void x86CPU::op16_pre_cs_override(){ //0x2E
earlz 0:217a7931b41f 84 SetSegments(cCS);
earlz 0:217a7931b41f 85 eip++;
earlz 0:217a7931b41f 86 *(uint32_t*)&op_cache=ReadDword(cCS,eip);
earlz 0:217a7931b41f 87 (this->*Opcodes[op_cache[0]])();
earlz 0:217a7931b41f 88
earlz 0:217a7931b41f 89 ResetSegments();
earlz 0:217a7931b41f 90 }
earlz 0:217a7931b41f 91
earlz 0:217a7931b41f 92 void x86CPU::op16_rep(){ //repe and repne..(different opcodes, but I make them possible to use the same function)
earlz 0:217a7931b41f 93 //use a string_compares variable...
earlz 0:217a7931b41f 94 if(*regs16[CX]==0){ //for this, not executing the instruction is almost as expensive...
earlz 0:217a7931b41f 95 *(uint16_t*)&op_cache=ReadWord(cCS,eip+1);
earlz 0:217a7931b41f 96 int i=0;
earlz 0:217a7931b41f 97 //get size of opcode and prefixes....
earlz 0:217a7931b41f 98 for(i=0;i<4;i++){
earlz 0:217a7931b41f 99 switch(op_cache[i]){
earlz 0:217a7931b41f 100 case 0x67:
earlz 0:217a7931b41f 101 case 0x66:
earlz 0:217a7931b41f 102 case 0x2E:
earlz 0:217a7931b41f 103 case 0x36:
earlz 0:217a7931b41f 104 case 0x3E:
earlz 0:217a7931b41f 105 case 0x26:
earlz 0:217a7931b41f 106 case 0x64:
earlz 0:217a7931b41f 107 case 0x65:
earlz 0:217a7931b41f 108 eip++;
earlz 0:217a7931b41f 109 break;
earlz 0:217a7931b41f 110 default:
earlz 0:217a7931b41f 111 eip++;
earlz 0:217a7931b41f 112 return;
earlz 0:217a7931b41f 113 }
earlz 0:217a7931b41f 114 }
earlz 0:217a7931b41f 115 return;
earlz 0:217a7931b41f 116 }else{
earlz 0:217a7931b41f 117 uint32_t tmp=eip;
earlz 0:217a7931b41f 118 uint8_t t2=op_cache[0];
earlz 0:217a7931b41f 119 eip++;
earlz 0:217a7931b41f 120 *(uint32_t*)&op_cache=ReadDword(cCS,eip);
earlz 0:217a7931b41f 121 (this->*Opcodes[op_cache[0]])();
earlz 0:217a7931b41f 122 (*regs16[CX])--;
earlz 0:217a7931b41f 123 eip=tmp-1;
earlz 0:217a7931b41f 124 if(string_compares==1){
earlz 0:217a7931b41f 125 string_compares=0;
earlz 0:217a7931b41f 126 if(t2==0xF2){ //repNE
earlz 0:217a7931b41f 127 if(freg.zf==1){ //exit...
earlz 0:217a7931b41f 128 eip+=2;
earlz 0:217a7931b41f 129 return;
earlz 0:217a7931b41f 130 }
earlz 0:217a7931b41f 131 }else{
earlz 0:217a7931b41f 132 if((volatile uint8_t)freg.zf==0){ //exit...
earlz 0:217a7931b41f 133 eip+=2;
earlz 0:217a7931b41f 134 return;
earlz 0:217a7931b41f 135 }
earlz 0:217a7931b41f 136 }
earlz 0:217a7931b41f 137 }
earlz 0:217a7931b41f 138 }
earlz 0:217a7931b41f 139 }
earlz 0:217a7931b41f 140
earlz 0:217a7931b41f 141 void x86CPU::op16_lock(){ //0xF0 prefix
earlz 0:217a7931b41f 142 #ifndef X86_MULTITHREADING
earlz 0:217a7931b41f 143 if(IsLocked()==1){
earlz 0:217a7931b41f 144 eip--;
earlz 0:217a7931b41f 145 return;
earlz 0:217a7931b41f 146 }
earlz 0:217a7931b41f 147 #endif
earlz 0:217a7931b41f 148 Lock();
earlz 0:217a7931b41f 149 eip++;
earlz 0:217a7931b41f 150 *(uint32_t*)&op_cache=ReadDword(cCS,eip);
earlz 0:217a7931b41f 151 //Add strict opcode testing for 386+
earlz 0:217a7931b41f 152 (this->*Opcodes[op_cache[0]])();
earlz 0:217a7931b41f 153 Unlock();
earlz 0:217a7931b41f 154 }
earlz 0:217a7931b41f 155
earlz 0:217a7931b41f 156
earlz 0:217a7931b41f 157
earlz 0:217a7931b41f 158 void x86CPU::op16_cbw(){
earlz 0:217a7931b41f 159 if((*regs8[AL]&0x80)==0){
earlz 0:217a7931b41f 160 *regs8[AH]=0;
earlz 0:217a7931b41f 161 }else{
earlz 0:217a7931b41f 162 *regs8[AH]=0xFF;
earlz 0:217a7931b41f 163 }
earlz 0:217a7931b41f 164 }
earlz 0:217a7931b41f 165
earlz 0:217a7931b41f 166
earlz 0:217a7931b41f 167
earlz 0:217a7931b41f 168 void x86CPU::op16_cwd(){
earlz 0:217a7931b41f 169 if(*regs16[AX]>=0x8000){
earlz 0:217a7931b41f 170 *regs16[DX]=0xFFFF;
earlz 0:217a7931b41f 171 }else{
earlz 0:217a7931b41f 172 *regs16[DX]=0;
earlz 0:217a7931b41f 173 }
earlz 0:217a7931b41f 174 }
earlz 0:217a7931b41f 175
earlz 0:217a7931b41f 176 void x86CPU::op16_escape(){
earlz 0:217a7931b41f 177 /**This is for FPU escape opcodes
earlz 0:217a7931b41f 178 this uses 0xD8 to 0xDF
earlz 0:217a7931b41f 179 **/
earlz 0:217a7931b41f 180 Onx86LibError();
earlz 0:217a7931b41f 181 //throw CpuInt_excp(UNDEV_IEXCP); //throw unknown device exception
earlz 0:217a7931b41f 182 }
earlz 0:217a7931b41f 183 void x86CPU::op16_wait(){
earlz 0:217a7931b41f 184 /**Does nothing...**/
earlz 0:217a7931b41f 185 Onx86LibError();
earlz 0:217a7931b41f 186 //throw CpuInt_excp(UNDEV_IEXCP);
earlz 0:217a7931b41f 187 }
earlz 0:217a7931b41f 188
earlz 0:217a7931b41f 189
earlz 0:217a7931b41f 190
earlz 0:217a7931b41f 191 /**so-called undocumented opcodes:**/
earlz 0:217a7931b41f 192
earlz 0:217a7931b41f 193 /**salc -0xD6- this is will set al on carry -no arguments
earlz 0:217a7931b41f 194 log: if cf=0 then al=0 else al=FF
earlz 0:217a7931b41f 195 **/
earlz 0:217a7931b41f 196 void x86CPU::op16_salc(){ //set al on carry
earlz 0:217a7931b41f 197 if(freg.cf==0){*regs8[AL]=0;
earlz 0:217a7931b41f 198 }else{*regs8[AL]=0xFF;
earlz 0:217a7931b41f 199 }
earlz 0:217a7931b41f 200
earlz 0:217a7931b41f 201 }
earlz 0:217a7931b41f 202
earlz 0:217a7931b41f 203
earlz 0:217a7931b41f 204
earlz 0:217a7931b41f 205
earlz 0:217a7931b41f 206
earlz 0:217a7931b41f 207
earlz 0:217a7931b41f 208
earlz 0:217a7931b41f 209
earlz 0:217a7931b41f 210 };
earlz 0:217a7931b41f 211
earlz 0:217a7931b41f 212
earlz 0:217a7931b41f 213
earlz 0:217a7931b41f 214