Finished
This commit is contained in:
parent
705c7bcb58
commit
d50c62106e
14 changed files with 344 additions and 156 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
Ha_rel 00000000004D
|
|
||||||
T0000001E6F2044772044904090500F202B010000904094500F202401000090409850
|
|
||||||
T00001E1A0F202001000090409C500F20136B2010985394347F200F3F2FFD
|
|
||||||
T0000470600001400000A
|
|
||||||
E000000
|
|
||||||
13
ass1/vhod_izhod/cat.log
Normal file
13
ass1/vhod_izhod/cat.log
Normal 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
7
ass1/vhod_izhod/cat.lst
Normal 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
6
ass2/files/arithr.obj
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
Ha_rel 000000000053
|
||||||
|
T0000001E6F204A77204A904090500F2031DD000103203A94500F2029DD000103202F
|
||||||
|
T00001E1E98500F2024DD00010320249C500F2016DD0001032010985094047F200F3F
|
||||||
|
T00003C022FFD
|
||||||
|
T00004D0600000F000005
|
||||||
|
E000000
|
||||||
3
ass2/files/cat.obj
Normal file
3
ass2/files/cat.obj
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Hcat 000000000009
|
||||||
|
T00000009D90000DD00013F2FF7
|
||||||
|
E000000
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
2
|
||||||
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue