a-only valcode description and dispatching

spec_demo test passes again
This commit is contained in:
Loic Nageleisen 2012-04-29 12:26:58 +02:00
parent 45e71c9ff5
commit 882f3709cc

View file

@ -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"""