Repository navigation
Expand file tree
/
Copy pathmain.js
More file actions
185 lines (143 loc) · 2.98 KB
/
Copy pathmain.js
File metadata and controls
185 lines (143 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
var fs = require('fs');
var input = process.argv[2];
var debug = true;
var BITS = 8;
var N_REG = 0x20;
// Named Registers
var PC = 0x0F; // Program Counter
var CIR = 0x10; // Current Instruction Register
var MDR = 0x12; // Memory Data Register
var CRR = 0x11; // Current Register Register
var IVR = 0x14; // Intermediate Value Register
var MAR = 0x13; // Memory Address Register
var SR = 0x15; // Status Register
// Status Codes
var EXIT = 0x01;
function log (s) {
if (debug) {
console.log(s);
}
}
function setup_ram () {
var RAM = [];
for (var i = 0; i < Math.pow(2, BITS); i++) {
RAM[i] = 0;
}
return RAM;
}
function setup_reg () {
var REG = [];
for (var i = 0; i < N_REG; i++) {
REG[i] = 0;
}
return REG;
}
function check_addr (reg, addr) {
return addr > Math.pow(2, BITS) || reg > N_REG;
}
function load_ (reg, addr) {
if (check_addr(reg, addr)) {
return false;
}
REG[reg] = RAM[addr];
return true;
}
function store (reg, addr) {
if (check_addr(reg, addr)) {
return false;
}
RAM[addr] = REG[reg];
return true;
}
function execute () {
switch (REG[CIR]) {
case 0x00:
// NOP
console.log('NOP')
break;
case 0x01:
// LOAD
log('LOAD');
load_(REG[CRR], REG[MAR]);
break;
case 0x02:
// STORE
log('STORE');
store(REG[CRR], REG[MAR]);
break;
case 0x03:
// BRANCH
log('BRANCH');
REG[PC] = REG[MAR] - 1;
break;
case 0x04:
// SET
log('SET');
REG[REG[CRR]] = REG[IVR];
break;
case 0x05:
// ADD
log('ADD');
REG[REG[CRR]] += REG[IVR];
break;
case 0x06:
// SUB
log('SUB');
REG[REG[CRR]] -= REG[IVR];
break;
case 0x07:
// BNZ
log('BNZ');
if (REG[REG[CRR]] != 0) {
REG[PC] = REG[MAR] - 1;
}
break;
case 0x08:
// EXIT
log('EXIT');
REG[SR] |= EXIT;
break;
}
}
function cpu () {
REG[PC] = 0x0;
while (REG[PC] >= 0 && REG[PC] < Math.pow(2, BITS)) {
// Fetch:
// Put instruction in MDR
load_(MDR, REG[PC]);
// Get the opcode
REG[CIR] = REG[MDR] >> 4;
// Get the operand
REG[CRR] = REG[MDR] & 0x0F;
if ([0x1, 0x2, 0x3, 0x7].indexOf(REG[CIR]) > -1) {
// Means a RAM address is in the next memory location
load_(MAR, ++REG[PC]);
}
if ([0x4, 0x5, 0x6].indexOf(REG[CIR]) > -1) {
// Means a number literal is in the next memory location
load_(IVR, ++REG[PC]);
}
// Execute:
execute()
if (REG[SR] & EXIT) {
return;
}
REG[PC]++;
}
}
var RAM = setup_ram();
var REG = setup_reg();
RAM[0x00] = 0x41;
RAM[0x01] = 0x05;
RAM[0x02] = 0x51;
RAM[0x03] = 0x15;
if (input || !process.stdin.isTTY) {
var fd = input ? fs.openSync(input, 'r') : process.stdin.fd;
var buf = new Buffer(1);
for (var i=0; fs.readSync(fd, buf, 0, 1) == 1; i++) {
RAM[i] = buf[0];
}
}
cpu();
console.log(REG);
console.log(RAM.slice(0, 20));