1. Kevin Veroneau
  2. simple-cpu

Commits

Kevin Veroneau  committed 145ae0b

Updated documentation and removed CursesHook.

  • Participants
  • Parent commits 08de9ed
  • Branches default

Comments (0)

Files changed (3)

File CursesHook.py

-"""
-This python module includes a CPU Hook that enables controlled apps to use the ncurses library.
-This is an example of how you might extend the CPU simulator to access the outside world.
-"""
-
-from cpu import BaseCPUHook
-import curses
-
-class CursesHook(BaseCPUHook):
-    opcode = 67
-    opname = 'cur'
-    stdscr = None
-    def cleanup(self):
-        if self.stdscr is None:
-            return
-        self.stdscr.keypad(0)
-        curses.echo()
-        curses.nocbreak()
-        curses.endwin()
-        self.stdscr = None
-    def hook_1(self):
-        if self.stdscr is None:
-            self.stdscr = curses.initscr()
-            curses.noecho()
-            curses.cbreak()
-            self.stdscr.keypad(1)
-            try:
-                curses.start_color()
-            except:
-                pass
-            self.wins = []
-            self.style = curses.A_NORMAL
-    def hook_2(self):
-        if self.stdscr is None:
-            return
-        self.cpu.mem.push()
-        self.cpu.mem.ptr = self.cpu.ax.b
-        self.wins.append(curses.newwin(self.cpu.mem.read().b, self.cpu.mem.read().b, self.cpu.mem.read().b, self.cpu.mem.read().b))
-        self.cpu.ax.value = len(self.wins)-1
-        self.cpu.mem.pop()
-    def hook_3(self):
-        if self.stdscr is None:
-            return
-        self.cpu.mem.push()
-        self.cpu.mem.ptr = self.cpu.bx.b
-        text = self.cpu.mem.readstring()
-        self.cpu.mem.pop()
-        self.wins[self.cpu.ax.b].addstr(self.cpu.cx.b, self.cpu.dx.b, text, self.style)
-    def hook_4(self):
-        if self.stdscr is None:
-            return
-        self.cpu.cx.value = self.wins[self.cpu.ax.b].getch()
-    def hook_10(self):
-        if self.stdscr is None:
-            return
-        self.wins[self.cpu.ax.b].idlok(self.cpu.bx.b)
-    def hook_11(self):
-        if self.stdscr is None:
-            return
-        self.cpu.mem.push()
-        self.cpu.mem.ptr = self.cpu.bx.b
-        border = self.cpu.mem.read(8)
-        self.wins[self.cpu.ax.b].border(*list(border))
-        self.cpu.mem.pop()
-    def hook_255(self):
-        self.cleanup()

File cpu-hooks.txt

View file
 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 not by the op-codes/coder.
+The CPU Hooks interface has changed a lot since it was first released, it no longer supports custom op-code creation, as that
+made little sense, as CPUs don't just get new op-codes when you insert new hardware.  Rather they usually have their own
+memory addresses they access and that's how the CPU talks to the new hardware.  This I believe is called DMA(direct memory access).
 
-There is a Base class which must be sub-classed to make hooks work, there is an example Hook provided.
+The new hooks system works similar to the original system where you sub-class a special class and create methods there.
 
-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.
+The class you need to sub-class is BaseCPUHook, and you need to supply one class variable, called ports.  Here is an
+example Hello World one, taken from the previous Hooks example and tailored for the new system:
 
-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.
+class HelloWorldHook(BaseCPUHook):
+    """ This is an example I/O Hook which demonstrates how the I/O hook system works. """
+    ports = [32,33]
+    def out_32(self, addr):
+        self.addr = addr
+    def in_32(self):
+        self.cpu.mem[self.addr] = "Hello World!"
+        return self.addr
+    def out_33(self, reg):
+        sys.stdout.write("%s\n" % getattr(self.cpu, self.cpu.var_map[reg]).b)
 
-Here is the example HelloWorldHook to see how easy it is to use:
+Here we are telling the CPU that this virtual I/O device can be accessed on CPU I/O ports 32 and 33.  And we supply some logic for
+these ports to work within the CPU/Virtual Machine.  The first method "out_32" is an OUTPUT method, where the CPU can send some
+data over to this virtual device to process.  This is in the form of a register, so it will be a 16-bit integer.  The second
+method "in_32" allows the CPU to request data from this virtual device, the data returned should be a 16-bit integer.
 
---------------
-class HelloWorldHook(BaseCPUHook):
-    opcode = 60
-    opname = 'hlo'
-    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:
---------------
-hlo 32
-hlo 33
-int 1
-boot 0
---------------
-With this new updated version, you can select the opname along with the opcode in the subclass, and the coder will use it.
+To access these methods in your code using the included Coder interface, you can use them like so:
+
+mov ax,300
+out 32,ax
+in ax,32
+mov ax,1
+out 33,ax
+
+By using the standard OUT and IN operations you can write and read data from your virtual I/O device.
+The Virtual I/O device also has access to the CPU, and can access memory and other registers.
+You can use "self.cpu" to access the connected CPUs resources.

File introduction.txt

View file
 
 This file is provided as an introduction to how this works internally, please see the other text files for usage.
 
-The CPU core is fully customizable, but if any of the memory sizes are changed, it can break compatibility with other binary files.
-That being said, if your goal of using this code is to build your own virtual machine for your application, then feel free to change the memory sizes to suit your requirements:
+The CPU core is fully customizable, but if any of the op-codes are changed, it can break compatibility with other binary files.
+That being said, if your goal of using this code is to build your own virtual machine for your application, then feel free to change the op-codes to suit your requirements.
 
-CPU Klass:
-  Here you can add new registers, which you will also need to add new op-codes for manipulating them.
-  Default registers use the Unit class to define them.
+CPU Klass(sub-class of CPUCore):
   In the __init__ of this class is where the CPU Memory, persistent storage, and shared memory is initialized.
-  mem is a Memory class, using the default size of 64 bytes.  Increase the 64 to increase the size of the binary files and available executable memory.
-  storage is a Storage class, which is a subclass of Memory, using the default size of 4K.  This is the persistent storage which is accessed using a software interrupt.  Various code can storage and access data from here.
-  imem is a Memory class, using the default size of 1K.  This is the shared memory, where executable code can store non-executable data.  If you want to execute data from here, you need to first move it into CPU Memory.
+  mem is a Memory class, using the default size of 4096 bytes.
   The __init__ function also manages the loading of an initial binary file into the CPU itself.
   Example to load and run a binary file:
     c = CPU('myapp')
     c.run()
   You can add a parameter into run() to tell it where to start executing, say if your binary file has a header.
 
+CPUCore Klass:
+  This class is where all the magic happens, you shouldn't need to alter anything in here unless you have very specific requirements.
+  Instead you should either sub-class this and implement the needed __init__ method to initialize memory and devices, or
+  use the included CPU class which has support for standard OS disk and memory storage.
+
+CPURegisters Klass:
+  This class controls the CPU registers, you can subclass this and add/remove registers by changing the class variables.
+  registers variable is a list of all the available registers.
+  pushable variable is a list of registers which can be pushed onto the stack without any adverse effects at runtime.
+
 InvalidInterrupt Exception:
   This exception is raised if your binary code attempts to call an unhandled interrupt.
 
+CPUException Exception:
+  This exception is raised if there is a bytecode runtime error, usually caused by an error in the user's bytecode.
+
 HelloWorldHook Klass(sub-class of BaseCPUHook):
-  This is an example CPU Hook to display how a hook is created and used, it provided 2 functions to your binary.
-  This CPU hook is attached to CPU op-code 60, and the op-code used in the Coder is 'hlo'.
-  Function 32 just displays hello world to standard output.
-  Function 33 is an example of a debugging function which displays the current state of the CPU registers.
+  This is an example CPU Hook to display how a hook is created and used, it provided 3 functions to your binary.
+  This CPU hook is attached to CPU I/O ports 32 and 33.
+  I/O port 32 just stores hello world to CPU memory.
+  I/O port 33 is an example of a debugging function which displays the current state of the CPU registers.
+
+ConIOHook Klass(sub-class of BaseCPUHook):
+  This implements a basic tty-based display and keyboard for basic input/output operations from the CPU.
+  This CPU hook is attached to CPU I/O ports 4000, and 8000.
+  I/O port 4000 is input only and reads a single key stroke from the keyboard.
+  I/O port 8000 is output only and writes a character to the screen.
 
 BaseCPUHook Klass:
   This class is intended to be extended with your own CPU Hook code.  Please see HelloWorldHook as an example.
     self.storage = Storage('storage', 4096)
 
 Memory Klass:
-  This class is initialized with the size of memory to allocate(using StringIO).
+  This class is initialized with the size of memory to allocate(using mmap).
   There are many functions in this class which control the memory access facility, which the CPU uses.
   These functions will not be directly edited or used by you, as they are already implemented in the CPU op-codes.
   Essentually, this class is exposed as an array.  The CPU gets and sets memory locations using array syntax:
     mem[36] = 4
   This class also keeps track of the current pointer location, which is used by the CPU for various operations.
-  It is also able to read a null-terminated string with a helper function, which a software interrupt exposes.
+  It is also able to read a null-terminated string with a helper function.
   Other features include the clearing of all memory, local block copying, and local block clearing.
   Example:
     self.mem = Memory(64)
 
 Unit Klass:
-  This class I sometimes wonder if I really should have created it and built everything around it...
-  Here, the memory values are stored and validated to prevent Python exceptions.
-  It provides the facility to add and subtract Units or ints, and conditional matching.
-  It controls the attribute setting to prevent values outside the 255 range, which this CPU simulator does not yet support.
+  This is the base data Unit which this CPU Virtual Machine uses to exchange data between code, memory, and disk.
+  This class is meant to be sub-classed, see other Unit classes below for examples on how sub-classing works.
 
-Unit16 Klass:
-  This class is a subclass of Unit klass above, but is able to store 16-bit integers in 2-bytes.
+UInt8 Klass:
+  This is a Unit that only supports 8-bit integers.
 
-Please read the other included text files for more information on how to use this CPU simulator toolkit.
+UInt16 Klass:
+  This is a Unit that only supports 16-bit integers. This Unit is mostly used with memory addresses.
+
+UInt32 Klass:
+  This is a Unit that only supports 32-bit integers. This is not used much in the code at all, as the VM isn't really 32-bit address enabled.
+
+Please read the other included text files for more information on how to use this CPU simulator toolkit.