#ifdef SYSTEMC
#include "systemc.h"
#endif
#include <iostream>
#include "../include/Sim2OS.h"

using namespace std;
using namespace environment;
using namespace environment::sim2os;

#ifdef SYSTEMC
int sc_main (int argc, char * argv[])
#else
int    main (int argc, char * argv[])
#endif
{
  cout << "<main> Begin" << endl;

  SOCLIB_SEGMENT_TABLE * segtable = new SOCLIB_SEGMENT_TABLE;
  segtable->setMSBNumber    (8);
  segtable->setDefaultTarget(0,0);
  
  //shared data segment

  const int TEXT_BASE          = 0x1000;
  const int DATA_CACHED_BASE   = 0x2000;
  const int DATA_UNCACHED_BASE = 0x3000;
  const int STACK_BASE         = 0x4000;
  const int TTY_BASE           = 0x5000;
  const int SIM2OS_BASE        = 0x6000;
  const int RAMLOCK_BASE       = 0x7000;
  
  const int TEXT_SIZE          = 0x100;
  const int DATA_CACHED_SIZE   = 0x100;
  const int DATA_UNCACHED_SIZE = 0x100;
  const int STACK_SIZE         = 0x100;
  const int TTY_SIZE           = 0x100;
  const int SIM2OS_SIZE        = 0x100;
  const int RAMLOCK_SIZE       = 0x100;

  // Add a segment   :name        , address of base    , size               , global index , local index, uncache
  segtable->addSegment("text"      , TEXT_BASE          , TEXT_SIZE          , 0            ,0           , false);
  segtable->addSegment("data"      , DATA_CACHED_BASE   , DATA_CACHED_SIZE   , 0            ,0           , false);
  segtable->addSegment("data_unc"  , DATA_UNCACHED_BASE , DATA_UNCACHED_SIZE , 0            ,0           , true );
  segtable->addSegment("stack"     , STACK_BASE         , STACK_SIZE         , 0            ,0           , false);
  segtable->addSegment("tty"       , TTY_BASE           , TTY_SIZE           , 0            ,0           , true );
  segtable->addSegment("sim2os"    , SIM2OS_BASE        , SIM2OS_SIZE        , 0            ,0           , true );
  segtable->addSegment("ramlock"   , RAMLOCK_BASE       , RAMLOCK_SIZE       , 0            ,0           , true );

  segtable->print();

  Parameters * param = new Parameters (segtable);
  
  Sim2OS * my_sim2os = new Sim2OS ("my_sim2os",param);

  cout << *my_sim2os << endl;

  my_sim2os->transition();
  my_sim2os->transition();
  my_sim2os->transition();
  my_sim2os->transition();
  my_sim2os->transition();
  my_sim2os->transition();
  my_sim2os->transition();
  my_sim2os->transition(); // cycle 8

  my_sim2os->parameter(1,(void*)  21071981);
  my_sim2os->parameter(2,(void*)0xdeadbeef);
  my_sim2os->parameter(0,(void*)5); // SERVICE_CLOCK

  cout << *my_sim2os << endl;
  my_sim2os->execute();
  cout << *my_sim2os << endl;

//   char * pathname = "toto.txt";
//   int    flags    = O_CREAT;
//   mode_t mode     = 0777;

//   my_sim2os->parameter(1,(void*)pathname);
//   my_sim2os->parameter(2,(void*)flags   );
//   my_sim2os->parameter(3,(void*)mode    );
//   my_sim2os->parameter(0,(void*)0       );

//   cout << *my_sim2os << endl;
//   my_sim2os->execute();
//   cout << *my_sim2os << endl;

  delete my_sim2os;
  delete param;
  delete segtable;

  cout << "<main> End" << endl;

  return EXIT_SUCCESS;
}
