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
ops/etc.cpp@0:217a7931b41f, 2012-03-04 (annotated)
- Committer:
- earlz
- Date:
- Sun Mar 04 08:15:47 2012 +0000
- Revision:
- 0:217a7931b41f
Who changed what in which revision?
User | Revision | Line number | New 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 |