#include <syscall.h>
#include <context-switch.h>
#include <bwio.h>

int Create (AP* Args) {
  //bwprintf(COM2,"Create: Arg location:%d\n\r",Args);
  asm volatile ("swi 0\n\t" );
//  bwprintf(COM2,"Back to Create\n\r");
  register int RetVal asm("r0");
  int Return = RetVal;
  return Return;
}

int MyTid() {
  int Address = (int )(&MyTid);
  //bwprintf(COM2,"MyTid Address: %d\n\r",Address);
  asm volatile ("swi 1\n\t");
  register int RetVal asm("r0");
  int R = RetVal;
  //bwprintf(COM2,"Back to MyTid, my tid is %d, My Address is %d\n\r",R);
  return R;
}

int MyParentTid() {
    asm volatile ("swi 2\n\t");
    register int RetVal asm("r0");
    return RetVal;

}

void Pass() {
  
  asm volatile ("swi 3\n\t");
  
}

void Exit() {
  //bwprintf(COM2,"Before SWI exit\n\r");
  asm volatile ("swi 4\n\t");
}

int ActualSend(AP* Args){
   asm volatile ("swi 5\n\t");
   register int RetVal asm("r0");
   int R = RetVal;
   return R;
}

// tid is that of the one its sending to
int Send (int TaskID, void* Msg, int MsgLen, void* Reply, int ReplyLen) {
  AP Args;
  Args.arg0 = (void *)(TaskID);
  Args.arg1 = Msg;
  bwprintf(COM2,"Send_USR: Msg: %d\n\r",Msg);
  Args.arg2 = (void *)(MsgLen);
  Args.arg3 = Reply;
  Args.arg4 = (void *)(ReplyLen);

  int MyID = MyTid();
  bwprintf(COM2,"Send: Task %d send MsgLen %d\n\r",TaskID,MsgLen);
  int Return = ActualSend(&Args);
  
  return Return;
}

int ActualReceive(AP* Args){
  asm volatile ("swi 6\n\t");
  register int RetVal asm("r0");
  int Return = RetVal;
  return Return;
}

int Receive (int TaskID, void* Msg, int MsgLen) {
  AP Args;
  Args.arg0 = (void *)(TaskID);
  Args.arg1 = (void *)(Msg);
  Args.arg2 = (void *)(MsgLen);
  bwprintf(COM2,"Receive_USR: TaskID%d, Msglen%d\n\r",TaskID,MsgLen);
  int Return = ActualReceive(&Args);
  return Return;
}

int ActualReplay(AP* Args){
  asm volatile ("swi 7\n\t");
  register int RetVal asm("r0");
  int Return = RetVal;
  return Return;
}

/* 
The calling task and the sender return at the same logical time. If they are of the same priority the sender runs first.
*/
int Reply (int TaskID, void* Reply, int ReplyLen) {
  AP Args;
  Args.arg0 = (void *)(TaskID);
  Args.arg1 = (void *)(Reply);
  Args.arg2 = (void *)(ReplyLen);

  int Return = ActualReplay(&Args);
  return Return;
}

int RecordNameServer(AP* Args){
  asm volatile("swi 8\n\t");
  register int RetVal asm("r0");
  int Return = RetVal;
  return Return;
}

Buffer** GetAllSendQ(){
  asm volatile("swi 11");
  register int RetVal asm("r0");
  Buffer** Return = (Buffer **)RetVal;
  return Return;
}