Commits

Kevin Veroneau  committed 5fbbc18

Initial code import.

  • Participants

Comments (0)

Files changed (1)

+from cStringIO import StringIO
+import sys
+
+class Unit(object):
+    def __init__(self, default=0):
+        self.value = default
+    def __setattr__(self, name, value):
+        if name == 'value':
+            if isinstance(value, str):
+                value = ord(value)
+            if isinstance(value, int):
+                if value > 255 or value < 0:
+                    raise ValueError
+                object.__setattr__(self, '_value', value)
+            else:
+                raise TypeError
+    def __add__(self, other):
+        if isinstance(other, int):
+            return Unit(self._value + other)
+        elif isinstance(other, Unit):
+            return Unit(self._value + other.b)
+        else:
+            raise NotImplemented
+    def __sub__(self, other):
+        if isinstance(other, int):
+            return Unit(self._value - other)
+        elif isinstance(other, Unit):
+            return Unit(self._value - other.b)
+        else:
+            raise NotImplemented
+    def __eq__(self, other):
+        if isinstance(other, int) and self._value == other:
+            return True
+        elif isinstance(other, Unit) and self._value == other.b:
+            return True
+        else:
+            return False
+    def __ne__(self, other):
+        if isinstance(other, int) and self._value != other:
+            return True
+        elif isinstance(other, Unit) and self._value != other.b:
+            return True
+        else:
+            return False
+    @property
+    def b(self):
+        """Get the byte value."""
+        return self._value
+    @property
+    def c(self):
+        """Get the ascii value."""
+        return chr(self._value)
+
+class Memory(object):
+    def __init__(self, size):
+        self.mem = StringIO()
+        self.size = size
+        self.clear()
+    def clear(self):
+        self.mem.seek(0)
+        self.mem.write('\x00' * self.size)
+        self.mem.seek(0)
+        self._ptr = 0
+    def __len__(self):
+        return self.size
+    def __check_key(self, key):
+        if not isinstance(key, int):
+            raise TypeError
+        if key < 0 or key > self.size-1:
+            raise IndexError
+        self._ptr = self.ptr
+    def __getitem__(self, key):
+        self.__check_key(key)
+        self.mem.seek(key)
+        value = self.mem.read(1)
+        self.mem.seek(self._ptr)
+        return Unit(value)
+    def __setitem__(self, key, value):
+        self.__check_key(key)
+        self.mem.seek(key)
+        self.write(value)
+        self.mem.seek(self._ptr)
+    @property
+    def ptr(self):
+        return self.mem.tell()
+    @ptr.setter
+    def ptr(self, value):
+        if not isinstance(value, int):
+            raise TypeError
+        if value < 0 or value > self.size-1:
+            raise ValueError
+        self.mem.seek(value)
+    def read(self, bytes=1):
+        if self.eom:
+            print "Memory error: %d" % self.ptr
+        if bytes == 1:
+            return Unit(self.mem.read(1))
+        return self.mem.read(bytes)
+    def write(self, value):
+        if isinstance(value, Unit):
+            self.mem.write(value.c)
+        elif isinstance(value, int):
+            self.mem.write(chr(value))
+        elif isinstance(value, str):
+            self.mem.write(value)
+        else:
+            raise ValueError
+    def readstring(self, term='\x00'):
+        s = ''
+        while True:
+            if self.ptr > self.size-1: break
+            c = self.mem.read(1)
+            if c == term: break
+            s += c
+        return s
+    @property
+    def eom(self):
+        return self.ptr > self.size-1
+    def memcopy(self, src, dest, size):
+        self._ptr = self.ptr
+        self.mem.seek(src)
+        buf = self.mem.read(size)
+        self.mem.seek(dest)
+        self.mem.write(buf)
+        self.mem.seek(self._ptr)
+    def memclear(self, src, size):
+        self._ptr = self.ptr
+        self.mem.seek(src)
+        self.mem.write('\x00' * size)
+        self.mem.seek(self._ptr)
+
+class Storage(Memory):
+    def __init__(self, filename, size):
+        self.size = size
+        try:
+            self.mem = open(filename, 'r+b')
+        except IOError:
+            self.mem = open(filename, 'w+b')
+            self.clear()
+
+class Coder(object):
+    bc_map = {
+        'int': 1,
+        'ax': 2,
+        'bx': 3,
+        'cx': 4,
+        'dx': 5,
+        'jmp': 6,
+        'push': 7,
+        'pop': 8,
+        'call': 9,
+        'cx++': 10,
+        'cx--': 11,
+        'addcx': 12,
+        'subcx': 13,
+        'use': 14,
+        'if=': 15,
+        'if!': 16,
+    }
+    def __init__(self, cpu):
+        if not isinstance(cpu, CPU):
+            raise TypeError
+        self.cpu = cpu
+    def parse(self, c):
+        try:
+            sp = c.index(' ')
+            return (c[0:sp], c[sp+1:])
+        except ValueError:
+            return (c, '')
+    def __call__(self):
+        while True:
+            op, arg = self.parse(raw_input("%d " % self.cpu.mem.ptr))
+            if op in self.bc_map:
+                self.cpu.mem.write(self.bc_map[op])
+                if arg != '':
+                    self.cpu.mem.write(int(arg))
+            elif op == 'boot':
+                if arg != '':
+                    self.cpu.run(int(arg))
+                else:
+                    self.cpu.run(self.cpu.mem.ptr)
+            elif op == 'string':
+                for c in arg:
+                    self.cpu.mem.write(2)
+                    self.cpu.mem.write(ord(c))
+                    self.cpu.mem.write(1)
+                    self.cpu.mem.write(3)
+            elif op == 'ptr':
+                if arg != '':
+                    self.cpu.mem.ptr = int(arg)
+                else:
+                    print self.cpu.mem.ptr
+            elif op == 'dump':
+                if arg != '':
+                    ptr = int(arg)
+                else:
+                    ptr = self.cpu.mem.ptr
+                print self.cpu.mem[ptr].b
+            elif op == 'dump+':
+                print self.cpu.mem.read().b
+            elif op == 'savebin':
+                if arg != '':
+                    self.cpu.savebin(arg)
+            elif op == 'loadbin':
+                if arg != '':
+                    self.cpu.loadbin(arg)
+            elif op == 'clear':
+                self.cpu.mem.clear()
+            elif op == 'data':
+                for c in arg:
+                    self.cpu.mem.write(ord(c))
+                self.cpu.mem.write(0)
+            elif op == 'set':
+                if arg != '':
+                    self.cpu.mem.write(int(arg))
+            elif op == 'bp':
+                if arg != '':
+                    self.cpu.bp = int(arg)
+                else:
+                    self.cpu.bp = self.cpu.mem.ptr
+            elif op == 'cbp':
+                del self.cpu.bp
+            elif op == '.' or self.cpu.mem.eom:
+                break
+        self.cpu.savebin('dump')
+
+class CPU(object):
+    ax = Unit()
+    bx = Unit()
+    cx = Unit()
+    dx = Unit()
+    def __init__(self, filename=None):
+        self.mem = Memory(64)
+        self.storage = Storage('storage', 4096)
+        self.imem = Memory(1024)
+        if filename != None:
+            self.loadbin(filename)
+    def loadbin(self, filename):
+        self.mem.clear()
+        self.mem.write(open(filename, 'rb').read())
+        self.mem.ptr = 0
+    def savebin(self, filename):
+        open(filename, 'wb').write(self.mem.mem.getvalue())
+    def dump(self):
+        self.mem.ptr = 0
+        for i in range(0, (len(self.mem)/2)-1):
+            print "%d, %d" % (self.mem.read().b, self.mem.read().b)
+    def do_int(self, i):
+        if i == 1:
+            return 1
+        elif i == 2:
+            print "CPU: Screen support not implemented."
+        elif i == 3:
+            sys.stdout.write("%s" % self.ax.c)
+        elif i == 4:
+            print "CPU: Screen support not implemented."
+        elif i == 5:
+            self.mem.memcopy(self.ax.b, self.bx.b, self.cx.b)
+        elif i == 6:
+            self.mem.memclear(self.ax.b, self.cx.b)
+        elif i == 7:
+            self.storage.ptr = self.ax.b
+        elif i == 8:
+            ptr = self.mem.ptr
+            self.mem.ptr = self.ax.b
+            self.mem.write(self.storage.read(self.cx.b))
+            self.mem.ptr = ptr
+        elif i == 9:
+            ptr = self.mem.ptr
+            self.mem.ptr = self.ax.b
+            self.storage.write(self.mem.read(self.cx.b))
+            self.mem.ptr = ptr
+        elif i == 10:
+            ptr = self.mem.ptr
+            self.mem.ptr = self.ax.b
+            print self.mem.readstring()
+            self.mem.ptr = ptr
+        elif i == 11:
+            print "Single key input not implemented."
+            self.mem[self.cx.b] = 'A'
+        elif i == 12:
+            ptr = self.mem.ptr
+            self.mem.ptr = self.ax.b
+            s = raw_input()
+            for c in s:
+                self.mem.write(ord(c))
+            self.mem.write(0)
+            self.cx.value = len(s)
+            self.mem.ptr = ptr
+        elif i == 40:
+            ptr = self.mem.ptr
+            self.mem.ptr = self.ax.b
+            self.imem.ptr = self.bx.b
+            self.imem.write(self.mem.read(self.cx.b))
+            self.mem.memclear(self.ax.b, self.cx.b)
+            self.mem.ptr = ptr
+        elif i == 41:
+            ptr = self.mem.ptr
+            self.imem.ptr = self.ax.b
+            self.mem.ptr = self.bx.b
+            self.mem.write(self.imem.read(self.cx.b))
+            self.imem.memclear(self.ax.b, self.cx.b)
+            self.mem.ptr = ptr
+        elif i == 42:
+            self.imem.ptr = self.ax.b
+            self.storage.write(self.imem.read(self.cx.b))
+        elif i == 43:
+            self.imem.ptr = self.ax.b
+            self.imem.write(self.storage.read(self.cx.b))
+        elif i == 255:
+            self.savebin('dump')
+            cli = Coder(self)
+            cli()
+        return 0
+    def run(self, ptr=0):
+        self.mem.ptr = ptr
+        exitcode = 0
+        sjmp = ptr
+        while True:
+            if 'bp' in self.__dict__ and self.bp == self.mem.ptr: break
+            if self.mem.eom: break
+            op = self.mem.read().b
+            if op == 1:
+                rt = self.do_int(self.mem.read().b)
+                if rt == 1:
+                    exitcode = 1
+                    break
+            elif op == 2:
+                self.ax = self.mem.read()
+            elif op == 3:
+                self.bx = self.mem.read()
+            elif op == 4:
+                self.cx = self.mem.read()
+            elif op == 5:
+                self.dx = self.mem.read()
+            elif op == 6:
+                jmp = self.mem.read()
+                self.mem.ptr = jmp.b
+            elif op == 7:
+                sjmp = self.mem.ptr
+            elif op == 8:
+                self.mem.ptr = sjmp
+            elif op == 9:
+                sjmp = self.mem.ptr + 1
+                jmp = self.mem.read()
+                self.mem.ptr = jmp.b
+            elif op == 10:
+                self.cx += 1
+            elif op == 11:
+                self.cx -= 1
+            elif op == 12:
+                self.cx += self.mem.read()
+            elif op == 13:
+                self.cx -= self.mem.read()
+            elif op == 14:
+                self.cx = self.mem[self.cx.b]
+            elif op == 15:
+                if self.cx == self.mem.read():
+                    self.mem.ptr = self.dx.b
+            elif op == 16:
+                if self.cx != self.mem.read():
+                    self.mem.ptr = self.dx.b
+
+if __name__ == '__main__':
+    import readline
+    c = CPU('bios')
+    cli = Coder(c)
+    cli()