Popravil fileDevice.cpp tako da dejansko naredi datoteke, če še ne obstajajo
This commit is contained in:
parent
8222f8dd0a
commit
74cc571eef
270 changed files with 104 additions and 74 deletions
324
ass2/machine.cpp
324
ass2/machine.cpp
|
|
@ -1,324 +0,0 @@
|
|||
#include <array>
|
||||
#include <stdexcept>
|
||||
#include "machine.h"
|
||||
#include "device.h"
|
||||
#include "inputDevice.h"
|
||||
#include "outputDevice.h"
|
||||
#include "fileDevice.h"
|
||||
#include "opcode.h"
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
machine::machine() {
|
||||
registri.fill(0); //konstruktor -> vsi registri so 0 na zacetku
|
||||
|
||||
naprave[0] = make_unique<InputDevice>(cin); //0 = std vhod
|
||||
naprave[1] = make_unique<InputDevice>(cout); //1 = std izhod
|
||||
naprave[2] = make_unique<InputDevice>(cerr); //2 = std izhod za napake
|
||||
|
||||
for (int i = 3; i < 256; i++) { //inicializacija ostalih naprav
|
||||
string fname = "file" + to_string(i) + ".dat";
|
||||
naprave[i] = make_unique<fileDevice>(fname);
|
||||
}
|
||||
|
||||
ukaziF2 = {
|
||||
{"ADDR", [&](int r1, int r2){setReg(r2, getReg(r1)+getReg(r2)); return true;}},
|
||||
{"SUBR", [&](int r1, int r2){setReg(r2, getReg(r2)-getReg(r1)); return true;}},
|
||||
{"MULR", [&](int r1, int r2){setReg(r2, getReg(r2)*getReg(r1)); return true;}},
|
||||
{"DIVR", [&](int r1, int r2){setReg(r2, getReg(r2)/getReg(r1)); return true;}},
|
||||
{"CLEAR", [&](int r1, int){setReg(r1, 0); return true; }},
|
||||
{"COMPR", [&](int r1, int r2){int v1 = getReg(r1), v2 = getReg(r2);
|
||||
if (v1 < v2) setSW(CC_LT);
|
||||
else if (v1 == v2) setSW(CC_EQ);
|
||||
else setSW(CC_GT);
|
||||
return true;}},
|
||||
{"RMO", [&](int r1, int r2){setReg(r2, getReg(r1)); return true;}},
|
||||
{"SHIFTR", [&](int r1, int n){int val = getReg(r1);setReg(r1, val >> n);return true;}},
|
||||
{"SHIFTL", [&](int r1, int n){int val = getReg(r1);setReg(r1, val << n);return true;}},
|
||||
{"TIXR", [&](int r1, int){int x = getX()+1; setX(x); int v2 = getReg(r1);
|
||||
if (x < v2) setSW(CC_LT);
|
||||
else if (x == v2) setSW(CC_EQ);
|
||||
else setSW(CC_GT);
|
||||
return true;}},
|
||||
};
|
||||
|
||||
ukaziSICF3F4 = {
|
||||
{"ADD", [&](int m){setA(getA()+getWord(m)); return true;}},
|
||||
{"SUB", [&](int m){setA(getA()-getWord(m)); return true;}},
|
||||
{"MUL", [&](int m){setA(getA()*getWord(m)); return true;}},
|
||||
{"DIV", [&](int m){if(getWord(m) == 0) divisionByZero();setA(getA()/getWord(m)); return true;}},
|
||||
{"AND", [&](int m){setA(getA()&getWord(m)); return true;}},
|
||||
{"OR", [&](int m){setA(getA()|getWord(m)); return true;}},
|
||||
{"COMP", [&](int m){int a = getA(); int b = getWord(m);
|
||||
if (a < b) setSW(CC_LT);
|
||||
else if (a == b) setSW(CC_EQ);
|
||||
else setSW(CC_GT);
|
||||
return true;}},
|
||||
{"J", [&](int m){setPC(m); return true;}},
|
||||
{"JEQ", [&](int m){if (getSW() == CC_EQ){setPC(m);}
|
||||
else {setPC(getPC()+1);} return true;}},
|
||||
{"JGT", [&](int m){if (getSW() == CC_GT) {setPC(m);}
|
||||
else {setPC(getPC()+1);} return true;}},
|
||||
{"JLT", [&](int m){if (getSW() == CC_LT){setPC(m);}
|
||||
else{setPC(getPC()+1);} return true;}},
|
||||
{"JSUB", [&](int m){setL(getPC()); setPC(m); return true;}},
|
||||
{"RSUB", [&](int m){setPC(getL()); return true;}},
|
||||
{"LDA", [&](int m){setA(getWord(m)); return true;}},
|
||||
{"LDB", [&](int m){setB(getWord(m)); return true;}},
|
||||
{"LDT", [&](int m){setT(getWord(m)); return true;}},
|
||||
{"LDX", [&](int m){setX(getWord(m)); return true;}},
|
||||
{"LDS", [&](int m){setS(getWord(m)); return true;}},
|
||||
{"LDL", [&](int m){setL(getWord(m)); return true;}},
|
||||
{"LDCH", [&](int m){setA(getByte(m)); return true;}}, //POPRAVIT
|
||||
{"STA", [&](int m){setWord(m, getA()); return true;}},
|
||||
{"STB", [&](int m){setWord(m, getB()); return true;}},
|
||||
{"STT", [&](int m){setWord(m, getT()); return true;}},
|
||||
{"STX", [&](int m){setWord(m, getX()); return true;}},
|
||||
{"STL", [&](int m){setWord(m, getL()); return true;}},
|
||||
{"STS", [&](int m){setWord(m, getS()); return true;}},
|
||||
{"STCH", [&](int m){setByte(m, getA()); return true;}}, //POPRAVIT
|
||||
{"TIX", [&](int m){setX(getX()+1);
|
||||
if (getX() < getWord(m)) setSW(CC_LT);
|
||||
else if (getX() == getWord(m)) setSW(CC_EQ);
|
||||
else setSW(CC_GT);
|
||||
return true;}},
|
||||
{"WD", [&](int m){return true;}},//POPRAVIT
|
||||
{"RD", [&](int m){return true;}},//POPRAVIT
|
||||
};
|
||||
}
|
||||
|
||||
//machine::getterji, setterji
|
||||
int machine::getA() {return registri[A];}
|
||||
void machine::setA(int a) {registri[A] = a;}
|
||||
|
||||
int machine::getX() {return registri[X];}
|
||||
void machine::setX(int x) {registri[X] = x;}
|
||||
|
||||
int machine::getL() {return registri[L];}
|
||||
void machine::setL(int l) {registri[L] = l;}
|
||||
|
||||
int machine::getB() {return registri[B];}
|
||||
void machine::setB(int b) {registri[B] = b;}
|
||||
|
||||
int machine::getS() {return registri[S];}
|
||||
void machine::setS(int s) {registri[S] = s;}
|
||||
|
||||
int machine::getT() {return registri[T];}
|
||||
void machine::setT(int t) {registri[T] = t;}
|
||||
|
||||
double machine::getF() {return F_val;}
|
||||
void machine::setF(double f) {F_val = f;}
|
||||
|
||||
int machine::getPC() {return registri[PC];}
|
||||
void machine::setPC(int pc) {registri[PC] = pc;}
|
||||
|
||||
int machine::getSW() {return registri[SW];}
|
||||
void machine::setSW(int sw) {registri[SW] = sw;}
|
||||
|
||||
int machine::getReg(int r) {
|
||||
return r!=6 ? registri[r] : F_val;
|
||||
}
|
||||
void machine::setReg(int r, int val) {
|
||||
if (r == 6) {
|
||||
F_val = val;
|
||||
} else {
|
||||
registri[r] = val;
|
||||
}
|
||||
}
|
||||
|
||||
int machine::getByte(int adr) {
|
||||
return (adr <= MAX_ADRESS && adr >= 0) ? pomnilnik[adr] : throw out_of_range("Naslov je izven pomnilniškega obmocja: " + to_string(adr));
|
||||
}
|
||||
void machine::setByte(int adr, int val) {
|
||||
if (adr < 0 || adr > MAX_ADRESS) outOfMemoryRange(adr);
|
||||
if (val < 0 || val > 255) throw invalid_argument("Byte ima vrednost med 0 in 255.");
|
||||
pomnilnik[adr] = static_cast<uint8_t>(val);
|
||||
|
||||
}
|
||||
|
||||
int machine::getWord(int adr) {
|
||||
if (adr < 0 || adr + 2 > MAX_ADRESS) outOfMemoryRange(adr+2);
|
||||
|
||||
int byte1 = pomnilnik[adr];
|
||||
int byte2 = pomnilnik[adr+1];
|
||||
int byte3 = pomnilnik[adr+2];
|
||||
|
||||
return (byte1 << 16) | (byte2 << 8) | byte3;
|
||||
}
|
||||
|
||||
void machine::setWord(int adr, int val) {
|
||||
if (adr < 0 || adr + 2 > MAX_ADRESS) outOfMemoryRange(adr+2);
|
||||
if (val < 0 || val > 0xFFFFFF) throw invalid_argument("Beseda mora imeti vrednost med 0 in 0xFFFFFF.");
|
||||
|
||||
pomnilnik[adr] = (val >> 16) & 0xFF; //val = 0x00123456 -> hočemo 12, val >> 16 -> 0x00000012 & 0x000000ff = 0x12
|
||||
pomnilnik[adr+1] = (val >> 8) & 0xFF;
|
||||
pomnilnik[adr+2] = (val) & 0xFF;
|
||||
}
|
||||
|
||||
Device& machine::getDevice(uint8_t dev) {
|
||||
if (dev > 255)
|
||||
throw out_of_range("Naprava ne obstaja, izberite napravo med 0 in 255");
|
||||
|
||||
if (!naprave[dev])
|
||||
throw runtime_error("Naprava ni inicializirana");
|
||||
|
||||
return *naprave[dev]; //rabmo returnat pointer, ker nase naprave so shranjene kakor unique pointerji
|
||||
}
|
||||
|
||||
|
||||
void machine::setDevice(uint8_t num, unique_ptr<Device> dev) {
|
||||
if (num > 255)
|
||||
throw out_of_range("Naprava ne obstaja, izberite napravo med 0 in 255");
|
||||
|
||||
naprave[num] = move(dev);
|
||||
}
|
||||
|
||||
void machine::setFileDevice(uint8_t num, const string& filename) {
|
||||
if (num <= 2 || num > 255) {
|
||||
throw out_of_range("Samo naprave med 3 in 255 imajo lahko poljubno ime");
|
||||
}
|
||||
naprave[num] = make_unique<fileDevice>(filename);
|
||||
}
|
||||
|
||||
int getUN(int n, int x, int b, int p, int e, int operand) {
|
||||
//NEED TO IMPLEMENT
|
||||
return 1;
|
||||
}
|
||||
|
||||
void machine::outOfMemoryRange(int memory) {
|
||||
throw out_of_range("Naslov je izven pomnilniškega obmocja: " + to_string(memory));
|
||||
}
|
||||
|
||||
void machine::notImplemented(const string& mnemonic) {
|
||||
throw runtime_error("Mnemonic ni implementiran: " + mnemonic);
|
||||
}
|
||||
|
||||
void machine::invalidOpcode (int opcode) {
|
||||
throw invalid_argument("Opcode ne obstaja: " + to_string(opcode) + ".");
|
||||
}
|
||||
|
||||
void machine::invalidAdressing() {
|
||||
throw invalid_argument("Ta način naslavljanja ni podprt.");
|
||||
}
|
||||
|
||||
void machine::invalidRegister(const string& mnemonic, int r1, int r2) {
|
||||
throw invalid_argument("Neveljaven register v ukazu" + mnemonic + " r1 = " + to_string(r1) + " r2 = " + to_string(r2));
|
||||
}
|
||||
|
||||
uint8_t machine::fetch() {
|
||||
return machine::getByte(registri[PC]++);
|
||||
}
|
||||
|
||||
void machine::execute() {
|
||||
uint8_t opcode8 = fetch();
|
||||
uint8_t opcode6 = opcode8 & 0xFC;
|
||||
|
||||
auto it = Opcode::OPCODES.find(opcode6);
|
||||
if (it == Opcode::OPCODES.end()) {
|
||||
invalidOpcode(opcode6);
|
||||
return;
|
||||
}
|
||||
|
||||
InstructionInfo ii = it->second;
|
||||
bool uspesno = false;
|
||||
|
||||
switch (ii.format) {
|
||||
case 1:
|
||||
uspesno = execF1(opcode8, ii.mnemonic);
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
uint8_t operand = fetch();
|
||||
uspesno = execF2(opcode8, operand, ii.mnemonic);
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
uint8_t b2 = fetch();
|
||||
uint8_t b3 = fetch();
|
||||
uspesno = execSIC_F3_F4(opcode8, b2, b3, ii.mnemonic);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (uspesno) return;
|
||||
else {
|
||||
throw runtime_error("Izvajanje ukaza je bilo neuspešno");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//TO DO, racunanje uporabnih naslovov!!!!
|
||||
bool machine::execF1(uint8_t opcode, const string& mnemonic){
|
||||
//FIX, FLOAT, HIO, TIO, SIO, NORM
|
||||
auto it = Opcode::OPCODES.find(opcode);
|
||||
InstructionInfo ii = it->second;
|
||||
string name = ii.mnemonic;
|
||||
|
||||
if (name == "FIX") {
|
||||
setA(static_cast<int>(getF()));
|
||||
return true;
|
||||
} else if (name == "FLOAT") {
|
||||
setF(static_cast<double>(getA()));
|
||||
return true;
|
||||
} else if (name == "HIO") {
|
||||
//halt I/0 na kanalu (A)
|
||||
return true;
|
||||
} else if (name == "TIO") {
|
||||
//test I/O na kanalu (A)
|
||||
return true;
|
||||
} else if (name == "SIO") {
|
||||
//start I/O na kanalu (A), adress kanala je dan na (S)
|
||||
return true;
|
||||
} else if (name == "NORM") {
|
||||
//normalizirej (F), v c++ so ze vsa double stevila normalizirana
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool machine::execF2(uint8_t opcode, uint8_t operand, const string& mnemonic){
|
||||
uint8_t r1 = (operand & 0xF0) >> 4;
|
||||
uint8_t r2 = (operand & 0x0F);
|
||||
auto it = ukaziF2.find(mnemonic);
|
||||
|
||||
if (it == ukaziF2.end()) notImplemented(mnemonic); return false;
|
||||
if (r1 > 9 || r2 > 9 || r1 < 0 || r2 < 0) invalidRegister(mnemonic, r1, r2); return false;
|
||||
|
||||
return it->second(r1, r2);
|
||||
}
|
||||
|
||||
bool machine::execSIC_F3_F4(uint8_t byte1, uint8_t byte2, uint8_t byte3, const string& mnemonic) {
|
||||
uint8_t n = (byte1 >> 7) & 1;
|
||||
uint8_t i = (byte1 >> 6) & 1;
|
||||
uint8_t x = (byte2 >> 7) & 1;
|
||||
uint8_t b = (byte2 >> 6) & 1;
|
||||
uint8_t p = (byte2 >> 5) & 1;
|
||||
uint8_t e = (byte2 >> 4) & 1;
|
||||
|
||||
if (n == 0 && i == 0) {
|
||||
//imamo format SIC
|
||||
|
||||
} else if (e == 1) {
|
||||
//imamo format 4
|
||||
} else {
|
||||
//imamo format 3
|
||||
}
|
||||
}
|
||||
//TO DO
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue