forked from vaguilar/js-y86
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathysim.js
106 lines (91 loc) · 2.28 KB
/
ysim.js
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
var fs = require('fs');
var _ = require('./js/underscore.js')._;
eval(fs.readFileSync('js/general.js', { encoding: 'utf8' }));
eval(fs.readFileSync('js/instr.js', { encoding: 'utf8' }));
eval(fs.readFileSync('js/assem.js', { encoding: 'utf8' }));
eval(fs.readFileSync('js/syntax.js', { encoding: 'utf8' }));
eval(fs.readFileSync('js/y86.js', { encoding: 'utf8' }));
function copy (src) {
var len = src.byteLength;
var dst = new Uint8Array(len);
for (var i = 0; i < len; i++)
dst[i] = src[i];
return dst;
}
function diff (a, b) {
var addresses = {};
for (var i = 0; i < MEM_SIZE; i++)
if (a[i] !== b[i])
addresses[Math.floor(i / 4) * 4] = true;
var changes = [];
for (var addr in addresses)
if (addresses.hasOwnProperty(addr))
changes.push({
address: +addr,
oldValue: LD(+addr, a),
newValue: LD(+addr, b)
})
changes.sort(function (a, b) { return a.address - b.address; });
return changes;
}
function assemble (source) {
return ASSEMBLE(source);
}
function run (object) {
RESET();
var initialState = toByteArray(object);
MEMORY = copy(initialState);
while (PC < MEM_SIZE && STAT === 'AOK') {
STEP();
}
return {
pc: PC,
modifiedMemory: diff(initialState, MEMORY),
registers: {
eax: REG[0],
ecx: REG[1],
edx: REG[2],
ebx: REG[3],
esp: REG[4],
ebp: REG[5],
esi: REG[6],
edi: REG[7]
},
flags: {
sf: SF,
zf: ZF,
of: OF
},
status: STAT,
error: ERR
}
}
exports.assemble = assemble;
exports.run = run;
var usage = 'Usage: node ysim.js (c source.ys object.yo | r object.yo)';
if (require.main === module) {
if (process.argv[2] === 'c') {
if (process.argv.length !== 5) {
console.log(usage);
return;
}
var source = fs.readFileSync(process.argv[3], { encoding: 'utf8' });
var object = assemble(source);
if (object.errors.length) {
console.error(object.errors.map(function (e) { return 'Error at line ' + e[0] + ': ' + e[1]; }).join('\n'));
process.exit(1);
return;
}
fs.writeFile(process.argv[4], object.obj);
} else if (process.argv[2] === 'r') {
if (process.argv.length !== 4) {
console.log(usage);
return;
}
var object = fs.readFileSync(process.argv[3], { encoding: 'utf8' });
var result = run(object);
console.log(require('util').inspect(result));
} else {
console.log(usage);
}
}