

#include <vpi_user.h>
#include <string.h>


#include "simuqtc.h"

int stopSimuFlag;

int keyPressed, keyReleased;

static int getcdata_compiletf(char *user_data)
{
return 0;
}

static int getcdata_calltf(char *user_data)
{


  vpiHandle sys_tf_ref, arg_iter;
  vpiHandle val1_h, val2_h, val3_h;
  s_vpi_value value;

  unsigned int addr, data, byteVal;
  
  sys_tf_ref = vpi_handle(vpiSysTfCall,NULL);
  arg_iter = vpi_iterate(vpiArgument, sys_tf_ref);

  val1_h = vpi_scan(arg_iter);
  val2_h = vpi_scan(arg_iter);
  val3_h = vpi_scan(arg_iter);

  //
  value.format = vpiIntVal;
  value.value.integer = stopSimuFlag;
	vpi_put_value ( val1_h, &value, 0, vpiNoDelay );

  value.value.integer = getKeyPressed();
	vpi_put_value ( val2_h, &value, 0, vpiNoDelay );

  value.value.integer = getKeyReleased();
	vpi_put_value ( val3_h, &value, 0, vpiNoDelay );

  
  return 0;

}

static int pcout_compiletf(char *user_data)
{
return 0;
}

static int pcout_calltf(char *user_data)
{

	int linelen = 133;

  vpiHandle sys_tf_ref, arg_iter;
  vpiHandle addr_h, data_h, byteVal_h;
  s_vpi_value value;

  unsigned int addr, data, byteVal;
  
  sys_tf_ref = vpi_handle(vpiSysTfCall,NULL);
  arg_iter = vpi_iterate(vpiArgument, sys_tf_ref);

  addr_h = vpi_scan(arg_iter);
  data_h = vpi_scan(arg_iter);
  byteVal_h = vpi_scan(arg_iter);

  //
  value.format = vpiIntVal;
  vpi_get_value(addr_h, &value);
  addr = value.value.integer;

  vpi_get_value(data_h, &value);
  data = value.value.integer;

	vpi_get_value(byteVal_h, &value);
	byteVal = value.value.integer;

  /* do it */
  //value.value.integer = (unsigned char)img_src->imageData[ (row*img_src->widthStep) + col ];
  
	addr = (4 * addr) % 8192;
	addr = addr + byteVal;
	int line = addr / linelen;
	int col = addr % linelen;

	// vpi_printf ( "%d * %d = %d ", line, col, data );

	put_xy_c ( line, col, data );




  /* return it */
  //vpi_put_value(dout_h, &value, 0, vpiNoDelay);
  
  return 0;

}

static int cwin_compiletf(char*user_data)
{
return 0;
}

static int cwin_calltf(char*user_data)
{

cwin_calltf_cpp ();

return 0;
}

static int simu_compiletf(char*user_data)
{
return 0;
}

static int simu_calltf(char*user_data)
{
int x = 0;
int y = 0;
int c = 0;

vpiHandle tos = vpi_handle_by_name ( "cpu_tb.UUT.tos", NULL);
vpiHandle ir = vpi_handle_by_name ( "cpu_tb.UUT.ir", NULL);

s_vpi_value value_s = {vpiHexStrVal};
p_vpi_value value_p = &value_s;

char tosval[40];
char irval[40];

vpi_get_value ( tos, value_p );
strcpy ( tosval, value_p->value.str );

vpi_get_value ( ir, value_p );
strcpy ( irval, value_p->value.str );

if (strncmp (irval, "ff3c", 4) == 0) {
	vpi_printf("++ print %d: tos = %s\n", outcnt++, tosval);
	put_xy_c(x++,y,c++);
}

return 0;
}

void simu_register()
{
s_vpi_systf_data tf_data;

tf_data.type      = vpiSysTask;
tf_data.tfname    = "$simu";
tf_data.calltf    = simu_calltf;
tf_data.compiletf = simu_compiletf;
tf_data.sizetf    = 0;
tf_data.user_data = 0;
vpi_register_systf(&tf_data);

tf_data.type      = vpiSysTask;
tf_data.tfname    = "$close_window";
tf_data.calltf    = cwin_calltf;
tf_data.compiletf = cwin_compiletf;
tf_data.sizetf    = 0;
tf_data.user_data = 0;
vpi_register_systf(&tf_data);

tf_data.type      = vpiSysTask;
tf_data.tfname    = "$put_char_out";
tf_data.calltf    = pcout_calltf;
tf_data.compiletf = pcout_compiletf;
tf_data.sizetf    = 0;
tf_data.user_data = "$put_char_out";
vpi_register_systf(&tf_data);

tf_data.type      = vpiSysTask;
tf_data.tfname    = "$get_c_data";
tf_data.calltf    = getcdata_calltf;
tf_data.compiletf = getcdata_compiletf;
tf_data.sizetf    = 0;
tf_data.user_data = "$get_c_data";
vpi_register_systf(&tf_data);

}

void (*vlog_startup_routines[])() = {
		simu_register,
    main_simu,
    0
};

