This is a little test program for x86Lib for a demonstration on how to use it for emulating 8086 programs

Dependencies:   x86Lib mbed

Committer:
earlz
Date:
Sun Mar 04 08:16:36 2012 +0000
Revision:
0:03a56f060a1c

        

Who changed what in which revision?

UserRevisionLine numberNew 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