Commit bbf6360e authored by Brandon Warner's avatar Brandon Warner
Browse files

added more instructions and started work on designing a test framework

parent 6bc724ae
......@@ -31,7 +31,7 @@ INSTS = [
{"inst":"ld","size":2,"arg_re":re.compile("c, *([^\\s]*)"), "bytecode": 0x0E, "out":struct.Struct('<BB')}, # ld c, *
{"inst":"rrca","size":1,"arg_re":None, "bytecode": 0x0F, "out":struct.Struct('<B')}, # rrca
{"inst":"djnz","size":2,"arg_re":re.compile("([^\\s]*)"), "bytecode": 0x10, "out":struct.Struct('<BB')}, # djnz *
{"inst":"djnz","size":2,"arg_re":re.compile("([^\\s]*)"), "bytecode": 0x10, "out":struct.Struct('<Bb')}, # djnz *
{"inst":"ld","size":3,"arg_re":re.compile("de, *(0x[a-fA-F0-9]{1,4}|[A-Z_]+)"), "bytecode": 0x11, "out":struct.Struct('<BH')},# ld de,**
{"inst":"ld","size":1,"arg_re":re.compile("\\(de\\), *a"), "bytecode": 0x12, "out":struct.Struct('<B')}, # ld (de), a
{"inst":"inc","size":1,"arg_re":re.compile("de"), "bytecode": 0x13, "out":struct.Struct('<B')}, # inc de
......@@ -48,9 +48,9 @@ INSTS = [
{"inst":"ld","size":2,"arg_re":re.compile("e, *([^\\s]*)"), "bytecode": 0x1E, "out":struct.Struct('<BB')}, # ld e, *
{"inst":"rra","size":1,"arg_re":None, "bytecode": 0x1F, "out":struct.Struct('<B')}, # rra
{"inst": "jr", "size": 2, "arg_re": re.compile("nz, *([^\\s]*)"), "bytecode": 0x20, "out": struct.Struct('<Bb')}, # jp nz, *
{"inst": "jr", "size": 2, "arg_re": re.compile("nz, *([^\\s]*)"), "bytecode": 0x20, "out": struct.Struct('<Bb')}, # jr nz, *
{"inst": "ld", "size": 3, "arg_re": re.compile("hl, *(0x[a-fA-F0-9]{1,4}|[A-Z_]+)"), "bytecode": 0x21, "out": struct.Struct('<BH')}, # ld hl,**
{"inst": "ld", "size": 1, "arg_re": re.compile("\\(hl\\), *a"), "bytecode": 0x22, "out": struct.Struct('<B')}, # ld (hl), a
{"inst": "ld", "size": 3, "arg_re": re.compile("\\((0x[a-fA-F0-9]{1,4}|[A-Z_]+)\\), hl"), "bytecode": 0x22, "out": struct.Struct('<BH')}, # ld (**), hl
{"inst": "inc", "size": 1, "arg_re": re.compile("hl"), "bytecode": 0x23, "out": struct.Struct('<B')}, # inc hl
{"inst": "inc", "size": 1, "arg_re": re.compile("h"), "bytecode": 0x24, "out": struct.Struct('<B')}, # inc h
{"inst": "dec", "size": 1, "arg_re": re.compile("h"), "bytecode": 0x25, "out": struct.Struct('<B')}, # dec h
......@@ -59,11 +59,38 @@ INSTS = [
{"inst": "jr", "size": 2, "arg_re": re.compile("z, *([^\\s]*)"), "bytecode": 0x28, "out": struct.Struct('<Bb')}, # jr z, *
{"inst": "add", "size": 1, "arg_re": re.compile("hl, *hl"), "bytecode": 0x29, "out": struct.Struct('<B')}, # add hl, hl
{"inst": "ld", "size": 3, "arg_re": re.compile("hl, *\\((0x[a-fA-F0-9]{1,4}|[A-Z_]+)\\)"), "bytecode": 0x2A, "out": struct.Struct('<BH')}, # ld hl, (**)
{"inst": "dec", "size": 1, "arg_re": re.compile("hl"), "bytecode": 0x2B, "out": struct.Struct('<B')}, # hl
{"inst": "dec", "size": 1, "arg_re": re.compile("hl"), "bytecode": 0x2B, "out": struct.Struct('<B')}, # dec hl
{"inst": "inc", "size": 1, "arg_re": re.compile("l"), "bytecode": 0x2C, "out": struct.Struct('<B')}, # inc l
{"inst": "dec", "size": 1, "arg_re": re.compile("l"), "bytecode": 0x2D, "out": struct.Struct('<B')}, # dec l
{"inst": "ld", "size": 2, "arg_re": re.compile("l, *([^\\s]*)"), "bytecode": 0x2E, "out": struct.Struct('<BB')}, # ld l, *
{"inst": "cpl", "size": 1, "arg_re": None, "bytecode": 0x2F, "out": struct.Struct('<B')}, # cpl
{"inst": "jr", "size": 2, "arg_re": re.compile("nc, *([^\\s]*)"), "bytecode": 0x30, "out": struct.Struct('<Bb')}, # jp nc, *
{"inst": "ld", "size": 3, "arg_re": re.compile("sp, *(0x[a-fA-F0-9]{1,4}|[A-Z_]+)"), "bytecode": 0x31, "out": struct.Struct('<BH')}, # ld sp,**
{"inst": "ld", "size": 3, "arg_re": re.compile("\\((0x[a-fA-F0-9]{1,4}|[A-Z_]+)\\), *a"), "bytecode": 0x32, "out": struct.Struct('<BH')}, # ld (**), a
{"inst": "inc", "size": 1, "arg_re": re.compile("sp"), "bytecode": 0x33, "out": struct.Struct('<B')}, # inc sp
{"inst": "inc", "size": 1, "arg_re": re.compile("\\(hl\\)"), "bytecode": 0x34, "out": struct.Struct('<B')}, # inc hl
{"inst": "dec", "size": 1, "arg_re": re.compile("\\(hl\\)"), "bytecode": 0x35, "out": struct.Struct('<B')}, # dec hl
{"inst": "ld", "size": 2, "arg_re": re.compile("\\(hl\\), *([^\\s]*)"), "bytecode": 0x36, "out": struct.Struct('<BB')}, # ld hl, *
{"inst": "scf", "size": 1, "arg_re": None, "bytecode": 0x37, "out": struct.Struct('<B')}, # scf
{"inst": "jr", "size": 2, "arg_re": re.compile("c, *([^\\s]*)"), "bytecode": 0x38, "out": struct.Struct('<Bb')}, # jr c, *
{"inst": "add", "size": 1, "arg_re": re.compile("hl, *sp"), "bytecode": 0x39, "out": struct.Struct('<B')}, # add hl, sp
{"inst": "ld", "size": 3, "arg_re": re.compile("a, *\\((0x[a-fA-F0-9]{1,4}|[A-Z_]+)\\)"), "bytecode": 0x3A, "out": struct.Struct('<BH')}, # ld a, (**)
{"inst": "dec", "size": 1, "arg_re": re.compile("sp"), "bytecode": 0x3B, "out": struct.Struct('<B')}, # dec sp
{"inst": "inc", "size": 1, "arg_re": re.compile("a"), "bytecode": 0x3C, "out": struct.Struct('<B')}, # inc a
{"inst": "dec", "size": 1, "arg_re": re.compile("a"), "bytecode": 0x3D, "out": struct.Struct('<B')}, # dec a
{"inst": "ld", "size": 2, "arg_re": re.compile("a, *([^\\s]*)"), "bytecode": 0x3E, "out": struct.Struct('<BB')}, # ld a, *
{"inst": "ccf", "size": 1, "arg_re": None, "bytecode": 0x3F, "out": struct.Struct('<B')}, # ccf
{"inst":"ld","size":1,"arg_re":re.compile("b, *b"), "bytecode": 0x40, "out":struct.Struct('<B')}, # ld b, b
{"inst":"ld","size":1,"arg_re":re.compile("b, *c"), "bytecode": 0x41, "out":struct.Struct('<B')}, # ld b, c
{"inst":"ld","size":1,"arg_re":re.compile("b, *d"), "bytecode": 0x42, "out":struct.Struct('<B')}, # ld b, d
{"inst":"ld","size":1,"arg_re":re.compile("b, *e"), "bytecode": 0x43, "out":struct.Struct('<B')}, # ld b, e
{"inst":"ld","size":1,"arg_re":re.compile("b, *h"), "bytecode": 0x44, "out":struct.Struct('<B')}, # ld b, h
{"inst":"ld","size":1,"arg_re":re.compile("b, *l"), "bytecode": 0x45, "out":struct.Struct('<B')}, # ld b, l
{"inst":"ld","size":1,"arg_re":re.compile("b, *\\(hl\\)"), "bytecode": 0x46, "out":struct.Struct('<B')}, # ld b, (hl)
{"inst":"ld","size":1,"arg_re":re.compile("b, *a"), "bytecode": 0x47, "out":struct.Struct('<B')}, # ld b, a
]
HEX_RE = re.compile("0x[A-Fa-f0-9]+")
......@@ -103,21 +130,28 @@ def get_inst(inst,args=None):
return (None, None)
def parse_arg(arg, parsed_lines):
if HEX_RE.match(arg):
if HEX_RE.fullmatch(arg):
return int(arg, 16)
elif INT_RE.match(arg):
elif INT_RE.fullmatch(arg):
return int(arg)
elif LABEL_RE.match(arg):
elif LABEL_RE.fullmatch(arg):
for pl in parsed_lines:
if "label" in pl.keys():
if arg == pl["label"]:
return pl['addr']
elif CHAR_RE.match(arg):
if "addr" in pl.keys():
return pl['addr']
else:
print("error")
pprint.pprint(pl)
return None
elif CHAR_RE.fullmatch(arg):
m = CHAR_RE.match(arg)
return ord(m.groups()[0])
def assemble(input, output):
LABELS = {}
addr = 0
code_lines = get_all_code(input)
if VERBOSE:
for l in code_lines:
......@@ -131,6 +165,7 @@ def assemble(input, output):
t = {}
i = 0
r = "code"
inquote = False
while i < len(line):
c = line[i]
......@@ -139,11 +174,14 @@ def assemble(input, output):
if len(l) > 0:
t[r] = "".join(l).strip()
elif c == ":":
if len(l) > 0:
t["label"] = "".join(l).strip()
l = []
if not inquote:
if len(l) > 0:
t["label"] = "".join(l).strip()
l = []
else:
pass #TODO throw error at empty label name
else:
pass #TODO throw error at empty label name
l.append(c)
elif c == ";":
if len(l) > 0:
t[r] = "".join(l).strip()
......@@ -151,46 +189,48 @@ def assemble(input, output):
r = "comment"
else:
l.append(c)
if c in "\"\'":
inquote = not inquote
i = i + 1
#print("\"%s\"[%i]=%s (%s):%s" % (line, i, c, "".join(l), r))
#print(t)
if len(l) > 0:
t[r] = "".join(l).strip()
parsed_lines.append(t)
if "code" in t.keys() and len(t["code"]) == 0:
t.pop("code", None)
for pl in parsed_lines:
if "code" in pl.keys():
i = INSTRUCTION_RE.match(pl["code"])
if "code" in t.keys():
i = INSTRUCTION_RE.match(t["code"])
if i is not None:
ig = i.groups()
pl['inst'] = ig[0]
t['inst'] = ig[0]
if len(ig[1]) > 0:
pl['args'] = ig[1]
t['args'] = ig[1]
#if VERBOSE: pprint.pprint(i.groups())
else:
print("error: " + pl["code"])
print("error[" + line + "]: \"" + t["code"] + "\"")
pprint.pprint(t)
# Parse to get inst
for pl in parsed_lines:
if "code" in pl.keys():
ist = get_inst(pl["inst"], pl["args"] if "args" in pl.keys() else None)
ist = get_inst(t["inst"], t["args"] if "args" in t.keys() else None)
pprint.pprint(ist)
pl["id"] = ist[0]
t["id"] = ist[0]
if ist[1] is not None:
pl["re_match"] = ist[1]
pprint.pprint(parsed_lines)
t["re_match"] = ist[1]
if "inst" in t.keys():
if t["inst"] not in ['defb','defs','org','seek', 'equ']:
if "id" in t.keys() and t["id"] is not None:
t["addr"] = addr
addr = addr + t["id"]["size"]
else:
pprint.pprint(t)
elif t['inst'] == "org":
addr = int(t["args"],0)
elif "label" in t.keys():
t["addr"] = addr
addr = 0
for pl in parsed_lines:
if pl["inst"] not in ['defb','defs','org','seek']:
if "id" in pl.keys():
pl["addr"] = addr
addr = addr + pl["id"]["size"]
elif pl['inst'] == "org":
addr = int(pl["args"],0)
parsed_lines.append(t)
pprint.pprint(parsed_lines)
......@@ -202,10 +242,11 @@ def assemble(input, output):
for pl in parsed_lines:
if "id" in pl.keys() and pl["id"] is not None:
if "arg" in pl.keys():
if pl['id']['inst'] == "jr":
pl['arg'] = (pl['addr'] + 2 - pl['arg']) * -1
if pl['id']['inst'] in ["jr","djnz"]:
pl['arg'] = pl['arg'] - pl['addr'] - 2
print("jr")
pprint.pprint(pl)
print(type(pl['id']['bytecode']))
pl["bin"] = pl["id"]["out"].pack(pl['id']['bytecode'], pl['arg'])
else:
pl["bin"] = pl["id"]["out"].pack(pl['id']['bytecode'])
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment