Assuming you have a CPU with instruction set of the following form (where A, B, D are various forms of memory, pc-relative, register, constant access, etc.):
- Op
- Op A
- Op -> D
- Op A -> D
- Op A,B
- Op A,B -> D
Pseudo Code:
class CPUModel
{
typedef unsigned long Register;
typedef unsigned long Value;
class Registers
{
Register PC;
...
}
class Operation
{
enum OpCode { ... }
enum Kind { Reg, Rel, Abs, Const, ... }
class Source
{
Value value;
Kind kind;
...
Value Get()
{
switch(kind)
{
case Const:
return value;
case Reg:
return Cpu.Registers[value];
case Rel:
return Sys.Memory[Cpu.Registers.PC + value];
case Abs:
return Sys.Memory[value];
...
}
}
}
class Destination
{
Value value;
Kind kind;
...
void Set(Value v)
{
switch(kind)
{
case Reg:
Cpu.Registers[value] = v;
break;
case Rel:
Sys.Memory[Cpu.Registers.PC + value] = v;
break;
case Abs:
Sys.Memory[value] = v;
break;
...
}
}
}
...
Operation(Word w)
{
code = DecodeOp(w);
src1 = Source.DecodeFirst(w);
src2 = Source.DecodeSecond(w);
dest = Destination.Decode(w);
}
}
void Run(Address loc)
{
Registers.PC = loc;
Halt = false;
while (!Halt)
{
FetchDecodeAndExecute();
sys.DumpSystemState();
}
}
void FetchDecodeAndExecute()
{
Word w = Sys.Memory[Registers.PC];
Operation op = new Operation(w);
Execute(op);
}
void Execute(Operation op)
{
switch(op.code)
{
case Halt:
Halt = true;
break;
case Add:
op.dest.Set(op.src1.Get() + op.src2.Get());
Registers.PC += op.Length();
break;
...
case Jump:
Registers.PC = op.src1.Get();
break;
...
}
}
}
class MemoryModel
{
...
}
class DeviceXModel
{
...
}
class System
{
...
System()
{
}
void Init()
{
Cpu = new CPUModel(this);
Mem = new MemoryModel(this);
DevX = new DeviceXModel(this);
...
}
void Run(Address loc)
{
Cpu.Run(loc);
}
}
void Simulate(File image file, Addrsss loc)
{
System sys = new System();
sys.Init();
sys.LoadImageIntoMemory(loc, imageFile);
sys.Run(loc);
}
Have Fun!
Cheers
Andi