casm.l |
casm.y |
casm.h |
Makefile
%{
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include "casm.h"
typedef struct label_array {
char data[100][80];
int addr[100];
} label_array;
int x;
int i, str_cntr;
int errno;
int cmd_cntr = 0;
FILE* ausgabe;
unsigned int command;
label_array my_labelarray;
%}
%token ERROR
%token WS KM RM LE
%token reg imm lab str
%token DW
%token LW SW PDI PDO
%token HI SET XCH
%token ADD SUB MUL DIV MOD PCA PCS
%token AND OR XOR SHL SHR RTL RTR FBS CBS
%token CST CGT CE
%token JMP JMR BEZ BGZ ISP ISD IRD IRE
%token LDA SVA DTA
%start lines
%%
lines :stmt LE
|data_assign LE
|stmt LE lines
|data_assign LE lines
|RM LE lines
|lab LE lines
|RM LE
|WS lines
|LE
|LE lines
;
/*---------------------------------------------*/
/*data_assign*/
data_assign :DW WS imm { printf("found DW!\n"); assemble(d_type, yylval, 0, 0, 0); }
|DW WS str {
for (str_cntr = 1; yytext[str_cntr] != '\''; str_cntr++) {
if (yytext[str_cntr] < 32) printf("Warning: control char in string!\r\n");
assemble(d_type , yytext[str_cntr] , str_cntr-1 , 0 ,0 );
}
printf("found DW/S! \n");
}
;
/*---------------------------------------------*/
/*stmt*/
stmt :data_transfer
|stmt_sets
|arithmetics
|logical
|conditions
|sqce_control
|special
;
/*---------------------------------------------*/
/*stmt-data_transfer*/
data_transfer :data
|data_peripheral
;
/*---------------------------------------------*/
data :LW WS reg KM reg { printf("found LW!\n"); assemble(r_type, op_NUL, $3, $5, sc_LW); }
|SW WS reg KM reg { printf("found SW!\n"); assemble(r_type, op_NUL, $3, $5, sc_SW); }
;
/*---------------------------------------------*/
data_peripheral :peri_reg_cmd
|peri_imm_cmd
;
peri_reg_cmd :PDI WS reg KM reg { printf("found PDI_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_PDI); }
|PDO WS reg KM reg { printf("found PDI_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_PDO); }
;
peri_imm_cmd :PDI WS reg KM imm { printf("found PDI_imm\n"); assemble(i_type, op_PDI, $3, $5, 0); }
|PDO WS reg KM imm { printf("found PDI_imm\n"); assemble(i_type, op_PDO, $3, $5, 0); }
;
/*---------------------------------------------*/
/*stmt-sets*/
stmt_sets :set_reg_cmd
|set_imm_cmd
|set_lab_cmd
;
set_reg_cmd :HI WS reg KM reg { printf("found HI__reg\n"); assemble(r_type, op_NUL, $3, $5, sc_HI ); }
|SET WS reg KM reg { printf("found SET_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_SET); }
|XCH WS reg KM reg { printf("found XCH_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_XCH); }
;
set_imm_cmd :HI WS reg KM imm { printf("found HI__imm\n"); assemble(i_type, op_HI , $3, $5, 0); }
|SET WS reg KM imm { printf("found SET_imm\n"); assemble(i_type, op_SET, $3, $5, 0); }
;
set_lab_cmd :SET WS reg KM lab { printf("found SET_lab\n"); assemble(i_type, op_SET, $3, search4Label(my_labelarray, yytext), 0); }
;
/*---------------------------------------------*/
/*stmt-arithmetics*/
arithmetics :ADD WS reg KM reg { printf("found ADD_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_ADD); }
|ADD WS reg KM imm { printf("found ADD_imm\n"); assemble(i_type, op_ADD, $3, $5, 0); }
|SUB WS reg KM reg { printf("found SUB_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_SUB); }
|SUB WS reg KM imm { printf("found SUB_imm\n"); assemble(i_type, op_SUB, $3, $5, 0); }
|MUL WS reg KM reg { printf("found MUL_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_MUL); }
|MUL WS reg KM imm { printf("found MUL_imm\n"); assemble(i_type, op_MUL, $3, $5, 0); }
|DIV WS reg KM reg { printf("found DIV_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_DIV); }
|DIV WS reg KM imm { printf("found DIV_imm\n"); assemble(i_type, op_DIV, $3, $5, 0); }
|MOD WS reg KM reg { printf("found MOD_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_MOD); }
|MOD WS reg KM imm { printf("found MOD_imm\n"); assemble(i_type, op_MOD, $3, $5, 0); }
|PCA WS reg KM reg { printf("found PCA_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_PCA); }
|PCA WS reg KM imm { printf("found PCA_imm\n"); assemble(i_type, op_PCA, $3, $5, 0); }
|PCS WS reg KM reg { printf("found PCS_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_PCS); }
|PCS WS reg KM imm { printf("found PCS_imm\n"); assemble(i_type, op_PCS, $3, $5, 0); }
;
/*---------------------------------------------*/
/*stmt-logical*/
logical :arit_reg_cmd
|arit_imm_cmd
;
arit_reg_cmd :AND WS reg KM reg { printf("found AND_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_AND); }
|OR WS reg KM reg { printf("found OR__reg\n"); assemble(r_type, op_NUL, $3, $5, sc_OR ); }
|XOR WS reg KM reg { printf("found XOR_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_XOR); }
|SHL WS reg KM reg { printf("found SHL_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_SHL); }
|SHR WS reg KM reg { printf("found SHR_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_SHR); }
|RTL WS reg KM reg { printf("found RTL_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_RTL); }
|RTR WS reg KM reg { printf("found RTR_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_RTR); }
|FBS WS reg KM reg { printf("found FBS_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_FBS); }
|CBS WS reg KM reg { printf("found CBS_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_CBS); }
;
arit_imm_cmd :AND WS reg KM imm { printf("found AND_imm\n"); assemble(i_type, op_AND, $3, $5, 0); }
|OR WS reg KM imm { printf("found OR__imm\n"); assemble(i_type, op_OR , $3, $5, 0); }
|XOR WS reg KM imm { printf("found XOR_imm\n"); assemble(i_type, op_XOR, $3, $5, 0); }
|SHL WS reg KM imm { printf("found SHL_imm\n"); assemble(i_type, op_SHL, $3, $5, 0); }
|SHR WS reg KM imm { printf("found SHR_imm\n"); assemble(i_type, op_SHR, $3, $5, 0); }
|RTL WS reg KM imm { printf("found RTL_imm\n"); assemble(i_type, op_RTL, $3, $5, 0); }
|RTR WS reg KM imm { printf("found RTR_imm\n"); assemble(i_type, op_RTR, $3, $5, 0); }
|FBS WS reg KM imm { printf("found FBS_imm\n"); assemble(i_type, op_FBS, $3, $5, 0); }
|CBS WS reg KM imm { printf("found CBS_imm\n"); assemble(i_type, op_CBS, $3, $5, 0); }
;
/*--------------------------------------------- */
/*stmt-conditions*/
conditions :cond_reg_cmd
|cond_imm_cmd
;
cond_reg_cmd :CST WS reg KM reg { printf("found CST_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_CST); }
|CGT WS reg KM reg { printf("found CGT_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_CGT); }
|CE WS reg KM reg { printf("found CE__reg\n"); assemble(r_type, op_NUL, $3, $5, sc_CE ); }
;
cond_imm_cmd :CST WS reg KM imm { printf("found CST_imm\n"); assemble(i_type, op_CST, $3, $5, 0); }
|CGT WS reg KM imm { printf("found CGT_imm\n"); assemble(i_type, op_CGT, $3, $5, 0); }
|CE WS reg KM imm { printf("found CE__imm\n"); assemble(i_type, op_CE , $3, $5, 0); }
;
/*---------------------------------------------*/
/*stmt-sqce_control*/
sqce_control :jmp_reg_cmd
|jmp_imm_cmd
|jmp_lab_cmd
|bch_reg_cmd
|bch_imm_cmd
|bch_lab_cmd
|isp_cmd
|ISD { printf("found ISD!\n"); assemble(v_type, op_NUL, 0, 0, sc_ISD ); }
|IRD { printf("found IRD!\n"); assemble(v_type, op_NUL, 0, 0, sc_IRD ); }
|IRE { printf("found IRE!\n"); assemble(v_type, op_NUL, 0, 0, sc_IRE ); }
;
jmp_reg_cmd :JMP WS reg { printf("found JMP_reg\n"); assemble(v_type, op_NUL, $3, 0, sc_JMP); }
|JMR WS reg { printf("found JMR_reg\n"); assemble(v_type, op_NUL, $3, 0, sc_JMR); }
;
jmp_imm_cmd :JMP WS imm { printf("found JMP_imm\n"); assemble(j_type, op_JMP, $3, 0, 0); }
|JMR WS imm { printf("found JMR_imm\n"); assemble(j_type, op_JMR, $3, 0, 0); }
;
jmp_lab_cmd :JMP WS lab { printf("found JMP_lab\n"); assemble(j_type, op_JMP, search4Label(my_labelarray, yytext), 0, 0); }
|JMR WS lab { printf("found JMR_lab\n"); assemble(j_type, op_JMR, search4Label(my_labelarray, yytext), 0, 0); }
;
bch_reg_cmd :BEZ WS reg KM reg { printf("found BEZ_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_BEZ ); }
|BGZ WS reg KM reg { printf("found BGZ_reg\n"); assemble(r_type, op_NUL, $3, 0, sc_BGZ ); }
;
bch_imm_cmd :BEZ WS reg KM imm { printf("found BEZ_imm\n"); assemble(i_type, op_BEZ, $3, $5, 0); }
|BGZ WS reg KM imm { printf("found BGZ_imm\n"); assemble(i_type, op_BGZ, $3, $5, 0); }
;
bch_lab_cmd :BEZ WS reg KM lab { printf("found BEZ_lab\n"); assemble(i_type, op_BEZ, $3, search4Label(my_labelarray, yytext), 0); }
|BGZ WS reg KM lab { printf("found BGZ_lab\n"); assemble(i_type, op_BGZ, $3, search4Label(my_labelarray, yytext), 0); }
;
isp_cmd :ISP WS reg KM reg { printf("found ISP_reg\n"); assemble(r_type, op_NUL, $3, $5, sc_ISP); }
|ISP WS reg KM imm { printf("found ISP_imm\n"); assemble(i_type, op_ISP, $3, $5, 0); }
|ISP WS reg KM lab { printf("found ISP_lab\n"); assemble(i_type, op_ISP, $3, search4Label(my_labelarray, yytext), 0); }
;
/*---------------------------------------------*/
/*stmt-special*/
special :special_reg_cmd
|special_imm_cmd
|special_lab_cmd
;
special_reg_cmd :LDA WS reg { printf("found LDA_reg\n"); assemble(v_type, op_NUL, $3, 0, sc_LDA); }
|SVA WS reg { printf("found SVA_reg\n"); assemble(v_type, op_NUL, $3, 0, sc_SVA); }
;
special_imm_cmd :LDA WS imm { printf("found LDA_imm\n"); assemble(i_type, op_LDA, $3, 0, 0); }
|SVA WS imm { printf("found SVA_imm\n"); assemble(j_type, op_SVA, $3, 0, 0); }
|DTA WS imm { printf("found DTA_imm\n"); assemble(j_type, op_DTA, $3, 0, 0); }
;
special_lab_cmd :LDA WS lab { printf("found LDA_lab\n"); assemble(j_type, op_LDA, search4Label(my_labelarray, yytext), 0, 0); }
|SVA WS lab { printf("found SVA_lab\n"); assemble(j_type, op_SVA, search4Label(my_labelarray, yytext), 0, 0); }
|DTA WS lab { printf("found DTA_lab\n"); assemble(j_type, op_DTA, search4Label(my_labelarray, yytext) - cmd_cntr - 1, 0, 0); }
;
/*---------------------------------------------*/
%%
#include "lex.yy.c"
int collectLabels(FILE* _eingabe, label_array* array) {
char zeile[256] ;
char zeichen = 0;
int running = 0;
int i = 0;
int s = 0;
int char_cnt = 0;
int label_count = 0;
int command_counter = 0;
int stringstart = 0;
int stringend = 0;
int k;
do {
running = fread(&zeichen, 1, 1, _eingabe);
zeile[i] = zeichen;
i++;
if ((zeichen == '\n') || (running == 0 )) {
if (running == 0 && zeichen != '\n') {
zeile[i] = '\0';
}
zeile[i - 1] = '\0';
i = s = 0;
for (i = 0; zeile[i] == ' ' || zeile[i] == '\r'; i++) s++; // CR/Space ignore
for (i = 0; zeile[s] != '\0'; i = i + 1, s = s + 1) zeile[i] = zeile[s];
zeile[i] = '\0';
if ((zeile[0] >= 'a' && zeile[0] <= 'z') || (zeile[0] >= 'A' && zeile[0] <= 'Z')) {
for (i = 3; zeile[i] && zeile[i] != '\'' && zeile[i] != ';'; i++); // find stringdef start
if (zeile[i] == '\'') // if a stringdef start has been found
for (k = i + 1; zeile[k] && zeile[k] != '\''; k++) // increase counter stringsize times
command_counter++;
else
command_counter++;
}
if (zeile[0] == '(' ) {
for (i = 0; zeile[i] != ')' && zeile[i] != '\0'; i++);
zeile[i+1] = '\0';
array->addr[label_count] = command_counter + char_cnt;
strcpy(array->data[label_count], zeile);
label_count++;
}
memset(zeile, 0, sizeof(zeile));
i = s = 0 ;
}
} while (running);
return label_count;
};
int search4Label(label_array array, char* my_label) {
int counter;
for (i = 0; my_label[i] != '\0'; i++)
if (my_label[i] == ')') {
my_label[i+1] = '\0';
break;
}
for (counter = 0; counter < 100; counter++ ) {
if (!array.data[counter][0]) { return -1; }
if (!strcmp(array.data[counter], my_label)) break;
}
return array.addr[counter];
}
void assemble(int typ, unsigned int opcode, unsigned int param1, unsigned int param2, unsigned int sc) {
unsigned int temp1, temp2, temp3, temp4;
temp1 = temp2 = temp3 = temp4 = 0;
command = 0;
if (param1 == -1) yyerror("Label not found");
if (typ == j_type) {
temp1 = temp1 | opcode;
temp1 = temp1 << 27;
temp2 = temp2 | param1;
command = command | temp1;
command = command | temp2;
}
if (typ == i_type) {
temp1 = temp1 | opcode;
temp1 = temp1 << 27;
temp2 = temp2 | param1;
temp2 = temp2 << 22;
temp3 = temp3 | param2;
command = command | temp1;
command = command | temp2;
command = command | temp3;
}
if (typ == r_type) {
temp1 = temp1 | opcode;
temp1 = temp1 << 27;
temp2 = temp2 | param1;
temp2 = temp2 << 22;
temp3 = temp3 | param2;
temp3 = temp3 << 17;
temp4 = temp4 | sc;
command = command | temp1;
command = command | temp2;
command = command | temp3;
command = command | temp4;
}
if (typ == v_type) {
temp1 = temp1 | opcode;
temp1 = temp1 << 27;
temp2 = temp2 | param1;
temp2 = temp2 << 22;
temp4 = temp4 | sc;
command = command | temp1;
command = command | temp2;
command = command | temp4;
}
if (typ == d_type) {
cmd_cntr+=param2;
command = opcode;
}
for (i = 0; i < 4; i++) fprintf(ausgabe, "%c", (command >> (3-i)*8));
cmd_cntr++;
}
int yyerror(char* s) {
fprintf(stderr, "Error in Zeile %i : %s \n", zeile, s);
}
int main(int argc,char** argv) {
memset(&my_labelarray, 0, sizeof(label_array));
if (argc != 3) {
printf("Usage %s outputfile inputfile \n", argv[0]);
exit(1);
}
ausgabe = fopen(argv[1], "wb+");
if (!ausgabe) {
printf("Cant open %s\n", argv[1]);
exit(1);
}
yyin = fopen(argv[2], "r");
if (!yyin) {
printf("%s, File not Found\n", argv[2]);
exit(1);
}
x = collectLabels(yyin, &my_labelarray);
printf("found %i Label(s) \n", x);
fseek(yyin, 0, 0);
errno = yyparse();
fclose(ausgabe);
//for debug only
printf("%d commands found!\n",cmd_cntr);
//debug end
return errno;
}