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

Dependencies:   x86Lib mbed

main.cpp

Committer:
earlz
Date:
2012-03-04
Revision:
0:03a56f060a1c

File content as of revision 0:03a56f060a1c:

#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++;
    }






}