2019-04-17 21:03:20 -04:00
|
|
|
#!/usr/bin/python
|
|
|
|
# Generate almost all possible combination for instructions from instruction
|
|
|
|
# tables
|
|
|
|
|
2019-04-20 22:37:38 -04:00
|
|
|
import sys
|
|
|
|
|
2019-04-21 11:49:20 -04:00
|
|
|
# Those lines below are improperly assembled by scas and are skipped by tests.
|
|
|
|
BLACKLIST = {
|
|
|
|
"AND (IX)",
|
|
|
|
"AND (IY)",
|
|
|
|
}
|
|
|
|
|
2019-04-17 21:03:20 -04:00
|
|
|
argspecTbl = {
|
|
|
|
'A': "A",
|
|
|
|
'B': "B",
|
|
|
|
'C': "C",
|
2019-04-21 13:58:13 -04:00
|
|
|
'k': "(C)",
|
2019-04-17 21:03:20 -04:00
|
|
|
'D': "D",
|
|
|
|
'E': "E",
|
|
|
|
'H': "H",
|
|
|
|
'L': "L",
|
2019-04-21 14:49:33 -04:00
|
|
|
'I': "I",
|
|
|
|
'R': "R",
|
2019-04-17 21:03:20 -04:00
|
|
|
'h': "HL",
|
|
|
|
'l': "(HL)",
|
|
|
|
'd': "DE",
|
|
|
|
'e': "(DE)",
|
|
|
|
'b': "BC",
|
|
|
|
'c': "(BC)",
|
|
|
|
'a': "AF",
|
|
|
|
'f': "AF'",
|
2019-04-20 22:56:22 -04:00
|
|
|
'X': "IX",
|
2019-04-17 21:03:20 -04:00
|
|
|
'x': "(IX)",
|
2019-04-20 22:56:22 -04:00
|
|
|
'Y': "IY",
|
2019-04-17 21:03:20 -04:00
|
|
|
'y': "(IY)",
|
|
|
|
's': "SP",
|
|
|
|
'p': "(SP)",
|
|
|
|
'Z': "Z",
|
|
|
|
'z': "NZ",
|
|
|
|
'=': "NC",
|
|
|
|
'+': "P",
|
|
|
|
'-': "M",
|
|
|
|
'1': "PO",
|
|
|
|
'2': "PE",
|
|
|
|
}
|
|
|
|
|
|
|
|
argGrpTbl = {
|
|
|
|
chr(0x01): "bdha",
|
|
|
|
chr(0x02): "ZzC=",
|
|
|
|
chr(0x03): "bdhs",
|
2019-04-20 22:56:22 -04:00
|
|
|
chr(0x04): "bdXs",
|
|
|
|
chr(0x05): "bdYs",
|
2019-04-17 21:03:20 -04:00
|
|
|
chr(0x0a): "ZzC=+-12",
|
|
|
|
chr(0x0b): "BCDEHLA",
|
|
|
|
}
|
|
|
|
|
2019-04-20 22:37:38 -04:00
|
|
|
def cleanupLine(line):
|
|
|
|
line = line.strip()
|
|
|
|
idx = line.rfind(';')
|
|
|
|
if idx >= 0:
|
|
|
|
line = line[:idx]
|
|
|
|
return line
|
|
|
|
|
|
|
|
def getDbLines(fp, tblname):
|
|
|
|
lookingFor = f"{tblname}:"
|
|
|
|
line = fp.readline()
|
|
|
|
while line:
|
|
|
|
line = cleanupLine(line)
|
|
|
|
if line == lookingFor:
|
|
|
|
break
|
|
|
|
line = fp.readline()
|
|
|
|
else:
|
|
|
|
raise Exception(f"{tblname} not found")
|
|
|
|
|
|
|
|
result = []
|
|
|
|
line = fp.readline()
|
|
|
|
while line:
|
|
|
|
line = cleanupLine(line)
|
|
|
|
if line:
|
|
|
|
if not line.startswith('.db'):
|
|
|
|
break
|
|
|
|
result.append([s.strip() for s in line[4:].split(',')])
|
|
|
|
line = fp.readline()
|
|
|
|
return result
|
2019-04-17 21:03:20 -04:00
|
|
|
|
|
|
|
def genargs(argspec):
|
|
|
|
if not argspec:
|
|
|
|
return ''
|
|
|
|
if not isinstance(argspec, str):
|
|
|
|
argspec = chr(argspec)
|
|
|
|
if argspec in 'nmNM':
|
|
|
|
bits = 16 if argspec in 'NM' else 8
|
|
|
|
nbs = [str(1 << i) for i in range(bits)]
|
|
|
|
if argspec in 'mM':
|
|
|
|
nbs = [f"({n})" for n in nbs]
|
|
|
|
return nbs
|
2019-04-21 10:55:47 -04:00
|
|
|
if argspec in 'xy':
|
|
|
|
# IX/IY displacement is special
|
|
|
|
base = argspecTbl[argspec]
|
|
|
|
result = [base]
|
|
|
|
argspec = argspec.upper()
|
|
|
|
for n in [1, 10, 100, 127]:
|
|
|
|
result.append(f"(I{argspec}+{n})")
|
|
|
|
# TODO: support minus
|
|
|
|
return result
|
2019-04-17 21:03:20 -04:00
|
|
|
if argspec in argspecTbl:
|
|
|
|
return [argspecTbl[argspec]]
|
|
|
|
grp = argGrpTbl[argspec]
|
|
|
|
return [argspecTbl[a] for a in grp]
|
|
|
|
|
2019-04-21 11:49:20 -04:00
|
|
|
def p(line):
|
|
|
|
if line not in BLACKLIST:
|
|
|
|
print(line)
|
|
|
|
|
2019-04-17 21:03:20 -04:00
|
|
|
|
|
|
|
def main():
|
2019-04-20 22:37:38 -04:00
|
|
|
asmfile = sys.argv[1]
|
|
|
|
with open(asmfile, 'rt') as fp:
|
|
|
|
instrTbl = getDbLines(fp, 'instrTBl')
|
|
|
|
for row in instrTbl:
|
2019-04-30 20:25:38 -04:00
|
|
|
n = row[0][2:] # remove I_
|
2019-04-20 22:37:38 -04:00
|
|
|
# we need to adjust for zero-char name filling
|
2019-04-30 20:25:38 -04:00
|
|
|
a1 = eval(row[1])
|
|
|
|
a2 = eval(row[2])
|
2019-04-17 21:03:20 -04:00
|
|
|
args1 = genargs(a1)
|
2019-04-21 12:58:28 -04:00
|
|
|
# special case handling
|
|
|
|
if n == 'JP' and isinstance(a1, str) and a1 in 'xy':
|
|
|
|
# we don't test the displacements for IX/IY because there can't be
|
|
|
|
# any.
|
|
|
|
args1 = args1[:1]
|
2019-07-02 14:12:29 -04:00
|
|
|
if n in {'BIT', 'SET', 'RES'}:
|
2019-04-21 13:41:55 -04:00
|
|
|
# we only want to keep 1, 2, 4
|
|
|
|
args1 = args1[:3]
|
2019-04-21 13:58:13 -04:00
|
|
|
if n == 'IM':
|
|
|
|
args1 = [0, 1, 2]
|
2019-04-17 21:03:20 -04:00
|
|
|
if args1:
|
|
|
|
for arg1 in args1:
|
|
|
|
args2 = genargs(a2)
|
|
|
|
if args2:
|
|
|
|
for arg2 in args2:
|
2019-04-21 11:49:20 -04:00
|
|
|
p(f"{n} {arg1}, {arg2}")
|
2019-04-17 21:03:20 -04:00
|
|
|
else:
|
2019-04-21 11:49:20 -04:00
|
|
|
p(f"{n} {arg1}")
|
2019-04-17 21:03:20 -04:00
|
|
|
else:
|
2019-04-21 11:49:20 -04:00
|
|
|
p(n)
|
2019-04-17 21:03:20 -04:00
|
|
|
pass
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|