// This file is part of uVM. // // uVM 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. // // uVM 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 uVM. If not, see . // // #include #include "../include/cpu.h" int main(int argc, char* argv[]) { // Allocate an 800 word stack size to the CPU on initialization CPU c(800); // XXX: // Until I find a unit testing framework these vectors of bytecode will // serve as (terrible) tests. // Answer: 3 std::vector code_iadd { CPU::opcode::IPUSH, 0x1, CPU::opcode::IPUSH, 0x2, CPU::opcode::IADD, CPU::opcode::PRINT, CPU::opcode::HALT }; // Answer: 1 std::vector code_isub { CPU::opcode::IPUSH, 0x1, CPU::opcode::IPUSH, 0x2, CPU::opcode::ISUB, CPU::opcode::PRINT, CPU::opcode::HALT }; // Answer: 16 std::vector code_imul { CPU::opcode::IPUSH, 0x4, CPU::opcode::IPUSH, 0x4, CPU::opcode::IMUL, CPU::opcode::PRINT, CPU::opcode::HALT, }; // Answer: 1 std::vector code_idiv { CPU::opcode::IPUSH, 0x4, CPU::opcode::IPUSH, 0x4, CPU::opcode::IDIV, CPU::opcode::PRINT, CPU::opcode::HALT, }; // Answer: 3 % 4 = 3 (0 remainder 3) std::vector code_irem { CPU::opcode::IPUSH, 0x4, CPU::opcode::IPUSH, 0x3, CPU::opcode::IREM, CPU::opcode::PRINT, CPU::opcode::HALT, }; // Answer: 8 // This tests unconditional jumping. If the JMP instruction fails the code will fail to // answer correctly. std::vector code_jmp { CPU::opcode::IPUSH, 0x4, CPU::opcode::IPUSH, 0x4, CPU::opcode::JMP, 0x7, // JMP to 0x7 - the 8th line of code in memory CPU::opcode::ISUB, CPU::opcode::IADD, CPU::opcode::PRINT, CPU::opcode::HALT, }; // Answer: 10 // This tests the use of conditional jumps to implement a simple while loop. std::vector code_jc { CPU::opcode::IPUSH, 0xA, // Limit CPU::opcode::ISAVE1, // Store the limit CPU::opcode::IPUSH, 0x0, // Counter CPU::opcode::ISAVE2, // Store the counter CPU::opcode::IPUSH, 0x0, // Accumulator (for our print) CPU::opcode::ISAVE0, // Store the accumulator CPU::opcode::ILOAD1, // Load the limit CPU::opcode::ILOAD2, // Load the counter CPU::opcode::CMP, // Compare limit to counter CPU::opcode::JC, 0x1A, // Jump to PRINT if true CPU::opcode::ILOAD0, // Load the accumulator CPU::opcode::IPUSH, 0x1, // Push 1 onto the stack to be added to the accumulator CPU::opcode::IADD, // Add 1 to the accumulator CPU::opcode::ISAVE0, // Take the top of the stack, store it in t0 and pop it off CPU::opcode::ILOAD2, // Reload the counter CPU::opcode::IPUSH, 0x1, // Push 1 onto the stack to be added to the counter CPU::opcode::IADD, // Add one to the accumulator CPU::opcode::ISAVE2, // Store the counter CPU::opcode::JMP, 0x9, // Jump to the CMP statement CPU::opcode::ILOAD0, // Load the accumulator for PRINT CPU::opcode::PRINT, CPU::opcode::HALT, }; c.load(code_jc); c.run(); return 0; }