Computer Architecture Lab/WS2007/Project -1 Lab2/Project -1 Lab2
Chain edit
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
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
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
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
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
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
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
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);
}