#include <stdio.h>   /* required for file operations */
#include <stdlib.h>

FILE *fr;            /* declare the file pointer */

typedef struct{
	/*ARM User Mode registers*/
	int registers[16];
	/*Current Program Status Register*/
	int CPSR;
	/*Main Memory*/
	int main_memory[4096];
	/* Array to store required info about Simulation*/
	int SIM_info[32];
	} ARMStruct;

int SetupMemory(ARMStruct *mem, char *in_file){
	int n = 0, temp, size;
	unsigned int * buffer;
	fr = fopen (in_file, "rb");  /* open the file for reading */
	if(fr == 0){
		printf("Error input file \"%s\" does not exist\n",in_file);
		return 0;
	}

	fseek(fr, 0, SEEK_END);
	size = ftell(fr);
	buffer = malloc(size);
	fseek(fr, 0, SEEK_SET);
	fread(mem->main_memory, 4, size/4, fr);

	/*
	while(n < size/4)
	{
		printf("%.2X ", mem->main_memory[n]);
		n++;
	 }
	printf("\n");
	*/
	 fclose(fr);
	return 1;
}

int Finalize(ARMStruct *mem, char *out_file){
	int i;

	fr = fopen (out_file, "w");

	if(fr == 0){
		printf("Error output file %s does not exist\n",out_file);
		return 0;
	}
	
	/*Print out to file contents of User Registers*/
	fprintf(fr, "Registers:\n");
	for(i = 0; i < 16; i++){
		fprintf(fr,"%d\n", mem->registers[i]);
	}

	/*Print out to file contents of the SIM info*/
	fprintf(fr, "SIM Info:\n");
	for(i = 0; i < 32; i++){
		fprintf(fr,"%d\n", mem->SIM_info[i]);
	}

	/*Print out to file contents of the SIM info*/
	fprintf(fr, "CPSR:\n");
	fprintf(fr,"%d\n", mem->CPSR);

	fclose(fr);
	return 1;
}

void Simulator(ARMStruct *mem){
	
	/*You can use "mem->field_name" to access the different fields of the ARMStruct*/

	/*YOUR CODE GOES HERE*/
}


int main(int argc, char *argv[]){
	
	/*Memory Allocation of ARMStruct*/
	ARMStruct * mem;
	mem = (ARMStruct *) malloc(sizeof(ARMStruct));

	if(argc != 3){
		printf("Error incorrect usage\n");
		printf("a.out [input_file_name] [output_file_name]\n");
		return 0;	
	}
	
	/*Attempt to setup the instructions into ARMStruct->main_memory from given file*/
	if(!SetupMemory(mem, argv[1])){
		return 0;	
	}

	/*Run your Simulator*/
	Simulator(mem);	

	/*Print setup to file*/
	if(!Finalize(mem, argv[2])){
		return 0;	
	}
}

