Commits

Kevin Veroneau committed 1f36694

Added CPU op-code Hooks to enable custom plugin classes to perform custom Python code when called from your binary image.

Comments (0)

Files changed (2)

+Simple CPU Simulator -- CPU Hooks interface
+
+CPU Hooks can allow custom op-codes to be added and removed like a plugin system.
+For example, say you temporarily add a virtual device attached to the CPU, then later remove it.
+The inserting/removing is controlled in Python and no by the op-codes/coder.
+
+There is a Base class which must be sub-classed to make hooks work, there is an example Hook provided.
+
+Since these are custom op-codes being hooked into the CPU, there is of course no coder commands for these codes, as a result in order to use them, you must manually use the "set" coder command or add them via a hex-editor.
+The hooks have full access to the CPU core, it's registers, and attached memory and storage.
+A hook has the same ability as a standard software interrupt in the simulated CPU.
+
+You could for example create a hook which can create a GUI using wxWindows for example, or TK.
+A hook can also attach itself to the hosts network interface and allow your simulated CPU to access the Internet.
+
+Here is the example HelloWorldHook to see how easy it is to use:
+
+--------------
+class HelloWorldHook(BaseCPUHook):
+    def hook_32(self):
+        print "Hello World!"
+    def hook_33(self):
+        print "Current Register values:"
+        print self.cpu.ax.b
+        print self.cpu.bx.b
+        print self.cpu.cx.b
+        print self.cpu.dx.b
+--------------
+In the coder interface, you can access both functions via:
+--------------
+set 60
+set 32
+set 60
+set 33
+boot 0
+--------------
+Note the manual op-codes there.  In the future, I may add the ability to enable the coder to reflect these new op-codes using a custom command to make things easier.
                 break
         self.cpu.savebin('dump')
 
+class BaseCPUHook(object):
+    def __init__(self, cpu):
+        if not isinstance(cpu, CPU):
+            raise TypeError
+        self.cpu = cpu
+    def __call__(self, i):
+        try:
+            func = getattr(self, "hook_%d" % i)
+        except AttributeError:
+            raise InvalidInterrupt("HOOK %d is not defined." % i)
+        func()
+
+class HelloWorldHook(BaseCPUHook):
+    def hook_32(self):
+        print "Hello World!"
+    def hook_33(self):
+        print "Current Register values:"
+        print self.cpu.ax.b
+        print self.cpu.bx.b
+        print self.cpu.cx.b
+        print self.cpu.dx.b
+
 class InvalidInterrupt(Exception):
     pass
 
         self.mem = Memory(64)
         self.storage = Storage('storage', 4096)
         self.imem = Memory(1024)
+        self.cpu_hooks = {}
         if filename != None:
             self.loadbin(filename)
     def loadbin(self, filename):
         self.mem.ptr = 0
     def savebin(self, filename):
         open(filename, 'wb').write(self.mem.mem.getvalue())
+    def add_cpu_hook(self, klass, opcode):
+        hook = klass(self)
+        self.cpu_hooks.update({opcode: hook})
     def dump(self):
         self.mem.ptr = 0
         for i in range(0, (len(self.mem)/2)-1):
             elif op == 16:
                 if self.cx != self.mem.read():
                     self.mem.ptr = self.dx.b
+            elif self.cpu_hooks.has_key(op):
+                self.cpu_hooks[op](self.mem.read().b)
 
 if __name__ == '__main__':
     #import readline
     c = CPU('hello.bin')
+    #c.add_cpu_hook(HelloWorldHook, 60)
     c.run()
     #cli = Coder(c)
     #cli()