mirror of
https://github.com/lloeki/python-dcpu_16.git
synced 2025-12-06 09:54:39 +01:00
doc + cosmetic
This commit is contained in:
parent
bf055e998e
commit
64f3622ebe
1 changed files with 45 additions and 30 deletions
75
dcpu_16.py
75
dcpu_16.py
|
|
@ -1,21 +1,30 @@
|
||||||
|
"""DCPU-16 implementation. (c) 2012, Loic Nageleisen
|
||||||
|
|
||||||
|
Spec: http://0x10c.com/doc/dcpu-16.txt
|
||||||
|
|
||||||
|
See LICENSE for licensing information.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
from __future__ import print_function, division
|
from __future__ import print_function, division
|
||||||
|
|
||||||
|
|
||||||
|
# DCPU-16 spec version
|
||||||
|
spec = '1.1'
|
||||||
|
|
||||||
|
|
||||||
|
# log tool
|
||||||
def log(string):
|
def log(string):
|
||||||
print(" << %s" % string)
|
print(" << %s" % string)
|
||||||
|
|
||||||
#http://0x10c.com/doc/dcpu-16.txt
|
# width constants
|
||||||
spec = '1.1'
|
|
||||||
|
|
||||||
w = 16
|
w = 16
|
||||||
wmask = 2**w - 1
|
wmask = 2**w - 1
|
||||||
|
|
||||||
literals = [l for l in xrange(0, 0x20)]
|
|
||||||
|
|
||||||
_opcode_map = {}
|
_opcode_map = {}
|
||||||
_valcode_map = {}
|
|
||||||
|
|
||||||
|
|
||||||
class opcode(object):
|
class opcode(object):
|
||||||
|
"""Opcode decorator"""
|
||||||
def __init__(self, *opcode):
|
def __init__(self, *opcode):
|
||||||
self.opcode = opcode
|
self.opcode = opcode
|
||||||
|
|
||||||
|
|
@ -31,7 +40,9 @@ class opcode(object):
|
||||||
return _opcode_f
|
return _opcode_f
|
||||||
|
|
||||||
|
|
||||||
|
_valcode_map = {}
|
||||||
class valcode(object):
|
class valcode(object):
|
||||||
|
"""Valcode decorator"""
|
||||||
def __init__(self, valcode):
|
def __init__(self, valcode):
|
||||||
self.valcode = valcode
|
self.valcode = valcode
|
||||||
|
|
||||||
|
|
@ -49,19 +60,45 @@ class valcode(object):
|
||||||
|
|
||||||
|
|
||||||
class Register(object):
|
class Register(object):
|
||||||
|
"""Register descriptor"""
|
||||||
def __init__(self, regcode=None):
|
def __init__(self, regcode=None):
|
||||||
self.regcode = regcode
|
self.regcode = regcode
|
||||||
|
|
||||||
def __get__(self, c, type=None):
|
def __get__(self, c, type=None):
|
||||||
if self.regcode is not None:
|
if self.regcode is not None:
|
||||||
return c.r[self.regcode]
|
return c.r[self.regcode]
|
||||||
else:
|
else:
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def __set__(self, c, value):
|
def __set__(self, c, value):
|
||||||
if self.regcode is not None:
|
if self.regcode is not None:
|
||||||
c.r[self.regcode] = value & wmask
|
c.r[self.regcode] = value & wmask
|
||||||
else:
|
else:
|
||||||
self.value = value & wmask
|
self.value = value & wmask
|
||||||
|
|
||||||
|
def make_pointer(c, codestr):
|
||||||
|
"""creates a pointer func that evaluates codestr"""
|
||||||
|
def getter(c=c):
|
||||||
|
return eval("%s" % codestr)
|
||||||
|
def setter(data, c=c):
|
||||||
|
exec("%s = %r" % (codestr, data)) in {}, {'c': c, 'data': data}
|
||||||
|
pointer = getter
|
||||||
|
pointer.codestr = codestr
|
||||||
|
pointer.set = setter
|
||||||
|
return pointer
|
||||||
|
|
||||||
|
def pointerize(f):
|
||||||
|
"""wraps a function that generates a codestr to create a pointer"""
|
||||||
|
if f.func_code.co_argcount == 1:
|
||||||
|
ptrz = lambda c: make_pointer(c, f(c))
|
||||||
|
elif f.func_code.co_argcount == 2:
|
||||||
|
ptrz = lambda c, code: make_pointer(c, f(c, code))
|
||||||
|
else:
|
||||||
|
raise Exception('%s has too many arguments' % f.__name__)
|
||||||
|
ptrz.__name__ = 'ptr_to_%s' % f.__name__
|
||||||
|
ptrz.__doc__ = f.__doc__
|
||||||
|
return ptrz
|
||||||
|
|
||||||
|
|
||||||
@opcode(0x0, 0x01)
|
@opcode(0x0, 0x01)
|
||||||
def JSR(c, a):
|
def JSR(c, a):
|
||||||
|
|
@ -184,29 +221,6 @@ def IFB(c, a, b):
|
||||||
c.skip = True
|
c.skip = True
|
||||||
|
|
||||||
|
|
||||||
def make_pointer(c, codestr):
|
|
||||||
"""creates a pointer func that evaluates codestr"""
|
|
||||||
def getter(c=c):
|
|
||||||
return eval("%s" % codestr)
|
|
||||||
def setter(data, c=c):
|
|
||||||
exec("%s = %r" % (codestr, data)) in {}, {'c': c, 'data': data}
|
|
||||||
pointer = getter
|
|
||||||
pointer.codestr = codestr
|
|
||||||
pointer.set = setter
|
|
||||||
return pointer
|
|
||||||
|
|
||||||
def pointerize(f):
|
|
||||||
"""wraps a function that generates a codestr to create a pointer"""
|
|
||||||
if f.func_code.co_argcount == 1:
|
|
||||||
ptrz = lambda c: make_pointer(c, f(c))
|
|
||||||
elif f.func_code.co_argcount == 2:
|
|
||||||
ptrz = lambda c, code: make_pointer(c, f(c, code))
|
|
||||||
else:
|
|
||||||
raise Exception('%s has too many arguments' % f.__name__)
|
|
||||||
ptrz.__name__ = 'ptr_to_%s' % f.__name__
|
|
||||||
ptrz.__doc__ = f.__doc__
|
|
||||||
return ptrz
|
|
||||||
|
|
||||||
@valcode(range(0x00, 0x08))
|
@valcode(range(0x00, 0x08))
|
||||||
@pointerize
|
@pointerize
|
||||||
def register(c, code):
|
def register(c, code):
|
||||||
|
|
@ -318,6 +332,7 @@ class Memory(object):
|
||||||
|
|
||||||
|
|
||||||
class CPU(object):
|
class CPU(object):
|
||||||
|
"""DCPU-16"""
|
||||||
def __init__(c, memory=Memory(), debug=False):
|
def __init__(c, memory=Memory(), debug=False):
|
||||||
c.m = memory
|
c.m = memory
|
||||||
c.clear()
|
c.clear()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue