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

Chain
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
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
Inserts C Structures and does some substitutions to convert the assembler program into a valid C file

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
 * 1) !/bin/sh

sedScript1.sed
SED script which converts assembler commands into c function names

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
 * 1) sed comment - This script changes macroname-> macroname_
 * 1) 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
Calculates valid prog. adresses for labels and substitute them within the rom.vhdl

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;i0){ 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; }
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) include 
 * 1) define PC_MAX 4	// 4 decimal, 12 bit PC
 * 2) define LABELS_MAX 3 // max. amount of labels supposed

asm1.sh
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 ~/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  $1.vhd echo echo Cleaning... rm $1.bin
 * 1) ./$1.ao > $1.ao2

mip.c
Converts ascii machine code file into a binary file

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; }
 * 1) include 
 * 2) include 

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


 * 1) include 
 * 2) include 
 * 3) include 
 * 1) define EXTENSION &pc


 * 1) define LABEL(a)  a=LABEL_NEW(&a,EXTENSION);
 * 1) define TOASCII_(S,T,D)  TOASCII(S,T,D,EXTENSION)
 * 2) define ADD_(S,T,D)  ADD(S,T,D,EXTENSION)
 * 3) define ADDU_(S,T,D) ADDU(S,T,D,EXTENSION)
 * 4) define AND_(S,T,D)  AND(S,T,D,EXTENSION)
 * 1) define BZS_(I)		BZS(I,EXTENSION)
 * 2) define BR_(I) 	    	BR(I,EXTENSION)
 * 3) define BOS_(I) 	BOS(I,EXTENSION)
 * 4) define BON_(I) 	BON(I,EXTENSION)
 * 5) define BOR_(I) 	BOR(I,EXTENSION)
 * 6) define BZC_(I) 	BZC(I,EXTENSION)
 * 7) define BSS_(I) 	BSS(I,EXTENSION)
 * 8) define BSC_(I) 	BSS(I,EXTENSION)
 * 9) define BNC_(I) 	BNC(I,EXTENSION)
 * 10) define BNS_(I) 	BNS(I,EXTENSION)
 * 11) define BR__(I) 	BR(I,EXTENSION)
 * 12) define BRS_(I) 	BRS(I,EXTENSION)
 * 13) define BRC_(I) 	BRC(I,EXTENSION)
 * 1) define JR_(S)       JR(S,EXTENSION)
 * 2) define LB_(S,T)     LB(S,T,EXTENSION)
 * 3) define LLI_(T,I)    LLI(T,I,EXTENSION)
 * 4) define LW_(S,D)     LW(S,D,EXTENSION)	/* S ... Adresse, D ... Zielregister*/
 * 1) define MULT_(S,T,D) MULT(S,T,D,EXTENSION)
 * 2) define MULTU_(S,T,D) MULTU(S,T,D,EXTENSION)
 * 3) define NOOP_      NOOP(EXTENSION)
 * 4) define OR_(S,T,D)   OR(S,T,D,EXTENSION)


 * 1) define SB_(S,T)     SB(S,T,EXTENSION)
 * 2) define SLL_(T,D,I)  SLL(T,D,I,EXTENSION)
 * 3) define SLLV_(S,T,D) SLLV(S,T,D,EXTENSION)
 * 4) define SRA_(T,D,I)  SRA(T,D,I,EXTENSION)
 * 5) define SRL_(D,T,I)  SRL(D,T,I,EXTENSION)
 * 6) define SRLV_(S,T,D) SRLV(S,T,D,EXTENSION)
 * 1) define SUB_(S,T,D)  SUB(S,T,D,EXTENSION)
 * 2) define SUBU_(S,T,D) SUBU(S,T,D,EXTENSION)
 * 3) define SW_(S,T)     SW(S,T,EXTENSION)		  /* S ... Adressregister, T ... value*/
 * 4) define XOR_(S,T,D)  XOR(S,T,D,EXTENSION)
 * 1) define CALL_(I) 	    CALL(I,EXTENSION)
 * 2) define RETURN_ 	    RETURN(EXTENSION)
 * 1) define io_BUTTON0 "1"
 * 2) define io_BUTTON1 "2"
 * 3) define io_UART_RXD_HAS_NEW_VALUE "4"
 * 4) define io_UART_TXD_READY_TO_SEND "5"
 * 5) define io_UART_GET_RXD_BYTE      "6"
 * 1) define io_WD   "9"
 * 2) define io_LED0 "A"
 * 3) define io_LED1 "B"
 * 4) define io_UART_TXD_SEND_NOW "C"
 * 5) define io_UART_SET_TXD_BYTE "E"
 * 1) define opTOASCII "000011"
 * 1) define opADD  "111100" //## S ## T ## D ## 00000000000
 * 2) define opADDU "001100" //## S ## T ## D ## 00000000000
 * 3) define opAND  "101000" //## S ## T ## D ## 00000000000

/* typedef struct LABEL_TABLE{ int labelname; int labelpc; } s_label_table; */
 * 1) define opBZS  "100010" //## 0000000000  ## I
 * 2) define opBOS  "100001" //## 0000000000  ## I
 * 3) define opBON  "011101" //## 0000000000  ## I
 * 4) define opBOR  "011011" //## 0000000000  ## I
 * 1) define opBNC "010111"
 * 2) define opBNS "011101"
 * 3) define opBZC "011110"
 * 1) define opBR   "010001" //## 0000000000  ## I
 * 1) define opJR   "011000" //## S ## 000000000000000000000
 * 1) define opLLI  "010100" //## 00000 ## T ## I
 * 2) define opLW   "010010" //## S ## 00000 ## D ## 00000000000	/* S ... Adresse, D ... Zielregister*/
 * 1) define opMULT "111001" //## S ## T ## D ## 00000000000
 * 2) define opMULTU "001001" //## S ## T ## D ## 00000000000
 * 3) define opNOOP "111111" //## 00000000000000000000000000
 * 4) define opOR   "100111" //## S ## T ## D ## 00000000000
 * 1) define opSLL  "110011" //## 00000 ## T ## D ## I ## 000000
 * 2) define opSLLV "110000" //## S ## T ## D ## 00000000000
 * 3) define opSRA  "101110" //## 00000 ## T ## D ## I ## 000000
 * 4) define opSRL  "101101" //## 00000 ## T ## D ## I ## 000000
 * 5) define opSRLV "101011" //## S ## T ## D ## 00000000000
 * 1) define opSUB  "111010" //## S ## T ## D ## 00000000000
 * 2) define opSUBU "001010" //## S ## T ## D ## 00000000000
 * 3) define opSW   "001111" //## S ## T ## 0000000000000000		  /* S ... Adressregister, T ... value*/
 * 4) define opXOR  "100100" //## S ## T ## D ## 00000000000
 * 1) define START_MEM_REG 1
 * 2) define NUM_OF_MEM_REG 8

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;i1B 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=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); }