diff --git a/LICENSE b/LICENSE index d85bc28..2387953 100644 --- a/LICENSE +++ b/LICENSE @@ -213,8 +213,6 @@ To do so, attach the following notices to the program. It is safest to attach th This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Please note that the assembled code that gets output from this program is NOT under the GPL, and can be licensed under any other license at your choice. - This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . diff --git a/Makefile b/Makefile index 2ed6cbf..0d248f1 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ CXX = g++ # Source file SRC = main.cpp # Executable name -EXEC = pluto_isa_asm +EXEC = pluto_isa_emu # Default target all: diff --git a/README.md b/README.md index 418b76b..43008e4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # PlutoISA -This is an assembler for the custom made PlutoISA. +This is an emulator for the custom made PlutoISA. diff --git a/assembler.hpp b/assembler.hpp deleted file mode 100644 index 312e794..0000000 --- a/assembler.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -PlutoISA -Copyright (C) 2024 Patrick_Pluto - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - -Please note that the assembled code that gets output from this program is NOT under the GPL, and can be licensed under any other license at your choice. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -using namespace std; - -void assemble ( vector tokens, uint8_t *rom ) { - int index = 0; - - for ( const auto& part : tokens ) { - if ( part == "GET" ) { - rom[index] = 0x00; - } else if ( part == "LOAD" ) { - rom[index] = 0x01; - } else if ( part == "STORE" ) { - rom[index] = 0x02; - } else if ( part == "ADD" ) { - rom[index] = 0x03; - } else if ( part == "SUB" ) { - rom[index] = 0x04; - } else if ( part == "JMP" ) { - rom[index] = 0x05; - } else if ( part == "JEQ" ) { - rom[index] = 0x06; - } else if ( part == "HIN" ) { - rom[index] = 0x07; - } else { - uint8_t value = stoi(part, nullptr, 16); - rom[index] = value; - } - index += 1; - } -} - diff --git a/cpu.hpp b/cpu.hpp new file mode 100644 index 0000000..6ad2757 --- /dev/null +++ b/cpu.hpp @@ -0,0 +1,89 @@ +/* +PlutoISA +Copyright (C) 2024 Patrick_Pluto + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "tpu.hpp" + +using namespace std; + +uint8_t *registers = ( uint8_t * ) malloc ( 8 * sizeof ( uint8_t ) ); +uint8_t *memory = ( uint8_t * ) malloc ( 128 * sizeof ( uint8_t ) ); +uint8_t *pointer = ( uint8_t * ) malloc ( sizeof ( uint8_t ) ); + +void cpuInstructions ( uint8_t *rom ) { + cout << static_cast ( rom[*pointer] ) << endl; + cout << static_cast ( *pointer ) << endl; + switch ( rom[*pointer] ) { + case 0x00: // GET + registers[rom[*pointer + 1]] = rom[*pointer + 2]; + *pointer += 3; + break; + case 0x01: // LOAD + registers[rom[*pointer + 1]] = memory[rom[*pointer + 2]]; + *pointer += 3; + break; + case 0x02: // STORE + memory[rom[*pointer + 2]] = registers[rom[*pointer + 1]]; + *pointer += 3; + break; + case 0x03: // ADD + registers[rom[*pointer + 1]] = registers[rom[*pointer + 2]] + registers[rom[*pointer + 3]]; + *pointer += 4; + break; + case 0x04: // SUB + registers[rom[*pointer + 1]] = registers[rom[*pointer + 2]] - registers[rom[*pointer + 3]]; + *pointer += 4; + break; + case 0x05: // JMP + *pointer = rom[*pointer + 1]; + break; + case 0x06: // JEQ + if ( rom[*pointer + 2] == registers[rom[*pointer + 3]] ) { + *pointer = rom[*pointer + 1]; + } + break; + case 0x07: // HIN + cin >> registers[rom[*pointer + 1]]; + *pointer += 2; + break; + default: + cout << "Invalid Instruction, quitting." << endl; + exit ( 1 ); + } +} + +void cpuEmulation ( uint8_t *rom ) { + const int targetFPS = 20; + const int frameDuration = 1000 / targetFPS; + *pointer = 0; + + while ( true ) { + auto start = chrono::high_resolution_clock::now(); + + cpuInstructions ( rom ); + textProcessing ( registers[7] ); + + auto end = chrono::high_resolution_clock::now(); + chrono::duration elapsed = end - start; + + if ( elapsed.count() < frameDuration ) { + this_thread::sleep_for ( chrono::milliseconds ( frameDuration ) - elapsed ); + } + } +} + diff --git a/main.cpp b/main.cpp index 6931a68..6170dcb 100644 --- a/main.cpp +++ b/main.cpp @@ -4,15 +4,12 @@ Copyright (C) 2024 Patrick_Pluto This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. -Please note that the assembled code that gets output from this program is NOT under the GPL, and can be licensed under any other license at your choice. - This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include "assembler.hpp" -#include "split.hpp" +#include "cpu.hpp" using namespace std; @@ -20,14 +17,11 @@ int main ( int argc, char *argv[] ) { const char *filename = argv[1]; const int rom_size = 256; - ifstream file(filename); // Open the file - string asmCode((istreambuf_iterator(file)), istreambuf_iterator()); + ifstream file ( filename, ios::binary ); uint8_t *rom = ( uint8_t * ) malloc ( rom_size * sizeof ( uint8_t ) ); - assemble(splitAsm(asmCode), rom); + file.read ( reinterpret_cast ( rom ), rom_size ); - ofstream outFile(argv[2], ios::binary);; - outFile.write(reinterpret_cast(rom), rom_size * sizeof ( uint8_t )); + cpuEmulation ( rom ); } - diff --git a/split.hpp b/split.hpp deleted file mode 100644 index 23cc311..0000000 --- a/split.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* -PlutoISA -Copyright (C) 2024 Patrick_Pluto - -This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - -Please note that the assembled code that gets output from this program is NOT under the GPL, and can be licensed under any other license at your choice. - -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ - -#pragma once - -#include -#include -#include -#include - -using namespace std; - -vector splitAsm(string asmSource) -{ - for (char& ch : asmSource) { - if (ch == '\n') { - ch = ' '; - } - } - - stringstream ss(asmSource); - - string token; - vector tokens; - char delimiter = ' '; - - while (getline(ss, token, delimiter)) { - tokens.push_back(token); - } - - return tokens; -} - diff --git a/tpu.hpp b/tpu.hpp new file mode 100644 index 0000000..35b1edf --- /dev/null +++ b/tpu.hpp @@ -0,0 +1,139 @@ +/* +PlutoISA +Copyright (C) 2024 Patrick_Pluto + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see . +*/ + +#pragma once + +#include +#include +#include + +using namespace std; + +void textProcessing ( uint8_t ch ) { + switch ( ch ) { + case 0x01: + cout << "0"; + break; + case 0x02: + cout << "1"; + break; + case 0x03: + cout << "2"; + break; + case 0x04: + cout << "3"; + break; + case 0x05: + cout << "4"; + break; + case 0x06: + cout << "5"; + break; + case 0x07: + cout << "6"; + break; + case 0x08: + cout << "7"; + break; + case 0x09: + cout << "8"; + break; + case 0x0A: + cout << "9"; + break; + case 0x0B: + cout << "A"; + break; + case 0x0C: + cout << "B"; + break; + case 0x0D: + cout << "C"; + break; + case 0x0E: + cout << "D"; + break; + case 0x0F: + cout << "E"; + break; + case 0x10: + cout << "F"; + break; + case 0x11: + cout << "G"; + break; + case 0x12: + cout << "H"; + break; + case 0x13: + cout << "I"; + break; + case 0x14: + cout << "J"; + break; + case 0x15: + cout << "K"; + break; + case 0x16: + cout << "L"; + break; + case 0x17: + cout << "M"; + break; + case 0x18: + cout << "N"; + break; + case 0x19: + cout << "O"; + break; + case 0x1A: + cout << "P"; + break; + case 0x1B: + cout << "Q"; + break; + case 0x1C: + cout << "R"; + break; + case 0x1D: + cout << "S"; + break; + case 0x1E: + cout << "T"; + break; + case 0x1F: + cout << "U"; + break; + case 0x20: + cout << "V"; + break; + case 0x21: + cout << "W"; + break; + case 0x22: + cout << "X"; + break; + case 0x23: + cout << "Y"; + break; + case 0x24: + cout << "Z"; + break; + case 0x25: + cout << " "; + break; + case 0x26: + cout << endl; + break; + default: + break; + } +}