Jordan Earls
/
x86Lib_Tester
This is a little test program for x86Lib for a demonstration on how to use it for emulating 8086 programs
main.cpp@0:03a56f060a1c, 2012-03-04 (annotated)
- Committer:
- earlz
- Date:
- Sun Mar 04 08:16:36 2012 +0000
- Revision:
- 0:03a56f060a1c
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
earlz | 0:03a56f060a1c | 1 | #include "mbed.h" |
earlz | 0:03a56f060a1c | 2 | |
earlz | 0:03a56f060a1c | 3 | DigitalOut myled(LED1); |
earlz | 0:03a56f060a1c | 4 | DigitalOut errorled(LED2); |
earlz | 0:03a56f060a1c | 5 | DigitalOut aliveled(LED3); |
earlz | 0:03a56f060a1c | 6 | Serial pc(USBTX, USBRX); // tx, rx |
earlz | 0:03a56f060a1c | 7 | |
earlz | 0:03a56f060a1c | 8 | LocalFileSystem local("local"); |
earlz | 0:03a56f060a1c | 9 | |
earlz | 0:03a56f060a1c | 10 | #include <iostream> |
earlz | 0:03a56f060a1c | 11 | #include <stdio.h> |
earlz | 0:03a56f060a1c | 12 | #include <fstream> |
earlz | 0:03a56f060a1c | 13 | #include <string.h> |
earlz | 0:03a56f060a1c | 14 | #include <stdlib.h> |
earlz | 0:03a56f060a1c | 15 | #undef X86LIB_BUILD //so we don't need special makefile flags for this specific file. |
earlz | 0:03a56f060a1c | 16 | #include <x86Lib.h> |
earlz | 0:03a56f060a1c | 17 | |
earlz | 0:03a56f060a1c | 18 | using namespace std; |
earlz | 0:03a56f060a1c | 19 | using namespace x86Lib; |
earlz | 0:03a56f060a1c | 20 | |
earlz | 0:03a56f060a1c | 21 | static const uint32_t ROM_START=0xC0000; |
earlz | 0:03a56f060a1c | 22 | uint8_t *ptr_memory; |
earlz | 0:03a56f060a1c | 23 | size_t size_memory; |
earlz | 0:03a56f060a1c | 24 | void init_memory(){ |
earlz | 0:03a56f060a1c | 25 | pc.printf("loading memory?\n"); |
earlz | 0:03a56f060a1c | 26 | size_memory=0x1000; |
earlz | 0:03a56f060a1c | 27 | ptr_memory=new uint8_t[size_memory];//new uint8_t[size_memory]; |
earlz | 0:03a56f060a1c | 28 | ptr_memory[0]=10; |
earlz | 0:03a56f060a1c | 29 | //memset((void*)ptr_memory,0x66,size_memory); //initialize it all to 0x66, an invalid opcode |
earlz | 0:03a56f060a1c | 30 | pc.printf("about to load file\n"); |
earlz | 0:03a56f060a1c | 31 | |
earlz | 0:03a56f060a1c | 32 | int size; |
earlz | 0:03a56f060a1c | 33 | FILE* fh; |
earlz | 0:03a56f060a1c | 34 | |
earlz | 0:03a56f060a1c | 35 | fh = fopen("/local/bios.x86", "rb"); //binary mode |
earlz | 0:03a56f060a1c | 36 | pc.printf("getting size"); |
earlz | 0:03a56f060a1c | 37 | if(fh != NULL){ |
earlz | 0:03a56f060a1c | 38 | if( fseek(fh, 0, SEEK_END) ){ |
earlz | 0:03a56f060a1c | 39 | exit(1); |
earlz | 0:03a56f060a1c | 40 | } |
earlz | 0:03a56f060a1c | 41 | } |
earlz | 0:03a56f060a1c | 42 | |
earlz | 0:03a56f060a1c | 43 | size = ftell(fh); |
earlz | 0:03a56f060a1c | 44 | fseek(fh,0,SEEK_SET); |
earlz | 0:03a56f060a1c | 45 | pc.printf("size is %i\n",size); |
earlz | 0:03a56f060a1c | 46 | //Load bios... |
earlz | 0:03a56f060a1c | 47 | fread((char*)ptr_memory,1,size,fh); |
earlz | 0:03a56f060a1c | 48 | pc.printf("file read\n"); |
earlz | 0:03a56f060a1c | 49 | fclose(fh); |
earlz | 0:03a56f060a1c | 50 | pc.printf("file closed\n"); |
earlz | 0:03a56f060a1c | 51 | int i; |
earlz | 0:03a56f060a1c | 52 | } |
earlz | 0:03a56f060a1c | 53 | |
earlz | 0:03a56f060a1c | 54 | /*Yea yea. hackjob, I know.. but I want this to work!**/ |
earlz | 0:03a56f060a1c | 55 | class PCMemory : MemoryDevice{ |
earlz | 0:03a56f060a1c | 56 | uint8_t *ptr; |
earlz | 0:03a56f060a1c | 57 | uint32_t size; |
earlz | 0:03a56f060a1c | 58 | public: |
earlz | 0:03a56f060a1c | 59 | PCMemory(){ |
earlz | 0:03a56f060a1c | 60 | //init_memory(); |
earlz | 0:03a56f060a1c | 61 | } |
earlz | 0:03a56f060a1c | 62 | virtual void Read(uint32_t address,int count,void *buffer){ |
earlz | 0:03a56f060a1c | 63 | //pc.printf("memory read: 0x%x; count: %i\n",address,count); |
earlz | 0:03a56f060a1c | 64 | //address=address-0xF0000; |
earlz | 0:03a56f060a1c | 65 | //pc.printf("Z\n"); |
earlz | 0:03a56f060a1c | 66 | /*for(int i=0;i<count;i++){ |
earlz | 0:03a56f060a1c | 67 | //pc.printf("buffer: 0x%x; ptr_memory:0x%x\n",buffer,ptr_memory); |
earlz | 0:03a56f060a1c | 68 | int tmp1=(int)ptr_memory[address+i]; |
earlz | 0:03a56f060a1c | 69 | // pc.printf("tmp1: %i\n",(int)tmp1); |
earlz | 0:03a56f060a1c | 70 | ((uint8_t*)buffer)[i]=tmp1; |
earlz | 0:03a56f060a1c | 71 | }*/ |
earlz | 0:03a56f060a1c | 72 | |
earlz | 0:03a56f060a1c | 73 | memcpy(buffer,&ptr_memory[address],count); |
earlz | 0:03a56f060a1c | 74 | } |
earlz | 0:03a56f060a1c | 75 | virtual void Write(uint32_t address,int count,void *buffer){ |
earlz | 0:03a56f060a1c | 76 | //address=address-0xF0000; |
earlz | 0:03a56f060a1c | 77 | /* for(int i=0;i<count;i++){ |
earlz | 0:03a56f060a1c | 78 | ptr_memory[address]=((uint8_t*)buffer)[i]; |
earlz | 0:03a56f060a1c | 79 | }*/ |
earlz | 0:03a56f060a1c | 80 | memcpy(&ptr_memory[address],buffer,count); |
earlz | 0:03a56f060a1c | 81 | } |
earlz | 0:03a56f060a1c | 82 | }; |
earlz | 0:03a56f060a1c | 83 | |
earlz | 0:03a56f060a1c | 84 | |
earlz | 0:03a56f060a1c | 85 | volatile bool int_cause; |
earlz | 0:03a56f060a1c | 86 | volatile uint8_t int_cause_number=0; |
earlz | 0:03a56f060a1c | 87 | |
earlz | 0:03a56f060a1c | 88 | |
earlz | 0:03a56f060a1c | 89 | |
earlz | 0:03a56f060a1c | 90 | |
earlz | 0:03a56f060a1c | 91 | |
earlz | 0:03a56f060a1c | 92 | |
earlz | 0:03a56f060a1c | 93 | void WritePort(uint16_t port,uint32_t val){ |
earlz | 0:03a56f060a1c | 94 | /*Not going to try to emulate actual hardware...but rather just give us some useful |
earlz | 0:03a56f060a1c | 95 | functions to try out...*/ |
earlz | 0:03a56f060a1c | 96 | static uint8_t interrupt_start=0; |
earlz | 0:03a56f060a1c | 97 | static uint8_t counter=0; |
earlz | 0:03a56f060a1c | 98 | switch(port){ |
earlz | 0:03a56f060a1c | 99 | case 0: //print asci char of val |
earlz | 0:03a56f060a1c | 100 | myled=val; |
earlz | 0:03a56f060a1c | 101 | pc.printf("val: %i\n",val); |
earlz | 0:03a56f060a1c | 102 | break; |
earlz | 0:03a56f060a1c | 103 | case 1: |
earlz | 0:03a56f060a1c | 104 | pc.printf("output: %c\n",(char)val); |
earlz | 0:03a56f060a1c | 105 | break; |
earlz | 0:03a56f060a1c | 106 | |
earlz | 0:03a56f060a1c | 107 | default: |
earlz | 0:03a56f060a1c | 108 | pc.printf("undefined port\n"); |
earlz | 0:03a56f060a1c | 109 | break; |
earlz | 0:03a56f060a1c | 110 | } |
earlz | 0:03a56f060a1c | 111 | |
earlz | 0:03a56f060a1c | 112 | |
earlz | 0:03a56f060a1c | 113 | } |
earlz | 0:03a56f060a1c | 114 | |
earlz | 0:03a56f060a1c | 115 | uint32_t ReadPort(uint16_t port){ |
earlz | 0:03a56f060a1c | 116 | switch(port){ |
earlz | 0:03a56f060a1c | 117 | case 0x30: |
earlz | 0:03a56f060a1c | 118 | uint8_t tmp; |
earlz | 0:03a56f060a1c | 119 | cin.read((char*)&tmp,1); |
earlz | 0:03a56f060a1c | 120 | return tmp; |
earlz | 0:03a56f060a1c | 121 | break; |
earlz | 0:03a56f060a1c | 122 | |
earlz | 0:03a56f060a1c | 123 | default: |
earlz | 0:03a56f060a1c | 124 | pc.printf("undefined port\n"); |
earlz | 0:03a56f060a1c | 125 | return 0; |
earlz | 0:03a56f060a1c | 126 | break; |
earlz | 0:03a56f060a1c | 127 | } |
earlz | 0:03a56f060a1c | 128 | } |
earlz | 0:03a56f060a1c | 129 | |
earlz | 0:03a56f060a1c | 130 | void port_read(x86CPU *thiscpu,uint16_t port,int size,void *buffer){ |
earlz | 0:03a56f060a1c | 131 | uint32_t val; |
earlz | 0:03a56f060a1c | 132 | val=ReadPort(port); |
earlz | 0:03a56f060a1c | 133 | if(size==1){ |
earlz | 0:03a56f060a1c | 134 | *(uint8_t*)buffer=val; |
earlz | 0:03a56f060a1c | 135 | }else if(size==2){ |
earlz | 0:03a56f060a1c | 136 | *(uint16_t*)buffer=val; |
earlz | 0:03a56f060a1c | 137 | }else{ |
earlz | 0:03a56f060a1c | 138 | exit(1); |
earlz | 0:03a56f060a1c | 139 | //throw; |
earlz | 0:03a56f060a1c | 140 | } |
earlz | 0:03a56f060a1c | 141 | } |
earlz | 0:03a56f060a1c | 142 | void port_write(x86CPU *thiscpu,uint16_t port,int size,void *buffer){ |
earlz | 0:03a56f060a1c | 143 | uint32_t val; |
earlz | 0:03a56f060a1c | 144 | if(size==1){ |
earlz | 0:03a56f060a1c | 145 | val=*(uint8_t*)buffer; |
earlz | 0:03a56f060a1c | 146 | }else if(size==2){ |
earlz | 0:03a56f060a1c | 147 | val=(uint16_t)*(uint16_t*)buffer; |
earlz | 0:03a56f060a1c | 148 | }else{ |
earlz | 0:03a56f060a1c | 149 | exit(1); |
earlz | 0:03a56f060a1c | 150 | } |
earlz | 0:03a56f060a1c | 151 | WritePort(port,val); |
earlz | 0:03a56f060a1c | 152 | } |
earlz | 0:03a56f060a1c | 153 | |
earlz | 0:03a56f060a1c | 154 | class PCPorts : PortDevice{ |
earlz | 0:03a56f060a1c | 155 | public: |
earlz | 0:03a56f060a1c | 156 | ~PCPorts(){} |
earlz | 0:03a56f060a1c | 157 | void Read(uint16_t port,int size,void *buffer){ |
earlz | 0:03a56f060a1c | 158 | port_read(NULL,port,size,buffer); |
earlz | 0:03a56f060a1c | 159 | } |
earlz | 0:03a56f060a1c | 160 | void Write(uint16_t port,int size,void *buffer){ |
earlz | 0:03a56f060a1c | 161 | port_write(NULL,port,size,buffer); |
earlz | 0:03a56f060a1c | 162 | } |
earlz | 0:03a56f060a1c | 163 | }; |
earlz | 0:03a56f060a1c | 164 | |
earlz | 0:03a56f060a1c | 165 | PCMemory memory; |
earlz | 0:03a56f060a1c | 166 | PCPorts ports; |
earlz | 0:03a56f060a1c | 167 | |
earlz | 0:03a56f060a1c | 168 | x86CPU **cpu_ctrl; |
earlz | 0:03a56f060a1c | 169 | |
earlz | 0:03a56f060a1c | 170 | void each_opcode(x86CPU *thiscpu){ |
earlz | 0:03a56f060a1c | 171 | if(int_cause){ |
earlz | 0:03a56f060a1c | 172 | int_cause=false; |
earlz | 0:03a56f060a1c | 173 | thiscpu->Int(int_cause_number); |
earlz | 0:03a56f060a1c | 174 | } |
earlz | 0:03a56f060a1c | 175 | } |
earlz | 0:03a56f060a1c | 176 | |
earlz | 0:03a56f060a1c | 177 | |
earlz | 0:03a56f060a1c | 178 | //typedef unsigned uint128_t __attribute__((mode(TI))); |
earlz | 0:03a56f060a1c | 179 | int main(){ |
earlz | 0:03a56f060a1c | 180 | aliveled=1; |
earlz | 0:03a56f060a1c | 181 | pc.printf("alive\n"); |
earlz | 0:03a56f060a1c | 182 | uint32_t test=0; |
earlz | 0:03a56f060a1c | 183 | void *t2; |
earlz | 0:03a56f060a1c | 184 | t2=&test; |
earlz | 0:03a56f060a1c | 185 | ((uint8_t*)t2)[0]=((uint8_t*)t2)[1]; |
earlz | 0:03a56f060a1c | 186 | |
earlz | 0:03a56f060a1c | 187 | MemorySystem Memory; |
earlz | 0:03a56f060a1c | 188 | PortSystem Ports; |
earlz | 0:03a56f060a1c | 189 | pc.printf("memory and ports constructed\n"); |
earlz | 0:03a56f060a1c | 190 | init_memory(); |
earlz | 0:03a56f060a1c | 191 | pc.printf("memory loaded\n"); |
earlz | 0:03a56f060a1c | 192 | uint8_t cpu_i=0; |
earlz | 0:03a56f060a1c | 193 | static const uint8_t cpu_number=1; |
earlz | 0:03a56f060a1c | 194 | cpu_ctrl=new x86CPU *[cpu_number]; |
earlz | 0:03a56f060a1c | 195 | pc.printf("cpu created\n"); |
earlz | 0:03a56f060a1c | 196 | Memory.Add(0xF0000,0xF0000+0x1000,(MemoryDevice*)&memory); |
earlz | 0:03a56f060a1c | 197 | pc.printf("memory added\n"); |
earlz | 0:03a56f060a1c | 198 | pc.printf("!"); |
earlz | 0:03a56f060a1c | 199 | fflush(stdout); |
earlz | 0:03a56f060a1c | 200 | Ports.Add(0,0xFFFF,(PortDevice*)&ports); |
earlz | 0:03a56f060a1c | 201 | pc.printf("!"); |
earlz | 0:03a56f060a1c | 202 | fflush(stdout); |
earlz | 0:03a56f060a1c | 203 | for(cpu_i=0;cpu_i<cpu_number;cpu_i++){ |
earlz | 0:03a56f060a1c | 204 | cpu_ctrl[cpu_i]=new x86CPU(); |
earlz | 0:03a56f060a1c | 205 | cpu_ctrl[cpu_i]->Memory=(MemorySystem*)&Memory; |
earlz | 0:03a56f060a1c | 206 | cpu_ctrl[cpu_i]->Ports=(PortSystem*)&Ports; |
earlz | 0:03a56f060a1c | 207 | #ifdef ENABLE_OPCODE_CALLBACK |
earlz | 0:03a56f060a1c | 208 | cpu_ctrl[cpu_i]->EachOpcodeCallback=&each_opcode; |
earlz | 0:03a56f060a1c | 209 | #endif |
earlz | 0:03a56f060a1c | 210 | pc.printf("!"); |
earlz | 0:03a56f060a1c | 211 | fflush(stdout); |
earlz | 0:03a56f060a1c | 212 | } |
earlz | 0:03a56f060a1c | 213 | cpu_i=0; |
earlz | 0:03a56f060a1c | 214 | pc.printf("ready!\n\n"); |
earlz | 0:03a56f060a1c | 215 | |
earlz | 0:03a56f060a1c | 216 | |
earlz | 0:03a56f060a1c | 217 | for(;;){ |
earlz | 0:03a56f060a1c | 218 | if(cpu_i==cpu_number){ |
earlz | 0:03a56f060a1c | 219 | cpu_i=0; |
earlz | 0:03a56f060a1c | 220 | } |
earlz | 0:03a56f060a1c | 221 | pc.printf("."); |
earlz | 0:03a56f060a1c | 222 | //try{ |
earlz | 0:03a56f060a1c | 223 | cpu_ctrl[cpu_i]->Exec(500000); |
earlz | 0:03a56f060a1c | 224 | //cpu2->Cycle(); |
earlz | 0:03a56f060a1c | 225 | if(int_cause){ |
earlz | 0:03a56f060a1c | 226 | int_cause=false; |
earlz | 0:03a56f060a1c | 227 | cpu_ctrl[cpu_i]->Int(int_cause_number); |
earlz | 0:03a56f060a1c | 228 | } |
earlz | 0:03a56f060a1c | 229 | //} |
earlz | 0:03a56f060a1c | 230 | /*catch(CpuPanic_excp err){ |
earlz | 0:03a56f060a1c | 231 | cout << "CPU Panic! CPU Number=" << (int)cpu_i <<endl; |
earlz | 0:03a56f060a1c | 232 | cout << "Message: " << err.desc << endl; |
earlz | 0:03a56f060a1c | 233 | cout << "Code: 0x" << hex << err.code << endl; |
earlz | 0:03a56f060a1c | 234 | //cout << "Opcode: 0x" << hex << (int)op_cache[0] << endl; |
earlz | 0:03a56f060a1c | 235 | for(cpu_i=0;cpu_i<cpu_number;cpu_i++){ |
earlz | 0:03a56f060a1c | 236 | cout << "CPU #" << (int)cpu_i << endl; |
earlz | 0:03a56f060a1c | 237 | cpu_ctrl[cpu_i]->DumpState(cout); |
earlz | 0:03a56f060a1c | 238 | cout << endl; |
earlz | 0:03a56f060a1c | 239 | } |
earlz | 0:03a56f060a1c | 240 | return 0; |
earlz | 0:03a56f060a1c | 241 | for(;;){} |
earlz | 0:03a56f060a1c | 242 | } |
earlz | 0:03a56f060a1c | 243 | catch(Default_excp err){ |
earlz | 0:03a56f060a1c | 244 | cout << "!!Undefined Error!!" << endl; |
earlz | 0:03a56f060a1c | 245 | cout << "File: " << err.file << endl; |
earlz | 0:03a56f060a1c | 246 | cout << "Function: " << err.func << "()" <<endl; |
earlz | 0:03a56f060a1c | 247 | cout << "Line: " << err.line << endl; |
earlz | 0:03a56f060a1c | 248 | return 0; |
earlz | 0:03a56f060a1c | 249 | for(;;){} |
earlz | 0:03a56f060a1c | 250 | } |
earlz | 0:03a56f060a1c | 251 | */ |
earlz | 0:03a56f060a1c | 252 | cpu_i++; |
earlz | 0:03a56f060a1c | 253 | } |
earlz | 0:03a56f060a1c | 254 | |
earlz | 0:03a56f060a1c | 255 | |
earlz | 0:03a56f060a1c | 256 | |
earlz | 0:03a56f060a1c | 257 | |
earlz | 0:03a56f060a1c | 258 | |
earlz | 0:03a56f060a1c | 259 | |
earlz | 0:03a56f060a1c | 260 | } |
earlz | 0:03a56f060a1c | 261 | |
earlz | 0:03a56f060a1c | 262 | |
earlz | 0:03a56f060a1c | 263 | |
earlz | 0:03a56f060a1c | 264 | |
earlz | 0:03a56f060a1c | 265 | |
earlz | 0:03a56f060a1c | 266 | |
earlz | 0:03a56f060a1c | 267 | |
earlz | 0:03a56f060a1c | 268 | |
earlz | 0:03a56f060a1c | 269 | |
earlz | 0:03a56f060a1c | 270 | |
earlz | 0:03a56f060a1c | 271 | |
earlz | 0:03a56f060a1c | 272 | |
earlz | 0:03a56f060a1c | 273 |