21 |
Introduction
22 |
This simulator provides a simplified assembler syntax (based on TEXT BOOK "Computer Science: An Overview") and is simulating a 8-bit cpu.
23 |
The simulator consists of a 8-bit cpu and 256 bytes of memory. All instructions (code) and variables (data) needs to fit inside the memory. For simplicity every instruction (and operand) is 2 byte.
24 |
Syntax
25 |
The syntax is similar as most assemblers are using. Every instruction must be on their own line. Labels are optional and must either start with a letter or a dot (.) and end with a colon.
26 |
label: instruction operands ; Comment
27 |
Valid number formats for constants are:
28 |
29 | Decimal: 200
30 | Hex: 0xA4
31 |
32 |
It is possible to define a number using a character or multiple numbers (see instruction DB) by using a string.
33 |
34 | Character: 'A'
35 | String: "Hello World!"
36 |
37 |
Operands can either be one of the 16 general purpose registers, a memory address or a constant.
38 | Instead of defining an address as a constant or by using a register you can use labels. The assembler will then replace the label with the corresponding constant.
39 |
40 | General purpose (GP) register: R0-RE
41 | Timer interrupt register: RF
42 | Address using a constant: 100
43 | Address using a label: label
44 |
45 |
MOVE S, R
46 |
MOVE the bit pattern found in register R to register S.
47 |
48 | MOVE reg, reg
49 |
50 |
DB - Variable
51 |
Defines a variable. A variable can either be a single number, character or a string.
52 |
53 | DB constant
54 |
55 |
integer/float Addition
56 |
Adds two numbers together.
57 |
58 | ADDI regR, regS, regT ; regR=regS+regT integer
59 | ADDF regR, regS, regT ; regR=regS+regT float
60 |
61 |
Logical instructions
62 |
The following logical instructions are supported: AND, OR, XOR.
63 |
64 | AND regR, regS, regT ; R=S & T
65 | OR regR, regS, regT ; R=S | T
66 | XOR regR, regS, regT ; R=S ^ T
67 |
68 |
Shift instructions
69 |
The following shift instructions are supported: ROTATE to right.
70 |
71 | ROT regR, numX ; regR=regR rotate-right numX times
72 |
73 |
JUMP - jump if equal
74 |
JUMP to the instruction located in the memory cell at address XY if the bit pattern in register R is equal to the bit
75 | pattern in register 0. Otherwise, continue with the normal sequence of execution. (The jump is implemented by
76 | copying XY into the program counter during the execute phase.)
77 |
78 |
79 | JUMP regR, numXY
80 |
81 |
JUMPL - jump if less
82 |
JUMPL to the instruction located in the memory cell at address XY if the bit pattern in register R is less than the bit
83 | pattern in register 0. Otherwise, continue with the normal sequence of execution. (The jump is implemented by
84 | copying XY into the program counter during the execute phase.)
85 |
86 |
87 | JUMPL regR, numXY
88 |
89 |
90 |
HALT
91 |
Stops operation of the processor. Hit Reset button to reset IP before restarting.
92 |
93 | HALT
94 |
95 |
LOADM (Load from Memory)
96 |
LOAD the register R with the bit pattern found in the memory cell whose address is XY.
97 |
98 | LOADM regR, numXY
99 |
100 |
LOADB (Load with Bit Pattern)
101 |
LOAD the register R with the bit pattern XY.
102 |
103 | LOADB regR, numXY
104 |
105 |
LOADP (Load via Pointer)
106 |
LOAD the register R with the contents of the memory cell whose address is found in register S.
107 |
108 | LOADP regR, regS
109 |
110 |
STOREM (Store to Memory)
111 |
STORE the bit pattern found in register R in the memory cell whose address is XY.
112 |
113 | STOREM regR, numXY
114 |
115 |
STOREP (Store via Pointer)
116 |
STORE the contents of register R in the memory cell whose address is found in register S.
117 |
118 | STOREP regR, regS
119 |
120 |
121 |
122 |
123 |
by Yuanchun Shi, Yu Chen, Junjie Mao, Yukang Yan (2015) | MIT License | Source Code
124 |
by Marco Schweighauser (2015) | MIT License | Blog
125 |
126 |
127 |
128 |
--------------------------------------------------------------------------------
/src/emulator/cpu.js:
--------------------------------------------------------------------------------
1 | function log(msg) {
2 | setTimeout(function() {
3 | throw new Error(msg);
4 | }, 0);
5 | }
6 |
7 | app.service('cpu', ['opcodes', 'memory', function(opcodes, memory) {
8 | var cpu = {
9 | step: function() {
10 | var self = this;
11 |
12 | var byteToNumber = function(val) {
13 | if (val < 128) {
14 | return val;
15 | } else {
16 | return val - 255;
17 | }
18 | };
19 |
20 | var readReg = function(id) {
21 | return self.gpr[id];
22 | };
23 |
24 | var writeReg = function(id, val) {
25 | self.gpr[id] = val;
26 | if (id == 15) {
27 | self.updateTimer = true;
28 | if (val > 0) {
29 | self.countdown = val;
30 | } else {
31 | self.countdown = 0;
32 | }
33 | }
34 | };
35 |
36 | var findHighestBit = function(bits, max) {
37 | var i;
38 | for (i = max; i >= 0; i--) {
39 | if ((bits >> i) !== 0)
40 | break;
41 | }
42 | return i;
43 | };
44 |
45 | var floatingAdd = function(a, b) {
46 | var a_sign = (a & 0x80) >> 7, a_expo = ((a & 0x70) >> 4), a_mant = a & 0x0F;
47 | var b_sign = (b & 0x80) >> 7, b_expo = ((b & 0x70) >> 4), b_mant = b & 0x0F;
48 | var a_fix = (a_mant << a_expo), b_fix = (b_mant << b_expo);
49 | var result_sign, result_fix;
50 | if (a_sign == b_sign) {
51 | result_sign = a_sign;
52 | result_fix = a_fix + b_fix;
53 | } else {
54 | if (a_fix > b_fix) {
55 | result_sign = a_sign;
56 | result_fix = a_fix - b_fix;
57 | } else if (a_fix < b_fix) {
58 | result_sign = b_sign;
59 | result_fix = b_fix - a_fix;
60 | } else {
61 | result_fix = 0;
62 | result_sign = 0;
63 | }
64 | }
65 | var result_expo = findHighestBit(result_fix, 16) - 3;
66 | if (result_expo > 7) {
67 | result_expo = 7;
68 | } else if (result_expo < 0) {
69 | result_expo = 0;
70 | }
71 | var result_mant = (result_fix >> result_expo) & 0xF;
72 | var result = (result_sign << 7) | (result_expo << 4) | result_mant;
73 | return result;
74 | };
75 |
76 | var updateIR = function(instr) {
77 | self.ir = '';
78 | if (instr[0] <= 15)
79 | self.ir += '0' + instr[0].toString(16);
80 | else
81 | self.ir += instr[0].toString(16);
82 | if (instr[1] <= 15)
83 | self.ir += '0' + instr[1].toString(16);
84 | else
85 | self.ir += instr[1].toString(16);
86 | };
87 |
88 | self.updateTimer = false;
89 | self.status = '';
90 |
91 | var instr = [memory.load(self.ip), memory.load(self.ip + 1)];
92 | var opcode = instr[0] >> 4;
93 | var regDest = instr[0] & 0x0F, regSource1 = instr[1] >> 4, regSource2 = instr[1] & 0x0F;
94 | var mem = instr[1], num = instr[1];
95 | updateIR(instr);
96 | self.ip = (self.ip + 2) & 0xFF;
97 | switch(opcode) {
98 | case opcodes.LOAD_FROM_MEMORY:
99 | writeReg(regDest, memory.load(mem));
100 | break;
101 | case opcodes.LOAD_WITH_CONSTANT:
102 | writeReg(regDest, num);
103 | break;
104 | case opcodes.STORE_TO_MEMORY:
105 | memory.store(mem, readReg(regDest));
106 | break;
107 | case opcodes.MOVE:
108 | writeReg(regSource2, readReg(regSource1));
109 | break;
110 | case opcodes.ADD_INT:
111 | writeReg(regDest, (readReg(regSource1) + readReg(regSource2)) & 0xFF);
112 | break;
113 | case opcodes.ADD_FLOAT:
114 | writeReg(regDest, floatingAdd(readReg(regSource1), readReg(regSource2)));
115 | break;
116 | case opcodes.OR:
117 | writeReg(regDest, readReg(regSource1) | readReg(regSource2));
118 | break;
119 | case opcodes.AND:
120 | writeReg(regDest, readReg(regSource1) & readReg(regSource2));
121 | break;
122 | case opcodes.XOR:
123 | writeReg(regDest, readReg(regSource1) ^ readReg(regSource2));
124 | break;
125 | case opcodes.ROTATE:
126 | var delta = num % 8, val = readReg(regDest);
127 | writeReg(regDest, (val >> delta) + ((val & ((1 << delta) - 1)) << (8 - delta)));
128 | break;
129 | case opcodes.JUMP_IF_EQUAL:
130 | if (readReg(regDest) == readReg(0)) {
131 | self.ip = mem;
132 | }
133 | break;
134 | case opcodes.HALT:
135 | self.ip = (self.ip - 2) & 0xFF;
136 | return false;
137 | case opcodes.LOAD_FROM_POINTER:
138 | writeReg(regDest, memory.load(readReg(regSource2)));
139 | break;
140 | case opcodes.STORE_TO_POINTER:
141 | memory.store(readReg(regSource2), readReg(regDest));
142 | break;
143 | case opcodes.JUMP_IF_LESS:
144 | if (byteToNumber(readReg(regDest)) < byteToNumber(readReg(0))) {
145 | self.ip = mem;
146 | }
147 | break;
148 | }
149 |
150 | if (self.countdown > 0 && !self.updateTimer) {
151 | self.countdown -= 1;
152 | if (self.countdown === 0) {
153 | memory.store(0xFD, self.ip);
154 | self.ip = 0x80;
155 | self.countdown = readReg(15);
156 | self.status = '(Interrupted!)';
157 | }
158 | }
159 |
160 | return true;
161 | },
162 | reset: function() {
163 | var self = this;
164 |
165 | self.gpr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
166 | self.ip = 0;
167 | self.ir = '0000';
168 | self.status = '';
169 |
170 | self.countdown = 0;
171 | self.updateTimer = false;
172 | }
173 | };
174 |
175 | cpu.reset();
176 | return cpu;
177 | }]);
178 |
179 | /*
180 | * Local variables:
181 | * c-basic-offset: 4
182 | * tab-width: 4
183 | * indent-tabs-mode: nil
184 | * End:
185 | */
186 |
--------------------------------------------------------------------------------
/controller.js:
--------------------------------------------------------------------------------
1 | app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memory', 'printer', 'assembler', 'uploader', function ($document, $scope, $timeout, $http, cpu, memory, printer, assembler, uploader) {
2 | $scope.printer = printer;
3 | $scope.memory = memory;
4 | $scope.cpu = cpu;
5 | $scope.error = '';
6 | $scope.isRunning = false;
7 | $scope.displayHex = true;
8 | $scope.displayInstr = true;
9 | $scope.displayA = false;
10 | $scope.displayB = false;
11 | $scope.displayC = false;
12 | $scope.displayD = false;
13 | $scope.speeds = [{speed: 1, desc: "1 HZ"},
14 | {speed: 4, desc: "4 HZ"},
15 | {speed: 8, desc: "8 HZ"},
16 | {speed: 16, desc: "16 HZ"}];
17 | $scope.speed = 4;
18 | $scope.example = '';
19 | $scope.examples = [];
20 |
21 | $scope.code = ";; Choose an example above or write your own code here :)";
22 | $scope.reset = function () {
23 | cpu.reset();
24 | memory.reset();
25 | printer.reset();
26 | $scope.error = '';
27 | $scope.selectedLine = -1;
28 | $scope.mapping = undefined;
29 | };
30 |
31 | $scope.executeStep = function () {
32 | if (!$scope.checkPrgrmLoaded()) {
33 | $scope.assemble();
34 | }
35 |
36 | try {
37 | // Execute
38 | var res = cpu.step();
39 |
40 | // Mark in code
41 | if (cpu.ip in $scope.mapping) {
42 | $scope.selectedLine = $scope.mapping[cpu.ip];
43 | }
44 |
45 | return res;
46 | } catch (e) {
47 | $scope.error = e;
48 | return false;
49 | }
50 | };
51 |
52 | var runner;
53 | $scope.run = function () {
54 | if (!$scope.checkPrgrmLoaded()) {
55 | $scope.assemble();
56 | }
57 |
58 | $scope.isRunning = true;
59 | runner = $timeout(function () {
60 | if ($scope.executeStep() === true) {
61 | $scope.run();
62 | } else {
63 | $scope.isRunning = false;
64 | }
65 | }, 1000 / $scope.speed);
66 | };
67 |
68 | $scope.stop = function () {
69 | $timeout.cancel(runner);
70 | $scope.isRunning = false;
71 | };
72 |
73 | $scope.checkPrgrmLoaded = function () {
74 | for (var i = 0, l = memory.data.length; i < l; i++) {
75 | if (memory.data[i] !== 0) {
76 | return true;
77 | }
78 | }
79 |
80 | return false;
81 | };
82 |
83 | $scope.getChar = function (value) {
84 | var text = String.fromCharCode(value);
85 |
86 | if (text.trim() === '') {
87 | return '\u00A0\u00A0';
88 | } else {
89 | return text;
90 | }
91 | };
92 |
93 | $scope.assemble = function () {
94 | try {
95 | $scope.reset();
96 |
97 | var assembly = assembler.go($scope.code);
98 | $scope.mapping = assembly.mapping;
99 | var binary = assembly.code;
100 | $scope.labels = assembly.labels;
101 |
102 | if (binary.length > memory.data.length)
103 | throw "Binary code does not fit into the memory. Max " + memory.data.length + " bytes are allowed";
104 |
105 | for (var i = 0, l = binary.length; i < l; i++) {
106 | memory.data[i] = binary[i];
107 | }
108 |
109 | if ($scope.labels['.entry'] !== undefined) {
110 | cpu.ip = $scope.labels['.entry'];
111 | }
112 | } catch (e) {
113 | if (e.line !== undefined) {
114 | $scope.error = e.line + " | " + e.error;
115 | $scope.selectedLine = e.line;
116 | } else {
117 | $scope.error = e.error;
118 | }
119 | }
120 | };
121 |
122 | $scope.upload = function () {
123 | try {
124 | $scope.reset();
125 |
126 | var binarycode = uploader.go($scope.code);
127 | $scope.mapping = binarycode.mapping;
128 | var binary = binarycode.code;
129 | $scope.labels = binarycode.labels;
130 |
131 | if (binary.length > memory.data.length)
132 | throw "Binary code does not fit into the memory. Max " + memory.data.length + " bytes are allowed";
133 |
134 | for (var i = 0, l = binary.length; i < l; i++) {
135 | memory.data[i] = binary[i];
136 | }
137 | } catch (e) {
138 | if (e.line !== undefined) {
139 | $scope.error = e.line + " | " + e.error;
140 | $scope.selectedLine = e.line;
141 | } else {
142 | $scope.error = e.error;
143 | }
144 | }
145 | };
146 |
147 | $scope.compile = function () {
148 | $.post('/',{"1":$scope.code},function(response){
149 | console.debug("called"); $scope.code = response; $scope.assemble();});
150 | };
151 |
152 | $scope.initExamples = function() {
153 | var response = $http.get('examples/scandir.php');
154 | response.success(function(data, status, headers, config) {
155 | var filelist = String(data).split(',');
156 | for (var i = 0, l = filelist.length; i < l; i++) {
157 | var contents = filelist[i].split('|');
158 | var filename = contents[0], desc = contents[1];
159 | $scope.examples.push({id: filename, desc: desc});
160 | }
161 | });
162 | response.error(function(data, status, headers, config) {
163 | console.error("ajax failed");
164 | });
165 | };
166 |
167 | $scope.showExample = function(key) {
168 | var response = $http.get('examples/' + $scope.example);
169 |
170 | response.success(function(data, status, headers, config) {
171 | $scope.code = data;
172 | });
173 | response.error(function(data, status, headers, config) {
174 | console.error("ajax failed");
175 | });
176 | };
177 |
178 | $scope.jumpToLine = function (index) {
179 | $document[0].getElementById('sourceCode').scrollIntoView();
180 | $scope.selectedLine = $scope.mapping[index];
181 | };
182 |
183 |
184 | $scope.isInstruction = function (index) {
185 | return $scope.mapping !== undefined &&
186 | $scope.mapping[index] !== undefined &&
187 | $scope.displayInstr;
188 | };
189 |
190 | $scope.getMemoryCellCss = function (index) {
191 | if ($scope.isInstruction(index)) {
192 | return 'instr-bg';
193 | } else {
194 | return '';
195 | }
196 | };
197 |
198 | $scope.getMemoryInnerCellCss = function (index) {
199 | if (index === cpu.ip) {
200 | return 'marker marker-ip';
201 | } else if (index === cpu.sp) {
202 | return 'marker marker-sp';
203 | } else if (index === cpu.gpr[0] && $scope.displayA) {
204 | return 'marker marker-a';
205 | } else if (index === cpu.gpr[1] && $scope.displayB) {
206 | return 'marker marker-b';
207 | } else if (index === cpu.gpr[2] && $scope.displayC) {
208 | return 'marker marker-c';
209 | } else if (index === cpu.gpr[3] && $scope.displayD) {
210 | return 'marker marker-d';
211 | } else {
212 | return '';
213 | }
214 | };
215 | }]);
216 |
217 | /*
218 | * Local variables:
219 | * c-basic-offset: 4
220 | * tab-width: 4
221 | * indent-tabs-mode: nil
222 | * End:
223 | */
224 |
--------------------------------------------------------------------------------
/src/ui/controller.js:
--------------------------------------------------------------------------------
1 | app.controller('Ctrl', ['$document', '$scope', '$timeout', '$http', 'cpu', 'memory', 'printer', 'assembler', 'uploader', function ($document, $scope, $timeout, $http, cpu, memory, printer, assembler, uploader) {
2 | $scope.printer = printer;
3 | $scope.memory = memory;
4 | $scope.cpu = cpu;
5 | $scope.error = '';
6 | $scope.isRunning = false;
7 | $scope.displayHex = true;
8 | $scope.displayInstr = true;
9 | $scope.displayA = false;
10 | $scope.displayB = false;
11 | $scope.displayC = false;
12 | $scope.displayD = false;
13 | $scope.speeds = [{speed: 1, desc: "1 HZ"},
14 | {speed: 4, desc: "4 HZ"},
15 | {speed: 8, desc: "8 HZ"},
16 | {speed: 16, desc: "16 HZ"}];
17 | $scope.speed = 4;
18 | $scope.example = '';
19 | $scope.examples = [];
20 |
21 | $scope.code = ";; Choose an example above or write your own code here :)";
22 | $scope.reset = function () {
23 | cpu.reset();
24 | memory.reset();
25 | printer.reset();
26 | $scope.error = '';
27 | $scope.selectedLine = -1;
28 | $scope.mapping = undefined;
29 | };
30 |
31 | $scope.executeStep = function () {
32 | if (!$scope.checkPrgrmLoaded()) {
33 | $scope.assemble();
34 | }
35 |
36 | try {
37 | // Execute
38 | var res = cpu.step();
39 |
40 | // Mark in code
41 | if (cpu.ip in $scope.mapping) {
42 | $scope.selectedLine = $scope.mapping[cpu.ip];
43 | }
44 |
45 | return res;
46 | } catch (e) {
47 | $scope.error = e;
48 | return false;
49 | }
50 | };
51 |
52 | var runner;
53 | $scope.run = function () {
54 | if (!$scope.checkPrgrmLoaded()) {
55 | $scope.assemble();
56 | }
57 |
58 | $scope.isRunning = true;
59 | runner = $timeout(function () {
60 | if ($scope.executeStep() === true) {
61 | $scope.run();
62 | } else {
63 | $scope.isRunning = false;
64 | }
65 | }, 1000 / $scope.speed);
66 | };
67 |
68 | $scope.stop = function () {
69 | $timeout.cancel(runner);
70 | $scope.isRunning = false;
71 | };
72 |
73 | $scope.checkPrgrmLoaded = function () {
74 | for (var i = 0, l = memory.data.length; i < l; i++) {
75 | if (memory.data[i] !== 0) {
76 | return true;
77 | }
78 | }
79 |
80 | return false;
81 | };
82 |
83 | $scope.getChar = function (value) {
84 | var text = String.fromCharCode(value);
85 |
86 | if (text.trim() === '') {
87 | return '\u00A0\u00A0';
88 | } else {
89 | return text;
90 | }
91 | };
92 |
93 | $scope.assemble = function () {
94 | try {
95 | $scope.reset();
96 |
97 | var assembly = assembler.go($scope.code);
98 | $scope.mapping = assembly.mapping;
99 | var binary = assembly.code;
100 | var disk = assembly.disk;
101 | $scope.labels = assembly.labels;
102 |
103 | if (binary.length > memory.data.length)
104 | throw {error: "Binary code does not fit into the memory. Max " + memory.data.length + " bytes are allowed"};
105 |
106 | if (disk.length > memory.diskdata.length)
107 | throw {error: "Disk data does not fit into the disk. Max " + memory.diskdata.length + " bytes are allowed"};
108 |
109 | for (var i = 0, l = binary.length; i < l; i++) {
110 | memory.data[i] = binary[i];
111 | }
112 |
113 | for (i = 0, l = disk.length; i < l; i++) {
114 | memory.diskdata[i] = disk[i];
115 | }
116 |
117 | if ($scope.labels['.entry'] !== undefined) {
118 | cpu.ip = $scope.labels['.entry'];
119 | }
120 | } catch (e) {
121 | if (e.line !== undefined) {
122 | $scope.error = e.line + " | " + e.error;
123 | $scope.selectedLine = e.line;
124 | } else {
125 | $scope.error = e.error;
126 | }
127 | }
128 | };
129 |
130 | $scope.upload = function () {
131 | try {
132 | $scope.reset();
133 |
134 | var binarycode = uploader.go($scope.code);
135 | $scope.mapping = binarycode.mapping;
136 | var binary = binarycode.code;
137 | $scope.labels = binarycode.labels;
138 |
139 | if (binary.length > memory.data.length)
140 | throw "Binary code does not fit into the memory. Max " + memory.data.length + " bytes are allowed";
141 |
142 | for (var i = 0, l = binary.length; i < l; i++) {
143 | memory.data[i] = binary[i];
144 | }
145 | } catch (e) {
146 | if (e.line !== undefined) {
147 | $scope.error = e.line + " | " + e.error;
148 | $scope.selectedLine = e.line;
149 | } else {
150 | $scope.error = e.error;
151 | }
152 | }
153 | };
154 |
155 | $scope.compile = function () {
156 | $http.post('/', {"source": $scope.code}).success(function(response){
157 | $scope.code = response; $scope.assemble();});
158 | };
159 |
160 | $scope.initExamples = function() {
161 | var response = $http.get('examples/scandir.php');
162 | response.success(function(data, status, headers, config) {
163 | var filelist = String(data).split(',');
164 | for (var i = 0, l = filelist.length; i < l; i++) {
165 | var contents = filelist[i].split('|');
166 | var filename = contents[0], desc = contents[1];
167 | $scope.examples.push({id: filename, desc: desc});
168 | }
169 | });
170 | response.error(function(data, status, headers, config) {
171 | console.error("ajax failed");
172 | });
173 | };
174 |
175 | $scope.showExample = function(key) {
176 | var response = $http.get('examples/' + $scope.example);
177 |
178 | response.success(function(data, status, headers, config) {
179 | $scope.code = data;
180 | });
181 | response.error(function(data, status, headers, config) {
182 | console.error("ajax failed");
183 | });
184 | };
185 |
186 | $scope.jumpToLine = function (index) {
187 | $document[0].getElementById('sourceCode').scrollIntoView();
188 | $scope.selectedLine = $scope.mapping[index];
189 | };
190 |
191 |
192 | $scope.isInstruction = function (index) {
193 | return $scope.mapping !== undefined &&
194 | $scope.mapping[index] !== undefined &&
195 | $scope.displayInstr;
196 | };
197 |
198 | $scope.getMemoryCellCss = function (index) {
199 | if ($scope.isInstruction(index)) {
200 | return 'instr-bg';
201 | } else {
202 | return '';
203 | }
204 | };
205 |
206 | $scope.getMemoryInnerCellCss = function (index) {
207 | if (index === cpu.ip) {
208 | return 'marker marker-ip';
209 | } else if (index === cpu.sp) {
210 | return 'marker marker-sp';
211 | } else if (index === cpu.gpr[0] && $scope.displayA) {
212 | return 'marker marker-a';
213 | } else if (index === cpu.gpr[1] && $scope.displayB) {
214 | return 'marker marker-b';
215 | } else if (index === cpu.gpr[2] && $scope.displayC) {
216 | return 'marker marker-c';
217 | } else if (index === cpu.gpr[3] && $scope.displayD) {
218 | return 'marker marker-d';
219 | } else {
220 | return '';
221 | }
222 | };
223 | }]);
224 |
225 | /*
226 | * Local variables:
227 | * c-basic-offset: 4
228 | * tab-width: 4
229 | * indent-tabs-mode: nil
230 | * End:
231 | */
232 |
--------------------------------------------------------------------------------
/cucu/cucu.c:
--------------------------------------------------------------------------------
1 | #include