text: app.controller('Ctrl', ['$document', '$scope', '$timeout', 'cpu', 'memory', 'assembler', function ($document, $scope, $timeout, cpu, memory, assembler) {
      $scope.memory = memory;
      $scope.cpu = cpu;
      $scope.error = '';
      $scope.isRunning = false;
      $scope.displayHex = true;
      $scope.displayInstr = true;
      $scope.speeds = [{speed: 1, desc: "1 HZ"},
                       {speed: 4, desc: "4 HZ"},
                       {speed: 8, desc: "8 HZ"},
                       {speed: 16, desc: "16 HZ"}];
      $scope.speed = 16;
      $scope.outputStartIndex = 232;
  
      $scope.code = "; Simple example\n;for (char i = 0; i < 50; ++i)\njp loop\ni: db 0             ;char i = 0;\nloop: cmp [i], 50   ;check i against 50\njz end              ;goto end if i==50\ninc [i]             ;i++\njp loop             ;goto loop\nend:\n";
  
      $scope.reset = function () {
          cpu.reset();
          memory.reset();
          $scope.error = '';
          $scope.selectedLine = -1;
      };
  
      $scope.executeStep = function () {
          if (!$scope.checkPrgrmLoaded()) {
              $scope.assemble();
          }
  
          try {
              // Execute
              var res = cpu.step();
  
              // Mark in code
              if (cpu.ip in $scope.mapping) {
                  $scope.selectedLine = $scope.mapping[cpu.ip];
              }
  
              return res;
          } catch (e) {
              $scope.error = e;
              return false;
          }
      };
  
      var runner;
      $scope.run = function () {
          if (!$scope.checkPrgrmLoaded()) {
              $scope.assemble();
          }
  
          $scope.isRunning = true;
          runner = $timeout(function () {
              if ($scope.executeStep() === true) {
                  $scope.run();
              } else {
                  $scope.isRunning = false;
              }
          }, 1000 / $scope.speed);
      };
  
      $scope.stop = function () {
          $timeout.cancel(runner);
          $scope.isRunning = false;
      };
  
      $scope.checkPrgrmLoaded = function () {
          for (var i = 0, l = memory.data.length; i < l; i++) {
              if (memory.data[i] !== 0) {
                  return true;
              }
          }
  
          return false;
      };
  
      $scope.getChar = function (value) {
          var text = String.fromCharCode(value);
  
          if (text.trim() === '') {
              return '\u00A0\u00A0';
          } else {
              return text;
          }
      };
  
      $scope.assemble = function () {
          try {
              $scope.reset();
  
              var assembly = assembler.go($scope.code);
              $scope.mapping = assembly.mapping;
              var binary = assembly.code;
              $scope.labels = assembly.labels;
  
              if (binary.length > memory.data.length)
                  throw "Binary code does not fit into the memory. Max " + memory.data.length + " bytes are allowed";
  
              for (var i = 0, l = binary.length; i < l; i++) {
                  memory.data[i] = binary[i];
              }
          } catch (e) {
              if (e.line !== undefined) {
                  $scope.error = e.line + " | " + e.error;
                  $scope.selectedLine = e.line;
              } else {
                  $scope.error = e.error;
              }
          }
      };
  
      $scope.jumpToLine = function (index) {
          $document[0].getElementById('sourceCode').scrollIntoView();
          $scope.selectedLine = $scope.mapping[index];
      };
  
  
      $scope.isInstruction = function (index) {
          return $scope.mapping !== undefined &&
              $scope.mapping[index] !== undefined &&
              $scope.displayInstr;
      };
  
      $scope.getMemoryCellCss = function (index) {
          if (index >= $scope.outputStartIndex) {
              return 'output-bg';
          } else if ($scope.isInstruction(index)) {
              return 'instr-bg';
          } else {
              return '';
          }
      };
  
      $scope.getMemoryInnerCellCss = function (index) {
          if (index === cpu.ip) {
              return 'marker marker-ip';
          } else {
              return '';
          }
      };
  }]);
  