visit
Emulators are cool pieces of technology that allow users to run a totally different system on top of another one. Here, we'll explore how a CPU works and how its software can emulate one by implementing a simple machine that will run programs written for a fantasy CPU.
Emulators have a wide range of applications, like running x86 programs on ARM devices or running ARM Android applications on x86 Windows Desktops and even running your favorite retro game on an emulated computer/console on a Raspberry Pi.When a full system is emulated, the emulator software needs to handle all the hardware devices of those systems. This may include not only the CPU but also the video system, input devices, etc. However, the core concept of an emulator is nevertheless emulation of the CPU.11,0,10,42,6,255,30,0,11,0,0,11,1,1,11,3,1,60,1,10,2,0,20,
2,1,60,2,10,0,1,10,1,2,11,2,1,20,3,2,31,2,30,2,41,3,2,19,31,0,50
Using mnemonics makes the task of writing programs much easier for humans. If one writes programs using the instructions mnemonics it is said that he codes in assembly language. It only takes a simple step to transform these programs written in assembly language into binary instructions (e.g. machine language).Instructions and mnemonics for our fantasy CPU, as described below, are quite intuitive. But we need to know the CPU instructions if we want to emulate that CPU into software.
Note: Under each instruction is specified the number used to encode that particular instruction. Also registers R0, R1, R2, R3 are encoded as numbers 0, 1, 2, 3):
Loads the value from regsrc into regdst. E.g. regdst = regsrcMOVR reg_dst, reg_src
MOVR = 10
MOVV reg_dst, value
MOVV = 11
ADD reg_dst, reg_src
ADD = 20
SUB reg_dst, reg_src
SUB = 21
PUSH reg_src
PUSH = 30
POP reg_dst
POP = 31
JP addr
JP = 40
JL reg_1, reg_2, addr
JL = 41
CALL addr
CALL = 42
RET
RET = 50
PRINT reg
PRINT = 60
HALT
HALT = 255
let program = [11,0,10,42,6,255,30,0,11,0,0,11,1,1,11,3,1,60,1,10,2,0,20,
2,1,60,2,10,0,1,10,1,2,11,2,1,20,3,2,31,2,30,2,41,3,2,19,31,0,50];
Fact: PC register is a real register on many physical CPU architectures.The core of the CPU emulator is just a big “switch” statement that will process each instruction according to the specs.
let pc = 0;
let halted = false;
function run()
{
while(!halted)
{
runone();
}
}
function runone()
{
if (halted)
return;
let instr = program[pc];
switch(instr)
{
// handle each instruction according to specs
// also advance pc to prepare for the next fetch
// ...
}
}
switch(instr)
{
// movr rdst, rsrc
case 10:
pc++;
var rdst = program[pc++];
var rsrc = program[pc++];
regs[rdst] = regs[rsrc];
break;
// movv rdst, val
case 11:
pc++;
var rdst = program[pc++];
var val = program[pc++];
regs[rdst] = val;
break;
...
}
vm.load([11,0,10,42,6,255,30,0,11,0,0,11,1,1,11,3,1,60,1,10,2,0,20,
2,1,60,2,10,0,1,10,1,2,11,2,1,20,3,2,31,2,30,2,41,3,2,19,31,0,50]);
const MOVR = 10;
const MOVV = 11;
const ADD = 20;
const SUB = 21;
const PUSH = 30;
const POP = 31;
const JP = 40;
const JL = 41;
const CALL = 42;
const RET = 50;
const PRINT= 60;
const HALT = 255;
const R0 = 0;
const R1 = 1;
const R2 = 2;
const R3 = 3;
vm.load([
MOVV, R0, 10,
CALL, 6,
HALT,
// PrintFibo: (addr = 6)
PUSH, R0,
MOVV, R0, 0,
MOVV, R1, 1,
MOVV, R3, 1,
PRINT, R1,
// continue: (addr = 19)
MOVR, R2, R0,
ADD, R2, R1,
PRINT, R2,
MOVR, R0, R1,
MOVR, R1, R2,
MOVV, R2, 1,
ADD, R3, R2,
POP, R2,
PUSH, R2,
JL, R3, R2, 19,
POP, R0,
RET
]);
let code = `
// Loads value 10 in R0
// and calls Fibonacci routine
MOVV R0, 10
CALL 6
HALT
...
`;
let bytes = asm.assemble(code);
let src = asm.disassemble(
[11,0,10,42,6,255,30,0,11,0,0,11,1,1,11,3,1,60,1,10,2,0,20,
2,1,60,2,10,0,1,10,1,2,11,2,1,20,3,2,31,2,30,2,41,3,2,19,31,0,50]
);
0 11 0 10 MOVV R0, 10
3 42 6 CALL 6
5 255 HALT
6 30 0 PUSH R0
8 11 0 0 MOVV R0, 0
11 11 1 1 MOVV R1, 1
14 11 3 1 MOVV R3, 1
17 60 6 PRINT R1
19 10 2 0 MOVR R2, R0
22 20 2 1 ADD R2, R1
25 60 6 PRINT R2
27 10 0 1 MOVR R0, R1
30 10 1 2 MOVR R1, R2
33 11 2 1 MOVV R2, 1
36 20 3 2 ADD R3, R2
39 31 2 2 POP R2
41 30 2 PUSH R2
43 41 3 2 19 JL R3, R2, 19
47 31 0 2 POP R0
49 50 RET
Looking forward to your feedback and comments. Please let me know if you want to see more about this subject, perhaps even seeing the implementation of a full emulator. For more recreational coding programs please feel free to browse