mirror of
https://github.com/lloeki/python-dcpu_16.git
synced 2025-12-06 09:54:39 +01:00
a-only valcode description and dispatching
spec_demo test passes again
This commit is contained in:
parent
45e71c9ff5
commit
882f3709cc
1 changed files with 29 additions and 16 deletions
45
dcpu_16.py
45
dcpu_16.py
|
|
@ -48,21 +48,27 @@ class opcode(object):
|
||||||
|
|
||||||
|
|
||||||
_valcode_map = {}
|
_valcode_map = {}
|
||||||
|
_valcode_a_map = {}
|
||||||
class valcode(object):
|
class valcode(object):
|
||||||
"""Valcode decorator"""
|
"""Valcode decorator"""
|
||||||
def __init__(self, valcode):
|
def __init__(self, valcode, a=False):
|
||||||
self.valcode = valcode
|
self.valcode = valcode
|
||||||
|
self.a = a
|
||||||
|
|
||||||
def __call__(self, f):
|
def __call__(self, f):
|
||||||
_valcode_f = f
|
_valcode_f = f
|
||||||
_valcode_f.valcode = self.valcode
|
_valcode_f.valcode = self.valcode
|
||||||
|
if self.a:
|
||||||
|
valcode_map = _valcode_a_map
|
||||||
|
else:
|
||||||
|
valcode_map = _valcode_map
|
||||||
try:
|
try:
|
||||||
for code in self.valcode:
|
for code in self.valcode:
|
||||||
# currify with (bound) code
|
# currify with (bound) code
|
||||||
_valcode_map[code] = lambda c, code=code: _valcode_f(c, code)
|
valcode_map[code] = lambda c, code=code: _valcode_f(c, code)
|
||||||
_valcode_map[code].__name__ = '%s(code=0x%02X)' % (_valcode_f.__name__, code)
|
valcode_map[code].__name__ = '%s(code=0x%02X)' % (_valcode_f.__name__, code)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
_valcode_map[self.valcode] = _valcode_f
|
valcode_map[self.valcode] = _valcode_f
|
||||||
return _valcode_f
|
return _valcode_f
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -368,16 +374,16 @@ def next_word_plus_register_value(c, code):
|
||||||
|
|
||||||
@valcode(0x18)
|
@valcode(0x18)
|
||||||
@pointerize
|
@pointerize
|
||||||
def push_pop(c):
|
|
||||||
"""(PUSH / [--SP]) if in b, or (POP / [SP++]) if in a"""
|
|
||||||
pass
|
|
||||||
def push(c):
|
def push(c):
|
||||||
"""[--SP] / PUSH"""
|
"""[--SP] / PUSH if in b"""
|
||||||
c.sp -= 1
|
c.sp -= 1
|
||||||
v = "c.m[0x%04X]" % c.sp
|
v = "c.m[0x%04X]" % c.sp
|
||||||
return v
|
return v
|
||||||
|
|
||||||
|
@valcode(0x18, a=True)
|
||||||
|
@pointerize
|
||||||
def pop(c):
|
def pop(c):
|
||||||
"""[SP++] / POP"""
|
"""[SP++] / POP if in a"""
|
||||||
v = "c.m[0x%04X]" % c.sp
|
v = "c.m[0x%04X]" % c.sp
|
||||||
c.sp += 1
|
c.sp += 1
|
||||||
return v
|
return v
|
||||||
|
|
@ -432,7 +438,7 @@ def next_word(c):
|
||||||
c.pc += 1
|
c.pc += 1
|
||||||
return v
|
return v
|
||||||
|
|
||||||
@valcode(range(0x20, 0x40))
|
@valcode(range(0x20, 0x40), a=True)
|
||||||
@pointerize
|
@pointerize
|
||||||
def literal(c, code):
|
def literal(c, code):
|
||||||
"""literal value 0xFFFF-0x1E (-1..30) (literal) (only for a)"""
|
"""literal value 0xFFFF-0x1E (-1..30) (literal) (only for a)"""
|
||||||
|
|
@ -501,12 +507,12 @@ class CPU(object):
|
||||||
try:
|
try:
|
||||||
op = _opcode_map[opcode]
|
op = _opcode_map[opcode]
|
||||||
try:
|
try:
|
||||||
op = op[a_code]
|
op = op[b_code]
|
||||||
except TypeError:
|
except TypeError:
|
||||||
args = (c._pointer(b_code),
|
args = (c._pointer(b_code),
|
||||||
c._pointer(a_code))
|
c._pointer(a_code, a=True))
|
||||||
else:
|
else:
|
||||||
args = (c._pointer(a_code),)
|
args = (c._pointer(a_code, a=True),)
|
||||||
finally:
|
finally:
|
||||||
if c.debug:
|
if c.debug:
|
||||||
log(' '.join([op.__name__] + [arg.codestr for arg in args]))
|
log(' '.join([op.__name__] + [arg.codestr for arg in args]))
|
||||||
|
|
@ -514,12 +520,19 @@ class CPU(object):
|
||||||
raise Exception('Invalid opcode %s at PC=%04X' % (["%02X"%x for x in opcode], c.pc))
|
raise Exception('Invalid opcode %s at PC=%04X' % (["%02X"%x for x in opcode], c.pc))
|
||||||
return op, args
|
return op, args
|
||||||
|
|
||||||
def _pointer(c, code):
|
def _pointer(c, code, a=False):
|
||||||
"""get pointer to valcode"""
|
"""get pointer to valcode"""
|
||||||
try:
|
try:
|
||||||
return _valcode_map[code](c)
|
if a:
|
||||||
|
try: # a-only valcodes
|
||||||
|
return _valcode_a_map[code](c)
|
||||||
|
except KeyError: # fallback to other values
|
||||||
|
return _valcode_map[code](c)
|
||||||
|
else:
|
||||||
|
# no a-only values
|
||||||
|
return _valcode_map[code](c)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise Exception("Invalid valcode")
|
raise Exception("Invalid valcode: 0x%02x" % code)
|
||||||
|
|
||||||
def __getitem__(c, code):
|
def __getitem__(c, code):
|
||||||
"""get value of valcode"""
|
"""get value of valcode"""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue