#line 1 "run.c"
#line 1 "libc.c"
extern short putc();
extern short printf();
extern short print_short();
extern short getch();
extern short scanf();
extern short is_digit();
extern short atoi();
extern short strlen();
extern short strcpy();

short
is_digit(ch)
short ch;
{
   if(ch >= '0' && ch <= '9') {
      return 1;
   }
   return 0;
}

short
strlen(ptr)
char * ptr;
{
   short n;
   n = 0;
   while(*ptr) {
     n++;
     ptr++;
   }
   return n;
}

short
atoi(str)
char * str ;
{
   short ret;
   short i;
   short n;
   short off;
   short num[6];

   num[4] = 10000;
   num[3] = 1000;
   num[2] = 100;
   num[1] = 10;
   num[0] = 1;

   ret = 0;
   n = strlen(str);

   off = n - 1;

   for(i = 0; i < n; i++) {
      switch(str[i]) {
      case '0':
      break;
      case '1':
         ret = ret + 1 * num[off-i];
      break;
      case '2':
         ret = ret + 2 * num[off-i];
      break;
      case '3':
         ret = ret + 3 * num[off-i];
      break;
      case '4':
         ret = ret + 4 * num[off-i];
      break;
      case '5':
         ret = ret + 5 * num[off-i];
      break;
      case '6':
         ret = ret + 6 * num[off-i];
      break;
      case '7':
         ret = ret + 7 * num[off-i];
      break;
      case '8':
         ret = ret + 8 * num[off-i];
      break;
      case '9':
         ret = ret + 9 * num[off-i];
      break;
      }
   }

   return ret;
}


short
scanf(fmt)
char * fmt;
{
   char ** ptr;
   char * p;
   short * temp;
   char buffer[100];
   short offset;
   short ch;
   short count;

   offset = 0;
   count = 2;

   ptr = &fmt + count;

   for(p = fmt; *p; p++) {
      if(*p == '%') {
         p++;
         if(*p == 'd') {
            temp = (short*)(*ptr);

            ch = getch();
            putc(ch);

            offset = 0;

            while(is_digit(ch) && ch != '\r' && ch != '\n') {
               buffer[offset] = ch;
               offset++;
               ch = getch();
               putc(ch);
            }

            buffer[offset] = '\0';

            *temp = atoi(buffer); 

            count = count + 2;

            ptr = &fmt + count;
         }
         else if(*p == 'f') {
         }
         else if(*p == 's') {
         }
         else if(*p == 'c') {
         }
      }
      else {
      }
   }

   return 0;
}

short
print_short(number)
short number;
{
   short ret;
   short n;
   char byte_array[10];
   char buffer[10];
   short index;

   ret = 0;

   byte_array[0] = '0';
   byte_array[1] = '1';
   byte_array[2] = '2';
   byte_array[3] = '3';
   byte_array[4] = '4';
   byte_array[5] = '5';
   byte_array[6] = '6';
   byte_array[7] = '7';
   byte_array[8] = '8';
   byte_array[9] = '9';

   if(number == 0) {
      putc('0');
   }

   index = 0;
   while(number) {
      n = number % 10;
      number = number / 10;
      buffer[index] = byte_array[n];
      index++;
   }

   index--;
   while(index >= 0) {
      putc(buffer[index]);
      index--;
   }

   return ret;
}


short
printf(fmt)
char * fmt;
{
   char * ptr;
   short * ptr0;
   char * ptr1;
   short i,j;
   short ret;

   ret = 0;
   
   ptr = fmt;
   i = 2;

   while(*ptr) {
      if(*ptr == '%') {
         ptr++;
         if(*ptr == '%') {
            putc('%');
            ptr++;
         }
         else if(*ptr == 'x') {
            ptr0 = (&fmt) + i;
            tohex(*ptr0);
            i += 2;
            ptr++;
         }
         else if(*ptr == 'd') {
            ptr0 = &fmt + i;
            print_short(*ptr0);
            i += 2;
            ptr++;
         }
         else if(*ptr == 's') {
            ptr0 = &fmt + i;
            ptr1 = *ptr0;
            while(*ptr1) {
               putc(*ptr1);
               ptr1++;
            }
            i += 2;
            ptr++;
         }
         else {
            ptr++;
         }
      }
      else {
         putc(*ptr);
         ptr++;
      }
   }
   
   return 0;
}

void
strcpy(a,b)
char * a;
char * b;
{
   while(*a = *b) {
      a++;
      b++;
   }
}
#line 2 "run.c"






typedef short (*pf_t)();

extern void readline();
extern void bzero();
extern void gets();
extern short getch();
extern void putc();
extern void load_program();
extern short strcmp();
extern void readfile();
extern short findsector2();
extern void tohex();
extern short get_fat();
extern char* link_program();
extern void exit();

short
get_fat(i)
short i;
{
   char buffer[300];

   strcpy(buffer, "{hello16-0,aout-1,prog-2,c-3,}");

   return buffer[i];
}




























void
gets(ptr)
char * ptr;
{
   short ch;
   short i;

   i = 0;
   ch = getch();
   while (ch != '\r' && ch != '\n') {
      if (ch == '\b' && i > 0) {
         putc(ch);
         ch = getch(); 
         i--;
         ptr[i] = '\0';
         continue;
      }
      else if(ch == '\b') {
         ch = getch(); 
         continue;
      }
      putc(ch);
      ptr[i] = ch;
      i++;
      ch = getch();
   }
   ptr[i] = '\0';
printf("\r\n");
printf("ptr -> ");
printf(ptr);
printf("\r\n");
}

void
bzero(ptr,size)
char * ptr;
short size;
{
   short i;
   for(i = 0; i < size; i++) {
      ptr[i] = '\0';
   }
}

short
findsector2(cmd)
char * cmd;
{
   short i,j,ch;
   char buffer[1024];
   char name[1024];
   char sector[1024];

printf("find sector: cmd == \"%s\"\r\n", cmd);

   bzero(buffer, 1024);
   bzero(name, 1024);
   bzero(sector, 1024);

   for(i = 0; get_fat(i) != '}'; i++) {
      ch = get_fat(i);
      buffer[i] = ch;
   }

   buffer[i] = '}';

printf("fat=(%s)\r\n", buffer);

   j = 0;
   for(i = 1; buffer[i] != '}'; i++) {
      if(buffer[i] == '-') {
printf("name=(%s)\r\n", name);
         if(strcmp(name, cmd) == 0) {
            bzero(sector, 1024);
            i++;
            j = 0;
            while(buffer[i] != ',') {
               sector[j] = buffer[i];
               i++;
               j++;
            }
            break;
         }
         else {
            j = 0;
            bzero(name, 1024);
            bzero(sector, 1024);
            i++;
            while(buffer[i] != ',') {
               ch = buffer[i];
               sector[j] = ch;
               i++;
               j++;
            }
            j = 0;
            bzero(sector, 1024);
            i++;
            continue;
         }
      }
      if(buffer[i] != ',') {
         name[j] = buffer[i];
         j++;
      }
      else {
         j = 0;
         bzero(name, 1024);
      }
   }


printf("FAT = (%s)\r\n", buffer);

printf("NAME = (%s)\r\n", name);

printf("SECTOR = (%s)\r\n", sector);
printf("SECTOR = (%d)\r\n", atoi(sector));

   return atoi(sector);
}


void
load_program(cmd,code)
char * cmd;
char * code;
{
   short sector,i;
   printf("LOAD: %s\r\n", cmd);
   printf("CODE ADDRESS = %d\r\n", code);
   sector = findsector2(cmd);
   printf("SECTOR: %d\r\n", sector);
   readfile(sector,code);
}

short
strcmp(arg1,arg2)
char * arg1;
char * arg2;
{
   short ret,i,ch1,ch2;
   ret = 0;
   for(i = 0; arg1[i] && arg2[i]; i++) {
      ch1 = arg1[i];
      ch2 = arg2[i];
      if(ch1 == ch2) {

      }
      else if(ch1 < ch2) {
         ret = -1;
         break;
      }
      else if(ch1 > ch2) {
         ret = 1;
         break;
      }
   }
   return ret;
}

struct reloc {
   short addr0;
   short addr1;
   short is_label;
};

char*
link_program(code)
char * code;
{
   struct reloc reloc_array[10];
   char * name;
   char * word_ptr;
   char * code_ptr;
   char * temp_ptr;
   short 
   reloc_count,
   name_size, 
   entry_point,
   addr, 
   size, 
   addr0,
   addr1,
   addr2, 
   i, 
   j,
   fun_size,
   addr_size,
   code_size,
   fun_addr,
   offset; 
 
   reloc_count = 0;

   word_ptr = code;

   fun_size = *((short*)word_ptr);

   printf("fun_size == %d\r\n", fun_size);

   word_ptr += 2;

   for(i = 0; i < fun_size; i++) {
      name_size = *((short*)word_ptr);

      printf("name_size == %d\r\n", name_size);

      word_ptr += 2;

      name = word_ptr;

      printf("name == %s\r\n", name);

      word_ptr += name_size;

      entry_point = *((short*)word_ptr);

      printf("entry_point == %d\r\n", entry_point);

      word_ptr += 2;

      addr = *((short*)word_ptr);

      printf("addr == %d\r\n", addr);

      word_ptr += 2;

      size = *((short*)word_ptr);

      printf("size == %d\r\n", size);

      word_ptr += 2;

      for(j = 0; j < size; j++) {
         addr0 = *((short*)word_ptr);

         word_ptr += 2;

         fun_addr = addr0;

         printf("FUN_ADDR = %d\r\n", fun_addr);

         reloc_array[reloc_count].addr0 = fun_addr;
         reloc_array[reloc_count].addr1 = 0;
         reloc_array[reloc_count].is_label = 0;
         reloc_count++;

      }

   }

   size = *((short*)word_ptr);

   word_ptr += 2;

   printf("size == %d\r\n", size);

   for(i = 0; i < size; i++) {
      addr0 = *((short*)word_ptr);
      word_ptr += 2;
      addr1 = *((short*)word_ptr);
      word_ptr += 2;












   }

   code_size = *((short*)word_ptr);

   printf("code_size == %d\r\n", code_size);

   word_ptr += 2;

   code_ptr = word_ptr;

   printf("code_ptr == %d\r\n", code_ptr);

   printf("fun_addr == %d\r\n", fun_addr);

   printf("reloc_count == %d\r\n", reloc_count);














   temp_ptr = code_ptr + fun_addr;

   (*((short**)temp_ptr)) = (short*)printf;

   temp_ptr = code_ptr + addr0;

   (*((short**)temp_ptr)) = (short*)(code_ptr + addr1);

   return code_ptr;
}

int
main()
{
   char code[16000];
   char cmd[100];
   pf_t main_ptr;
   short i,rc;

   rc = 0;

   while(1) {
      printf("run> ");
      bzero(cmd,100);
      gets(cmd); 
      printf("\r\n");
      printf("cmd == %s\r\n", cmd);
      if(strcmp(cmd,"exit") == 0) {
         break;
      }
      printf("cmd: %s\r\n", cmd);
      bzero(code,16000);
      load_program(cmd,code);




      main_ptr = (pf_t)link_program(code);
      printf("MAIN[");
      printf("\r\n");

      rc = main_ptr();

      printf("\r\n");
      printf("]\r\n");
      printf("rc == %d\r\n", rc);
   }
   return 0;
}

