Computer Architecture Lab/WS2007/Project -1 Lab2/Project -1 Lab2

From Wikiversity
Jump to navigation Jump to search

Chain[edit | edit source]

To get a program into our processor Lucky, the following steps must be taken: - Create a asm file, e.g., test.asm in our "confortable" assembler language - Drag&Drop your asm file onto the Windows batch file "Update ROM File.bat" - - This will create a rom.vhdl for the Lucky processor which is automatically copied into the right directory - Open Quartus and start the Compilation - Burn the Programm onto the FPGA with USBrunner

Update ROM File.bat[edit | edit source]

Batch file for Drag&Drop compilation

@echo off
C:
chdir C:\cygwin\bin
bash "H:\WinXP\Assembler\mip\asm1.sh" %1
copy C:\cygwin\bin\rom.vhd  h:\WinXP\Processor\src\InstructionMemory\
copy C:\cygwin\bin\rom.vhd  %1.vhd
echo Press Enter to exit.
set /p UserName=

createAo.sh[edit | edit source]

Inserts C Structures and does some substitutions to convert the assembler program into a valid C file

#!/bin/sh
echo Creating Valid ao File...
echo "int d1 = -1;" > $1.labels
sed -n 's/.*LABEL(\(.*\)).*/int \1=(d1--);/gp' < $1 >> $1.labels
grep START\(\) < $1 > $1.check
echo /*Starting*/ >$1.temp
if [ -s $1.check ]; then
	cat < $1 >> $1.temp
else 
	echo "START()" >> $1.temp
	cat < $1 >> $1.temp
fi
echo /*Starting*/ >>$1.temp
sed '/START()/,$d' < $1.temp > $1.beginning
echo "START()" >> $1.beginning
sed '1,/START()/d' < $1.temp > $1.ending
sed 's/END()//g' < $1.ending > $1.ending2
echo "END()" >> $1.ending2
cat $1.beginning $1.labels $1.ending2 > $1.merged

rm $1.labels
rm $1.check
rm $1.temp
rm $1.beginning
rm $1.ending
rm $1.ending2
 
sed -f ~/WinXP/Assembler/mip/sedScript1.sed < $1.merged > $1.c
 
rm $1.merged

gcc -o ~/WinXP/Assembler/mip/asm_res.exe $1.c
~/WinXP/Assembler/mip/asm_res.exe > ~/WinXP/Assembler/mip/asm_res_pre.ao 2> ~/WinXP/Assembler/mip/asm_res_labels.ao
~/WinXP/Assembler/mip/adr_res.exe ~/WinXP/Assembler/mip/asm_res_pre.ao ~/WinXP/Assembler/mip/asm_res_labels.ao    ~/WinXP/Assembler/mip/asm_res.ao

sedScript1.sed[edit | edit source]

SED script which converts assembler commands into c function names

# sed comment - This script changes macroname-> macroname_
s/START()/#include \"lucky2.h\"\nvoid test()\n{\nint pc=0;char\* _l_v=\"\";\nPRE_STARTPROC(\&pc);\n/g
s/END()/\nENDPROC(\&pc,_l_v);\n}\nint main(){test();return 0;}/g
s/ADD/ADD_/g
s/ADDU/ADDU_/g
s/AND/AND_/g
s/BZS/BZS_/g
s/BOS/BOS_/g
s/BON/BON_/g
s/BOR/BOR_/g
s/JR/JR_/g
s/LB/LB_/g 
s/LLI/LLI_/g
s/LW/LW_/g 
s/MULT/MULT_/g 
s/MULTU/MULTU_/g
s/NOOP/NOOP_/g 
s/OR/OR_/g
s/SB/SB_/g
s/SLL/SLL_/g
s/SLLV/SLLV_/g
s/SRA/SRA_/g
s/SRL/SRL_/g
s/SRLV/SRLV_/g 
s/SUB/SUB_/g
s/SUBU/SUBU_/g 
s/SW/SW_/g 
s/XOR/XOR_/g
s/CALL/CALL_/g
s/RETURN/RETURN_/g
s/BNS/BNS_/g
s/BNC/BNC_/g
s/BCS/BCS_/g
s/BCC/BCC_/g
s/BRS/BRS_/g
s/BRC/BRC_/g
s/BZC/BZC_/g
s/TOASCII/TOASCII_/g 

s/BR(/BR_(/g
s/BR (/BR_ (/g

#ADD ADDU AND BZS BZC BOS BON BOR JR LB LLI LW MULT MULTU NOOP OR SB SLL SLLV SRA SRL SRLV SUB SUBU SW XOR

adr_res.exe / resolvebranches.c[edit | edit source]

Calculates valid prog. adresses for labels and substitute them within the rom.vhdl

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define PC_MAX 4	// 4 decimal, 12 bit PC
#define LABELS_MAX 3 // max. amount of labels supposed
 
typedef struct S_LABEL{
	int name;
	int location; // line
} s_label;

FILE* pin_File;		// machine-code with unresolved branches
FILE* pin_File2;  // file containing label-table
FILE* pout_File;	// output file with resolved labels/branches

s_label *labelreference;

void errorexit(char *msg);
void freeResources();
void allocateResources(char **argv);
void suckTheLabelFileDry();
void initArray(char *array);

void allocateResources(char **argv){

	if((pin_File = fopen(argv[1],"r"))==(FILE *)0){
		printf("Can't open file for reading: %s!",argv[1]);
		errorexit("");
	}
	if((pin_File2 = fopen(argv[2],"r"))==(FILE *)0){
		printf("Can't open file for reading: %s!",argv[2]);
		errorexit("");
	}
	if((pout_File = fopen(argv[3],"w"))==(FILE *)0){
		printf("Can't open file for writing: %s!",argv[3]);
		errorexit("");
	}

	suckTheLabelFileDry();
}

void suckTheLabelFileDry(){
	char c = 0;
	int i = 0;
	int j = 0;
	 
	char bend=0;
 
 
	int labelnr = 1;
	char temp[LABELS_MAX];
	int mallocsize = 10;
	initArray(temp);
 
	labelreference = (s_label *)malloc(sizeof(s_label)*mallocsize);
	memset(labelreference,0,sizeof(s_label)*mallocsize);
	 
	c = fgetc(pin_File2);
 
	while(bend==0){
		if(labelnr==mallocsize-1){
			mallocsize+=mallocsize;
			labelreference = (s_label *)realloc(labelreference,sizeof(s_label)*mallocsize);
			// yeye - memset, null-ref...
		}
	 
 
			for(i=0;i<LABELS_MAX;i++){
				c=fgetc(pin_File2);
				if(c=='-')break;
				temp[i]=c-'0';
				j++;
			}
			labelreference[labelnr].name=arch2int(temp,j);
			j=0;
			initArray(temp);
			for(i=0;i<PC_MAX;i++){
				if((c=fgetc(pin_File2))==EOF){
					bend=1;
					break;
				}
				if(c=='-')break;
				if(c=='\n'||c=='\r'){
					bend=1;
					break;
				}
				temp[i]=c-'0';
				j++;
			}
			
			labelreference[labelnr].location=arch2int(temp,j);
			labelnr++;
			
			j=0;
			initArray(temp);
	}

	//test table
	//printf("DEBUG: Labels stored from Label-only file...\n");
	for(i=1;i<labelnr;i++){
	//	printf("DEBUG: Leeched lable: #%i name= %i location= %i\n",i,labelreference[i].name,labelreference [i].location);
	}
 

}
void freeResources(){

	fclose(pin_File);
	fclose(pin_File2);
	fclose(pout_File);
 
	free(labelreference);
}

void errorexit(char *msg){
	fprintf(stderr,"Error! %s",msg);
	freeResources();
	exit(1);
}

void initArray(char *array){
	int i = 0;

	for(i=0;i<sizeof(array)/sizeof(array[0]);i++){
		array[i]=0;
	}


}

int arch2int(char *label, int j){
	
	int result = 0;
		result+=(label[0])*(int)pow(10,j-1);
		if(j==2) result+=(label[1]);
		if(j==3) result+=(label[1])*10+label[2];
	return result;
}

char *hex_to_bin_array[] = {
	"0000", "0001", "0010", "0011", "0100"
	, "0101", "0110", "0111", "1000", "1001"
	, "1010", "1011", "1100", "1101", "1110", "1111"
};

char* hex_to_bin (char* input, int length)
{
 int index = 0;
 int inplength = 0;
 int array_index;
 char tempbuf[100]="";
	char *resbuf = (char*) malloc (17);
	while (input[index] != 0)
	{
		if ((input[index] >= 48) && (input[index] <= 57))
		{       
			array_index = input[index] - 48;
		}
		else if ((input[index] >= 65) && (input[index] <= 70))
		{
			array_index = input[index] - 55;
		}
		else if ((input[index] >= 97) && (input[index] <= 102))
		{
			array_index = input[index] - 87;
		}
		else 
		{
			index ++; continue;
		}

		strcat (tempbuf, hex_to_bin_array [array_index]);
		index ++;
		inplength ++;
	}
	if (inplength*4 > length)
	{
		strcpy (resbuf,  tempbuf + inplength*4 - length);
	}
	else
	{
		strcpy (resbuf, "0000000000000000");
		strcpy (resbuf + length - inplength * 4, tempbuf);
	}
	return resbuf;
}

void resolveBranches(){
	 
	int currentline = 0; // count line numbers
	int c = 0;	// buffer character
	int tempc = 0;
 
	int i = 0;
	int j = 0;

	int relative = 0;
	char relativebinary[17];

	int looklabel = 0;

	char temp[LABELS_MAX];

	initArray(temp);

	while((c=fgetc(pin_File))!=EOF){
		if(c=='\n') currentline++;
		if(c==':') currentline--;
	 
		if(c=='-'){
			for(i=0;i<LABELS_MAX;i++){
				c=fgetc(pin_File);
				if(c==':' || c==EOF) { //discard label-marks
					initArray(temp);
					j=0;
					break;
				}
				if(c=='\n')	break; 

				temp[j]=c-'0';
				j++;
			}	
			looklabel=arch2int(temp,j);
			//printf("DEBUG: looking for label = %i\n",looklabel);
			initArray(temp);
			j=0;

			if(looklabel>0){
				relative=labelreference[looklabel].location-(currentline-1);
//				printf("DEBUG: New relative jump to label #%i: %i - %i = %i\n",labelreference [looklabel].name,labelreference[looklabel].location,currentline,relative);
				sprintf(relativebinary,"%x",relative);
//				printf("DEBUG: Relative jump (binary): %s\n",hex_to_bin(relativebinary,16));
				fputs(hex_to_bin(relativebinary,16),pout_File);
			}
		}

		if(c!='#'&&c!='!'&&c!='-'){
		 	fputc(c,pout_File);
		}
  
	}
 
}




int main(int argc, char **argv){


allocateResources(argv);

resolveBranches();

freeResources();
return 0;
}

asm1.sh[edit | edit source]

Preprocesses the assembler file converts the Lucky machine code program into a vhdl file

if [ $# -ne 1 ]; then
	echo Usage: asm.sh source.asm
	exit 0
fi
echo Compiling...
gcc -E $1 > $1.ao
#./$1.ao > $1.ao2
~/WinXP/Assembler/mip/mip.exe $1.ao $1.bin
echo Converting...
~/WinXP/Assembler/mip/romconv.exe $1.bin rom 32 12
cp rom.vhd ~/WinXP/Processor/src/InstructionMemory/
cat <rom.vhd > $1.vhd
echo
echo Cleaning...
rm $1.bin

mip.c[edit | edit source]

Converts ascii machine code file into a binary file

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int letter;
    int bin;    
    int counter; 

    FILE *fsrc  = fopen(argv[1], "r");
    FILE *fdest = fopen(argv[2] ,"wb");

    if (fsrc == NULL)
    {
      	 printf("MIP-Error: Bad source file name!");
        return 1;
    }

    if (fdest == NULL)
    {
     	printf("MIP-Error: Can't open destination file!");
        return 2;
    } 

    counter = 0;
    bin     = 0; 

    while( ( letter = fgetc( fsrc ) ) != EOF)
    {
	if (letter == '\n') continue;
        if (letter == '1')
	{
	    bin |= 1 << (7 - counter);
	}
        counter++;
	if (counter == 8)
        {    
	    fputc (bin, fdest);
	    //printf ("%x", bin);
	    counter = 0;
            bin     = 0;
        }
    }
    if (counter>0)
    {
        fputc (bin, fdest);
    }
    
    
    fclose (fsrc);
    fclose (fdest); 

    return 0;
}

lucky2.h[edit | edit source]

C Functions that substitute the assembler commands. They consists of printf functions to create machinecode


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define EXTENSION  &pc
#define LABEL(a)   a=LABEL_NEW(&a,EXTENSION);

#define TOASCII_(S,T,D)   TOASCII(S,T,D,EXTENSION)
#define ADD_(S,T,D)   ADD(S,T,D,EXTENSION)
#define ADDU_(S,T,D)  ADDU(S,T,D,EXTENSION)
#define AND_(S,T,D)   AND(S,T,D,EXTENSION)

#define BZS_(I)		BZS(I,EXTENSION)	
#define BR_(I) 	     	BR(I,EXTENSION)
#define BOS_(I) 	BOS(I,EXTENSION)
#define BON_(I) 	BON(I,EXTENSION)
#define BOR_(I) 	BOR(I,EXTENSION) 
#define BZC_(I) 	BZC(I,EXTENSION)	
#define BSS_(I) 	BSS(I,EXTENSION)
#define BSC_(I) 	BSS(I,EXTENSION)
#define BNC_(I) 	BNC(I,EXTENSION)
#define BNS_(I) 	BNS(I,EXTENSION)
#define BR__(I) 	BR(I,EXTENSION)
#define BRS_(I) 	BRS(I,EXTENSION) 
#define BRC_(I) 	BRC(I,EXTENSION)

#define JR_(S)        JR(S,EXTENSION)
#define LB_(S,T)      LB(S,T,EXTENSION)
#define LLI_(T,I)     LLI(T,I,EXTENSION)
#define LW_(S,D)      LW(S,D,EXTENSION)	/* S ... Adresse, D ... Zielregister*/
  
#define MULT_(S,T,D)  MULT(S,T,D,EXTENSION)
#define MULTU_(S,T,D) MULTU(S,T,D,EXTENSION)
#define NOOP_()       NOOP(EXTENSION)
#define OR_(S,T,D)    OR(S,T,D,EXTENSION) 
#define SB_(S,T)      SB(S,T,EXTENSION)
#define SLL_(T,D,I)   SLL(T,D,I,EXTENSION)
#define SLLV_(S,T,D)  SLLV(S,T,D,EXTENSION)
#define SRA_(T,D,I)   SRA(T,D,I,EXTENSION)
#define SRL_(D,T,I)   SRL(D,T,I,EXTENSION)
#define SRLV_(S,T,D)  SRLV(S,T,D,EXTENSION)

#define SUB_(S,T,D)   SUB(S,T,D,EXTENSION)
#define SUBU_(S,T,D)  SUBU(S,T,D,EXTENSION)
#define SW_(S,T)      SW(S,T,EXTENSION)		  /* S ... Adressregister, T ... value*/
#define XOR_(S,T,D)   XOR(S,T,D,EXTENSION)

#define CALL_(I) 	     CALL(I,EXTENSION)
#define RETURN_() 	     RETURN(EXTENSION) 

#define io_BUTTON0  "1"
#define io_BUTTON1  "2"
#define io_UART_RXD_HAS_NEW_VALUE  "4"
#define io_UART_TXD_READY_TO_SEND  "5"
#define io_UART_GET_RXD_BYTE       "6"

#define io_WD    "9"
#define io_LED0  "A"
#define io_LED1  "B"
#define io_UART_TXD_SEND_NOW  "C"
#define io_UART_SET_TXD_BYTE  "E"

#define opTOASCII "000011"

#define opADD   "111100" //## S ## T ## D ## 00000000000
#define opADDU  "001100" //## S ## T ## D ## 00000000000
#define opAND   "101000" //## S ## T ## D ## 00000000000
#define opBZS   "100010" //## 0000000000  ## I
#define opBOS   "100001" //## 0000000000  ## I
#define opBON   "011101" //## 0000000000  ## I
#define opBOR   "011011" //## 0000000000  ## I

#define opBNC "010111"
#define opBNS "011101"
#define opBZC "011110"

#define opBR    "010001" //## 0000000000  ## I

#define opJR    "011000" //## S ## 000000000000000000000

#define opLLI   "010100" //## 00000 ## T ## I
#define opLW    "010010" //## S ## 00000 ## D ## 00000000000	/* S ... Adresse, D ... Zielregister*/
  
#define opMULT  "111001" //## S ## T ## D ## 00000000000
#define opMULTU "001001" //## S ## T ## D ## 00000000000
#define opNOOP  "111111" //## 00000000000000000000000000
#define opOR    "100111" //## S ## T ## D ## 00000000000

#define opSLL   "110011" //## 00000 ## T ## D ## I ## 000000
#define opSLLV  "110000" //## S ## T ## D ## 00000000000
#define opSRA   "101110" //## 00000 ## T ## D ## I ## 000000
#define opSRL   "101101" //## 00000 ## T ## D ## I ## 000000
#define opSRLV  "101011" //## S ## T ## D ## 00000000000

#define opSUB   "111010" //## S ## T ## D ## 00000000000
#define opSUBU  "001010" //## S ## T ## D ## 00000000000
#define opSW    "001111" //## S ## T ## 0000000000000000		  /* S ... Adressregister, T ... value*/
#define opXOR   "100100" //## S ## T ## D ## 00000000000

#define START_MEM_REG 1
#define NUM_OF_MEM_REG 8

/*
typedef struct LABEL_TABLE{
	int labelname;

int labelpc;

} s_label_table;
*/
int UART_SEND 		= -100000;
int UART_SEND_INT0 	= -100001;
int UART_SEND_MEM 	= -100002;
int CALL_INT0 		= -100004;
int RETURN_INT0 	= -100005;
int START_INT0 		= -100006;
int UART_SEND_MEM_INT0 	= -100007;
int DEBUG_SEND_INT0	= -100008;
int UART_RECV 		= -100009;
int UART_RECV_INT0 	= -100010;

//int stackIsInitializued = 0;

char *hex_to_bin_array[] = {

"0000", "0001", "0010", "0011", "0100" , "0101", "0110", "0111", "1000", "1001" , "1010", "1011", "1100", "1101", "1110", "1111" };

char* hex_to_bin (char* input, int length)
{

int index = 0; int inplength = 0; int array_index; char tempbuf[100]=""; char *resbuf = (char*) malloc (17);

//printf("Input: %s", input);

while (input[index] != 0) { if ((input[index] >= 48) && (input[index] <= 57)) { array_index = input[index] - 48; } else if ((input[index] >= 65) && (input[index] <= 70)) { array_index = input[index] - 55; } else if ((input[index] >= 97) && (input[index] <= 102)) { array_index = input[index] - 87; } else { index ++; continue; }

strcat (tempbuf, hex_to_bin_array [array_index]); //printf ("Char: -%c-, ArrayIndex: %d, Strcat:%s, Tempbuf:%s\n",input[index], array_index, hex_to_bin_array [array_index],tempbuf); index ++; inplength ++; } if (inplength*4 > length) { strcpy (resbuf, tempbuf + inplength*4 - length); } else { strcpy (resbuf, "0000000000000000"); strcpy (resbuf + length - inplength * 4, tempbuf); } return resbuf;

}

/*ASCII char to hex-string*/
char* A2S (char inp)
{

char *buf = (char*) malloc (3); sprintf(buf, "%x", (int)inp); return buf;

}

void printSTI (char *op, char* regS, char* regT, char* im) { char temp[33];

strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, hex_to_bin (im, 16));

printf ("%s\n", temp); }

void printSTImCrude (char *op, char* regS, char* regT, char* im) { char temp[33];

strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, im); printf ("%s\n", temp); }

void printSTDI (char *op, char* regS, char* regT, char* regD,char* im) { char temp[33];

strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, hex_to_bin (regD, 5)); strcat (temp, hex_to_bin (im, 5)); strcat (temp, "000000"); printf ("%s\n", temp); }

void printTSD (char *op, char* regT, char* regS, char* regD) { char temp[33];

strcpy (temp, op); strcat (temp, hex_to_bin (regS, 5)); strcat (temp, hex_to_bin (regT, 5)); strcat (temp, hex_to_bin (regD, 5)); strcat (temp, "00000000000");

printf ("%s\n", temp); }

void TOASCII (char* regD, char* regS, char* regT, int *pc) { printTSD (opTOASCII, regT, regS, regD); (*pc)++; }


void LW (char* regD, char* regS, int *pc) { printTSD (opLW, "0", regS, regD); (*pc)++; }

void NOOP (int *pc) { char temp[33]; strcpy (temp, opNOOP); strcat (temp, "00000000000000000000000000"); printf ("%s\n", temp); (*pc)++; }

void JR (char* regS, int *pc) { printTSD (opJR, "0", regS, "0"); (*pc)++; }

void SW (char* regS, char* regT, int *pc) { printTSD (opSW, regT, regS, "0"); (*pc)++; }

char* handleBr(int jump_pc, int *pc) { int rel_pc = 0; static char Im[33]; char* ret; int i=0;

// char temp[50];

// strncpy(temp, jmpName, 50); // strncat(temp, "\0",2); // printf("CHECK %i - %s END CHECK\n",jump_pc, temp);

// for(i=0;i<LABEL_MAX_AMOUNT;i++){ // if((jump_pc ==labels[i].labelname)){

// if((rel_pc=labels[i].labelpc - (*pc))<0){ // rel_pc = rel_pc ^ 0xFFFF; // rel_pc += 1;

// } // break; // } // }


sprintf(Im, "%x", rel_pc);

ret = hex_to_bin (Im,16);

//printf("DEBUG ret=%i",ret);

if(jump_pc < 0) { sprintf (Im, "#!%i",jump_pc); // printf("Im = %s\n", Im); //ret = hex_to_bin ("0000000000000000", 16);//Im; ret = Im; // printf("RET=%s\n",ret); } else { rel_pc = jump_pc - (*pc) ; sprintf (Im, "%x", rel_pc); ret = hex_to_bin (Im, 16);

} // fprintf(stdout,"DEBUG-INFO: New branching to %i from %i: %s\n",jump_pc,(*pc),ret); return ret; }

//void BZS (int jump_pc, char* jmpName,int *pc) void BZS(int jump_pc, int *pc) { printSTImCrude (opBZS, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }

void BZC (int jump_pc, int *pc) { printSTImCrude (opBZC, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }

void BNS (int jump_pc, int *pc) { printSTImCrude (opBNS, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }


void BNC (int jump_pc, int *pc) { printSTImCrude (opBNC, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }

void BOR (int jump_pc, int *pc) { printSTImCrude (opBOR, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }

void BOS (int jump_pc, int *pc) { printSTImCrude (opBOS, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }

void BR (int jump_pc, int *pc) { printSTImCrude (opBR, "0", "0", handleBr(jump_pc, pc)); (*pc)++; }

void myBRrel (int relWidth, int *pc) { static char Im[33]; sprintf (Im, "%x", relWidth); printSTImCrude (opBR, "0", "0", hex_to_bin (Im, 16)); (*pc)++; }

void SSLV (char* regD, char* regS, char* regT, int *pc) { printTSD (opSLLV, regT, regS, regD); (*pc)++; }

void SUBU (char* regD, char* regS, char* regT, int *pc) { printTSD (opSUBU, regT, regS, regD); (*pc)++; }

void SUB (char* regD, char* regS, char* regT, int *pc) { printTSD (opSUB, regT, regS, regD); (*pc)++; }

void ADD (char* regD, char* regS, char* regT, int *pc) { printTSD (opADD, regT, regS, regD); (*pc)++; }

void MULT (char* regD, char* regS, char* regT, int *pc) { printTSD (opMULT, regT, regS, regD);(*pc)++; }

void MULTU (char* regD, char* regS, char* regT, int *pc) { printTSD (opMULTU, regT, regS, regD);(*pc)++; }

void ADDU (char* regD, char* regS, char* regT, int *pc) { printTSD (opADDU, regT, regS, regD);(*pc)++; }

void AND (char* regD, char* regS, char* regT, int *pc) { printTSD (opAND, regT, regS, regD);(*pc)++; }

void SRL (char* regD, char* regT, char* Im,int *pc) { printSTDI (opSRL, "0", regT, regD, Im); (*pc)++; }

void SLL (char* regD, char* regT, char* Im,int *pc) { printSTDI (opSLL, "0", regT, regD, Im); (*pc)++; }

void OR (char* regD, char* regS, char* regT, int *pc) { printTSD (opOR, regT, regS, regD);(*pc)++; }

void SRLV (char* regD, char* regS, char* regT, int *pc) { printTSD (opSRLV, regT, regS, regD);(*pc)++; }

void XOR (char* regD, char* regS, char* regT, int *pc) { printTSD (opXOR, regT, regS, regD);(*pc)++; }

void LLI (char* regT, char* Im, int *pc) { printSTI (opLLI, "0", regT, Im); (*pc)++; }

void LOAD_BIG_NUMBER(char* target, char* tempReg,char* Im, int *pc) { int i= 0; char bufLow[5]="0000\0"; char bufHigh[5]="0000\0"; bufLow[4]=0; bufHigh[5]=0; for(i=strlen(Im)-1;i>=0;i--){ if(i>3){ bufLow[i-4] = Im[i]; } else { bufHigh[i] = Im[i]; } } LLI(target,bufHigh,pc); //LoadHighbyte: SLL(target,target,"10",pc); LLI(tempReg,bufLow,pc); ADD(target,target,tempReg,pc); }


int LABEL_NEW (int *newLabel, int *pc) { fprintf(stderr, "#!%i:%i\n", (*newLabel), (*pc)); return (*pc); }

void ENDPROC (int *pc,char *labelStr) { //fprintf(stderr,"DEBUG INFO: Reached end at %i, Labels:\n%s",(*pc),labelStr); }

void savePCtoReg (char* regT, int pc) { char Im[33]; sprintf (Im, "%x", pc); printSTI (opLLI, "0", regT, Im); }

char * intToAscii(const char * regStr) { int n,i = 0; int sLen = strlen(regStr); char *resbuf = (char*) malloc (2*sLen); char *beginning = resbuf; for(i=0;i<sLen;i++){ n = sprintf (resbuf, "%X", regStr[i]); resbuf+=2; } return beginning; }

void CALL(int jmpLabel,int *pc) { ADD("1B","0","1F",pc); BR(CALL_INT0, pc); BR(jmpLabel,pc);

}
void RETURN(int *pc)
{

BR(RETURN_INT0, pc);

}

void RAMENTER_INT0(char* regBeginn,char *regSize,char *incre, const char* asciiStr, int *pc)
{

int stLen = strlen(asciiStr); int i =0; char buff[3] = "000"; char lenBuff[33]; buff[2]=0;

LLI (incre,"1",pc);

char * hexStr = intToAscii(asciiStr);

      	for(i=0;i<stLen;i++){

buff[0] = hexStr[2*i]; buff[1] = hexStr[2*i+1]; LLI(regSize,buff,pc); SW(regBeginn,regSize,pc); ADD(regBeginn,incre,regBeginn,pc); } sprintf (lenBuff, "%X",stLen);

lenBuff[16]='\0'; LLI(regSize,lenBuff,pc); SUB(regBeginn,regBeginn,regSize,pc);

}

void RAMENTER(char* regBeginn,char *regSize, const char* asciiStr, int *pc)
{

RAMENTER_INT0(regBeginn,regSize,"11", asciiStr, pc);

}

void DEBUG_SEND(char* availibleMemoryAdress,int *pc)
{

ADD("1B","9","0",pc); //Temporary "9"->1B ADD("9",availibleMemoryAdress,"0",pc); //overwrite "9" with the value to show (if we check "1D" it now still has the correct value, not altered by DebugSend) LLI("1C","1",pc); //load 1 for decrementing SUB("1D","1D","1C",pc); //decrement Stackpointer SW("1D","1B",pc); //"push" 1B=Original "9" on stack SUB("1D","1D","1C",pc); //decrement Stackpointer SW("1D","A",pc); //"push" "A" on stack LLI("A",availibleMemoryAdress,pc); //overwrite "A" with the register number to show CALL(DEBUG_SEND_INT0,pc); LLI("1C","1",pc); //load 1 for decrementing LW("A","1D",pc); //"pop" A ADD("1D","1D","1C",pc); //inc stack LW("9","1D",pc); //"pop" 9 ADD("1D","1D","1C",pc); //inc stack

}

void UART_SEND_STRING(const char* asciiStr,int *pc)
{

int stLen = strlen(asciiStr); int i; char buff[3] = "000"; buff[2]=0; char * hexStr = intToAscii(asciiStr);

      	for(i=0;i<stLen;i++){

buff[0] = hexStr[2*i]; buff[1] = hexStr[2*i+1]; LLI("9",buff,pc); CALL(UART_SEND,pc);

	}
}

void DEBUG_SEND_FUNC(int *pc)
{

int i; char byteBuff[33]; DEBUG_SEND_INT0 = LABEL_NEW (&DEBUG_SEND_INT0, pc); ADD("3","9","0",pc); //Value to be displayed ADD("4","A","0",pc); //Registernumber LLI("1","1",pc); UART_SEND_STRING("Content of reg 0x",pc); TOASCII("9", "4", "1", pc); CALL(UART_SEND,pc); TOASCII("9", "4", "0", pc); CALL(UART_SEND,pc); UART_SEND_STRING(" is: 0x",pc); for(i=7;i>=0;i--){ sprintf (byteBuff, "%X",i); LLI("2",byteBuff,pc); TOASCII("9", "3", "2", pc); CALL(UART_SEND,pc); } UART_SEND_STRING("\n\r",pc); RETURN(pc);

}

void UART_SEND_MEM_FUNC(int *pc)
{

char* sendMemoryStart = "9"; char* sendMemoryLength = "A"; char* sendContent = "9"; char* tempReg1 = "3"; UART_SEND_MEM = LABEL_NEW (&UART_SEND_MEM, pc); LLI (tempReg1,"1",pc); ADD("1",sendMemoryStart,"0",pc); ADD("2",sendMemoryLength,"0",pc); UART_SEND_MEM_INT0 = LABEL_NEW (&UART_SEND_MEM_INT0, pc); LW(sendContent,"1",pc); CALL(UART_SEND,pc); ADD("1","1",tempReg1,pc); SUB("2","2",tempReg1,pc); BZC (UART_SEND_MEM_INT0,pc); // if we are done leave RETURN(pc);

}

void UART_RECV_FUNC(int *pc)
{

char* tempReg1 = "1"; UART_RECV = LABEL_NEW(&UART_RECV, pc); LLI (tempReg1,io_UART_RXD_HAS_NEW_VALUE,pc); UART_RECV_INT0 = LABEL_NEW (&UART_RECV_INT0, pc); LW("9",tempReg1,pc); BZS(UART_RECV_INT0,pc); LLI (tempReg1,io_UART_GET_RXD_BYTE,pc); LW("9",tempReg1,pc); RETURN(pc);

}

void UART_SEND_FUNC(int *pc)
{

char* sendContent = "9"; char* tempReg1 = "1"; char* tempReg2 = "2";

UART_SEND = LABEL_NEW(&UART_SEND, pc); LLI (tempReg1,io_UART_TXD_READY_TO_SEND,pc); UART_SEND_INT0 = LABEL_NEW (&UART_SEND_INT0, pc); LW(tempReg2,tempReg1,pc); BZS(UART_SEND_INT0,pc); //Comment out for simulation LLI (tempReg2, io_UART_SET_TXD_BYTE,pc); // $2 := Address To UART send now flag SW(tempReg2,sendContent,pc); // set UART TXD BYTE to $6 LLI (tempReg1,"1",pc); LLI (tempReg2, io_UART_TXD_SEND_NOW,pc); SW(tempReg2,tempReg1,pc); // trigger UART send now flag SW(tempReg2,"0",pc); // disable UART send now flag RETURN(pc);

}
void PRE_STARTPROC(int *pc)
{

LLI("1D","1FF",pc); //Initialize Stack BR(START_INT0,pc); //Start User Program

CALL_INT0 = LABEL_NEW (&CALL_INT0, pc); //Call invoked (reg 0x1B has (callingAddress-1) int i; char memBuff[33]; LLI("1C","1",pc); //Increment/Decrement for(i=START_MEM_REG;i<(START_MEM_REG+NUM_OF_MEM_REG);i++) { sprintf (memBuff, "%X",i); memBuff[16]='\0'; SUB("1D","1D","1C",pc); //decrement Stackpointer SW("1D",memBuff,pc); //"push" on stack } SUB("1D","1D","1C",pc); //decrement Stackpointer LLI("1C", "3",pc); //(callingAddress-1) + 3 = next instr. after a call (return address) ADD("1C","1C","1B",pc); //correcting call Address SW ("1D","1C",pc); //"push" return address on Stack LLI("1C", "2",pc); //(callingAddress-1)+2 = (callingAddress+1) -> next instruction which is the actual branch to the function called ADD("1B","1B","1C",pc); //correcting backjmp JR("1B",pc); //backjmp

RETURN_INT0 = LABEL_NEW (&RETURN_INT0, pc); //Return invoked

LLI("1C","1",pc); LW("1B","1D",pc); ADD("1D","1D","1C",pc); for(i=(START_MEM_REG+NUM_OF_MEM_REG-1);i>=START_MEM_REG;i--) { sprintf (memBuff, "%X",i); memBuff[16]='\0'; LW(memBuff,"1D",pc); ADD("1D","1D","1C",pc); } JR("1B",pc);

	DEBUG_SEND_FUNC(pc);

UART_SEND_MEM_FUNC(pc); UART_RECV_FUNC(pc); UART_SEND_FUNC(pc); START_INT0 = LABEL_NEW (&START_INT0, pc);

}