summaryrefslogblamecommitdiffstats
path: root/main.hpp
blob: 58a73376500e95c8414778ba0615eb633400274b (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11

                 
                 



                                                                                               



                                                                                             
















                                                                                             
                                                                                                       































                                                                                        
                       
                                                   







                                                                                             
                                                                                       







                                                                                              
                       
                                                   






















































                                                                                                     
                                                                        









                                                                 
                                                                                     
                                                                   

                                                                          

          
#include <vector>
#include <queue>
#include <string>
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
		BUFINCLR,	// clears whatever is in the input buffer
		BUFOUTCLR,	// clears whatever is in the output 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, pri COPY je že
	};	// 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:
		public:
			vector<value_type> storage;
			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 vektorja in posledično binarne datoteke.
	 * 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:
		public:
			vector<value_type> storage;
			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) { // add bound checks
				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 [sizeof(struct instr)]);
			void deserialize (istream &, unsigned int);
			string serialize (struct instr * i, unsigned int);
			void pd (ostream &);
	};
}