//***************************************************************************
// File name : startup.c
// Designer : Chih-Chieh Tsao
// Create date: Dec. 14, 2007
// Description:
//              Startup code for dynamic loading,
//              modified from static part.
//***************************************************************************

#include <math.h>
#include "locator.h"
#include "startup.h"

//#define DEBUG
#define DEBUG_A

/*******************************************************************
* Name: startup
* Input: 
*        char *file_name : input file name
* Output: int
* Description: 
*        determine where the task would be placed 
*        in five preallocated task area statically.
*        For static locator, determined by user. (this function)
*        For dynamic locator, determined by OS.
*******************************************************************/
int startup(char *file_name)
{
    FILE *fp, *outfp;
    char *output_file_name;
    char getStringLine[STRING_LINE];

    // open read file and error check
    fp = fopen(file_name, "r");
    if(fp == NULL)
    {
	fprintf(stderr, "input file error\n");
	return -1;
    }
    
    file_name = strtok(file_name, ".");

    // open write file and error check
    output_file_name = strcat(file_name, ".asm");   //output file with Startup code (.s)
    outfp = fopen(output_file_name, "w");
    if(outfp == NULL)
    {
 	fprintf(stderr, "output file error\n");
	return -1;
    }      

    //include 
    fprintf(outfp, "\n#include \"intr.h\"\n");
    fprintf(outfp, "#include \"defines.h\"\n\n");

    //disable interrupt
    fprintf(outfp, "//disable interrupt\n");
    fprintf(outfp, "P0 WriteSFR.and sfr_intrctrl, 0xFE\n\n");
    text_size += 4;

    //assign stack and frame pointer of task
    fprintf(outfp, "\n//assign stack and frame pointer\n");
    //fprintf(outfp, "  lea R29, %#x\n", taskS_addr);
    fprintf(outfp, "  lea R29, %#x\n", taskF_addr - DataSize);
    fprintf(outfp, "  lea R30, %#x\n", taskF_addr);
    text_size += 4*4;

    //enable interrupt
    fprintf(outfp, "\n//enable interrupt\n");
    fprintf(outfp, "  ResetClock\n");
    fprintf(outfp, "  STI\n");
    fprintf(outfp, "  StartT0\n");
    text_size += 4*7;

    //call main function and return
    fprintf(outfp, "\n//call main() function\n");
    /*fgets(getStringLine, STRING_LINE, fp);
    fprintf(outfp, "%s", getStringLine);*/
    fprintf(outfp, "P0 jmp main\n");
    fprintf(outfp, "P0 jmp.reg R31\n\n");
    text_size += 4;

    fgets(getStringLine, STRING_LINE, fp);
    //attach task code
    while(fgets(getStringLine, STRING_LINE, fp) != NULL)
    {
        fprintf(outfp, "%s", getStringLine);
    }

    //substract 4 because the last line of code
    text_size -= 4;

    fprintf(stderr, "  Output file: %s\n", output_file_name);
    
    fclose(fp);
    fclose(outfp);
    
    return 0;
}

