This commit is contained in:
Timon 2025-12-10 18:28:54 +01:00
parent 705c7bcb58
commit d50c62106e
14 changed files with 344 additions and 156 deletions

View file

@ -7,28 +7,29 @@ program
ADDR S, A ADDR S, A
ADDR T, A ADDR T, A
STA sum STA sum
WD #1
. Odstejemo x in y . Odstejemo x in y
LDA S LDA x
SUBR T, A SUBR T, A
STA diff STA diff
WD #1
. Zmnozimo x in y . Zmnozimo x in y
LDA S LDA x
MULR T, A MULR T, A
STA prod STA prod
WD #1
. Zdelimo x in y . Zdelimo x in y
LDA S LDA x
DIVR T, A DIVR T, A
STA quot STA quot
WD #1
. Ostanek pri deljenju x z y . Ostanek pri deljenju x z y
LDA quot LDA quot
MULR T, A MULR T, A
SUBR A, S SUBR A, S
STS mod STS mod
#WD 1
halt J halt halt J halt
sum RESW 1 sum RESW 1
@ -37,7 +38,7 @@ quot RESW 1
prod RESW 1 prod RESW 1
mod RESW 1 mod RESW 1
x WORD 20 x WORD 15
y WORD 10 y WORD 5
END program END program

View file

@ -1,20 +1,20 @@
***** Section <default> ***** ***** Section <default> *****
Stats: size=77 blocks=77 symbols=10 literals=0 relocations=0 Stats: size=83 blocks=83 symbols=10 literals=0 relocations=0
Blocks Blocks
name start size #ins #dir #sto name start size #ins #dir #sto
<default> 00000 0004D 22 4 5 <default> 00000 00053 23 4 5
Symbols Symbols
name hex dec scope kind type description name hex dec scope kind type description
a_rel 000000 0 exported relative code label a_rel 000000 0 exported relative code label
diff 00003B 59 local relative data label diff 000041 65 local relative data label
halt 000035 53 local relative code label halt 00003B 59 local relative code label
mod 000044 68 local relative data label mod 00004A 74 local relative data label
prod 000041 65 local relative data label prod 000047 71 local relative data label
program 000000 0 local relative code label program 000000 0 local relative code label
quot 00003E 62 local relative data label quot 000044 68 local relative data label
sum 000038 56 local relative data label sum 00003E 62 local relative data label
x 000047 71 local relative data label x 00004D 77 local relative data label
y 00004A 74 local relative data label y 000050 80 local relative data label
Literals Literals
label definition label definition
Relocations Relocations

View file

@ -1,44 +1,42 @@
00000 a_rel START 0 00000 a_rel START 0
00000 6F2044 program LDS x 00000 6F204A program LDS x
00003 772044 LDT y 00003 77204A LDT y
00006 9040 ADDR S,A 00006 9040 ADDR S,A
00008 9050 ADDR T,A 00008 9050 ADDR T,A
0000A 0F202B STA sum 0000A 0F2031 STA sum
0000D 010000 LDA #0 . Reset A-ja 0000D DD0001 WD #1
. Odstejemo x in y . Odstejemo x in y
00010 9040 ADDR S,A 00010 03203A LDA x
00012 9450 SUBR T,A 00013 9450 SUBR T,A
00014 0F2024 STA diff 00015 0F2029 STA diff
00017 010000 LDA #0 00018 DD0001 WD #1
. Zmnozimo x in y . Zmnozimo x in y
0001A 9040 ADDR S,A 0001B 03202F LDA x
0001C 9850 MULR T,A 0001E 9850 MULR T,A
0001E 0F2020 STA prod 00020 0F2024 STA prod
00021 010000 LDA #0 00023 DD0001 WD #1
. Zdelimo x in y . Zdelimo x in y
00024 9040 ADDR S,A 00026 032024 LDA x
00026 9C50 DIVR T,A 00029 9C50 DIVR T,A
00028 0F2013 STA quot 0002B 0F2016 STA quot
0002E DD0001 WD #1
. Ostanek pri deljenju x z y . Ostanek pri deljenju x z y
0002B 6B2010 LDB quot 00031 032010 LDA quot
0002E 9853 MULR T,B 00034 9850 MULR T,A
00030 9434 SUBR B,S 00036 9404 SUBR A,S
00032 7F200F STS mod 00038 7F200F STS mod
. #WD 1
0003B 3F2FFD halt J halt
00035 3F2FFD halt J halt 0003E 000000 sum RESW 1
00041 000000 diff RESW 1
00044 000000 quot RESW 1
00047 000000 prod RESW 1
0004A 000000 mod RESW 1
00038 000000 sum RESW 1 0004D 00000F x WORD 15
0003B 000000 diff RESW 1 00050 000005 y WORD 5
0003E 000000 quot RESW 1
00041 000000 prod RESW 1
00044 000000 mod RESW 1
00047 000014 x WORD 20 00053 END program
0004A 00000A y WORD 10
0004D END program

View file

@ -1,5 +0,0 @@
Ha_rel 00000000004D
T0000001E6F2044772044904090500F202B010000904094500F202401000090409850
T00001E1A0F202001000090409C500F20136B2010985394347F200F3F2FFD
T0000470600001400000A
E000000

13
ass1/vhod_izhod/cat.log Normal file
View file

@ -0,0 +1,13 @@
***** Section <default> *****
Stats: size=9 blocks=9 symbols=2 literals=0 relocations=0
Blocks
name start size #ins #dir #sto
<default> 00000 00009 3 2 0
Symbols
name hex dec scope kind type description
cat 000000 0 exported relative code label
loop 000000 0 local relative code label
Literals
label definition
Relocations
address length flag symbol

7
ass1/vhod_izhod/cat.lst Normal file
View file

@ -0,0 +1,7 @@
00000 cat START 0
00000 D90000 loop RD #0
00003 DD0001 WD #1
00006 3F2FF7 J loop
00009 END cat

6
ass2/files/arithr.obj Normal file
View file

@ -0,0 +1,6 @@
Ha_rel 000000000053
T0000001E6F204A77204A904090500F2031DD000103203A94500F2029DD000103202F
T00001E1E98500F2024DD00010320249C500F2016DD0001032010985094047F200F3F
T00003C022FFD
T00004D0600000F000005
E000000

3
ass2/files/cat.obj Normal file
View file

@ -0,0 +1,3 @@
Hcat 000000000009
T00000009D90000DD00013F2FF7
E000000

View file

@ -0,0 +1 @@
2

View file

@ -19,6 +19,7 @@ class cpu {
bool isRunning(); bool isRunning();
void setSpeed(int kHz); void setSpeed(int kHz);
int getSpeed(); int getSpeed();
void step();
private: private:
void zankaUre(); void zankaUre();
}; };

View file

@ -18,7 +18,6 @@
class machine { class machine {
public: public:
// Register indices
static const int A = 0; static const int A = 0;
static const int X = 1; static const int X = 1;
static const int L = 2; static const int L = 2;
@ -29,7 +28,6 @@ public:
static const int PC = 8; static const int PC = 8;
static const int SW = 9; static const int SW = 9;
// Condition codes
static const int CC_LT = 0x00; static const int CC_LT = 0x00;
static const int CC_EQ = 0x40; static const int CC_EQ = 0x40;
static const int CC_GT = 0x80; static const int CC_GT = 0x80;
@ -39,7 +37,8 @@ public:
private: private:
std::array<int, 10> registri{}; std::array<int, 10> registri{};
double F_val = 0.0; double F_val = 0.0;
int program_end = 0;
int program_start = 0;
std::array<uint8_t, MAX_ADRESS> pomnilnik{}; std::array<uint8_t, MAX_ADRESS> pomnilnik{};
std::array<std::unique_ptr<Device>, 256> naprave{}; std::array<std::unique_ptr<Device>, 256> naprave{};
std::unordered_map<std::string, std::function<bool(int,int)>> ukaziF2; std::unordered_map<std::string, std::function<bool(int,int)>> ukaziF2;
@ -47,8 +46,7 @@ private:
public: public:
machine(); machine();
//getterji, setterji
// getters-setters
int getA(); void setA(int a); int getA(); void setA(int a);
int getX(); void setX(int x); int getX(); void setX(int x);
int getL(); void setL(int l); int getL(); void setL(int l);
@ -63,19 +61,21 @@ public:
int getReg(int r); int getReg(int r);
void setReg(int r, int val); void setReg(int r, int val);
// memory
int getByte(int adr); int getByte(int adr);
void setByte(int adr, int val); void setByte(int adr, int val);
int getWord(int adr); int getWord(int adr);
void setWord(int adr, int val); void setWord(int adr, int val);
void writeWord(int addr, int value);
int readWord(int addr);
int getUN(int n, int i, int x, int b, int p, int e, int operand); int getUN(int n, int i, int x, int b, int p, int e, int operand);
// devices //naprave
Device& getDevice(uint8_t dev); Device& getDevice(uint8_t dev);
void setDevice(uint8_t num, std::unique_ptr<Device> dev); void setDevice(uint8_t num, std::unique_ptr<Device> dev);
void setFileDevice(uint8_t num, const std::string& filename); void setFileDevice(uint8_t num, const std::string& filename);
void loadObj(const std::string &path);
// error helpers
// errorji
void notImplemented(const std::string& mnemonic); void notImplemented(const std::string& mnemonic);
void invalidOpcode(int opcode); void invalidOpcode(int opcode);
void invalidAdressing(); void invalidAdressing();
@ -83,9 +83,9 @@ public:
void outOfMemoryRange(int mem); void outOfMemoryRange(int mem);
void divisionByZero(); void divisionByZero();
// execution //execution
uint8_t fetch(); uint8_t fetch();
void execute(); bool execute();
bool execF1(uint8_t opcode, const std::string& mnemonic); bool execF1(uint8_t opcode, const std::string& mnemonic);
bool execF2(uint8_t opcode, uint8_t operand, const std::string& mnemonic); bool execF2(uint8_t opcode, uint8_t operand, const std::string& mnemonic);
bool execSIC_F3_F4(uint8_t b1, uint8_t b2, uint8_t b3, const std::string& mnemonic); bool execSIC_F3_F4(uint8_t b1, uint8_t b2, uint8_t b3, const std::string& mnemonic);

View file

@ -1,4 +1,5 @@
#include "../headers/cpu.h" #include "../headers/cpu.h"
#include <iostream>
void cpu::start() { void cpu::start() {
if (running) return; if (running) return;
@ -27,20 +28,24 @@ void cpu::setSpeed(int speedKhz) {
void cpu::zankaUre() { void cpu::zankaUre() {
while (running) { while (running) {
// 1. Izvedemo določeno št. ukazov na tick
for (int i = 0; i < operacijeNaTick; i++) { for (int i = 0; i < operacijeNaTick; i++) {
cpu::m->execute(); bool ok = cpu::m->execute();
if (!ok) {
running = false;
//std::cout << i << std::endl;
break;
}
} }
// 2. Izračunamo kolikokrat mora "tikati" na sekundo if (!running) break;
// speed_kHz = n tisoč ukazov / sekundo
// operacijeNaTick = koliko ukazov na en tik
// ticksPerSecond = (hitrostKhz * 1000) / operacijeNaTick
double ticksPerSecond = (hitrostKhz * 1000.0) / operacijeNaTick; double ticksPerSecond = (hitrostKhz * 1000.0) / operacijeNaTick;
double sleepTimeSec = 1.0 / ticksPerSecond; double sleepTimeSec = 1.0 / ticksPerSecond;
// 3. Ustavimo nit za izračunani čas
std::this_thread::sleep_for(std::chrono::duration<double>(sleepTimeSec)); std::this_thread::sleep_for(std::chrono::duration<double>(sleepTimeSec));
} }
} }
void cpu::step() {
cpu::m->execute();
}

View file

@ -63,48 +63,48 @@ machine::machine() {
{"LDX", [&](int m){setX(getWord(m)); return true;}}, {"LDX", [&](int m){setX(getWord(m)); return true;}},
{"LDS", [&](int m){setS(getWord(m)); return true;}}, {"LDS", [&](int m){setS(getWord(m)); return true;}},
{"LDL", [&](int m){setL(getWord(m)); return true;}}, {"LDL", [&](int m){setL(getWord(m)); return true;}},
{"LDCH", [&](int m){setA(getByte(m)); return true;}}, //POPRAVIT {"LDCH", [&](int m){setA(getByte(m)&0xFF); return true;}},
{"STA", [&](int m){setWord(m, getA()); return true;}}, {"STA", [&](int m){writeWord(m, getA()); return true;}},
{"STB", [&](int m){setWord(m, getB()); return true;}}, {"STB", [&](int m){setWord(m, getB()); return true;}},
{"STT", [&](int m){setWord(m, getT()); return true;}}, {"STT", [&](int m){setWord(m, getT()); return true;}},
{"STX", [&](int m){setWord(m, getX()); return true;}}, {"STX", [&](int m){setWord(m, getX()); return true;}},
{"STL", [&](int m){setWord(m, getL()); return true;}}, {"STL", [&](int m){setWord(m, getL()); return true;}},
{"STS", [&](int m){setWord(m, getS()); return true;}}, {"STS", [&](int m){setWord(m, getS()); return true;}},
{"STCH", [&](int m){setByte(m, getA()); return true;}}, //POPRAVIT {"STCH", [&](int m){setByte(m, getA()&0xFF); return true;}},
{"TIX", [&](int m){setX(getX()+1); {"TIX", [&](int m){setX(getX()+1);
if (getX() < getWord(m)) setSW(CC_LT); if (getX() < getWord(m)) setSW(CC_LT);
else if (getX() == getWord(m)) setSW(CC_EQ); else if (getX() == getWord(m)) setSW(CC_EQ);
else setSW(CC_GT); else setSW(CC_GT);
return true;}}, return true;}},
{"WD", [&](int m){return true;}},//POPRAVIT {"WD", [&](int m){getDevice(m).write(getA()&0xFF); return true;}},
{"RD", [&](int m){return true;}},//POPRAVIT {"RD", [&](int m){uint8_t c = getDevice(m).read()&0xFF; setA(c); return true;}},
}; };
} }
//machine::getterji, setterji //machine::getterji, setterji
int machine::getA() {return registri[A];} int machine::getA() {return registri[A];}
void machine::setA(int a) {registri[A] = a;} void machine::setA(int a) {registri[A] = a & 0xFFFFFF;}
int machine::getX() {return registri[X];} int machine::getX() {return registri[X];}
void machine::setX(int x) {registri[X] = x;} void machine::setX(int x) {registri[X] = x & 0xFFFFFF;}
int machine::getL() {return registri[L];} int machine::getL() {return registri[L];}
void machine::setL(int l) {registri[L] = l;} void machine::setL(int l) {registri[L] = l & 0xFFFFFF;}
int machine::getB() {return registri[B];} int machine::getB() {return registri[B];}
void machine::setB(int b) {registri[B] = b;} void machine::setB(int b) {registri[B] = b & 0xFFFFFF;}
int machine::getS() {return registri[S];} int machine::getS() {return registri[S];}
void machine::setS(int s) {registri[S] = s;} void machine::setS(int s) {registri[S] = s & 0xFFFFFF;}
int machine::getT() {return registri[T];} int machine::getT() {return registri[T];}
void machine::setT(int t) {registri[T] = t;} void machine::setT(int t) {registri[T] = t & 0xFFFFFF;}
double machine::getF() {return F_val;} double machine::getF() {return F_val;}
void machine::setF(double f) {F_val = f;} void machine::setF(double f) {F_val = f;}
int machine::getPC() {return registri[PC];} int machine::getPC() {return registri[PC];}
void machine::setPC(int pc) {registri[PC] = pc;} void machine::setPC(int pc) {registri[PC] = pc & 0xFFFFF;}
int machine::getSW() {return registri[SW];} int machine::getSW() {return registri[SW];}
void machine::setSW(int sw) {registri[SW] = sw;} void machine::setSW(int sw) {registri[SW] = sw;}
@ -142,13 +142,31 @@ machine::machine() {
void machine::setWord(int adr, int val) { void machine::setWord(int adr, int val) {
if (adr < 0 || adr + 2 > MAX_ADRESS) outOfMemoryRange(adr+2); 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."); if (val < 0 || val > 0xFFFFFF) throw invalid_argument("Beseda mora imeti vrednost med 0 in 0xFFFFFF." + to_string(val));
pomnilnik[adr] = (val >> 16) & 0xFF; //val = 0x00123456 -> hočemo 12, val >> 16 -> 0x00000012 & 0x000000ff = 0x12 pomnilnik[adr] = (val >> 16) & 0xFF; //val = 0x00123456 -> hočemo 12, val >> 16 -> 0x00000012 & 0x000000ff = 0x12
pomnilnik[adr+1] = (val >> 8) & 0xFF; pomnilnik[adr+1] = (val >> 8) & 0xFF;
pomnilnik[adr+2] = (val) & 0xFF; pomnilnik[adr+2] = (val) & 0xFF;
} }
int machine::readWord(int addr) {
uint8_t b1 = getByte(addr);
uint8_t b2 = getByte(addr + 1);
uint8_t b3 = getByte(addr + 2);
int value = (b1 << 16) | (b2 << 8) | b3;
return value & 0xFFFFFF;
}
void machine::writeWord(int addr, int value) {
// tukaj NE mečemo invalid_argument, ampak odrežemo na 24 bitov
int v = value & 0xFFFFFF;
setByte(addr, (v >> 16) & 0xFF);
setByte(addr + 1, (v >> 8) & 0xFF);
setByte(addr + 2, v & 0xFF);
}
Device& machine::getDevice(uint8_t dev) { Device& machine::getDevice(uint8_t dev) {
if (dev > 255) if (dev > 255)
throw out_of_range("Naprava ne obstaja, izberite napravo med 0 in 255"); throw out_of_range("Naprava ne obstaja, izberite napravo med 0 in 255");
@ -156,10 +174,9 @@ machine::machine() {
if (!naprave[dev]) if (!naprave[dev])
throw runtime_error("Naprava ni inicializirana"); throw runtime_error("Naprava ni inicializirana");
return *naprave[dev]; //rabmo returnat pointer, ker nase naprave so shranjene kakor unique pointerji return *naprave[dev]; //rabmo returnat pointer, ker naprave so shranjene kakor unique pointerji
} }
void machine::setDevice(uint8_t num, unique_ptr<Device> dev) { void machine::setDevice(uint8_t num, unique_ptr<Device> dev) {
if (num > 255) if (num > 255)
throw out_of_range("Naprava ne obstaja, izberite napravo med 0 in 255"); throw out_of_range("Naprava ne obstaja, izberite napravo med 0 in 255");
@ -174,39 +191,109 @@ machine::machine() {
naprave[num] = make_unique<fileDevice>(filename); naprave[num] = make_unique<fileDevice>(filename);
} }
int machine::getUN(int n, int i, int x, int b, int p, int e, int operand){ /*Ha_rel 000000 00004D
int UN; T 000000(zacetek) 1E(dolzina) 6F(byte) 20 44 77 20 44 90 40 90 50 0F 20 2B 01 00 00 90 40 94 50 0F 20 24 01 00 00 90 40 98 50
T 00001E 1A 0F202001000090409C500F20136B2010985394347F200F3F2FFD
T 000047 06 00001400000A
E 000000 <- zacetek programa
*/
if (e == 1) { void machine::loadObj(const string& path) {
UN = operand; ifstream file(path);
if (!file.is_open()) {
throw runtime_error("Ne morem odpreti OBJ datoteke: " + path);
} }
else if (n == 0 && i == 0) {
// SIC format
UN = operand;
}
else {
if (p == 1)//PC relativno
UN = PC + operand;
else if (b == 1)//Bazno relativno
UN = B + operand;
else
UN = operand;
}
//indeksno
if (x == 1)
UN += X;
//takojsnje
if (n == 0 && i == 1)
return UN;
//posredno string line;
if (n == 1 && i == 0) program_end = 0; // reset
return getWord(UN); program_start = 0;
//enostavno n=i=1 cout << "Nalagam OBJ: " << path << endl;
return UN;
while (getline(file, line)) {
if (line.empty()) continue;
char type = line[0];
if (type == 'H') {
string startHex = line.substr(7, 6);
string lenHex = line.substr(13, 6);
int start = stoi(startHex, nullptr, 16);
int len = stoi(lenHex, nullptr, 16);
program_start = start;
program_end = start;
} else if (type == 'T') {
string startHex = line.substr(1, 6);
string lenHex = line.substr(7, 2);
string data = line.substr(9);
int start = stoi(startHex, nullptr, 16);
int len = stoi(lenHex, nullptr, 16);
cout << "Nalozil " << len << " bajtou na " << hex << start << dec << endl;
for (int i = 0; i < len; i++) {
string byteHex = data.substr(i * 2, 2);
uint8_t value = stoi(byteHex, nullptr, 16);
setByte(start + i, value);
}
program_end = max(program_end, start + len);
} else if (type == 'E') {
if (line.size() > 1) {
string entryHex = line.substr(1);
program_start = stoi(entryHex, nullptr, 16);
}
setPC(program_start);
cout << "Zacetek programa = 0x" << hex << program_start << dec << endl;
}
}
file.close();
} }
int machine::getUN(int n, int i, int x, int b, int p, int e, int disp) {
int UN;
//F4 20b
if (e == 1) {
UN = disp & 0xFFFFF;
}
//SIC 15b
else if (n == 0 && i == 0) {
UN = disp & 0x7FFF;
}
//F3
else {
if (p == 1) {
UN = (getPC() + disp) & 0xFFFFF;
} else if (b == 1) {
UN = (getB() + disp) & 0xFFFFF;
} else {
UN = disp & 0xFFFFF;
}
}
//indeksno se lahko povsod pojavi
if (x == 1) {
UN = (UN + getX()) & 0xFFFFF;
}
//immediate -> vrnemo kr vrednost npr #0xb000
if (n == 0 && i == 1) {
return disp;
}
//UN je pointer na uporabni naslov
if (n == 1 && i == 0) {
return readWord(UN);
}
//enostavnu
return UN;
}
void machine::outOfMemoryRange(int memory) { void machine::outOfMemoryRange(int memory) {
throw out_of_range("Naslov je izven pomnilniškega obmocja: " + to_string(memory)); throw out_of_range("Naslov je izven pomnilniškega obmocja: " + to_string(memory));
@ -236,14 +323,22 @@ machine::machine() {
return machine::getByte(registri[PC]++); return machine::getByte(registri[PC]++);
} }
void machine::execute() { bool machine::execute() {
uint8_t opcode8 = fetch(); //cout << "[EXECUTE] PC = " << hex << getPC() << endl;
uint8_t opcode6 = opcode8 & 0xFC;
int oldPC = getPC(); // PC pred fetchom
uint8_t opcode8 = fetch();
uint8_t opcode6 = opcode8 & 0xFC;
//cout << "Fetched opcode8=" << hex << int(opcode8)
// << " opcode6=" << int(opcode6) << dec << endl;
auto it = Opcode::OPCODES.find(opcode6); auto it = Opcode::OPCODES.find(opcode6);
if (it == Opcode::OPCODES.end()) { if (it == Opcode::OPCODES.end()) {
invalidOpcode(opcode6); invalidOpcode(opcode6);
return; cout << "Narobe opcode\n";
return false;
} }
InstructionInfo ii = it->second; InstructionInfo ii = it->second;
@ -267,15 +362,25 @@ machine::machine() {
break; break;
} }
default: default:
break; cout << "format not found\n";
return false;
} }
if (uspesno) return; if (!uspesno) {
else { cout << "[EXEC] STOP at PC=" << hex << getPC() << " opcode=" << int(opcode8) << dec << endl;
throw runtime_error("Izvajanje ukaza je bilo neuspešno"); return false;
} }
//konec programa
if (getPC() >= program_end || getPC() == oldPC) {
cout << "END OF PROGRAM at PC=0x" << hex << getPC() << dec << endl;
return false;
}
return true;
} }
bool machine::execF1(uint8_t opcode, const string& mnemonic){ bool machine::execF1(uint8_t opcode, const string& mnemonic){
//FIX, FLOAT, HIO, TIO, SIO, NORM //FIX, FLOAT, HIO, TIO, SIO, NORM
auto it = Opcode::OPCODES.find(opcode); auto it = Opcode::OPCODES.find(opcode);
@ -301,7 +406,8 @@ machine::machine() {
//normalizirej (F) //normalizirej (F)
return true; return true;
} else { } else {
return true; cout << "Izvajanje F1 neuspesno" + mnemonic + "\n";
return false;
} }
} }
@ -310,44 +416,84 @@ machine::machine() {
bool machine::execF2(uint8_t opcode, uint8_t operand, const string& mnemonic){ bool machine::execF2(uint8_t opcode, uint8_t operand, const string& mnemonic){
uint8_t r1 = (operand & 0xF0) >> 4; uint8_t r1 = (operand & 0xF0) >> 4;
uint8_t r2 = (operand & 0x0F); uint8_t r2 = (operand & 0x0F);
auto it = ukaziF2.find(mnemonic); auto it = ukaziF2.find(mnemonic);
if (it == ukaziF2.end()) {
notImplemented(mnemonic);
return false;
}
if (r1 > 9 || r2 > 9) { // r1<0, r2<0 pri uint8_t itak nista možna
invalidRegister(mnemonic, r1, r2);
return false;
}
bool ok = it->second(r1, r2);
if (it == ukaziF2.end()) notImplemented(mnemonic); return false; if (!ok) {
if (r1 > 9 || r2 > 9 || r1 < 0 || r2 < 0) invalidRegister(mnemonic, r1, r2); return false; cout << "Izvajanje F2 neuspesno, ukaz: " << mnemonic << "\n";
return false;
return it->second(r1, r2); }
return true;
} }
bool machine::execSIC_F3_F4(uint8_t byte1, uint8_t byte2, uint8_t byte3, const string& mnemonic) { 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 n = (byte1 >> 1) & 1;
uint8_t i = (byte1 >> 6) & 1; uint8_t i = byte1 & 1;
uint8_t x = (byte2 >> 7) & 1; uint8_t x = (byte2 >> 7) & 1;
uint8_t b = (byte2 >> 6) & 1; uint8_t b = (byte2 >> 6) & 1;
uint8_t p = (byte2 >> 5) & 1; uint8_t p = (byte2 >> 5) & 1;
uint8_t e = (byte2 >> 4) & 1; uint8_t e = (byte2 >> 4) & 1;
int operand = 0; int UN = 0;
auto it = ukaziSICF3F4.find(mnemonic); //najdemo pripadajoc ukaz
if (it == ukaziSICF3F4.end()) notImplemented(mnemonic); return false;
if (n == 0 && i == 0) { int disp = 0;
//imamo format SIC int UN = 0;
operand = ((byte2 & 0x7F) << 8) | byte3;
UN = getUN(0, 0, x, 0, 0, 0, operand); //sicer ni res da so bpe nujno 0, ampak dobim cel operand ki ga rabim že z bitnimi operacijami auto it = ukaziSICF3F4.find(mnemonic);
} else if (e == 1) { if (it == ukaziSICF3F4.end()) {
//imamo format 4 notImplemented(mnemonic);
uint8_t byte4 = fetch(); return false;
operand = ((byte2 & 0x0F) << 16) | (byte3 << 8) | byte4;
UN = getUN(n, i, x, b, p, 1, operand);
} else {
//imamo format 3
operand = ((byte2 & 0x0F) << 8) | byte3;
if (operand & 0x800) { // če je bit 11 = 1
operand |= 0xFFFFF000; // napolni višje bite z 1
}
UN = getUN(n, i, x, b, p, 0, operand);
} }
return it->second(UN); // tukaj dejansko pozenemo ukaz z uporabnim naslovom /*cout << "EXEC: " << mnemonic
<< " n=" << int(n)
<< " i=" << int(i)
<< " x=" << int(x)
<< " b=" << int(b)
<< " p=" << int(p)
<< " e=" << int(e)
<< " byte2=" << hex << int(byte2)
<< " byte3=" << hex << int(byte3)
<< dec << "\n";*/
//SIC
if (n == 0 && i == 0) {
disp = ((byte2 & 0x7F) << 8) | byte3;
UN = getUN(0, 0, x, 0, 0, 0, disp);
}
//F4
else if (e == 1) {
uint8_t byte4 = fetch();
disp = ((byte2 & 0x0F) << 16) | (byte3 << 8) | byte4;
UN = getUN(n, i, x, b, p, 1, disp);
}
//F3
else {
disp = ((byte2 & 0x0F) << 8) | byte3;
//sign extension
if (disp & 0x800) {
disp |= 0xFFFFF000;
}
UN = getUN(n, i, x, b, p, 0, disp);
}
//cout << "operand=" << disp << " UN=" << hex << UN << dec << "\n";
bool ok = it->second(UN);
if (!ok) {
cout << "Izvajanje SIC/F3/F4 neuspesno, ukaz: " << mnemonic << "\n";
return false;
}
return true;
} }

View file

@ -1,12 +1,24 @@
#include "../headers/machine.h" #include "../headers/machine.h"
#include "../headers/cpu.h" #include "../headers/cpu.h"
#include <iostream>
int main(int argc, char const *argv[]){ int main(int argc, char const *argv[]){
machine m; machine m;
cpu procesor(&m); cpu procesor(&m);
m.loadObj("files/arithr.obj");
//m.loadObj("files/cat.obj");
procesor.setSpeed(100); procesor.setSpeed(100);
procesor.start(); procesor.start();
//stuff /*stuff
procesor.stop(); m.setA(50); //dela
m.getDevice(1).write(m.getA()); //dela->izpis na std izhod
m.getDevice(1).write(10); //izpis newlinea
m.getDevice(4).write(m.getA()); //dela->izpis v datoteko
*/
while (procesor.isRunning()) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
std::cout << "Program končan.\n";
return 0; return 0;
} }