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

Dependencies:   x86Lib mbed

Files at this revision

API Documentation at this revision

Comitter:
earlz
Date:
Sun Mar 04 08:16:36 2012 +0000
Commit message:

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
x86Lib.lib Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 03a56f060a1c main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Mar 04 08:16:36 2012 +0000
@@ -0,0 +1,273 @@
+#include "mbed.h"
+
+DigitalOut myled(LED1);
+DigitalOut errorled(LED2);
+DigitalOut aliveled(LED3);
+Serial pc(USBTX, USBRX); // tx, rx
+
+LocalFileSystem local("local"); 
+
+#include <iostream>
+#include <stdio.h>
+#include <fstream>
+#include <string.h>
+#include <stdlib.h>
+#undef X86LIB_BUILD //so we don't need special makefile flags for this specific file.
+#include <x86Lib.h>
+
+using namespace std;
+using namespace x86Lib;
+
+static const uint32_t ROM_START=0xC0000;
+uint8_t *ptr_memory;
+size_t size_memory;
+void init_memory(){
+    pc.printf("loading memory?\n");
+    size_memory=0x1000;
+    ptr_memory=new uint8_t[size_memory];//new uint8_t[size_memory];
+    ptr_memory[0]=10;
+    //memset((void*)ptr_memory,0x66,size_memory); //initialize it all to 0x66, an invalid opcode
+    pc.printf("about to load file\n");
+    
+    int size;
+    FILE* fh;
+
+    fh = fopen("/local/bios.x86", "rb"); //binary mode
+    pc.printf("getting size");
+    if(fh != NULL){
+        if( fseek(fh, 0, SEEK_END) ){
+            exit(1);
+        }
+    }
+
+    size = ftell(fh);
+    fseek(fh,0,SEEK_SET);
+    pc.printf("size is %i\n",size);
+    //Load bios...
+    fread((char*)ptr_memory,1,size,fh);
+    pc.printf("file read\n");
+    fclose(fh);
+    pc.printf("file closed\n");
+    int i;
+}
+
+/*Yea yea. hackjob, I know.. but I want this to work!**/
+class PCMemory : MemoryDevice{
+    uint8_t *ptr;
+    uint32_t size;
+    public:
+    PCMemory(){
+        //init_memory();
+    }
+    virtual void Read(uint32_t address,int count,void *buffer){
+        //pc.printf("memory read: 0x%x; count: %i\n",address,count);
+        //address=address-0xF0000;
+        //pc.printf("Z\n");
+        /*for(int i=0;i<count;i++){
+            //pc.printf("buffer: 0x%x; ptr_memory:0x%x\n",buffer,ptr_memory);
+            int tmp1=(int)ptr_memory[address+i];
+          //  pc.printf("tmp1: %i\n",(int)tmp1);
+            ((uint8_t*)buffer)[i]=tmp1;
+        }*/
+        
+        memcpy(buffer,&ptr_memory[address],count);
+    }
+    virtual void Write(uint32_t address,int count,void *buffer){
+        //address=address-0xF0000;
+       /* for(int i=0;i<count;i++){
+            ptr_memory[address]=((uint8_t*)buffer)[i];
+        }*/
+        memcpy(&ptr_memory[address],buffer,count);
+    }
+};
+
+
+volatile bool int_cause;
+volatile uint8_t int_cause_number=0;
+
+
+
+
+
+
+void WritePort(uint16_t port,uint32_t val){
+    /*Not going to try to emulate actual hardware...but rather just give us some useful
+    functions to try out...*/
+    static uint8_t interrupt_start=0;
+    static uint8_t counter=0;
+    switch(port){
+        case 0: //print asci char of val
+        myled=val;
+        pc.printf("val: %i\n",val);
+        break;
+        case 1:
+        pc.printf("output: %c\n",(char)val);
+        break;
+
+        default:
+        pc.printf("undefined port\n");
+        break;
+    }
+
+
+}
+
+uint32_t ReadPort(uint16_t port){
+    switch(port){
+        case 0x30:
+        uint8_t tmp;
+        cin.read((char*)&tmp,1);
+        return tmp;
+        break;
+
+        default:
+        pc.printf("undefined port\n");
+        return 0;
+        break;
+    }
+}
+
+void port_read(x86CPU *thiscpu,uint16_t port,int size,void *buffer){
+    uint32_t val;
+    val=ReadPort(port);
+    if(size==1){
+        *(uint8_t*)buffer=val;
+    }else if(size==2){
+        *(uint16_t*)buffer=val;
+    }else{
+        exit(1);
+        //throw;
+    }
+}
+void port_write(x86CPU *thiscpu,uint16_t port,int size,void *buffer){
+    uint32_t val;
+    if(size==1){
+        val=*(uint8_t*)buffer;
+    }else if(size==2){
+        val=(uint16_t)*(uint16_t*)buffer;
+    }else{
+        exit(1);
+    }
+    WritePort(port,val);
+}
+
+class PCPorts : PortDevice{
+    public:
+    ~PCPorts(){}
+    void Read(uint16_t port,int size,void *buffer){
+        port_read(NULL,port,size,buffer);
+    }
+    void Write(uint16_t port,int size,void *buffer){
+        port_write(NULL,port,size,buffer);
+    }
+};
+
+PCMemory memory;
+PCPorts ports;
+
+x86CPU **cpu_ctrl;
+
+void each_opcode(x86CPU *thiscpu){
+    if(int_cause){
+        int_cause=false;
+        thiscpu->Int(int_cause_number);
+    }
+}
+
+
+//typedef unsigned uint128_t __attribute__((mode(TI)));
+int main(){
+    aliveled=1;
+    pc.printf("alive\n");
+    uint32_t test=0;
+    void *t2;
+    t2=&test;
+    ((uint8_t*)t2)[0]=((uint8_t*)t2)[1];
+    
+    MemorySystem Memory;
+    PortSystem Ports;
+    pc.printf("memory and ports constructed\n");
+    init_memory();
+    pc.printf("memory loaded\n");
+    uint8_t cpu_i=0;
+    static const uint8_t cpu_number=1;
+    cpu_ctrl=new x86CPU *[cpu_number];
+    pc.printf("cpu created\n");
+    Memory.Add(0xF0000,0xF0000+0x1000,(MemoryDevice*)&memory);
+    pc.printf("memory added\n");
+    pc.printf("!");
+    fflush(stdout);
+    Ports.Add(0,0xFFFF,(PortDevice*)&ports);
+    pc.printf("!");
+    fflush(stdout);
+    for(cpu_i=0;cpu_i<cpu_number;cpu_i++){
+        cpu_ctrl[cpu_i]=new x86CPU();
+        cpu_ctrl[cpu_i]->Memory=(MemorySystem*)&Memory;
+        cpu_ctrl[cpu_i]->Ports=(PortSystem*)&Ports;
+#ifdef ENABLE_OPCODE_CALLBACK
+        cpu_ctrl[cpu_i]->EachOpcodeCallback=&each_opcode;
+#endif
+        pc.printf("!");
+        fflush(stdout);
+    }
+    cpu_i=0;
+    pc.printf("ready!\n\n");
+
+    
+    for(;;){
+        if(cpu_i==cpu_number){
+            cpu_i=0;
+        }
+        pc.printf(".");
+        //try{
+            cpu_ctrl[cpu_i]->Exec(500000);
+            //cpu2->Cycle();
+            if(int_cause){
+                int_cause=false;
+                cpu_ctrl[cpu_i]->Int(int_cause_number);
+            }
+        //}
+        /*catch(CpuPanic_excp err){
+            cout << "CPU Panic! CPU Number=" << (int)cpu_i <<endl;
+            cout << "Message: " << err.desc << endl;
+            cout << "Code: 0x" << hex << err.code << endl;
+            //cout << "Opcode: 0x" << hex << (int)op_cache[0] << endl;
+            for(cpu_i=0;cpu_i<cpu_number;cpu_i++){
+                cout << "CPU #" << (int)cpu_i << endl;
+                cpu_ctrl[cpu_i]->DumpState(cout);
+                cout << endl;
+            }
+            return 0;
+            for(;;){}
+        }
+        catch(Default_excp err){
+            cout << "!!Undefined Error!!" << endl;
+            cout << "File: " << err.file << endl;
+            cout << "Function: " << err.func << "()" <<endl;
+            cout << "Line: " << err.line << endl;
+            return 0;
+            for(;;){}
+        }
+        */
+        cpu_i++;
+    }
+
+
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 000000000000 -r 03a56f060a1c mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Mar 04 08:16:36 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/4c0c40fd0593
diff -r 000000000000 -r 03a56f060a1c x86Lib.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/x86Lib.lib	Sun Mar 04 08:16:36 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/earlz/code/x86Lib/#217a7931b41f