summaryrefslogtreecommitdiffstats
path: root/main.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.hpp')
-rw-r--r--main.hpp151
1 files changed, 151 insertions, 0 deletions
diff --git a/main.hpp b/main.hpp
new file mode 100644
index 0000000..f587fab
--- /dev/null
+++ b/main.hpp
@@ -0,0 +1,151 @@
+#include <vector>
+#include <queue>
+namespace ov {
+ using namespace std;
+ enum opts { // opts are pas-1 bits aftr last ram ptr (2**ras)-1 and can be w/r from prg
+ DEFAULT,
+ BUFOUT, // output from program in VM is always possible and no blocks
+ BUFIN, // input to program in VM is always possible and no blocks
+ BUFCLR, // clears whatever is in the buffer
+ OPTSLEN
+ }; // read those last bits with the COPY instruction with source/dest on last pointer
+ enum iobits {
+ INA, // input available, clear when read
+ IN, // input bit
+ OUTA, // output available, set when have output, cleared by VM when wrote
+ OUT, // output bit
+ IOLEN
+ };
+ enum instrs {
+ COPY,
+ NAND
+ };
+ struct instr { // deserializirana inštrukcija
+ unsigned int s = 0; // source
+ unsigned int d = 0; // destination
+ bool i = 0; // instruction
+ bool p = 0; // enobitni padding, lahko za metainštrukcije
+ }; // privzeto inicializiran na NOOP inštrukcijo
+ template<typename value_type, typename index_type, class Memory> class Mmu {
+ private:
+ class Cell {
+ private:
+ friend class Mmu;
+ Mmu & mmu;
+ index_type index;
+ Cell (Mmu & mmu, index_type index)
+ : mmu(mmu), index(index) {}
+ public:
+ operator value_type (void) {
+ return mmu.memory.peek(index);
+ }
+ value_type operator= (value_type value) {
+ mmu.memory.poke(index, value);
+ return value;
+ }
+ };
+ public:
+ Memory & memory;
+ Mmu (Memory & memory) : memory(memory) {}
+ Cell operator[] (index_type index) {
+ return Cell(*this, index);
+ }
+ value_type & operator() (index_type index) {
+ return memory.peek(index);
+ }
+ };
+ class Ov;
+ template<typename value_type, typename index_type> class Ram {
+ private:
+ vector<value_type> storage;
+ public:
+ Ov * ov;
+ value_type peek (index_type);
+ void poke(index_type, value_type);
+ Ram (Ov *);
+ };
+ /* v Program (memory) bi lahko uporabili metainštrukcije (tisti padding bit) v
+ * vsaki inštrukciji in v metainštrukcijah reprezentirali assembly org (lokacijo).
+ * s tem bi lahko imeli npr. 128 biten program counter in s tem zelo preproste jumpe,
+ * ne bi pa bilo treba narediti 2^128 vektor in posledično binarno datoteko.
+ * Tak način bi bilo verjetno težko implementirati na dejanski strojni opremi,
+ * tukaj pa bi v enem passu čez cel deserializan program memory zaznali te org
+ * metainštrukcije in naredili neko tabelo oziroma prevajalnik program counterja
+ * v lokacijo v vektorju. problem je, da bi se morala prevajalska tabela vsakič znova
+ * regenerirati, ko spreminjamo program memory.
+ * */
+ template<typename value_type, typename index_type> class Program {
+ private:
+ vector<value_type> storage;
+ public:
+ Ov * ov;
+ value_type & peek (index_type addr) {
+ return storage[addr];
+ }
+ void poke (index_type addr, value_type val) {
+ storage[addr] = val;
+ }
+ Program (Ov *);
+ };
+ class Ov {
+ private:
+ public:
+ queue<bool> inbuf;
+ queue<bool> outbuf;
+#define IS2RAS(is) ((is*8-2)/2)
+ class ras { // IS
+ private: // IT
+ public: // REALLY
+ unsigned short int & is; // THIS
+ operator unsigned short int (void) { // HARD
+ return IS2RAS(is); // TO
+ } // DEFINE
+ ras (class Ov * ov) : is(ov->is) {} // A
+ }; // GETTER
+ ras ras{this}; // FUNCTION
+ class rs {
+ private:
+ public:
+ unsigned short int & is;
+ operator unsigned int (void) {
+ return 1 << IS2RAS(is);
+ }
+ rs (class Ov * ov) : is(ov->is) {}
+ };
+ rs rs{this};
+ class ps {
+ private:
+ public:
+ unsigned short int & pas;
+ operator unsigned int (void) {
+ return 1 << pas;
+ }
+ ps (class Ov * ov) : pas(ov->pas) {}
+ };
+ ps ps{this};
+ unsigned short int is;
+ unsigned short int pas;
+ bool io[IOLEN];
+ bool opts[OPTSLEN];
+ unsigned int pc = 0; /* where the program starts --- at zero or where? */
+ Ram<bool, unsigned int> rstor{this};
+ Mmu<bool, unsigned int, class Ram<bool, unsigned int>> ram{rstor};
+ Program<struct instr, unsigned int> pstor{this};
+ Mmu<struct instr, unsigned, class Program<struct instr, unsigned>> pm{pstor};
+ Ov (unsigned short int is = 2, unsigned short int pas = 16)
+ : is(is), pas(pas) {
+ for (int i = 0; i < OPTSLEN; i++)
+ opts[i] = 0;
+ for (int i = 0; i < IOLEN; i++)
+ io[i] = 0;
+ }
+ void step (void);
+ bool out (void);
+ char outc (void);
+ void in (bool);
+ void inc (char);
+ struct instr deserialize (const char *);
+ void deserialize (istream &, unsigned int);
+ void pd (ostream); // print debug
+ };
+}