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
earlz 0:217a7931b41f 31 #ifndef X86LIB
earlz 0:217a7931b41f 32 #define X86LIB
earlz 0:217a7931b41f 33 #include <iostream>
earlz 0:217a7931b41f 34 #include <vector>
earlz 0:217a7931b41f 35 #include <stdint.h>
earlz 0:217a7931b41f 36 #include <string>
earlz 0:217a7931b41f 37 #include "mbed.h"
earlz 0:217a7931b41f 38
earlz 0:217a7931b41f 39 //! The main namespace of x86Lib
earlz 0:217a7931b41f 40 namespace x86Lib{
earlz 0:217a7931b41f 41
earlz 0:217a7931b41f 42 #ifdef X86LIB_BUILD
earlz 0:217a7931b41f 43 #include <config.h>
earlz 0:217a7931b41f 44 #endif
earlz 0:217a7931b41f 45
earlz 0:217a7931b41f 46 //! 8086 CPU level
earlz 0:217a7931b41f 47 static const uint32_t CPU086=1;
earlz 0:217a7931b41f 48 //! 186 CPU level
earlz 0:217a7931b41f 49 static const uint32_t CPU186=2|CPU086;
earlz 0:217a7931b41f 50 //! 286 real mode only CPU level
earlz 0:217a7931b41f 51 static const uint32_t CPU286_REAL=4|CPU186; //Only support real mode instructions
earlz 0:217a7931b41f 52 //! 286 CPU level
earlz 0:217a7931b41f 53 static const uint32_t CPU286=8|CPU286_REAL;
earlz 0:217a7931b41f 54 //! 386 real mode only CPU level
earlz 0:217a7931b41f 55 static const uint32_t CPU386_REAL=16|CPU286_REAL; //Only Support real mode instructions
earlz 0:217a7931b41f 56 //! 386 CPU level
earlz 0:217a7931b41f 57 static const uint32_t CPU386=32|CPU386_REAL|CPU286;
earlz 0:217a7931b41f 58 //! 486 CPU level
earlz 0:217a7931b41f 59 static const uint32_t CPU486=64|CPU386;
earlz 0:217a7931b41f 60 //! Pentium(586) CPU level
earlz 0:217a7931b41f 61 static const uint32_t CPU_PENTIUM=128|CPU486;
earlz 0:217a7931b41f 62 //! Pentium Pro CPU level
earlz 0:217a7931b41f 63 static const uint32_t CPU_PPRO=256|CPU_PENTIUM;
earlz 0:217a7931b41f 64 //! Default CPU level
earlz 0:217a7931b41f 65 /*! CPU_DEFAULT will use the CPU with the most complete emulation
earlz 0:217a7931b41f 66 */
earlz 0:217a7931b41f 67 static const uint32_t CPU_DEFAULT=0; //this is actually changed internally..
earlz 0:217a7931b41f 68
earlz 0:217a7931b41f 69
earlz 0:217a7931b41f 70
earlz 0:217a7931b41f 71
earlz 0:217a7931b41f 72
earlz 0:217a7931b41f 73
earlz 0:217a7931b41f 74 /**Exceptions...**/
earlz 0:217a7931b41f 75 //! Exception code for an infinite halt
earlz 0:217a7931b41f 76 static const uint32_t CLIHLT_EXCP=1; //cli/hlt...nothing to do
earlz 0:217a7931b41f 77 //! Exception code for memory access exception
earlz 0:217a7931b41f 78 static const uint32_t MEM_ACCESS_EXCP=3; //Memory Access Error...(can actually be page fault, or GPF, or stack fault...
earlz 0:217a7931b41f 79 //! Exception code for triple fault
earlz 0:217a7931b41f 80 /*! This code is always OR'd with another code
earlz 0:217a7931b41f 81 so that you can tell what caused the triple fault.
earlz 0:217a7931b41f 82 */
earlz 0:217a7931b41f 83 static const uint32_t TRIPLE_FAULT_EXCP=0x10000; //Triple fault...This should be ORd with the last exception
earlz 0:217a7931b41f 84
earlz 0:217a7931b41f 85
earlz 0:217a7931b41f 86
earlz 0:217a7931b41f 87 //! A debug exception
earlz 0:217a7931b41f 88 /*! This exception should really only be used when debugging.
earlz 0:217a7931b41f 89 It should be used as throw(Default_excp(__FILE__,__FUNCTION__,__LINE__));
earlz 0:217a7931b41f 90 */
earlz 0:217a7931b41f 91 class Default_excp{ //Internal only...these should never happen when released...
earlz 0:217a7931b41f 92
earlz 0:217a7931b41f 93 public:
earlz 0:217a7931b41f 94 /*!
earlz 0:217a7931b41f 95 \param file_ The file name in which the exception occured(use __FILE__)
earlz 0:217a7931b41f 96 \param func_ The function in which the exception occured(use __FUNCTION__)
earlz 0:217a7931b41f 97 \param line_ The line number which the excption occured on(use __LINE__)
earlz 0:217a7931b41f 98 */
earlz 0:217a7931b41f 99 Default_excp(std::string file_,std::string func_,int line_){
earlz 0:217a7931b41f 100 file=file_;
earlz 0:217a7931b41f 101 func=func_;
earlz 0:217a7931b41f 102 line=line_;
earlz 0:217a7931b41f 103 }
earlz 0:217a7931b41f 104 //! The file which the exception was thrown from
earlz 0:217a7931b41f 105 std::string file;
earlz 0:217a7931b41f 106 //! The function which the exception was thrown from
earlz 0:217a7931b41f 107 std::string func;
earlz 0:217a7931b41f 108 //! The line which the exception was thrown from
earlz 0:217a7931b41f 109 int line;
earlz 0:217a7931b41f 110 };
earlz 0:217a7931b41f 111
earlz 0:217a7931b41f 112 //! CPU Panic exception
earlz 0:217a7931b41f 113 /*! This exception is thrown out of x86CPU if a fatal CPU error occurs,
earlz 0:217a7931b41f 114 such as a triple fault.
earlz 0:217a7931b41f 115 */
earlz 0:217a7931b41f 116 class CpuPanic_excp{ //used for fatal CPU errors, such as triple fault..
earlz 0:217a7931b41f 117
earlz 0:217a7931b41f 118 public:
earlz 0:217a7931b41f 119 /*!
earlz 0:217a7931b41f 120 \param desc_ A text description of the error
earlz 0:217a7931b41f 121 \param code_ An exception code
earlz 0:217a7931b41f 122 */
earlz 0:217a7931b41f 123 CpuPanic_excp(std::string desc_,uint32_t code_){
earlz 0:217a7931b41f 124 desc=desc_;
earlz 0:217a7931b41f 125 code=code_;
earlz 0:217a7931b41f 126 }
earlz 0:217a7931b41f 127 //!A text description of the error
earlz 0:217a7931b41f 128 std::string desc;
earlz 0:217a7931b41f 129 //!An exception code
earlz 0:217a7931b41f 130 uint32_t code;
earlz 0:217a7931b41f 131 };
earlz 0:217a7931b41f 132
earlz 0:217a7931b41f 133 //! Memory error exception
earlz 0:217a7931b41f 134 /*! This should only be thrown out of the PhysMemory class
earlz 0:217a7931b41f 135 It is thrown out to tell x86CPU a memory exception has occured.
earlz 0:217a7931b41f 136 This does not always result in a triple fault.
earlz 0:217a7931b41f 137 /sa PhysMemory
earlz 0:217a7931b41f 138 */
earlz 0:217a7931b41f 139 class Mem_excp{ //Exclusively for the Memory Classes, these are caught and then a more appropriate excp is thrown
earlz 0:217a7931b41f 140 public:
earlz 0:217a7931b41f 141 /*!
earlz 0:217a7931b41f 142 \param address_ The address at which had problems being read or written
earlz 0:217a7931b41f 143 */
earlz 0:217a7931b41f 144 Mem_excp(uint32_t address_){
earlz 0:217a7931b41f 145 address=address_;
earlz 0:217a7931b41f 146 }
earlz 0:217a7931b41f 147 uint32_t address;
earlz 0:217a7931b41f 148 };
earlz 0:217a7931b41f 149
earlz 0:217a7931b41f 150 class System_excp{
earlz 0:217a7931b41f 151 public:
earlz 0:217a7931b41f 152 System_excp(){}
earlz 0:217a7931b41f 153 };
earlz 0:217a7931b41f 154
earlz 0:217a7931b41f 155 class x86CPU;
earlz 0:217a7931b41f 156 /**This will be used for memory mapped devices(including memory itself)**/
earlz 0:217a7931b41f 157 class MemoryDevice{
earlz 0:217a7931b41f 158 public:
earlz 0:217a7931b41f 159 virtual void Read(uint32_t address,int count,void *buffer)=0;
earlz 0:217a7931b41f 160 virtual void Write(uint32_t address,int count,void *data)=0;
earlz 0:217a7931b41f 161 virtual int Readable(uint32_t address,int count){
earlz 0:217a7931b41f 162 return 1;
earlz 0:217a7931b41f 163 //This is optional. It is currently not used in the CPU code
earlz 0:217a7931b41f 164 }
earlz 0:217a7931b41f 165 virtual int Writeable(uint32_t address,int count){
earlz 0:217a7931b41f 166 return 1;
earlz 0:217a7931b41f 167 //This is optional. It is currently not used in the CPU code
earlz 0:217a7931b41f 168 }
earlz 0:217a7931b41f 169 virtual inline ~MemoryDevice()=0;
earlz 0:217a7931b41f 170 };
earlz 0:217a7931b41f 171
earlz 0:217a7931b41f 172 inline MemoryDevice::~MemoryDevice(){}
earlz 0:217a7931b41f 173 void Onx86LibError();
earlz 0:217a7931b41f 174
earlz 0:217a7931b41f 175 class PortDevice{
earlz 0:217a7931b41f 176 public:
earlz 0:217a7931b41f 177 virtual void Read(uint16_t address,int count,void *buffer)=0;
earlz 0:217a7931b41f 178 virtual void Write(uint16_t address,int count,void *data)=0;
earlz 0:217a7931b41f 179 virtual inline ~PortDevice()=0;
earlz 0:217a7931b41f 180 };
earlz 0:217a7931b41f 181
earlz 0:217a7931b41f 182 inline PortDevice::~PortDevice(){}
earlz 0:217a7931b41f 183
earlz 0:217a7931b41f 184 typedef struct DeviceRange
earlz 0:217a7931b41f 185 {
earlz 0:217a7931b41f 186 union
earlz 0:217a7931b41f 187 {
earlz 0:217a7931b41f 188 class MemoryDevice *memdev;
earlz 0:217a7931b41f 189 class PortDevice *portdev;
earlz 0:217a7931b41f 190 };
earlz 0:217a7931b41f 191 uint32_t high;
earlz 0:217a7931b41f 192 uint32_t low;
earlz 0:217a7931b41f 193 }DeviceRange_t;
earlz 0:217a7931b41f 194 /*Myk I hate you. This is going to be harder to implement than I thought. lol */
earlz 0:217a7931b41f 195 class MemorySystem{
earlz 0:217a7931b41f 196 std::vector<DeviceRange_t> memorySystemVector;
earlz 0:217a7931b41f 197 protected:
earlz 0:217a7931b41f 198 //! Intended to be used to mark if the address space is locked.
earlz 0:217a7931b41f 199 volatile uint32_t locked;
earlz 0:217a7931b41f 200 public:
earlz 0:217a7931b41f 201 MemorySystem();
earlz 0:217a7931b41f 202 void Add(uint32_t low,uint32_t high,MemoryDevice *memdev);
earlz 0:217a7931b41f 203 void Remove(uint32_t low,uint32_t high);
earlz 0:217a7931b41f 204 void Remove(MemoryDevice *memdev);
earlz 0:217a7931b41f 205 int RangeFree(uint32_t low,uint32_t high);
earlz 0:217a7931b41f 206 void Read(uint32_t address,int count,void *buffer);
earlz 0:217a7931b41f 207 void Write(uint32_t address,int count,void *data);
earlz 0:217a7931b41f 208 //! Tells if memory is locked
earlz 0:217a7931b41f 209 /*!
earlz 0:217a7931b41f 210 \return 1 if memory is locked, 0 if not locked.
earlz 0:217a7931b41f 211 */
earlz 0:217a7931b41f 212 bool IsLocked(){return locked;}
earlz 0:217a7931b41f 213 //! Locks the address space
earlz 0:217a7931b41f 214 void Lock(){
earlz 0:217a7931b41f 215 while(locked==1){}
earlz 0:217a7931b41f 216 locked=1;
earlz 0:217a7931b41f 217 }
earlz 0:217a7931b41f 218 //! Unlocks the address space
earlz 0:217a7931b41f 219 void Unlock(){
earlz 0:217a7931b41f 220 locked=0;
earlz 0:217a7931b41f 221 }
earlz 0:217a7931b41f 222 void WaitLock(int haslock){
earlz 0:217a7931b41f 223 if(haslock==0){
earlz 0:217a7931b41f 224 while(locked>0){}
earlz 0:217a7931b41f 225 }
earlz 0:217a7931b41f 226 }
earlz 0:217a7931b41f 227 };
earlz 0:217a7931b41f 228
earlz 0:217a7931b41f 229 class PortSystem{
earlz 0:217a7931b41f 230 DeviceRange_t *list;
earlz 0:217a7931b41f 231 int count;
earlz 0:217a7931b41f 232 public:
earlz 0:217a7931b41f 233 PortSystem();
earlz 0:217a7931b41f 234
earlz 0:217a7931b41f 235 void Add(uint16_t low,uint16_t high,PortDevice *portdev);
earlz 0:217a7931b41f 236 void Remove(uint16_t low,uint16_t high);
earlz 0:217a7931b41f 237 void Remove(PortDevice *portdev);
earlz 0:217a7931b41f 238 int RangeFree(uint32_t low,uint32_t high);
earlz 0:217a7931b41f 239 void Read(uint16_t address,int count,void *buffer);
earlz 0:217a7931b41f 240 void Write(uint16_t address,int count,void *data);
earlz 0:217a7931b41f 241 };
earlz 0:217a7931b41f 242
earlz 0:217a7931b41f 243
earlz 0:217a7931b41f 244
earlz 0:217a7931b41f 245 //! The struct used to save the current state of x86CPU
earlz 0:217a7931b41f 246 struct x86SaveData{
earlz 0:217a7931b41f 247 //! General registers
earlz 0:217a7931b41f 248 uint32_t reg32[8];
earlz 0:217a7931b41f 249 //! Segment registers
earlz 0:217a7931b41f 250 uint16_t seg[7];
earlz 0:217a7931b41f 251 //! Segment register routing(in case of segment overrides)
earlz 0:217a7931b41f 252 uint8_t seg_route[7];
earlz 0:217a7931b41f 253 //! Instruction pointer
earlz 0:217a7931b41f 254 uint32_t eip;
earlz 0:217a7931b41f 255 //! Which opcode map is currently in use
earlz 0:217a7931b41f 256 uint32_t opcode_mode;
earlz 0:217a7931b41f 257 //! Flags register
earlz 0:217a7931b41f 258 uint16_t freg;
earlz 0:217a7931b41f 259 //! CPU level
earlz 0:217a7931b41f 260 uint32_t cpu_level;
earlz 0:217a7931b41f 261 };
earlz 0:217a7931b41f 262
earlz 0:217a7931b41f 263 };
earlz 0:217a7931b41f 264
earlz 0:217a7931b41f 265 #ifdef X86LIB_BUILD
earlz 0:217a7931b41f 266
earlz 0:217a7931b41f 267 #include <x86Lib_internal.h>
earlz 0:217a7931b41f 268 #endif
earlz 0:217a7931b41f 269
earlz 0:217a7931b41f 270
earlz 0:217a7931b41f 271
earlz 0:217a7931b41f 272 namespace x86Lib{
earlz 0:217a7931b41f 273
earlz 0:217a7931b41f 274 typedef void (x86Lib::x86CPU::*opcode)();
earlz 0:217a7931b41f 275 typedef struct{
earlz 0:217a7931b41f 276 unsigned char rm:3;
earlz 0:217a7931b41f 277 unsigned char extra:3;
earlz 0:217a7931b41f 278 unsigned char mod:2;
earlz 0:217a7931b41f 279 }
earlz 0:217a7931b41f 280 __attribute__((packed))mod_rm16; //this struct is a described mod r/m byte..
earlz 0:217a7931b41f 281
earlz 0:217a7931b41f 282 //Note, this will re-cache op_cache, so do not use op_cache afterward
earlz 0:217a7931b41f 283 //Also, eip should be on the modrm byte!
earlz 0:217a7931b41f 284 //On return, it is on the last byte of the modrm block, so no advancement needed unelss there is an immediate
earlz 0:217a7931b41f 285 //Also, this will advance EIP upon exiting the opcode(deconstruction)
earlz 0:217a7931b41f 286 class ModRM16{ //This is the best thing I have ever done...
earlz 0:217a7931b41f 287 //I love this class so much...am I cheating on her? lol
earlz 0:217a7931b41f 288 protected:
earlz 0:217a7931b41f 289 bool use_ss;
earlz 0:217a7931b41f 290 bool op_specific;
earlz 0:217a7931b41f 291 x86CPU *this_cpu;
earlz 0:217a7931b41f 292 private:
earlz 0:217a7931b41f 293 mod_rm16 modrm;
earlz 0:217a7931b41f 294 inline uint16_t GetRegD(); //This returns the register displacement value
earlz 0:217a7931b41f 295 inline uint16_t GetDisp();
earlz 0:217a7931b41f 296 public:
earlz 0:217a7931b41f 297 inline ModRM16(x86CPU* this_cpu_);
earlz 0:217a7931b41f 298 inline ~ModRM16();
earlz 0:217a7931b41f 299 //The r suffix means /r, which means for op_specific=1, use general registers
earlz 0:217a7931b41f 300 inline uint8_t ReadByter();
earlz 0:217a7931b41f 301 inline uint16_t ReadWordr();
earlz 0:217a7931b41f 302 inline uint32_t ReadDword();
earlz 0:217a7931b41f 303 inline void WriteByter(uint8_t byte);
earlz 0:217a7931b41f 304 inline void WriteWordr(uint16_t word);
earlz 0:217a7931b41f 305 inline void WriteDword(uint32_t dword);
earlz 0:217a7931b41f 306 inline uint8_t GetLength(); //This returns how many total bytes the modrm block consumes
earlz 0:217a7931b41f 307 inline uint8_t GetExtra(); //Get the extra fied from mod_rm
earlz 0:217a7931b41f 308 inline uint16_t ReadOffset(); //This is only used by LEA. It will obtain the offset and not dereference it...
earlz 0:217a7931b41f 309
earlz 0:217a7931b41f 310 }; //I hope that SIB and ModR/M32 will be this good!
earlz 0:217a7931b41f 311 //! The main CPU control class
earlz 0:217a7931b41f 312 /*! This class is the complete CPU. That being said, it is quite big
earlz 0:217a7931b41f 313 and has many functions. It completely emulates the x86 line of CPUs
earlz 0:217a7931b41f 314 */
earlz 0:217a7931b41f 315 class x86CPU{
earlz 0:217a7931b41f 316 friend class ModRM16;
earlz 0:217a7931b41f 317 volatile uint32_t reg32[8];
earlz 0:217a7931b41f 318 volatile uint16_t *regs16[8];
earlz 0:217a7931b41f 319 volatile uint8_t *regs8[8];
earlz 0:217a7931b41f 320 volatile uint16_t seg[7];
earlz 0:217a7931b41f 321 volatile uint32_t eip;
earlz 0:217a7931b41f 322 #ifdef X86LIB_BUILD
earlz 0:217a7931b41f 323 volatile FLAGS freg;
earlz 0:217a7931b41f 324 #else
earlz 0:217a7931b41f 325 volatile uint16_t freg;
earlz 0:217a7931b41f 326 #endif
earlz 0:217a7931b41f 327 volatile uint8_t op_cache[4];
earlz 0:217a7931b41f 328 volatile uint8_t ES;
earlz 0:217a7931b41f 329 volatile uint8_t CS;
earlz 0:217a7931b41f 330 volatile uint8_t SS;
earlz 0:217a7931b41f 331 volatile uint8_t DS;
earlz 0:217a7931b41f 332 volatile uint8_t FS;
earlz 0:217a7931b41f 333 volatile uint8_t GS;
earlz 0:217a7931b41f 334 volatile bool string_compares;
earlz 0:217a7931b41f 335 volatile uint8_t cli_count; //Whenever this is 1, an STI is done.
earlz 0:217a7931b41f 336 volatile bool int_pending;
earlz 0:217a7931b41f 337 volatile uint8_t int_number;
earlz 0:217a7931b41f 338 uint32_t cpu_level;
earlz 0:217a7931b41f 339 volatile bool busmaster;
earlz 0:217a7931b41f 340 void Init();
earlz 0:217a7931b41f 341 protected:
earlz 0:217a7931b41f 342 //! Do one CPU opcode
earlz 0:217a7931b41f 343 /*! This should be put in the main loop, as this is what makes the CPU work.
earlz 0:217a7931b41f 344 */
earlz 0:217a7931b41f 345 void Cycle();
earlz 0:217a7931b41f 346 opcode opcodes_16bit[256];
earlz 0:217a7931b41f 347 opcode *Opcodes;
earlz 0:217a7931b41f 348
earlz 0:217a7931b41f 349 /*!
earlz 0:217a7931b41f 350 \return 0 if no interrupts are pending
earlz 0:217a7931b41f 351 */
earlz 0:217a7931b41f 352 int CheckInterrupts();
earlz 0:217a7931b41f 353 public:
earlz 0:217a7931b41f 354 #ifdef ENABLE_OPCODE_CALLBACK
earlz 0:217a7931b41f 355 void (*EachOpcodeCallback)(x86CPU *thiscpu);
earlz 0:217a7931b41f 356 #endif
earlz 0:217a7931b41f 357 MemorySystem *Memory;
earlz 0:217a7931b41f 358 PortSystem *Ports;
earlz 0:217a7931b41f 359 /*!
earlz 0:217a7931b41f 360 \param cpu_level The CPU level to use(default argument is default level)
earlz 0:217a7931b41f 361 \param flags special flags to control CPU (currently, there is none)
earlz 0:217a7931b41f 362 */
earlz 0:217a7931b41f 363 x86CPU(uint32_t cpu_level=0 ,uint32_t flags=0);
earlz 0:217a7931b41f 364 /*!
earlz 0:217a7931b41f 365 \param save The x86SaveData class to restore the cpu to
earlz 0:217a7931b41f 366 \param flags special flags to control CPU (currently, there is none)
earlz 0:217a7931b41f 367 */
earlz 0:217a7931b41f 368 x86CPU(x86SaveData &save,uint32_t flags=0);
earlz 0:217a7931b41f 369
earlz 0:217a7931b41f 370 //!Runs the CPU for the specified cyclecount.
earlz 0:217a7931b41f 371 void Exec(int cyclecount);
earlz 0:217a7931b41f 372
earlz 0:217a7931b41f 373 //! Dump CPU state
earlz 0:217a7931b41f 374 /*! This will dump cpu state to output. This is mainly used for debugging, as it is not flexible.
earlz 0:217a7931b41f 375 \param output output stream which to use.
earlz 0:217a7931b41f 376 */
earlz 0:217a7931b41f 377 void DumpState(std::ostream &output);
earlz 0:217a7931b41f 378 //! Cause a CPU interrupt
earlz 0:217a7931b41f 379 /*! This will cause a CPU interrupt(unless interrupt flag is cleared)
earlz 0:217a7931b41f 380 Note! This does not resolve IRQs! This takes normal interrupt numbers(0-255)
earlz 0:217a7931b41f 381 \param num Interrupt number
earlz 0:217a7931b41f 382 */
earlz 0:217a7931b41f 383 void Int(uint8_t num);
earlz 0:217a7931b41f 384 //! Saves CPU state
earlz 0:217a7931b41f 385 /*! This will completely save the CPU state of the current x86CPU class
earlz 0:217a7931b41f 386 \param save_data_buffer This should be a free memory area the size of x86SaveData
earlz 0:217a7931b41f 387 */
earlz 0:217a7931b41f 388 void SaveState(x86SaveData *save_data_buffer);
earlz 0:217a7931b41f 389 //!Loads CPU state
earlz 0:217a7931b41f 390 /*! This will completely reset and reload the cpu state.
earlz 0:217a7931b41f 391 \param load_data where the x86SaveData is located
earlz 0:217a7931b41f 392 */
earlz 0:217a7931b41f 393 void LoadState(x86SaveData &load_data);
earlz 0:217a7931b41f 394
earlz 0:217a7931b41f 395 //!Completely resets the CPU
earlz 0:217a7931b41f 396 void Reset();
earlz 0:217a7931b41f 397 //~x86CPU();
earlz 0:217a7931b41f 398 //!Locks the PhysMemory in use, and declares this CPU as busmaster
earlz 0:217a7931b41f 399 void Lock();
earlz 0:217a7931b41f 400 //!Unlocks the PhysMemory in use
earlz 0:217a7931b41f 401 void Unlock();
earlz 0:217a7931b41f 402 //! Tells if PhysMemory in use is locked
earlz 0:217a7931b41f 403 /*!
earlz 0:217a7931b41f 404 \return 1 if PhysMemory in use is locked, otherwise returns 0
earlz 0:217a7931b41f 405 */
earlz 0:217a7931b41f 406 bool IsLocked();
earlz 0:217a7931b41f 407 /*Added after inital multi-branch switch over*/
earlz 0:217a7931b41f 408 //!Checks if an interrupt is on the stack waiting to be answered.
earlz 0:217a7931b41f 409 /*!
earlz 0:217a7931b41f 410 \return 1 if an interrupt is waiting to be answered by the CPU, else, 0.
earlz 0:217a7931b41f 411 */
earlz 0:217a7931b41f 412 bool IntPending();
earlz 0:217a7931b41f 413
earlz 0:217a7931b41f 414 /*End public interface*/
earlz 0:217a7931b41f 415 #ifdef X86LIB_BUILD
earlz 0:217a7931b41f 416 private:
earlz 0:217a7931b41f 417 #include <opcode_def.h>
earlz 0:217a7931b41f 418 #endif
earlz 0:217a7931b41f 419
earlz 0:217a7931b41f 420 };
earlz 0:217a7931b41f 421
earlz 0:217a7931b41f 422
earlz 0:217a7931b41f 423
earlz 0:217a7931b41f 424 #ifdef X86LIB_BUILD
earlz 0:217a7931b41f 425 #define X86_POST_CPU
earlz 0:217a7931b41f 426 #include "x86Lib_internal.h"
earlz 0:217a7931b41f 427 #undef X86_POST_CPU
earlz 0:217a7931b41f 428 #endif
earlz 0:217a7931b41f 429
earlz 0:217a7931b41f 430
earlz 0:217a7931b41f 431
earlz 0:217a7931b41f 432
earlz 0:217a7931b41f 433
earlz 0:217a7931b41f 434
earlz 0:217a7931b41f 435
earlz 0:217a7931b41f 436
earlz 0:217a7931b41f 437
earlz 0:217a7931b41f 438
earlz 0:217a7931b41f 439
earlz 0:217a7931b41f 440
earlz 0:217a7931b41f 441
earlz 0:217a7931b41f 442
earlz 0:217a7931b41f 443
earlz 0:217a7931b41f 444
earlz 0:217a7931b41f 445
earlz 0:217a7931b41f 446
earlz 0:217a7931b41f 447
earlz 0:217a7931b41f 448 }
earlz 0:217a7931b41f 449
earlz 0:217a7931b41f 450
earlz 0:217a7931b41f 451 #endif
earlz 0:217a7931b41f 452