From 89e202f49b9857dcd3627fbc4e0262125d729bbc Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 04:09:39 +0200 Subject: adding all instructions and displays --- ue3/mycpu/test/memory1 | 1 + ue3/mycpu/test/program1 | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 ue3/mycpu/test/memory1 create mode 100644 ue3/mycpu/test/program1 (limited to 'ue3/mycpu/test') diff --git a/ue3/mycpu/test/memory1 b/ue3/mycpu/test/memory1 new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/ue3/mycpu/test/memory1 @@ -0,0 +1 @@ +20 diff --git a/ue3/mycpu/test/program1 b/ue3/mycpu/test/program1 new file mode 100644 index 0000000..ae5e9d2 --- /dev/null +++ b/ue3/mycpu/test/program1 @@ -0,0 +1,13 @@ +# set R2 = 10 +LOAD R2, R1 + +# start of loop +label Loop: +inc R3 +sub R4, R3, R2 +test R4 +jumpz EndLoop +write WDEZ, R3 +jumpa Loop + +label EndLoop: -- cgit v1.3 From 3c6f886d5a8bfd36c796b963d6e3178ad9577742 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 16:55:17 +0200 Subject: * added documentation (no more TODOs) * added testsuite + testcase * used copyctor instead of assign operator more often --- .hgignore | 1 + ue3/mycpu/ccpu.cpp | 3 ++- ue3/mycpu/ccpu.h | 6 +++-- ue3/mycpu/cdisplay.h | 9 ++++--- ue3/mycpu/cinstruction.cpp | 4 ++-- ue3/mycpu/cinstruction.h | 6 ++--- ue3/mycpu/cprogram.cpp | 6 ++--- ue3/mycpu/cprogram.h | 5 ++-- ue3/mycpu/displays.h | 8 ++++--- ue3/mycpu/instructions.cpp | 6 ++--- ue3/mycpu/instructions.h | 57 ++++++++++++++++++++++++++++++++------------ ue3/mycpu/mycpu.cpp | 25 ++++++++++++------- ue3/mycpu/test/test.sh | 40 +++++++++++++++++++++++++++++++ ue3/mycpu/test/test1_memory | 1 + ue3/mycpu/test/test1_output | 19 +++++++++++++++ ue3/mycpu/test/test1_program | 13 ++++++++++ 16 files changed, 161 insertions(+), 48 deletions(-) create mode 100755 ue3/mycpu/test/test.sh create mode 100644 ue3/mycpu/test/test1_memory create mode 100644 ue3/mycpu/test/test1_output create mode 100644 ue3/mycpu/test/test1_program (limited to 'ue3/mycpu/test') diff --git a/.hgignore b/.hgignore index 2dd5fef..b96a5d0 100644 --- a/.hgignore +++ b/.hgignore @@ -5,6 +5,7 @@ syntax: glob *.so *.swp *~ +tmpfile ue1/imgsynth/imgsynth ue2/imgsynth/test/*_out* ue2/imgsynth2/imgsynth2 diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp index 16209e2..af86200 100644 --- a/ue3/mycpu/ccpu.cpp +++ b/ue3/mycpu/ccpu.cpp @@ -1,7 +1,8 @@ /** * @module ccpu * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CPU implementation. Used as a container for memory and instructions. + * Implements an run method to execute the program (= the instructions). * @date 10.05.2009 */ diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h index 01c897f..05b5c03 100644 --- a/ue3/mycpu/ccpu.h +++ b/ue3/mycpu/ccpu.h @@ -1,7 +1,8 @@ /** * @module ccpu * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CPU implementation. Used as a container for memory and instructions. + * Implements a run method to execute the program (= the instructions). * @date 10.05.2009 */ @@ -18,7 +19,8 @@ /** * @class CCPU * - * TODO + * CPU implementation. Used as a container for memory and instructions. + * Implements a run method to execute the program (= the instructions). */ class CCPU { diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h index ed9b84d..c2a84a6 100644 --- a/ue3/mycpu/cdisplay.h +++ b/ue3/mycpu/cdisplay.h @@ -1,7 +1,7 @@ /** * @module cdisplay * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Abstract class for displays * @date 10.05.2009 */ @@ -11,7 +11,7 @@ /** * @class CDisplay * - * TODO + * Abstract class for displays */ class CDisplay { @@ -26,9 +26,8 @@ class CDisplay * @conditions none */ CDisplay(std::string name) - { - m_name = name; - } + : m_name(name) + {} /** * @method ~CDisplay diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp index 57acd5f..5c1bd5c 100644 --- a/ue3/mycpu/cinstruction.cpp +++ b/ue3/mycpu/cinstruction.cpp @@ -1,8 +1,8 @@ /** * @module cinstruction * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO - * @date 10.05.2009 + * @brief Abstract class for displays + * @date 13.05.2009 */ #include diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h index 40e9ddc..942d8cf 100644 --- a/ue3/mycpu/cinstruction.h +++ b/ue3/mycpu/cinstruction.h @@ -1,8 +1,8 @@ /** * @module cinstruction * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO - * @date 10.05.2009 + * @brief Abstract class for displays + * @date 13.05.2009 */ #ifndef CINSTRUCTION_H @@ -17,7 +17,7 @@ class CCPU; /** * @class CInstruction * - * TODO + * Abstract class for displays */ class CInstruction { diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index f904bce..1a450f5 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -1,7 +1,7 @@ /** * @module cprogram * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CProgram extends std::vector and adds a method for parsing programfile * @date 12.05.2009 */ @@ -75,7 +75,7 @@ void CProgram::compile(std::istream& in) /* get instruction name */ size_t pos = line.find_first_of(' '); - string instrname = line.substr(0, pos); + string instrname(line.substr(0, pos)); /* search and create instruction */ CInstruction *instrptr = NULL; @@ -112,7 +112,7 @@ void CProgram::compile(std::istream& in) { if (instrparams.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); - string label = instrparams.front(); + string label(instrparams.front()); if (label.length() < 2 || label[ label.length() - 1] != ':') throw runtime_error("Label has invalid syntax"); m_labels[ label.substr(0, label.length() - 1) ] = size(); diff --git a/ue3/mycpu/cprogram.h b/ue3/mycpu/cprogram.h index c145832..27e7647 100644 --- a/ue3/mycpu/cprogram.h +++ b/ue3/mycpu/cprogram.h @@ -1,7 +1,7 @@ /** * @module cprogram * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CProgram extends std::vector and adds a method for parsing programfile * @date 10.05.2009 */ @@ -16,7 +16,8 @@ /** * @class CProgram * - * TODO + * CProgram extends std::vector and adds a method for parsing + * programfile. This adds instances of CInstruction to CProgram itself. */ class CProgram : public std::vector diff --git a/ue3/mycpu/displays.h b/ue3/mycpu/displays.h index f7adbdb..87b9408 100644 --- a/ue3/mycpu/displays.h +++ b/ue3/mycpu/displays.h @@ -1,7 +1,7 @@ /** * @module displays * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Implementations of CDisplay * @date 10.05.2009 */ @@ -14,7 +14,8 @@ /** * @class CDisplayWDEZ * - * TODO + * Implementation of CDisplay + * Prints CDat to stdout as decimal */ class CDisplayWDEZ : public CDisplay @@ -35,7 +36,8 @@ class CDisplayWDEZ /** * @class CDisplayWHEX * - * TODO + * Implementation of CDisplay + * Prints CDat to stdout as decimal */ class CDisplayWHEX : public CDisplay diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp index a6ac611..c2ce096 100644 --- a/ue3/mycpu/instructions.cpp +++ b/ue3/mycpu/instructions.cpp @@ -1,7 +1,7 @@ /** * @module instructions * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Implementations of CInstruction * @date 10.05.2009 */ @@ -162,7 +162,7 @@ void CInstructionLoad::execute(CCPU *cpu) { checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); - CDat val = cpu->getRegisters()[ m_regidx2 ]; + CDat val(cpu->getRegisters()[ m_regidx2 ]); cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ]; } @@ -184,7 +184,7 @@ void CInstructionStore::execute(CCPU *cpu) { checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); - CDat val = cpu->getRegisters()[ m_regidx2 ]; + CDat val(cpu->getRegisters()[ m_regidx2 ]); (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ]; } diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h index 0e4d99c..a52b991 100644 --- a/ue3/mycpu/instructions.h +++ b/ue3/mycpu/instructions.h @@ -1,7 +1,7 @@ /** * @module instructions * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Implementations of CInstruction * @date 10.05.2009 */ @@ -14,7 +14,9 @@ /** * @class CInstructionInc * - * TODO + * Implementation of assembler command "inc" + * Syntax: inc R1 + * (R1++) */ class CInstructionInc : public CInstruction @@ -41,7 +43,9 @@ class CInstructionInc /** * @class CInstructionDec * - * TODO + * Implementation of assembler command "dec" + * Syntax: dec R1 + * (R1--) */ class CInstructionDec : public CInstruction @@ -68,7 +72,9 @@ class CInstructionDec /** * @class CInstructionAdd * - * TODO + * Implementation of assembler command "add" + * Syntax: add R1, R2, R3 + * (R1 = R2 + R3) */ class CInstructionAdd : public CInstruction @@ -97,7 +103,9 @@ class CInstructionAdd /** * @class CInstructionSub * - * TODO + * Implementation of assembler command "sub" + * Syntax: sub R1, R2, R3 + * (R1 = R2 - R3) */ class CInstructionSub : public CInstruction @@ -126,7 +134,9 @@ class CInstructionSub /** * @class CInstructionMul * - * TODO + * Implementation of assembler command "mul" + * Syntax: mul R1, R2, R3 + * (R1 = R2 * R3) */ class CInstructionMul : public CInstruction @@ -155,7 +165,9 @@ class CInstructionMul /** * @class CInstructionDiv * - * TODO + * Implementation of assembler command "div" + * Syntax: div R1, R2, R3 + * (R1 = R2 / R3) */ class CInstructionDiv : public CInstruction @@ -184,7 +196,9 @@ class CInstructionDiv /** * @class CInstructionLoad * - * TODO + * Implementation of assembler command "load" + * Syntax: load R1, R2 + * (R1 = memory[R2]) */ class CInstructionLoad : public CInstruction @@ -212,7 +226,9 @@ class CInstructionLoad /** * @class CInstructionStore * - * TODO + * Implementation of assembler command "store" + * Syntax: store R1, R2 + * (memory[R2] = R1) */ class CInstructionStore : public CInstruction @@ -240,7 +256,9 @@ class CInstructionStore /** * @class CInstructionTest * - * TODO + * Implementation of assembler command "test" + * Syntax: test R1 + * (R1 == 0: zeroflag: true, R1 < 0: signflag: true) */ class CInstructionTest : public CInstruction @@ -267,7 +285,8 @@ class CInstructionTest /** * @class CInstructionLabel * - * TODO + * Implementation of assembler command "label" + * Syntax: label name: */ class CInstructionLabel : public CInstruction @@ -294,7 +313,9 @@ class CInstructionLabel /** * @class CInstructionJumpA * - * TODO + * Implementation of assembler command "jumpa" + * Syntax: jumpa labelname + * (jump to labelname) */ class CInstructionJumpA : public CInstruction @@ -321,7 +342,9 @@ class CInstructionJumpA /** * @class CInstructionJumpZ * - * TODO + * Implementation of assembler command "jumpz" + * Syntax: jumpz labelname + * (jump to labelname if zeroflag) */ class CInstructionJumpZ : public CInstruction @@ -348,7 +371,9 @@ class CInstructionJumpZ /** * @class CInstructionJumpS * - * TODO + * Implementation of assembler command "jumps" + * Syntax: jumps labelname + * (jump to labelname if signflag) */ class CInstructionJumpS : public CInstruction @@ -375,7 +400,9 @@ class CInstructionJumpS /** * @class CInstructionWrite * - * TODO + * Implementation of assembler command "write" + * Syntax: write DEV, R1 + * (write R1 to DEV, which is a name of a display) */ class CInstructionWrite : public CInstruction diff --git a/ue3/mycpu/mycpu.cpp b/ue3/mycpu/mycpu.cpp index 08861a4..b25e721 100644 --- a/ue3/mycpu/mycpu.cpp +++ b/ue3/mycpu/mycpu.cpp @@ -1,10 +1,14 @@ /** * @module mycpu * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO - * @date 11.05.2009 + * @brief mycpu executes a programfile (in simple assembler) by parsing the + * programfile first. This creates a vector of instructions, which will + * be executed in linear order (except jumps) afterwards. In order to + * initialize the memory of the cpu before execution an optional + * memoryfile can be passed as commandline option. + * @date 13.05.2009 * @par Exercise - * 3 + * 4 */ #include @@ -29,7 +33,11 @@ namespace po = boost::program_options; * @exception none * @conditions none * - * TODO + * parse commandline options, create and initialize memory, + * create cprogram instance, which parses the programfile and + * execute CCPU::run() + * On error print error message to stderr. + * Unknown commandline options will print a usage message. */ int main(int argc, char* argv[]) { @@ -88,7 +96,7 @@ int main(int argc, char* argv[]) } #if DEBUG - memory.dump(cout); + memory.dump(cerr); #endif } @@ -116,7 +124,7 @@ int main(int argc, char* argv[]) } #if DEBUG - program.dump(cout); + program.dump(cerr); #endif @@ -128,7 +136,7 @@ int main(int argc, char* argv[]) cpu.setProgram(&program); cpu.run(); #if DEBUG - //cpu.dumpRegisters(cout); + //cpu.dumpRegisters(cerr); #endif } catch(runtime_error& ex) @@ -136,8 +144,7 @@ int main(int argc, char* argv[]) cerr << me << ": Error while executing program:" << endl << " " << ex.what() << endl; #if DEBUG - memory.dump(cout); - //cpu.dumpRegisters(cout); + memory.dump(cerr); #endif return 1; } diff --git a/ue3/mycpu/test/test.sh b/ue3/mycpu/test/test.sh new file mode 100755 index 0000000..ad2ae4d --- /dev/null +++ b/ue3/mycpu/test/test.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +binary="./mycpu" +tmpfile="test/tmpfile" +inputs=( $(ls test/* | grep _program | sort -n) ) + +for input in ${inputs[@]} +do + echo "Testing $input ..." + + programfile="$input" + args="-c $programfile" + memoryfile="${input/_program/_memory}" + reffile="${input/_program/_output}" + if [ -e "$memoryfile" ] + then + args+=" -m $memoryfile" + fi + + if [ ! -e "$reffile" ] + then + echo " ERROR: reference file $reffile doesn't exist" + exit 1 + fi + + rm -rf "$tmpfile" + echo " Executing $binary $args ..." + $binary $args > $tmpfile + + md5_1=$(md5sum < "$reffile") + md5_2=$(md5sum < "$tmpfile") + if [ "$md5_1" != "$md5_2" ] + then + echo " ERROR: output and $reffile differ" + diff -Nau $reffile $tmpfile + exit 1 + else + echo " SUCCESS" + fi +done diff --git a/ue3/mycpu/test/test1_memory b/ue3/mycpu/test/test1_memory new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/ue3/mycpu/test/test1_memory @@ -0,0 +1 @@ +20 diff --git a/ue3/mycpu/test/test1_output b/ue3/mycpu/test/test1_output new file mode 100644 index 0000000..ac30dc2 --- /dev/null +++ b/ue3/mycpu/test/test1_output @@ -0,0 +1,19 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 diff --git a/ue3/mycpu/test/test1_program b/ue3/mycpu/test/test1_program new file mode 100644 index 0000000..ae5e9d2 --- /dev/null +++ b/ue3/mycpu/test/test1_program @@ -0,0 +1,13 @@ +# set R2 = 10 +LOAD R2, R1 + +# start of loop +label Loop: +inc R3 +sub R4, R3, R2 +test R4 +jumpz EndLoop +write WDEZ, R3 +jumpa Loop + +label EndLoop: -- cgit v1.3 From ad6ca84f6e93f983de926ae71f31f42325986f61 Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 14 May 2009 18:15:28 +0200 Subject: * making cdisplay a template * adding some asserts * adding classdiagramm and protokoll * fixing protokoll.pdf in ue1 --- ue1/protokoll.pdf | Bin 283846 -> 283840 bytes ue3/mycpu/cdisplay.h | 26 +++++--- ue3/mycpu/cinstruction.cpp | 2 + ue3/mycpu/instructions.cpp | 34 +++++++++++ ue3/mycpu/test/memory1 | 1 - ue3/mycpu/test/program1 | 13 ---- ue3/mycpu/test/test.sh | 4 +- ue3/protokoll.pdf | Bin 0 -> 405263 bytes ue3/protokoll/mycpu.png | Bin 0 -> 111899 bytes ue3/protokoll/mycpu.vpp | Bin 0 -> 129025 bytes ue3/protokoll/protokoll.tex | 144 +++++++++++++++++++++++++++++++++++++++----- 11 files changed, 185 insertions(+), 39 deletions(-) delete mode 100644 ue3/mycpu/test/memory1 delete mode 100644 ue3/mycpu/test/program1 create mode 100644 ue3/protokoll.pdf create mode 100644 ue3/protokoll/mycpu.png create mode 100644 ue3/protokoll/mycpu.vpp (limited to 'ue3/mycpu/test') diff --git a/ue1/protokoll.pdf b/ue1/protokoll.pdf index d1a72ac..3682945 100644 Binary files a/ue1/protokoll.pdf and b/ue1/protokoll.pdf differ diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h index 0a0a723..1523f68 100644 --- a/ue3/mycpu/cdisplay.h +++ b/ue3/mycpu/cdisplay.h @@ -1,7 +1,7 @@ /** * @module cdisplay * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief Abstract class for displays + * @brief Abstract template class for displays * @date 10.05.2009 */ @@ -9,15 +9,16 @@ #define CDISPLAY_H 1 /** - * @class CDisplay + * @class CDisplayT * - * Abstract class for displays + * Abstract template class for displays */ -class CDisplay +template +class CDisplayT { public: /** - * @method CDisplay + * @method CDisplayT * @brief Default ctor * @param name name of display * @return - @@ -25,12 +26,12 @@ class CDisplay * @exception none * @conditions none */ - CDisplay(std::string name) + CDisplayT(std::string name) : m_name(name) {} /** - * @method ~CDisplay + * @method ~CDisplayT * @brief Default dtor * @param - * @return - @@ -38,7 +39,7 @@ class CDisplay * @exception none * @conditions none */ - virtual ~CDisplay() + virtual ~CDisplayT() {} /** @@ -64,7 +65,7 @@ class CDisplay * @exception none * @conditions none */ - virtual void display(const CDat &value) = 0; + virtual void display(const T &value) = 0; protected: /* members */ @@ -72,6 +73,13 @@ class CDisplay std::string m_name; }; +/** + * @class CDisplay + * + * Memory definition for CCPU + */ +typedef CDisplayT CDisplay; + #endif /* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp index 5c1bd5c..a766015 100644 --- a/ue3/mycpu/cinstruction.cpp +++ b/ue3/mycpu/cinstruction.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "cinstruction.h" #include "ccpu.h" @@ -35,6 +36,7 @@ const unsigned CInstruction::parseRegister(const std::string& str) inline void CInstruction::checkRegister(CCPU *cpu, const unsigned regidx) { + assert(cpu != NULL); if (regidx >= cpu->getRegisterCount()) { stringstream sstr; diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp index c2ce096..ef9e944 100644 --- a/ue3/mycpu/instructions.cpp +++ b/ue3/mycpu/instructions.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "instructions.h" using namespace std; @@ -22,6 +23,8 @@ void CInstructionInc::compile(std::list& params) void CInstructionInc::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); cpu->getRegisters()[ m_regidx1 ]++; } @@ -40,6 +43,8 @@ void CInstructionDec::compile(std::list& params) void CInstructionDec::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); cpu->getRegisters()[ m_regidx1 ]--; } @@ -62,6 +67,8 @@ void CInstructionAdd::compile(std::list& params) void CInstructionAdd::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); @@ -87,6 +94,8 @@ void CInstructionSub::compile(std::list& params) void CInstructionSub::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); @@ -137,6 +146,8 @@ void CInstructionDiv::compile(std::list& params) void CInstructionDiv::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); @@ -160,6 +171,9 @@ void CInstructionLoad::compile(std::list& params) void CInstructionLoad::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); + assert(cpu->getMemory() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); CDat val(cpu->getRegisters()[ m_regidx2 ]); @@ -182,6 +196,9 @@ void CInstructionStore::compile(std::list& params) void CInstructionStore::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); + assert(cpu->getMemory() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); CDat val(cpu->getRegisters()[ m_regidx2 ]); @@ -202,6 +219,8 @@ void CInstructionTest::compile(std::list& params) void CInstructionTest::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); if (cpu->getRegisters()[ m_regidx1 ] == CDat(0)) cpu->setFlagZero(true); @@ -223,6 +242,9 @@ void CInstructionJumpA::compile(std::list& params) void CInstructionJumpA::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); + assert(cpu->getProgram() != NULL); if (m_addr.empty()) throw runtime_error("Empty address"); cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); @@ -242,8 +264,13 @@ void CInstructionJumpZ::compile(std::list& params) void CInstructionJumpZ::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); + assert(cpu->getProgram() != NULL); if (!cpu->getFlagZero()) return; + if (m_addr.empty()) + throw runtime_error("Empty address"); cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } @@ -261,8 +288,13 @@ void CInstructionJumpS::compile(std::list& params) void CInstructionJumpS::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); + assert(cpu->getProgram() != NULL); if (!cpu->getFlagSign()) return; + if (m_addr.empty()) + throw runtime_error("Empty address"); cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } @@ -282,6 +314,8 @@ void CInstructionWrite::compile(std::list& params) void CInstructionWrite::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); if (m_dev.empty()) throw runtime_error("Empty device"); diff --git a/ue3/mycpu/test/memory1 b/ue3/mycpu/test/memory1 deleted file mode 100644 index 209e3ef..0000000 --- a/ue3/mycpu/test/memory1 +++ /dev/null @@ -1 +0,0 @@ -20 diff --git a/ue3/mycpu/test/program1 b/ue3/mycpu/test/program1 deleted file mode 100644 index ae5e9d2..0000000 --- a/ue3/mycpu/test/program1 +++ /dev/null @@ -1,13 +0,0 @@ -# set R2 = 10 -LOAD R2, R1 - -# start of loop -label Loop: -inc R3 -sub R4, R3, R2 -test R4 -jumpz EndLoop -write WDEZ, R3 -jumpa Loop - -label EndLoop: diff --git a/ue3/mycpu/test/test.sh b/ue3/mycpu/test/test.sh index ad2ae4d..ff1076c 100755 --- a/ue3/mycpu/test/test.sh +++ b/ue3/mycpu/test/test.sh @@ -32,9 +32,11 @@ do if [ "$md5_1" != "$md5_2" ] then echo " ERROR: output and $reffile differ" - diff -Nau $reffile $tmpfile + diff -Naur "$reffile" "$tmpfile" + rm -rf "$tmpfile" exit 1 else echo " SUCCESS" fi + rm -rf "$tmpfile" done diff --git a/ue3/protokoll.pdf b/ue3/protokoll.pdf new file mode 100644 index 0000000..3d8c5eb Binary files /dev/null and b/ue3/protokoll.pdf differ diff --git a/ue3/protokoll/mycpu.png b/ue3/protokoll/mycpu.png new file mode 100644 index 0000000..570d50a Binary files /dev/null and b/ue3/protokoll/mycpu.png differ diff --git a/ue3/protokoll/mycpu.vpp b/ue3/protokoll/mycpu.vpp new file mode 100644 index 0000000..1f4b264 Binary files /dev/null and b/ue3/protokoll/mycpu.vpp differ diff --git a/ue3/protokoll/protokoll.tex b/ue3/protokoll/protokoll.tex index 8b413e7..dd53735 100644 --- a/ue3/protokoll/protokoll.tex +++ b/ue3/protokoll/protokoll.tex @@ -38,44 +38,110 @@ Manuel Mausz, \matrnr 0728348\\ Abbildung~\ref{fig:classdiagram1} zeigt das Klassendiagramm der Aufgabe. -TODO +Als Datentyp für Register und Hauptspeicher der CPU wurde ein allgemeines +Template implementiert, welche andere Datentypen oder Klasse umhüllen kann. +Zudem wurden die gängigsten Operatoren definiert, die man sich von einem +Datentyp erwarten kann. Gemäß der Aufgabenstellung wurde der Datentyp CDat als +umhüllter Integer-Wert definiert. + +Der Hauptspeicher der CPU wurde als abgeleitetes Template \mbox{CVectorMem} des +Templates \mbox{std::vector} implementiert, damit dieses um die +Methode \mbox{initialize} und \mbox{dump} erweitert werden konnten. Erstere +dient zur Initialisierung des Hauptspeichers bzw. Füllung des Vectors, +zweiteres zur Debugausgabe. Der Datentyp CMem wurde via typedef als +\mbox{CVectorMem} mit dem Templateargument CDat definiert. Somit enthält der +Hauptspeicher nur Elemente des Typs CDat. + +Die geforderten zwei Display-Klassen \mbox{CDisplayWDEZ} und +\mbox{CDisplayWHEX} wurden von der abstrakten Klasse CDisplay abgeleitet, welche +selbst als Template CDisplayT mit dem Templateargument CDat definiert ist. + +Der Programmspeicher \mbox{CProgram} wurde vom Template +\mbox{std::vector} abgeleitet. Somit ist diese Klasse, ähnlich +wie CMem, selbst ein Vector. Zudem wurden weitere Methoden hinzugefügt. Die +Methode \mbox{compile} dient zum Kompilieren bzw. Umwandeln des +Syntax der Programmdatei in Instanzen der Klasse CInstruction, die später von +der CPU ausgeführt werden. Zur Umwandlung werden bei der Instantiierung von +\mbox{CProgram} sämtliche erlaubten Instruktionen (also Instanzen von +\mbox{CInstruction}) in ein \mbox{std::set} eingefügt. Im Zuge der Methode +\mbox{compile} wird durch Iterieren die jeweilige Instruktion gesucht und durch +Anwendung des Designpattern \textit{Factory method pattern} die Instruktion +dupliziert und in \mbox{CProgram} gespeichert. Labels werden zwecks Effizienz in +einer \mbox{std::map} festgehalten. + +Die jeweiligen unterstützen Instruktionen wurden wie gefordert von der Klasse +\mbox{CInstruction} abgeleitet. \mbox{CInstruction} fordert die +Implementierung einer Methode \mbox{compile}, die während des parsens der +Programmdatei von \mbox{CProgram} aufgerufen werden, als auch eine Methode +\mbox{execute}, die im Zuge der Ausführung des Programms von CCPU +aufgerufen werden. + +Die eigentliche CPU wird durch die Klasse \mbox{CCPU} implementiert. Diese +dient hauptsächlich als Container für die einzelnen, notwendigen Teile +(Hauptspeicher, Programmspeicher, Displays, ...) und besitzt daher entsprechend +viele get- und set-Funktionen. Die Methode \mbox{run} dient zur Ausführung des +Programms und ist eine Schleife, die über die Instruktionen iteriert und die +Methode \mbox{execute} aufruft. %================================================================== -\begin{figure}[htb] - \begin{center} - \epsfxsize=0.9\textwidth\epsfbox{mycpu.png} - \end{center} - \caption{Klassendiagramm 1} - \label{fig:classdiagram1} -\end{figure} +\begin{center} + \begin{figure}[htb] + \epsfxsize=1.6\textwidth\epsfbox{mycpu.png} + \caption{Klassendiagramm 1} + \label{fig:classdiagram1} + \end{figure} +\end{center} %================================================================== \subsection{Verwaltung der Ressourcen} -TODO +Alle Objekte, die im Konstruktor alloziert werden, werden im Destruktor wieder +freigegeben. Die Objekte, die über die \textit{Factory method pattern} +alloziert werden, werden im Zuge des Destruktor des Vectors bzw. +von \mbox{CProgram} wieder freigegeben. \subsection{Fehlerbehandlung} -TODO +Es wurden keine eigenen Exceptions eingeführt. Statt dessen werden Exceptions +meist in Exceptions des Typs \mbox{std::runtime\_error} umgewandelt. Da die +Hierarchie nicht sehr tief ist, fängt lediglich \mbox{CPropram::compile} +Exceptions des Typs \mbox{std::runtime\_error}, um zusätzliche Information an +den ursprünglichen Aufrufer der Methode weiterzugeben. Dies geschieht ebenfalls +per Exception des Typs \mbox{std::runtime\_error}. \subsection{Implementierung} -TODO - +Siehe Punkt~\ref{Design} und Abbildung~\ref{fig:classdiagram1} sowie +Punkt~\ref{Listings}.\\ +Es wurde viel mit Templates gearbeitet. \section{Projektverlauf} \subsection{Probleme und Fallstricke} -TODO +Abgesehen von den mittlerweile üblichen Schwierigkeiten die Angabe bzw. +die Gedanken dessen Verfassers verstehen zu wollen, arbeitete das erste Design +noch vermehrt mit Text. Unter anderem hatte die Methode +\mbox{CInstruction::execute} einen Parameter des Typs \mbox{std::string}, was +zum dazu führte, das die Instruktion bei jeder Aufführung (zum Beispiel durch +Jumps) erneut geparsed werden musste. \subsection{Arbeitsaufwand} \begin{tabular}{ll} \toprule - Entwicklungsschritt / Meilenstein & Arbeitsaufwand in Stunden\\ + Entwicklungsschritt / Meilenstein & Arbeitsaufwand\\ + \midrule + Erstes Design & 3 Stunden\\ + \hline + Implementierung & 3 Tage\\ + \hline + Anpassung des Designs und der Implementierung & 4 Stunden\\ + \hline + Dokumentation (Doxygen) und Überprüfung aller\\ + Anforderungen gemäß der Programmierrichtlinien & 4 Stunden\\ \hline - TODO & TODO\\ + Erstellung des Protokolls & 3 Stunden\\ \bottomrule \end{tabular} @@ -88,5 +154,53 @@ TODO \subsection{mycpu.cpp} \lstinputlisting{../mycpu/mycpu.cpp} +\newpage +\subsection{cdat.h} +\lstinputlisting{../mycpu/cdat.h} + +\newpage +\subsection{cmem.h} +\lstinputlisting{../mycpu/cmem.h} + +\newpage +\subsection{cinstruction.h} +\lstinputlisting{../mycpu/cinstruction.h} + +\newpage +\subsection{cinstruction.cpp} +\lstinputlisting{../mycpu/cinstruction.cpp} + +\newpage +\subsection{instructions.h} +\lstinputlisting{../mycpu/instructions.h} + +\newpage +\subsection{instructions.cpp} +\lstinputlisting{../mycpu/instructions.cpp} + +\newpage +\subsection{cdisplay.h} +\lstinputlisting{../mycpu/cdisplay.h} + +\newpage +\subsection{displays.h} +\lstinputlisting{../mycpu/displays.h} + +\newpage +\subsection{cprogram.h} +\lstinputlisting{../mycpu/cprogram.h} + +\newpage +\subsection{cprogram.cpp} +\lstinputlisting{../mycpu/cprogram.cpp} + +\newpage +\subsection{ccpu.h} +\lstinputlisting{../mycpu/ccpu.h} + +\newpage +\subsection{ccpu.cpp} +\lstinputlisting{../mycpu/ccpu.cpp} + \end{document} -- cgit v1.3