// Asamblor.cpp : Converteste un fisier din limbaj de asamblare in cod masina Savage16. #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #include "tchar.h" #include "conio.h" #include "string" #include "iostream" #include #include "fstream" #include "sstream" #include "algorithm" #include "ctype.h" #include "bitset" #include #define filename "SD_Read.asm" using namespace std; bool read_file (void); // Citeste fisierul sursa string format_line (string c); // Formateaza o linie de cod bool get_aliases (void); // Extrage tabela cu alias-uri si le inlocuieste in fisier bool get_labels (void); // Creeaza tabela cu etichete int get_addr (string lab); // Returneaza adresa corespunzatoare etichetei lab void split (int line); // Sparge instructiunea in op_code si operanzi bool is_register (string c); bool is_in_port (string c); bool is_out_port (string c); bool is_flag (string c); bool is_data (string c); int get_register (string c); int get_port (string c); int get_set_flag (string c); int get_clr_flag (string c); int get_data (string c); int get_jump (string c); string convBase(unsigned int v, int base); // Converteste din baza 10 in baza 2 sau 16 void display_code(bool); // Afiseaza codul masina pe ecran bool make_set (void); bool make_jmp (void); bool make_add (void); bool OpenComm(void); void CloseComm(void); bool WriteComm(int x); bool ReadComm(unsigned short* x); ofstream f; HANDLE hComm; ostringstream error; int size = 0; string s[4096]; int code[4096]; int actual_size = 0; int error_line[4096]; int labels_count = 0; string label[512]; int addr[512]; int alias_count = 0; string alias_l[512]; string alias_r[512]; int param_count; string param[100]; int current = -1; int value; int _tmain(int argc, _TCHAR* argv[]) { int i; unsigned short data; string g; string out_filename; out_filename = filename; out_filename.append(".log"); f.open(out_filename.c_str(), ios::out); if (!f.is_open()) { error << "Eroare la deschiderea fisierului destinatie pentru log !" << endl << endl; return false; } if (!read_file()) goto exit; cout << "S-a deschis fisierul sursa <<" << filename << ">> cu succes. " << endl << endl; f << "S-a deschis fisierul sursa <<" << filename << ">> cu succes. " << endl << endl; if (!get_aliases()) goto exit; if (alias_count == 1) { cout << "A fost extras un alias: " << endl; cout << " 1: " << alias_l[0] << " -> " << alias_r[0] << endl; f << "A fost extras un alias: " << endl; f << " 1: " << alias_l[0] << " -> " << alias_r[0] << endl; } else if (alias_count > 1) { cout << "Au fost extrase " << alias_count << " alias-uri: " << endl; f << "Au fost extrase " << alias_count << " alias-uri: " << endl; for (i = 0; i < alias_count; i++) { cout << " " << i + 1 << ": " << alias_l[i] << " -> " << alias_r[i] << endl; f << " " << i + 1 << ": " << alias_l[i] << " -> " << alias_r[i] << endl; } } else { cout << "Nu a fost gasit nici un alias." << endl; f << "Nu a fost gasit nici un alias." << endl; } if (!get_labels()) goto exit; if (labels_count == 1) { cout << "A fost extrasa o eticheta: " << endl; cout << " 1: " << label[0] << " -> " << addr[0] << endl; f << "A fost extrasa o eticheta: " << endl; f << " 1: " << label[0] << " -> " << addr[0] << endl; } else if (labels_count > 1) { cout << endl << "Au fost extrase " << labels_count << " etichete: " << endl; f << endl << "Au fost extrase " << labels_count << " etichete: " << endl; for (i = 0; i < labels_count; i++) { cout << " " << i + 1 << ": " << label[i] << " -> " << addr[i] << endl; f << " " << i + 1 << ": " << label[i] << " -> " << addr[i] << endl; } } else { cout << "Nu a fost gasita nici o eticheta." << endl; f << "Nu a fost gasita nici o eticheta." << endl; } cout << endl << "Se incepe asamblarea... " << endl << endl; f << endl << "Se incepe asamblarea... " << endl << endl; for (current = 0; current < size; current++) { split(current); value = 0; if (param[0] == "set" || param[0] == "clr") { if (!make_set()) goto exit; value |= 0xd7 << 24; display_code(true); continue; } if (param[0] == "jmp" || param[0] == "jc" || param[0] == "jnc" || param[0] == "jo" || param[0] == "jno" || param[0] == "jn" || param[0] == "jp" || param[0] == "jz" || param[0] == "jnz" || param[0] == "je" || param[0] == "jne" || param[0] == "jl" || param[0] == "jle" || param[0] == "jg" || param[0] == "jge" || param[0] == "call") { if (!make_jmp()) goto exit; if (param[0] == "jmp") value |= 0xe0 << 24; else if (param[0] == "call") value |= 0xe1 << 24; else { value |= 0xc3 << 24; value |= get_jump(param[0]) << 20; } display_code(true); continue; } if (param[0] == "nop" || param[0] == "stop" || param[0] == "ret" || param[0] == "pushf" || param[0] == "popf") { if (param_count > 1) { error << "Eroare la linia " << error_line[current] << ". Instructiunea '"<< param[0] <<"' nu accepta parametrii ! " << endl << endl; goto exit; } if (param[0] == "stop") value = 0xc1 << 24; else if (param[0] == "ret") value = 0xe2 << 24; else if (param[0] == "pushf") value = 0xf1 << 24; else if (param[0] == "popf") value = 0xf4 << 24; display_code(true); continue; } if (param[0] == "add" || param[0] == "adc" || param[0] == "sub" || param[0] == "sbb" || (param[0] == "and" && !is_out_port(param[1])) || (param[0] == "or" && !is_out_port(param[1])) || (param[0] == "xor" && !is_out_port(param[1])) || param[0] == "mult" || param[0] == "div" || param[0] == "shr" || param[0] == "shl") { if (!make_add()) goto exit; if (param[0] == "adc" || param[0] == "sbb" || param[0] == "div") value |= 1 << 24; if (param[0] == "sub" || param[0] == "sbb") value |= 1 << 28; else if (param[0] == "and") value |= 2 << 28; else if (param[0] == "or") value |= 3 << 28; else if (param[0] == "xor" || param[0] == "div") value |= 4 << 28; else if (param[0] == "shr" || "mult") value |= 5 << 28; else if (param[0] == "shl") value |= 6 << 28; if (param[0] == "mult" || param[0] == "div") value &= 0xfbffffff; display_code(true); continue; } if (param[0] == "or" || param[0] == "and" || param[0] == "xor") { if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count != 3) { error << "Eroare la linia " << error_line[current] << ". Lipseste operandul sursa ! " << endl << endl; goto exit; } if (param[0] == "and") value = 1 << 22; else if (param[0] == "or") value = 2 << 22; else value = 3 << 22; value |= get_port(param[1]) << 20; if (is_register(param[2])) { value |= get_register(param[2]) << 12; value |= 0xc4 << 24; display_code(true); continue; } if (is_data(param[2])) { if (get_data(param[2]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; goto exit; } value |= get_data(param[2]); value |= 0xc6 << 24; display_code(true); continue; } error << "Eroare la linia " << error_line[current] << ". Operandul sursa nu este registru sau data numerica ! " << endl << endl; goto exit; } if (param[0] == "push" | param[0] == "pop") { if (param_count > 2) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count == 1) { error << "Eroare la linia " << error_line[current] << ". Lipseste registrul ! " << endl << endl; goto exit; } if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Registru invalid ! " << endl << endl; goto exit; } if (param[0] == "push") { value = get_register(param[1]) << 16; value |= 0xf2 << 24; } else { value = get_register(param[1]) << 20; value |= 0xf8 << 24; } display_code(true); continue; } if (param[0] == "load") { if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count != 3) { error << "Eroare la linia " << error_line[current] << ". Prea putini parametrii ! " << endl << endl; goto exit; } if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Registru destinatie invalid ! " << endl << endl; goto exit; } if (is_register(param[2])) { value = 0xd9 << 24; value |= get_register(param[1]) << 20; value |= get_register(param[2]) << 12; display_code(true); continue; } if (is_data(param[2])) { value = 0xdb << 24; value |= get_register(param[1]) << 20; if (get_data(param[2]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; goto exit; } value |= get_data(param[2]); display_code(true); continue; } error << "Eroare la linia " << error_line[current] << ". Registru pointer invalid sau adresa de citire invalida ! " << endl << endl; goto exit; } if (param[0] == "store") { if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count != 3) { error << "Eroare la linia " << error_line[current] << ". Prea putini parametrii ! " << endl << endl; goto exit; } if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Registru sursa invalid ! " << endl << endl; goto exit; } if (is_register(param[2])) { value = 0xc8 << 24; value |= get_register(param[1]) << 16; value |= get_register(param[2]) << 12; display_code(true); continue; } if (is_data(param[2])) { value = 0xca << 24; value |= get_register(param[1]) << 16; if (get_data(param[2]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; goto exit; } value |= get_data(param[2]); display_code(true); continue; } error << "Eroare la linia " << error_line[current] << ". Registru pointer invalid sau adresa de citire invalida ! " << endl << endl; goto exit; } if (param[0] == "test" || param[0] == "inc" || param[0] == "dec") { if (param_count == 1) { error << "Eroare la linia " << error_line[current] << ". Lipseste operandul ! " << endl << endl; goto exit; } if (param_count != 2) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Operandul trebuie sa fie un registru ! " << endl << endl; goto exit; } if (param[0] == "test") { value = 0x16 << 24; value |= get_register(param[1]) << 16; } else if (param[0] == "inc") { value = 0x0e << 24; value |= get_register(param[1]) << 20; value |= get_register(param[1]) << 16; value |= 1; } else { value = 0x1e << 24; value |= get_register(param[1]) << 20; value |= get_register(param[1]) << 16; value |= 1; } display_code(true); continue; } if (param[0] == "neg" || param[0] == "com" || param[0] == "rol" || param[0] == "ror") { if (param_count == 1) { error << "Eroare la linia " << error_line[current] << ". Instructiunea are nevoie de cel putin un operand! " << endl << endl; goto exit; } if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count == 2) { if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Operandul nu este un registru ! " << endl << endl; goto exit; } value |= get_register(param[1]) << 20; value |= get_register(param[1]) << 16; } if (param_count == 3) { if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Registru destinatie invalid! " << endl << endl; goto exit; } if (!is_register(param[2])) { error << "Eroare la linia " << error_line[current] << ". Registru sursa invalid! " << endl << endl; goto exit; } value |= get_register(param[1]) << 20; value |= get_register(param[2]) << 16; } if (param[0] == "neg") value |= 0x8c << 24; else if (param[0] == "com") value |= 0x7c << 24; else if (param[0] == "rol") value |= 0x9d << 24; else value |= 0xad << 24; display_code(true); continue; } if (param[0] == "cmp") { if (param_count == 1) { error << "Eroare la linia " << error_line[current] << ". Lipsa operanzi ! " << endl << endl; goto exit; } if (param_count == 2) { error << "Eroare la linia " << error_line[current] << ". Lipseste un operand ! " << endl << endl; goto exit; } if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Primul registru sursa invalid! " << endl << endl; goto exit; } if (is_register(param[2])) { value = 0x14 << 24; value |= get_register(param[1]) << 16; value |= get_register(param[2]) << 12; display_code(true); continue; } if (is_data(param[2])) { value = 0x16 << 24; value |= get_register(param[1]) << 16; if (get_data(param[2]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; goto exit; } value |= get_data(param[2]); display_code(true); continue; } error << "Eroare la linia " << error_line[current] << ". Al doilea operand trebuie sa fie un registru sau o data numerica ! " << endl << endl; goto exit; } if ((param[0] == "mov" && !is_out_port(param[1]) && !is_in_port(param[2])) || param[0] == "movf") { if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count != 3) { error << "Eroare la linia " << error_line[current] << ". Prea putini parametrii ! " << endl << endl; goto exit; } if (!is_register(param[1])) if (param[0] == "movf") { error << "Eroare la linia " << error_line[current] << ". Registru destinatie invalid ! " << endl << endl; goto exit; } else if (param[0] == "mov") { error << "Eroare la linia " << error_line[current] << ". Registru destinatie sau port de iesire invalid ! " << endl << endl; goto exit; } if (is_register(param[2])) { if (param[0] == "movf") value = 0xbc << 24; else value = 0xb8 << 24; value = 0xb8 << 24; value |= get_register(param[1]) << 20; value |= get_register(param[2]) << 12; display_code(true); continue; } if (param[0] == "movf") { error << "Eroare la linia " << error_line[current] << ". Registru sursa invalid ! " << endl << endl; goto exit; } if (is_data(param[2])) { value = 0xba << 24; value |= get_register(param[1]) << 20; if (get_data(param[2]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; goto exit; } value |= get_data(param[2]); display_code(true); continue; } error << "Eroare la linia " << error_line[current] << ". Registru sursa invalid, port de intrare invalid sau data numerica invalida ! " << endl << endl; goto exit; } if ((param[0] == "mov" && !is_in_port(param[2])) || param[0] == "out") { if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count != 3) { if (param[0] == "mov") error << "Eroare la linia " << error_line[current] << ". Lipseste operandul sursa ! " << endl << endl; else error << "Eroare la linia " << error_line[current] << ". Prea putini parametrii ! " << endl << endl; goto exit; } if (!is_out_port(param[1])) { error << "Eroare la linia " << error_line[current] << ". Operandul destinatie nu este un port de iesire ! " << endl << endl; goto exit; } value |= get_port(param[1]) << 20; if (is_register(param[2])) { value |= get_register(param[2]) << 12; value |= 0xc4 << 24; display_code(true); continue; } if (is_data(param[2])) { if (get_data(param[2]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; goto exit; } value |= get_data(param[2]); value |= 0xc6 << 24; display_code(true); continue; } error << "Eroare la linia " << error_line[current] << ". Operandul sursa nu este registru sau data numerica ! " << endl << endl; goto exit; } if (param[0] == "mov" || param[0] == "in") { if (param_count > 3) { error << "Eroare la linia " << error_line[current] << ". Prea multi parametrii ! " << endl << endl; goto exit; } if (param_count != 3) { if (param[0] == "mov") error << "Eroare la linia " << error_line[current] << ". Lipseste operandul destinatie ! " << endl << endl; else error << "Eroare la linia " << error_line[current] << ". Prea putini parametrii ! " << endl << endl; goto exit; } if (!is_in_port(param[2])) { error << "Eroare la linia " << error_line[current] << ". Operandul sursa nu este un port de intrare ! " << endl << endl; goto exit; } value = get_port(param[2]); if (is_register(param[1])) { value |= get_register(param[1]) << 20; value |= 0xde << 24; display_code(true); continue; } error << "Eroare la linia " << error_line[current] << ". Operandul destinatie nu este registru ! " << endl << endl; goto exit; } error << "Eroare la linia " << error_line[current] << ". Instructiune necunoscuta: '" << param[0] << "' ! " << endl << endl; goto exit; } if (size > 1) { cout << endl << "Au fost asamblate " << size <<" instructiuni valide." << endl << endl; f << endl << "Au fost asamblate " << size <<" instructiuni valide." << endl << endl; } else { cout << endl << "A fost asamblata o singura instructiune valida." << endl << endl; f << endl << "A fost asamblata o singura instructiune valida." << endl << endl; } if (!OpenComm()) goto exit; cout << "S-a initializat portul COM1 cu succes. " << endl << endl; f << "S-a initializat portul COM1 cu succes. " << endl << endl; for (i = 0; i < size; i++) { if (!WriteComm(code[i])) goto exit; } cout << "Programare finalizata cu succes !" << endl << endl; f << "Programare finalizata cu succes !" << endl << endl; cout << "Continutul memoriei de date (1024 locatii): " << endl << endl; f << "Continutul memoriei de date (1024 locatii): " << endl << endl; for (i = 0; i < 1024; i++) { if (!ReadComm(&data)) goto exit; f << setfill('0'); f << "La adresa " << setw(4) << dec << i << " avem valoarea: 0x" << setw(4) << hex << data << " ( " << setw(5) << dec << data << " )." << endl; } cout << endl << endl; f << endl << endl << "end of log"; f.close(); CloseComm(); return 0; exit: if ((current != -1) && (current < size)) display_code(false); cout << endl << error.str(); cout << endl << endl; f << endl << error.str(); f << endl << endl << "end of log"; f.close(); CloseComm(); return 1; } bool read_file (void) { ifstream f; f.open(filename, ios::in); if (!f.is_open()) { error << "Eroare la deschiderea fisierului sursa !" << endl << endl; return false; } while (!f.eof()) { actual_size++; getline(f, s[size]); s[size] = format_line(s[size]); if(s[size].find("//") != string::npos) s[size].erase(s[size].find("//")); s[size] = format_line(s[size]); if(s[size].find("/") != string::npos) { error << "Eroare la linia " << error_line[current] << ". Caracter ilegal: '/' ! " << endl << endl; f.close(); return false; } else if (!s[size].empty()) { error_line[size] = actual_size; size++; } } f.close(); if (!size) { error << "Fisierul sursa nu contine nici o instructiune !" << endl << endl; return false; } return true; } string format_line (string c) { string d; size_t i; d.clear(); for (i=0; i='0' && c[i]<='9') || (c[i]>='A' && c[i]<='z') || c[i] == ' ' || c[i] == '_' || c[i] == '/') d.append(c.substr(i,1)); if (c[i] == ' ' || c[i] == ',') d.append(" "); } while(d.find(" ") != string::npos) { d.erase(d.find(" "), 1); } transform(d.begin(), d.end(), d.begin(), tolower); if (d[0] == ' ') d.erase(0, 1); if (!d.empty()) if (d[d.length() - 1] == ' ') d.erase(d.length() - 1, 1); return d; } bool get_aliases (void) { int i; int j; string t; string l; string r; for (i = 0; i < size; i++) { split(i); if (param[0] == "alias") { if (param_count > 3) { error << "Eroare la linia " << error_line[i] << ". Prea multe aliasuri ! " << endl << endl; return false; } if (param_count == 1) { error << "Eroare la linia " << error_line[i] << ". Lipsesc parametrii pentru alias ! " << endl << endl; return false; } if (param_count == 2) { error << "Eroare la linia " << error_line[i] << ". Lipseste un alias ! " << endl << endl; return false; } if (is_register(param[1]) || is_in_port(param[1]) || is_out_port(param[1]) || is_flag(param[1]) || is_data(param[1])) { error << "Eroare la linia " << error_line[i] << ". Alias stanga invalid. Cuvant rezervat sau data numerica ! " << endl << endl; return false; } if (!is_register(param[2]) && !is_in_port(param[2]) && !is_out_port(param[2]) && !is_flag(param[2]) && !is_data(param[2])) { error << "Eroare la linia " << error_line[i] << ". Alias dreapta invalid. Este necesar un registru, port, fanion sau data numerica ! " << endl << endl; return false; } alias_l[alias_count] = param[1]; alias_r[alias_count++] = param[2]; size--; for (j = i--; j < size; j++) { s[j] = s[j+1]; error_line[j] = error_line[j+1]; } } } for (j = 0; j < alias_count; j++) { l = alias_l[j]; l.replace(0, 1, "."); r = alias_r[j]; r.replace(0, 1, "."); for (i = 0; i < size; i++) { t = s[i]; while (t.find(alias_l[j])!= string::npos) { if ((t.find(alias_l[j]) == 0) && (t.find(alias_l[j]) == (t.length() - alias_l[j].length()))) { s[i].replace(t.find(alias_l[j]), alias_l[j].length(), alias_r[j]); t.replace(t.find(alias_l[j]), alias_l[j].length(), r); continue; } if (t.find(alias_l[j]) == 0) { if (t[t.find(alias_l[j]) + alias_l[j].length()] == ' ') { s[i].replace(t.find(alias_l[j]), alias_l[j].length(), alias_r[j]); t.replace(t.find(alias_l[j]), alias_l[j].length(), r); } else t.replace(t.find(alias_l[j]), alias_l[j].length(), l); continue; } if (t.find(alias_l[j]) == (t.length() - alias_l[j].length())) { if (t[t.find(alias_l[j]) - 1] == ' ') { s[i].replace(t.find(alias_l[j]), alias_l[j].length(), alias_r[j]); t.replace(t.find(alias_l[j]), alias_l[j].length(), r); } else t.replace(t.find(alias_l[j]), alias_l[j].length(), l); continue; } if ((t[t.find(alias_l[j]) + alias_l[j].length()] == ' ') && (t[t.find(alias_l[j]) - 1] == ' ')) { s[i].replace(t.find(alias_l[j]), alias_l[j].length(), alias_r[j]); t.replace(t.find(alias_l[j]), alias_l[j].length(), r); continue; } t.replace(t.find(alias_l[j]), alias_l[j].length(), l); } } } return true; } bool get_labels (void) { int i; int j; for (i = 0; i < size; i++) { split(i); if (param[0] == "label") { if (param_count > 2) { error << "Eroare la linia " << error_line[i] << ". Prea multe etichete ! " << endl << endl; return false; } if (param_count == 1) { error << "Eroare la linia " << error_line[i] << ". Lipseste eticheta ! " << endl << endl; return false; } for (j = 0; j < labels_count; j++) if (label[j] == param[1]) { error << "Eroare la linia " << error_line[i] << ". Eticheta deja definita ! " << endl << endl; return false; } label[labels_count] = param[1]; addr[labels_count++] = i; size--; for (j = i--; j < size; j++) { s[j] = s[j+1]; error_line[j] = error_line[j+1]; } } } return true; } int get_addr (string lab) { char i; for (i = 0; i < labels_count; i++) if (label[i] == lab) return addr[i]; return size; } void split (int line) { string c; param_count = 0; c = s[line]; while(c.find(" ") != string::npos) { param[param_count++] = c.substr(0, c.find(" ")); c = c.substr(c.find(" ") + 1); } param[param_count++] = c; } bool is_register (string c) { if (c == "r0" || c == "r00") return true; if (c == "r1" || c == "r01") return true; if (c == "r2" || c == "r02") return true; if (c == "r3" || c == "r03") return true; if (c == "r4" || c == "r04") return true; if (c == "r5" || c == "r05") return true; if (c == "r6" || c == "r06") return true; if (c == "r7" || c == "r07") return true; if (c == "r8" || c == "r08") return true; if (c == "r9" || c == "r09") return true; if (c == "r10") return true; if (c == "r11") return true; if (c == "r12") return true; if (c == "r13") return true; if (c == "r14") return true; if (c == "r15" || c == "mask") return true; return false; } bool is_in_port (string c) { if (c == "pina") return true; if (c == "pinb") return true; if (c == "pinc") return true; if (c == "pind") return true; return false; } bool is_out_port (string c) { if (c == "porta") return true; if (c == "portb") return true; if (c == "portc") return true; if (c == "portd") return true; return false; } bool is_data (string c) { istringstream g(c); ostringstream d; int data; if (c[1] == 'x') { if (!(g >> hex >> data)) return false; else { d.str().empty(); d << setfill('0'); d << "0x" << setw(c.length() - 2) << hex << data; if (c != d.str()) return false; } } else if (!(g >> dec >> data)) return false; else { d.str().empty(); d << setfill('0'); d << setw(c.length()) << dec << data; if (c != d.str()) return false; } return true; } bool is_flag (string c) { if (c == "m" || c == "mf") return true; if (c == "e" || c == "ef") return true; if (c == "i" || c == "if") return true; if (c == "s" || c == "sf") return true; if (c == "c" || c == "cf") return true; if (c == "o" || c == "of") return true; if (c == "n" || c == "nf") return true; if (c == "z" || c == "zf") return true; return false; } int get_register (string c) { if (c == "r0" || c == "r00") return 0; if (c == "r1" || c == "r01") return 1; if (c == "r2" || c == "r02") return 2; if (c == "r3" || c == "r03") return 3; if (c == "r4" || c == "r04") return 4; if (c == "r5" || c == "r05") return 5; if (c == "r6" || c == "r06") return 6; if (c == "r7" || c == "r07") return 7; if (c == "r8" || c == "r08") return 8; if (c == "r9" || c == "r09") return 9; if (c == "r10") return 10; if (c == "r11") return 11; if (c == "r12") return 12; if (c == "r13") return 13; if (c == "r14") return 14; if (c == "r15" || c == "mask") return 15; return 0; } int get_port (string c) { if (c == "porta" || c == "pina") return 0; if (c == "portb" || c == "pinb") return 1; if (c == "portc" || c == "pinc") return 2; if (c == "portd" || c == "pind") return 3; return 0; } int get_data (string c) { istringstream g(c); int data; if (c[1] == 'x') g >> hex >> data; else g >> dec >> data; return data; } int get_jump (string c) { if (c == "jz" || c == "je") return 6; if (c == "jnz" || c == "jne") return 7; if (c == "jc") return 0; if (c == "jnc") return 1; if (c == "jo") return 2; if (c == "jno") return 3; if (c == "jn") return 4; if (c == "jp") return 5; if (c == "jl") return 8; if (c == "jge") return 9; if (c == "jle") return 10; if (c == "jg") return 11; return 0; } int get_set_flag (string c) { if (c == "m" || c == "mf") return 0xff80; if (c == "e" || c == "ef") return 0xff40; if (c == "i" || c == "if") return 0xff20; if (c == "s" || c == "sf") return 0xff10; if (c == "c" || c == "cf") return 0xff08; if (c == "o" || c == "of") return 0xff04; if (c == "n" || c == "nf") return 0xff02; if (c == "z" || c == "zf") return 0xff01; return 0; } int get_clr_flag (string c) { if (c == "m" || c == "mf") return 0x7f00; if (c == "e" || c == "ef") return 0xbf00; if (c == "i" || c == "if") return 0xdf00; if (c == "s" || c == "sf") return 0xef00; if (c == "c" || c == "cf") return 0xf700; if (c == "o" || c == "of") return 0xfb00; if (c == "n" || c == "nf") return 0xfd00; if (c == "z" || c == "zf") return 0xfe00; return 0; } string convBase(unsigned int v, int base) { string digits = "0123456789abcdef"; string result; ostringstream g; do { result = digits[v % base] + result; v /= base; } while(v); g.str().empty(); g << setfill('0'); g << setw(32) << result; if (base == 2) return g.str(); else return result; } void display_code(bool er) { char x; unsigned char i; string g; cout << setfill('0'); f << setfill('0'); if (actual_size < 10) x = 1; else if (actual_size < 100) x = 2; else if (actual_size < 1000) x = 3; else x = 4; g.empty(); for (i = 0; i < s[current].length(); i++) if (s[current][i] == ' ') g.append(", "); else g.append(s[current].substr(i, 1)); if (param_count > 1) g.replace(g.find(","), 1, " "); cout << "Linia " << setw(x) << error_line[current] << ": " << g << endl; f << "Linia " << setw(x) << error_line[current] << ": " << g << endl; if (er) { f << " " << convBase(value, 2).substr(0, 8) << endl; f << " " << convBase(value, 2).substr(8, 8) << endl; f << " " << convBase(value, 2).substr(16, 8) << endl; f << " " << convBase(value, 2).substr(24, 8) << endl << endl; f << " " << setw(8) << convBase(value, 16) << endl << endl << endl; } cout << setfill(' '); f << setfill(' '); code[current] = value; return; } bool make_set (void) { char j; if (param_count > 9) { error << "Eroare la linia " << error_line[current] << ". Prea multe fanioane ! " << endl << endl; return false; } if (param_count == 1) { error << "Eroare la linia " << error_line[current] << ". Lipsa fanioane ! " << endl << endl; return false; } if (param[0] == "clr") value = 0xffff; for (j = 1; j < param_count; j++) { if (!is_flag(param[j])) { error << "Eroare la linia " << error_line[current] << ". Fanion enonat: '" << param[j] << "' ! " << endl << endl; return false; } if (param[0] == "set") value |= get_set_flag(param[j]); else value &= get_clr_flag(param[j]); } return true; } bool make_jmp (void) { if (param_count > 2) { error << "Eroare la linia " << error_line[current] << ". Prea multe adrese de salt! " << endl << endl; return false; } if (param_count == 1) { error << "Eroare la linia " << error_line[current] << ". Lipsa adresa de salt ! " << endl << endl; return false; } if ((value = get_addr(param[1])) == size) { error << "Eroare la linia " << error_line[current] << ". Eticheta '" << param[1] << "' nu este definita ! " << endl << endl; return false; } return true; } bool make_add (void) { if (param_count > 4) { error << "Eroare la linia " << error_line[current] << ". Prea multi operanzi! " << endl << endl; return false; } if (param_count == 1) { error << "Eroare la linia " << error_line[current] << ". Lipsa operanzi ! " << endl << endl; return false; } if (param_count == 2) { error << "Eroare la linia " << error_line[current] << ". Lipseste un operand ! " << endl << endl; return false; } if (param_count == 3) { if (!is_register(param[1])) if (param[0] == "or" || param[0] == "xor" || param[0] == "and") { error << "Eroare la linia " << error_line[current] << ". Primul operand nu este un registru sau port de iesire! " << endl << endl; return false; } else { error << "Eroare la linia " << error_line[current] << ". Primul operand nu este un registru ! " << endl << endl; return false; } if (is_register(param[2])) { value = 0x0c << 24; value |= get_register(param[1]) << 20; value |= get_register(param[1]) << 16; value |= get_register(param[2]) << 12; return true; } if (is_data(param[2])) { value = 0x0e << 24; value |= get_register(param[1]) << 20; value |= get_register(param[1]) << 16; if (param[0] == "shr" || param[0] == "shl") { if (get_data(param[2]) > 0x000f) { error << "Eroare la linia " << error_line[current] << ". Numarul maxim de rotatii este 15 ! " << endl << endl; return false; } } else { if (get_data(param[2]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; return false; } } value |= get_data(param[2]); return true; } error << "Eroare la linia " << error_line[current] << ". Al doilea operand nu este registru sau data numerica ! " << endl << endl; return false; } if (param_count == 4) { if (!is_register(param[1])) { error << "Eroare la linia " << error_line[current] << ". Primul operand nu este un registru ! " << endl << endl; return false; } if (!is_register(param[2])) { error << "Eroare la linia " << error_line[current] << ". Al doilea operand nu este un registru ! " << endl << endl; return false; } if (is_register(param[3])) { value = 0x0c << 24; value |= get_register(param[1]) << 20; value |= get_register(param[2]) << 16; value |= get_register(param[3]) << 12; return true; } if (is_data(param[3])) { value = 0x0e << 24; value |= get_register(param[1]) << 20; value |= get_register(param[2]) << 16; if (param[0] == "shr" || param[0] == "shl") { if (get_data(param[3]) > 0x000f) { error << "Eroare la linia " << error_line[current] << ". Numarul maxim de rotatii este 15 ! " << endl << endl; return false; } } else { if (get_data(param[3]) > 0xffff) { error << "Eroare la linia " << error_line[current] << ". Constanta depaseste 16 biti ! " << endl << endl; return false; } } value |= get_data(param[3]); return true; } error << "Eroare la linia " << error_line[current] << ". Al treilea operand nu este registru sau data numerica ! " << endl << endl; return false; } return true; } bool OpenComm() { DCB dcb; hComm = CreateFile(L"COM1:", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hComm == INVALID_HANDLE_VALUE) { error << "Eroare la initializarea portului COM1 ! " << endl << endl; return false; } if(!SetupComm(hComm, 4096, 4096)) { error << "Eroare la initializarea portului COM1 ! " << endl << endl; return false; } if(!GetCommState(hComm, &dcb)) { error << "Eroare la initializarea portului COM1 ! " << endl << endl; return false; } dcb.BaudRate = CBR_115200; dcb.ByteSize = 8; dcb.Parity = EVENPARITY; dcb.StopBits = ONESTOPBIT; dcb.fRtsControl = RTS_CONTROL_DISABLE; dcb.fDtrControl = DTR_CONTROL_DISABLE; if (!SetCommState(hComm, &dcb)) { error << "Eroare la initializarea portului COM1 ! " << endl << endl; return false; } return true; } void CloseComm() { CloseHandle(hComm); } bool WriteComm(int x) { DWORD nSend; char* data; data = new char[4]; data[0] = x & 0xff; data[1] = x >> 8; data[2] = x >> 16; data[3] = x >> 24; if (!WriteFile(hComm, data, 4, &nSend, NULL)) { error << "Eroare la trimiterea datelor pe portul COM1 ! " << endl << endl; return false; } if (nSend != 4) { error << "Eroare la trimiterea datelor pe portul COM1 ! " << endl << endl; return false; } return true; } bool ReadComm(unsigned short* x) { DWORD nSend; unsigned short i; if(!ReadFile(hComm, &i, 2, &nSend, NULL)) { error << "Eroare la primirea datelor de la portul COM1 ! " << endl << endl; return false; } if (nSend != 2) { error << "Eroare la primirea datelor de la portul COM1 ! " << endl << endl; return false; } *x = i; return true; }