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 - 2010 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 namespace x86Lib{
earlz 0:217a7931b41f 33 using namespace std;
earlz 0:217a7931b41f 34
earlz 0:217a7931b41f 35
earlz 0:217a7931b41f 36
earlz 0:217a7931b41f 37
earlz 0:217a7931b41f 38
earlz 0:217a7931b41f 39
earlz 0:217a7931b41f 40 void x86CPU::op16_mov_r8_imm8(){ //0xB0+r
earlz 0:217a7931b41f 41 //I suppose the first real instruction is the hardest...
earlz 0:217a7931b41f 42 *regs8[op_cache[0]-0xB0]=op_cache[1];
earlz 0:217a7931b41f 43 eip++;
earlz 0:217a7931b41f 44 }
earlz 0:217a7931b41f 45
earlz 0:217a7931b41f 46 void x86CPU::op16_mov_r16_imm16(){ //0xB8+r
earlz 0:217a7931b41f 47 *regs16[op_cache[0]-0xB8]=*(uint16_t*)&op_cache[1];
earlz 0:217a7931b41f 48 eip+=2;
earlz 0:217a7931b41f 49 }
earlz 0:217a7931b41f 50
earlz 0:217a7931b41f 51 void x86CPU::op16_mov_sr_rm16(){ //0x8E
earlz 0:217a7931b41f 52 eip++;
earlz 0:217a7931b41f 53 ModRM16 rm16(this);
earlz 0:217a7931b41f 54 if(rm16.GetExtra()==cSS){ //if a mov into SS, then disable interrupts for 1 instruction.
earlz 0:217a7931b41f 55 cli_count=2;
earlz 0:217a7931b41f 56 freg._if=0;
earlz 0:217a7931b41f 57 }
earlz 0:217a7931b41f 58 seg[rm16.GetExtra()]=rm16.ReadWordr();
earlz 0:217a7931b41f 59 }
earlz 0:217a7931b41f 60
earlz 0:217a7931b41f 61 void x86CPU::op16_mov_rm16_sr(){ //0x8C
earlz 0:217a7931b41f 62 eip++;
earlz 0:217a7931b41f 63 ModRM16 rm16(this);
earlz 0:217a7931b41f 64 rm16.WriteWordr(seg[rm16.GetExtra()]);
earlz 0:217a7931b41f 65 }
earlz 0:217a7931b41f 66
earlz 0:217a7931b41f 67
earlz 0:217a7931b41f 68
earlz 0:217a7931b41f 69 void x86CPU::op16_mov_r16_rm16(){
earlz 0:217a7931b41f 70 eip++;
earlz 0:217a7931b41f 71 ModRM16 rm16(this);
earlz 0:217a7931b41f 72 *regs16[rm16.GetExtra()]=rm16.ReadWordr();
earlz 0:217a7931b41f 73 }
earlz 0:217a7931b41f 74
earlz 0:217a7931b41f 75 void x86CPU::op16_mov_rm16_r16(){
earlz 0:217a7931b41f 76 eip++;
earlz 0:217a7931b41f 77 ModRM16 rm16(this);
earlz 0:217a7931b41f 78 rm16.WriteWordr(*regs16[rm16.GetExtra()]);
earlz 0:217a7931b41f 79 }
earlz 0:217a7931b41f 80
earlz 0:217a7931b41f 81 void x86CPU::op16_mov_al_off8(){
earlz 0:217a7931b41f 82 *regs8[AL]=ReadByte(DS,*(uint16_t*)&op_cache[1]);
earlz 0:217a7931b41f 83 eip++;
earlz 0:217a7931b41f 84 eip++;
earlz 0:217a7931b41f 85 }
earlz 0:217a7931b41f 86 void x86CPU::op16_mov_ax_off16(){
earlz 0:217a7931b41f 87 *regs16[AX]=ReadWord(DS,*(uint16_t*)&op_cache[1]);
earlz 0:217a7931b41f 88 eip++;
earlz 0:217a7931b41f 89 eip++;
earlz 0:217a7931b41f 90 }
earlz 0:217a7931b41f 91
earlz 0:217a7931b41f 92 void x86CPU::op16_mov_rm8_r8(){
earlz 0:217a7931b41f 93 eip++;
earlz 0:217a7931b41f 94 ModRM16 rm(this);
earlz 0:217a7931b41f 95 rm.WriteByter(*regs8[rm.GetExtra()]);
earlz 0:217a7931b41f 96 }
earlz 0:217a7931b41f 97
earlz 0:217a7931b41f 98 void x86CPU::op16_mov_r8_rm8(){
earlz 0:217a7931b41f 99 eip++;
earlz 0:217a7931b41f 100 ModRM16 rm(this);
earlz 0:217a7931b41f 101 *regs8[rm.GetExtra()]=rm.ReadByter();
earlz 0:217a7931b41f 102 }
earlz 0:217a7931b41f 103 void x86CPU::op16_mov_off8_al(){
earlz 0:217a7931b41f 104 WriteByte(DS,*(uint16_t*)&op_cache[1],*regs8[AL]);
earlz 0:217a7931b41f 105 eip++;
earlz 0:217a7931b41f 106 eip++;
earlz 0:217a7931b41f 107 }
earlz 0:217a7931b41f 108
earlz 0:217a7931b41f 109 void x86CPU::op16_mov_off16_ax(){
earlz 0:217a7931b41f 110 WriteWord(DS,*(uint16_t*)&op_cache[1],*regs16[AX]);
earlz 0:217a7931b41f 111 eip++;eip++;
earlz 0:217a7931b41f 112 }
earlz 0:217a7931b41f 113
earlz 0:217a7931b41f 114 void x86CPU::op16_mov_m8_imm8(){
earlz 0:217a7931b41f 115 eip++;
earlz 0:217a7931b41f 116 ModRM16 rm(this);
earlz 0:217a7931b41f 117
earlz 0:217a7931b41f 118 //eventually fix this so that if r is used, then invalid opcode...
earlz 0:217a7931b41f 119 rm.WriteByter(ReadByte(cCS,eip+rm.GetLength()));
earlz 0:217a7931b41f 120 eip++;
earlz 0:217a7931b41f 121 }
earlz 0:217a7931b41f 122
earlz 0:217a7931b41f 123 void x86CPU::op16_mov_m16_imm16(){
earlz 0:217a7931b41f 124 eip++;
earlz 0:217a7931b41f 125 ModRM16 rm(this);
earlz 0:217a7931b41f 126 rm.WriteWordr(ReadWord(cCS,eip+rm.GetLength()));
earlz 0:217a7931b41f 127 eip++;
earlz 0:217a7931b41f 128 eip++;
earlz 0:217a7931b41f 129 }
earlz 0:217a7931b41f 130
earlz 0:217a7931b41f 131 void x86CPU::op16_lds(){
earlz 0:217a7931b41f 132 eip++;
earlz 0:217a7931b41f 133 ModRM16 rm(this);
earlz 0:217a7931b41f 134 uint32_t tmp=rm.ReadDword();
earlz 0:217a7931b41f 135 seg[cDS]=(tmp&0xFFFF0000)>>16;
earlz 0:217a7931b41f 136 *regs16[rm.GetExtra()]=(tmp&0xFFFF);
earlz 0:217a7931b41f 137 }
earlz 0:217a7931b41f 138
earlz 0:217a7931b41f 139 void x86CPU::op16_les(){
earlz 0:217a7931b41f 140 eip++;
earlz 0:217a7931b41f 141 ModRM16 rm(this);
earlz 0:217a7931b41f 142 uint32_t tmp=rm.ReadDword();
earlz 0:217a7931b41f 143 seg[cES]=(tmp&0xFFFF0000)>>16;
earlz 0:217a7931b41f 144 *regs16[rm.GetExtra()]=(tmp&0xFFFF);
earlz 0:217a7931b41f 145 }
earlz 0:217a7931b41f 146
earlz 0:217a7931b41f 147 void x86CPU::op16_lea(){ //wtf is the point of this instruction! why not just mov reg,immediate! seriously frikkin crazy designers of x86
earlz 0:217a7931b41f 148 eip++;
earlz 0:217a7931b41f 149 ModRM16 rm(this);
earlz 0:217a7931b41f 150 *regs16[rm.GetExtra()]=rm.ReadOffset();
earlz 0:217a7931b41f 151 }
earlz 0:217a7931b41f 152
earlz 0:217a7931b41f 153
earlz 0:217a7931b41f 154
earlz 0:217a7931b41f 155 void x86CPU::op16_push_imm8(){
earlz 0:217a7931b41f 156 eip++;
earlz 0:217a7931b41f 157 Push16(op_cache[1]);
earlz 0:217a7931b41f 158 }
earlz 0:217a7931b41f 159 void x86CPU::op16_push_m16(ModRM16 &rm){
earlz 0:217a7931b41f 160 Push16(rm.ReadWordr());
earlz 0:217a7931b41f 161 }
earlz 0:217a7931b41f 162
earlz 0:217a7931b41f 163 void x86CPU::op16_push_imm16(){ //0x68
earlz 0:217a7931b41f 164 eip++;
earlz 0:217a7931b41f 165 Push16(*(uint16_t*)&op_cache[1]);
earlz 0:217a7931b41f 166 eip++;
earlz 0:217a7931b41f 167 }
earlz 0:217a7931b41f 168
earlz 0:217a7931b41f 169
earlz 0:217a7931b41f 170 void x86CPU::op16_push_r16(){ //0x50+reg
earlz 0:217a7931b41f 171 Push16(*regs16[op_cache[0]-0x50]);
earlz 0:217a7931b41f 172 }
earlz 0:217a7931b41f 173
earlz 0:217a7931b41f 174 void x86CPU::op16_push_es(){
earlz 0:217a7931b41f 175 Push16(seg[ES]);
earlz 0:217a7931b41f 176 }
earlz 0:217a7931b41f 177
earlz 0:217a7931b41f 178 void x86CPU::op16_push_cs(){
earlz 0:217a7931b41f 179 Push16(seg[CS]);
earlz 0:217a7931b41f 180 }
earlz 0:217a7931b41f 181
earlz 0:217a7931b41f 182 void x86CPU::op16_push_ds(){
earlz 0:217a7931b41f 183 Push16(seg[DS]);
earlz 0:217a7931b41f 184 }
earlz 0:217a7931b41f 185
earlz 0:217a7931b41f 186
earlz 0:217a7931b41f 187 void x86CPU::op16_push_ss(){
earlz 0:217a7931b41f 188 Push16(seg[SS]);
earlz 0:217a7931b41f 189 }
earlz 0:217a7931b41f 190
earlz 0:217a7931b41f 191
earlz 0:217a7931b41f 192
earlz 0:217a7931b41f 193 void x86CPU::op16_pop_m16(ModRM16 &rm){
earlz 0:217a7931b41f 194 rm.WriteWordr(Pop16());
earlz 0:217a7931b41f 195 }
earlz 0:217a7931b41f 196
earlz 0:217a7931b41f 197 void x86CPU::op16_pop_r16(){ //0x58+reg
earlz 0:217a7931b41f 198 *regs16[op_cache[0]-0x58]=Pop16();
earlz 0:217a7931b41f 199 }
earlz 0:217a7931b41f 200
earlz 0:217a7931b41f 201
earlz 0:217a7931b41f 202 void x86CPU::op16_pop_es(){
earlz 0:217a7931b41f 203 seg[ES]=Pop16();
earlz 0:217a7931b41f 204 }
earlz 0:217a7931b41f 205
earlz 0:217a7931b41f 206 void x86CPU::op16_pop_ss(){
earlz 0:217a7931b41f 207 cli_count=2;
earlz 0:217a7931b41f 208 freg._if=0;
earlz 0:217a7931b41f 209 seg[SS]=Pop16();
earlz 0:217a7931b41f 210 }
earlz 0:217a7931b41f 211
earlz 0:217a7931b41f 212 void x86CPU::op16_pop_ds(){
earlz 0:217a7931b41f 213 seg[DS]=Pop16();
earlz 0:217a7931b41f 214 }
earlz 0:217a7931b41f 215
earlz 0:217a7931b41f 216
earlz 0:217a7931b41f 217
earlz 0:217a7931b41f 218 void x86CPU::op16_out_imm8_al(){
earlz 0:217a7931b41f 219 Ports->Write(op_cache[1],1,(void*)regs8[AL]);
earlz 0:217a7931b41f 220 eip++;
earlz 0:217a7931b41f 221 }
earlz 0:217a7931b41f 222
earlz 0:217a7931b41f 223 void x86CPU::op16_out_imm8_ax(){
earlz 0:217a7931b41f 224 Ports->Write(op_cache[1],2,(void*)regs16[AX]);
earlz 0:217a7931b41f 225 eip++;
earlz 0:217a7931b41f 226 }
earlz 0:217a7931b41f 227
earlz 0:217a7931b41f 228 void x86CPU::op16_out_dx_al(){
earlz 0:217a7931b41f 229 Ports->Write(*regs16[DX],1,(void*)regs8[AL]);
earlz 0:217a7931b41f 230 }
earlz 0:217a7931b41f 231
earlz 0:217a7931b41f 232 void x86CPU::op16_out_dx_ax(){
earlz 0:217a7931b41f 233 Ports->Write(*regs16[DX],2,(void*)regs16[AX]);
earlz 0:217a7931b41f 234 }
earlz 0:217a7931b41f 235
earlz 0:217a7931b41f 236
earlz 0:217a7931b41f 237 void x86CPU::op16_in_al_imm8(){
earlz 0:217a7931b41f 238 Ports->Read(op_cache[1],1,(void*)regs8[AL]);
earlz 0:217a7931b41f 239 eip++;
earlz 0:217a7931b41f 240 }
earlz 0:217a7931b41f 241
earlz 0:217a7931b41f 242 void x86CPU::op16_in_ax_imm8(){
earlz 0:217a7931b41f 243 Ports->Read(op_cache[1],2,(void*)regs16[AX]);
earlz 0:217a7931b41f 244 eip++;
earlz 0:217a7931b41f 245 }
earlz 0:217a7931b41f 246
earlz 0:217a7931b41f 247 void x86CPU::op16_in_al_dx(){
earlz 0:217a7931b41f 248 Ports->Read(*regs16[DX],1,(void*)regs8[AL]);
earlz 0:217a7931b41f 249 }
earlz 0:217a7931b41f 250
earlz 0:217a7931b41f 251 void x86CPU::op16_in_ax_dx(){
earlz 0:217a7931b41f 252 Ports->Read(*regs16[DX],2,(void*)regs16[AX]);
earlz 0:217a7931b41f 253 }
earlz 0:217a7931b41f 254
earlz 0:217a7931b41f 255
earlz 0:217a7931b41f 256
earlz 0:217a7931b41f 257 void x86CPU::op16_xchg_rm8_r8(){
earlz 0:217a7931b41f 258 #ifndef X86_MULTITHREADING
earlz 0:217a7931b41f 259 if(IsLocked()==1){
earlz 0:217a7931b41f 260 eip--;
earlz 0:217a7931b41f 261 return;
earlz 0:217a7931b41f 262 }
earlz 0:217a7931b41f 263 #endif
earlz 0:217a7931b41f 264 Lock();
earlz 0:217a7931b41f 265 eip++;
earlz 0:217a7931b41f 266 ModRM16 rm(this);
earlz 0:217a7931b41f 267 uint8_t tmp=*regs8[rm.GetExtra()];
earlz 0:217a7931b41f 268 *regs8[rm.GetExtra()]=rm.ReadByter();
earlz 0:217a7931b41f 269 rm.WriteByter(tmp);
earlz 0:217a7931b41f 270 Unlock();
earlz 0:217a7931b41f 271 }
earlz 0:217a7931b41f 272 void x86CPU::op16_xchg_rm16_r16(){
earlz 0:217a7931b41f 273 #ifndef X86_MULTITHREADING
earlz 0:217a7931b41f 274 if(IsLocked()==1){
earlz 0:217a7931b41f 275 eip--;
earlz 0:217a7931b41f 276 return;
earlz 0:217a7931b41f 277 }
earlz 0:217a7931b41f 278 #endif
earlz 0:217a7931b41f 279 Lock();
earlz 0:217a7931b41f 280 eip++;
earlz 0:217a7931b41f 281 ModRM16 rm(this);
earlz 0:217a7931b41f 282 uint16_t tmp=*regs16[rm.GetExtra()];
earlz 0:217a7931b41f 283 *regs16[rm.GetExtra()]=rm.ReadWordr();
earlz 0:217a7931b41f 284 rm.WriteWordr(tmp);
earlz 0:217a7931b41f 285 Unlock();
earlz 0:217a7931b41f 286 }
earlz 0:217a7931b41f 287
earlz 0:217a7931b41f 288 void x86CPU::op16_xchg_ax_r16(){ //0x90+r
earlz 0:217a7931b41f 289 uint16_t tmp=*regs16[AX];
earlz 0:217a7931b41f 290 *regs16[AX]=*regs16[op_cache[0]-0x90];
earlz 0:217a7931b41f 291 *regs16[op_cache[0]-0x90]=tmp;
earlz 0:217a7931b41f 292 }
earlz 0:217a7931b41f 293
earlz 0:217a7931b41f 294
earlz 0:217a7931b41f 295 void x86CPU::op16_xlatb(){
earlz 0:217a7931b41f 296 *regs8[AL]=ReadByte(DS,(*regs16[BX])+(*regs8[AL]));
earlz 0:217a7931b41f 297 }
earlz 0:217a7931b41f 298
earlz 0:217a7931b41f 299
earlz 0:217a7931b41f 300
earlz 0:217a7931b41f 301
earlz 0:217a7931b41f 302
earlz 0:217a7931b41f 303
earlz 0:217a7931b41f 304 };
earlz 0:217a7931b41f 305
earlz 0:217a7931b41f 306
earlz 0:217a7931b41f 307