1
0
Fork 0
mirror of https://github.com/ctruLua/ctruLua.git synced 2025-10-27 16:39:29 +00:00
ctruLua/libs/aemstro/aemstro_as.py
2015-08-17 21:10:54 +02:00

682 lines
19 KiB
Python

import sys
import os
import re
import copy
import struct
#TODO : add parsing checks, handle errors more gracefully
def toFloat24(f):
f=bytearray(struct.pack('f', f))
s=f[3]>>7
tmp=(((f[3]<<1)|(f[2]>>7))&0xFF)-0x40
tmp2=(((f[0])|(f[1]<<8)|(f[2]<<16))>>7)&0xFFFF
if tmp>=0:
tmp2|=tmp<<16
tmp2|=s<<23
else:
tmp2=s<<23
return tmp2
vshMain=None
vshEndmain=None
gshMain=None
gshEndmain=None
class DVLE(object):
def __init__(self, type):
self._main = 0
self._endmain = 0
self._type = type
self._const = []
self._label = []
self._labelmap = {}
self._outmap = []
self._inmap = []
self._symbol = bytearray()
self._symbolnum = 0
def setMain(self, main):
self._main = main
def setEndmain(self, endmain):
self._endmain = endmain
#binary word tuple
def addConstant(self, const):
self._const.append(const)
#(reg, v)
def addConstantB(self, const):
self._const.append(((const[0]<<16)|(0x0), const[1], 0, 0, 0))
#(reg, x, y, z, w)
def addConstantI(self, const):
self._const.append(((const[0]<<16)|(0x1), ((const[1]&0xff)|((const[2]&0xff)<<8)|((const[3]&0xff)<<16)|(const[4]<<24)), (0), (0), (0)))
#(reg, x, y, z, w)
def addConstantF(self, const):
self._const.append(((const[0]<<16)|(0x2), toFloat24(const[1]), toFloat24(const[2]), toFloat24(const[3]), toFloat24(const[4])))
#string
def addSymbol(self, s):
ret=len(self._symbol)
self._symbol+=bytearray(s, "ascii")+bytearray(b"\x00")
self._symbolnum+=1
return ret
#(code offset, symbol offset)
def addLabel(self, label):
self._label.append((label[0],self.addSymbol(label[1])))
self._labelmap[label[1]]=label[0]
def getLabelAddress(self, label):
if label in self._labelmap:
return self._labelmap[label]
else:
return 0x0
#binary word tuple
def addOutput(self, out):
self._outmap.append(out)
#(startreg, endreg, symbol offset)
def addInput(self, ind):
self._inmap.append((ind[0],ind[1],self.addSymbol(ind[2])))
def toBinary(self):
ret=[]
offsetConst=0x40
offsetLabel=offsetConst+len(self._const)*0x14
offsetOutmap=offsetLabel+len(self._label)*0x10
offsetInmap=offsetOutmap+len(self._outmap)*0x8
offsetSymbol=offsetInmap+len(self._inmap)*0x8
ret.append(0x454C5644) #DVLE magic
ret.append((self._type&1)<<16)
ret.append(self._main)
ret.append(self._endmain)
ret.append(0x00000000) # ?
ret.append(0x00000000) # ?
ret.append(offsetConst)
ret.append(len(self._const))
ret.append(offsetLabel)
ret.append(len(self._label))
ret.append(offsetOutmap)
ret.append(len(self._outmap))
ret.append(offsetInmap)
ret.append(len(self._inmap))
ret.append(offsetSymbol)
ret.append(len(self._symbol))
for k in self._const:
ret.append(k[0])
ret.append(k[1])
ret.append(k[2])
ret.append(k[3])
ret.append(k[4])
i=0
for k in self._label:
ret.append(i)
ret.append(k[0])
ret.append(0x00000000) # ?
ret.append(k[1])
i+=1
for k in self._outmap:
ret.append(k[0])
ret.append(k[1])
for k in self._inmap:
ret.append(k[2])
ret.append(((k[1]&0xFFFF)<<16)|(k[0]&0xFFFF))
retb=bytearray()
for k in ret:
retb+=struct.pack("I",k)
retb+=self._symbol
return retb
class DVLP(object):
def __init__(self):
self._code = []
self._opdesc = []
def clearCode(self):
self._code[:] = []
def addInstruction(self, inst):
self._code.append(inst)
return len(self._code)
def addOpdesc(self, opdesc):
self._opdesc.append(opdesc)
return len(self._opdesc)
def getCodelength(self):
return len(self._code)
def toBinary(self):
ret=[]
offsetCode=0x28
offsetOpdesc=offsetCode+len(self._code)*0x4
symbolOffset=offsetOpdesc+len(self._opdesc)*0x8
ret.append(0x504C5644) #DVLP magic
ret.append(0x00000000) # ?
ret.append(offsetCode)
ret.append(len(self._code))
ret.append(offsetOpdesc)
ret.append(len(self._opdesc))
ret.append(symbolOffset)
ret.append(0x00000000) # ?
ret.append(0x00000000) # ?
ret.append(0x00000000) # ?
retb=bytearray()
for k in ret:
retb+=struct.pack("I",k)
for k in self._code:
retb+=struct.pack("I",k)
for k in self._opdesc:
retb+=struct.pack("I",k[0])
retb+=struct.pack("I",k[1])
return retb
class DVLB(object):
def __init__(self):
self._dvlp = DVLP()
self._dvle = []
def getDVLP(self):
return self._dvlp
def addDVLE(self, dvle):
self._dvle.append(dvle)
def toBinary(self):
ret=[]
ret.append(0x424C5644) #DVLB magic
ret.append(len(self._dvle))
off=len(self._dvle)*0x4+0x8
retb=bytearray()
retb+=self._dvlp.toBinary()
for k in self._dvle:
retb+=bytearray([0x00]*(0 if len(retb)%4==0 else 4-(len(retb)%4)))
ret.append(off+len(retb))
retb+=k.toBinary()
retb2=bytearray()
for k in ret:
retb2+=struct.pack("I",k)
return retb2+retb
def getRegisterFromNameDst(s):
if s[0]=="o": # output
return int(s[1:])
elif s[0]=="v": # attribute
print("error : "+s+" cannot be accessed from dst")
elif s[0]=="r": # temporary register
return int(s[1:])+0x10
elif s[0]=="c": # uniform
print("error : "+s+" cannot be accessed from dst")
elif s[0]=="d": # direct hex; unambiguous
return int("0x"+s[1:],0)
else:
print("error : "+s+" is not a valid register name")
def getRegisterFromNameSrc1(s):
index=0
if "[" in s:
i=s.index("[")
index=s[i+1:-1]
s=s[:i]
if index=="a0.x":
index=1
elif index=="a0.y":
index=2
elif index=="aL":
index=3
if s[0]=="o": # output
print("error : "+s+" cannot be accessed from src1")
elif s[0]=="v": # attribute
return (int(s[1:]), index)
elif s[0]=="r": # temporary register
return (int(s[1:])+0x10, index)
elif s[0]=="c": # uniform
return (int(s[1:])+0x20, index)
elif s[0]=="d": # direct hex; unambiguous
return (int("0x"+s[1:],0), index)
else:
print("error : "+s+" is not a valid register name")
def getRegisterFromNameSrc2(s):
if s[0]=="o": # output
print("error : "+s+" cannot be accessed from src2")
elif s[0]=="v": # attribute
return int(s[1:])
elif s[0]=="r": # temporary register
return int(s[1:])+0x10
elif s[0]=="c": # uniform
print("error : "+s+" cannot be accessed from src2")
elif s[0]=="d": # direct hex; unambiguous
return int("0x"+s[1:],0)
else:
print("error : "+s+" is not a valid register name")
def assembleFormat11(d):
return (d["opcode"]<<26)|((d["dst"]&0x1F)<<24)|((d["src1"]&0x7F)<<17)|((d["src2"]&0x7F)<<10)|((d["src3"]&0x1F)<<5)|(d["extid"]&0x1F)
def parseFormat11(dvle, s):
operandFmt="[^\s,]*"
descFmt="(?:(?:0x)[0-9a-f]+)|[0-9a-f]+"
p=re.compile("^\s*("+operandFmt+"),\s*("+operandFmt+"),\s*("+operandFmt+"),\s*("+operandFmt+")\s*\(("+descFmt+")\)")
r=p.match(s)
if r:
src1 = getRegisterFromNameSrc1(r.group(2))
src2 = getRegisterFromNameSrc1(r.group(3))
return {"dst" : getRegisterFromNameDst(r.group(1)),
"src1" : src1[0],
"src2" : src2[0],
"src3" : getRegisterFromNameSrc2(r.group(4)),
"extid" : int(r.group(5),0)}
else:
raise Exception("encountered error while parsing instruction")
def assembleFormat12(d):
return (d["opcode"]<<26)|((d["dst"]&0x1F)<<24)|((d["src1"]&0x7F)<<17)|((d["src2"]&0x1F)<<12)|((d["src3"]&0x7F)<<5)|(d["extid"]&0x1F)
def parseFormat12(dvle, s):
operandFmt="[^\s,]*"
descFmt="(?:(?:0x)[0-9a-f]+)|[0-9a-f]+"
p=re.compile("^\s*("+operandFmt+"),\s*("+operandFmt+"),\s*("+operandFmt+"),\s*("+operandFmt+")\s*\(("+descFmt+")\)")
r=p.match(s)
if r:
src1 = getRegisterFromNameSrc1(r.group(2))
src3 = getRegisterFromNameSrc1(r.group(4))
return {"dst" : getRegisterFromNameDst(r.group(1)),
"src1" : src1[0],
"src2" : getRegisterFromNameSrc2(r.group(3)),
"src3" : src3[0],
"extid" : int(r.group(5),0)}
else:
raise Exception("encountered error while parsing instruction")
def assembleFormat1(d):
return (d["opcode"]<<26)|((d["dst"]&0x1F)<<21)|((d["idx"]&0x3)<<19)|((d["src1"]&0x7F)<<12)|((d["src2"]&0x1F)<<7)|(d["extid"]&0x7F)
def parseFormat1(dvle, s):
operandFmt="[^\s,]*"
descFmt="(?:(?:0x)[0-9a-f]+)|[0-9a-f]+"
p=re.compile("^\s*("+operandFmt+"),\s*("+operandFmt+"),\s*("+operandFmt+")\s*\(("+descFmt+")\)")
r=p.match(s)
if r:
src1 = getRegisterFromNameSrc1(r.group(2))
return {"dst" : getRegisterFromNameDst(r.group(1)),
"src1" : src1[0],
"idx" : src1[1],
"src2" : getRegisterFromNameSrc2(r.group(3)),
"extid" : int(r.group(4),0)}
else:
raise Exception("encountered error while parsing instruction")
def assembleFormat2(d):
print(d)
return (d["opcode"]<<26)|((d["flags"]&0xF)<<22)|((d["addr"]&0xFFF)<<10)|(d["ret"]&0x3FF)
def parseFormat2(dvle, s):
operandFmt1="[^\s,]*"
# operandFmt3="0b[01]+"
operandFmt3="([!]?)cmp.([xy])"
operandFmt3=operandFmt3+"\s*(?:(&&|\|\|)\s*"+operandFmt3+")?"
p=re.compile("^\s*("+operandFmt1+"),\s*("+operandFmt1+"),\s*"+operandFmt3+"\s*$")
# p=re.compile("^\s*("+operandFmt1+"),\s*("+operandFmt1+"),\s*("+operandFmt3+")\s*")
r=p.match(s)
if r:
neg = [0 if r.group(3)=="!" else 1, 0 if r.group(6)=="!" else 1]
comp = [2 if r.group(4)=="y" else 3, None if r.group(7)==None else (2 if r.group(7)=="y" else 3)]
op = r.group(5)
if comp[0]!=comp[1]:
flags=0
flags|=neg[0]<<comp[0]
flags|=neg[1]<<comp[1] if comp[1]!=None else 0
flags|=1 if op=="&&" else (0 if op=="||" else (3 if comp[0]==2 else 2))
# print(s)
# flags=int(r.group(3),0)
print(bin(flags))
return {"addr" : dvle.getLabelAddress(r.group(2)),
"ret" : dvle.getLabelAddress(r.group(1))-dvle.getLabelAddress(r.group(2)),
"flags" : flags}
else:
raise Exception("invalid or redundant condition "+s)
else:
raise Exception("encountered error while parsing instruction "+s)
def assembleFormat3(d):
return (d["opcode"]<<26)
def parseFormat3(dvle, s):
# doesn't check that there are no operands.
# (but really if you want to be an idiot and add useless operands to your code, go ahead)
return {}
def assembleFormat4(d):
return (d["opcode"]<<26)|((d["dst"]&0x1F)<<21)|((d["idx"]&0x3)<<19)|((d["src1"]&0x7F)<<12)|(d["extid"]&0x7F)
def parseFormat4(dvle, s):
operandFmt="[^\s,]*"
descFmt="(?:(?:0x)[0-9a-f]+)|[0-9a-f]+"
p=re.compile("^\s*("+operandFmt+"),\s*("+operandFmt+")\s*\(("+descFmt+")\)")
r=p.match(s)
if r:
src1 = getRegisterFromNameSrc1(r.group(2))
return {"dst" : getRegisterFromNameDst(r.group(1)),
"src1" : src1[0],
"idx" : src1[1],
"extid" : int(r.group(3),0)}
else:
raise Exception("encountered error while parsing instruction "+s)
def assembleFormat5(d):
return (d["opcode"]<<26)|((d["cmpx"]&0x7)<<24)|((d["cmpy"]&0x7)<<21)|((d["src1"]&0x7F)<<12)|((d["src2"]&0x1F)<<7)|(d["extid"]&0x7F)
cmpOp = {"eq" : 0x0, "ne" : 0x1, "lt" : 0x2, "le" : 0x3, "gt" : 0x4, "ge" : 0x5}
def parseFormat5(dvle, s):
operandFmt="[^\s,]*"
descFmt="(?:(?:0x)[0-9a-f]+)|[0-9a-f]+"
opFmt="[a-z]+"
p=re.compile("^\s*("+operandFmt+"),\s*("+opFmt+"),\s*("+opFmt+"),\s*("+operandFmt+")\s*\(("+descFmt+")\)")
r=p.match(s)
if r:
src1 = getRegisterFromNameSrc1(r.group(1))
return {"src1" : src1[0],
"idx" : src1[1],
"cmpx" : cmpOp[r.group(2)],
"cmpy" : cmpOp[r.group(3)],
"src2" : getRegisterFromNameSrc2(r.group(4)),
"extid" : int(r.group(5),0)}
else:
raise Exception("encountered error while parsing instruction (5)")
def assembleFormat6(d):
return (d["opcode"]<<26)|((d["dst"]&0x1F)<<21)|((d["src2"]&0x7F)<<7)|((d["src1"]&0x1F)<<14)|(d["extid"]&0x7F)
def parseFormat7(dvle, s):
operandFmt1="[^\s,]*"
operandFmt3="i[0-9]+"
p=re.compile("^\s*("+operandFmt1+"),\s*("+operandFmt3+")")
r=p.match(s)
if r:
return {"addr" : dvle.getLabelAddress(r.group(1))-1,
"ret" : 0,
"int" : int(r.group(2).strip()[1:],0)}
else:
raise Exception("encountered error while parsing instruction")
def assembleFormat7(d):
return (d["opcode"]<<26)|((d["int"]&0xF)<<22)|((d["addr"]&0xFFF)<<10)|(d["ret"]&0x3FF)
def parseFormat8(dvle, s):
operandFmt1="[^\s,]*"
operandFmt3="b[0-9]+"
p=re.compile("^\s*("+operandFmt1+"),\s*("+operandFmt1+"),\s*("+operandFmt3+")")
r=p.match(s)
if r:
return {"addr" : dvle.getLabelAddress(r.group(2)),
"ret" : dvle.getLabelAddress(r.group(1))-dvle.getLabelAddress(r.group(2)),
"bool" : int(r.group(3).strip()[1:],0)}
else:
raise Exception("encountered error while parsing instruction")
def assembleFormat8(d):
return (d["opcode"]<<26)|((d["bool"]&0xF)<<22)|((d["addr"]&0xFFF)<<10)|(d["ret"]&0x3FF)
def parseFormat9(dvle, s):
operandFmt1="true|false"
operandFmt3="vtx[0-9]+"
p=re.compile("^\s*("+operandFmt3+"),\s*("+operandFmt1+"),\s*("+operandFmt1+")")
r=p.match(s)
if r:
return {"unk" : r.group(3)=="true",
"prim" : r.group(2)=="true",
"vtx" : int(r.group(1).strip()[3:],0)}
else:
raise Exception("encountered error while parsing instruction")
def assembleFormat9(d):
return (d["opcode"]<<26)|((d["vtx"]&0x3)<<24)|((d["unk"]&0x1)<<22)|((d["prim"]&0x1)<<23)
def parseFormat10(dvle, s):
operandFmt1="[^\s,]*"
p=re.compile("^\s*("+operandFmt1+"),\s*("+operandFmt1+")")
r=p.match(s)
if r:
return {"addr" : dvle.getLabelAddress(r.group(1)),
"ret" : dvle.getLabelAddress(r.group(2))-dvle.getLabelAddress(r.group(1)),
"flags" : 0x0}
else:
raise Exception("encountered error while parsing instruction")
instList={}
fmtList=[(parseFormat1, assembleFormat1), (parseFormat2, assembleFormat2), (parseFormat3, assembleFormat3), (parseFormat4, assembleFormat4), (parseFormat5, assembleFormat5), (parseFormat1, assembleFormat6), (parseFormat7, assembleFormat7), (parseFormat8, assembleFormat8), (parseFormat9, assembleFormat9), (parseFormat10, assembleFormat2), (parseFormat11, assembleFormat11), (parseFormat12, assembleFormat12)]
instList["add"]={"opcode" : 0x00, "format" : 0}
instList["dp3"]={"opcode" : 0x01, "format" : 0}
instList["dp4"]={"opcode" : 0x02, "format" : 0}
instList["dph"]={"opcode" : 0x03, "format" : 0}
instList["op4"]={"opcode" : 0x04, "format" : 0}
instList["ex2"]={"opcode" : 0x05, "format" : 3}
instList["lg2"]={"opcode" : 0x06, "format" : 3}
instList["op7"]={"opcode" : 0x07, "format" : 3}
instList["mul"]={"opcode" : 0x08, "format" : 0}
instList["sge"]={"opcode" : 0x09, "format" : 0}
instList["slt"]={"opcode" : 0x0a, "format" : 0}
instList["flr"]={"opcode" : 0x0B, "format" : 3}
instList["max"]={"opcode" : 0x0C, "format" : 0}
instList["min"]={"opcode" : 0x0D, "format" : 0}
instList["rcp"]={"opcode" : 0x0E, "format" : 3}
instList["rsq"]={"opcode" : 0x0F, "format" : 3}
instList["mova"]={"opcode" : 0x12, "format" : 3}
instList["mov"]={"opcode" : 0x13, "format" : 3}
instList["dphi"]={"opcode" : 0x18, "format" : 5}
instList["op19"]={"opcode" : 0x19, "format" : 5}
instList["sgei"]={"opcode" : 0x1a, "format" : 5}
instList["slti"]={"opcode" : 0x1b, "format" : 5}
instList["nop"]={"opcode" : 0x21, "format" : 2}
instList["end"]={"opcode" : 0x22, "format" : 2}
instList["call"] ={"opcode" : 0x24, "format" : 9}
instList["ifu"] ={"opcode" : 0x27, "format" : 7}
instList["ifc"] ={"opcode" : 0x28, "format" : 1}
instList["loop"] ={"opcode" : 0x29, "format" : 6}
instList["emit"]={"opcode" : 0x2a, "format" : 2}
instList["setemit"]={"opcode" : 0x2b, "format" : 8}
instList["cmp"]={"opcode" : 0x2e, "format" : 4}
instList["madi"]={"opcode" : 0x30, "format" : 11}
instList["mad"]={"opcode" : 0x38, "format" : 10}
def parseConst(dvlp, dvle, s):
s=s.split(",")
s[0]=s[0].strip()
if s[0][0]=="b":
# bool constant
dvle.addConstantB((int(s[0][1:],0), int(s[1])))
elif s[0][0]=="i":
# int vec4 constant
dvle.addConstantI((int(s[0][1:],0), int(s[1],0), int(s[2],0), int(s[3],0), int(s[4],0)))
elif s[0][0]=="c":
# float vec4 constant
dvle.addConstantF((int(s[0][1:],0), float(s[1]), float(s[2]), float(s[3]), float(s[4])))
outputTypes={"result.position" : 0x0,
"result.normalquat" : 0x1,
"result.color" : 0x2,
"result.texcoord0" : 0x3,
"result.texcoord0w" : 0x4,
"result.texcoord1" : 0x5,
"result.texcoord2" : 0x6,
"result.view" : 0x8}
def parseOut(dvlp, dvle, s):
s=s.split(",")
s[0]=s[0].replace(" ", "")
s[1]=s[1].replace(" ", "")
s[2]=s[2].replace(" ", "")
reg=int(s[0][1:])
if s[1] in outputTypes:
type=outputTypes[s[1]]
mask=int(s[2], 0)
dvle.addOutput((type|(reg<<16), mask))
swizVal={"w":0x3,"z":0x2,"y":0x1,"x":0x0}
def parseOpdesc(dvlp, dvle, s):
s=s.split(",")
for k in range(len(s)):
s[k]=s[k].replace(" ", "")
#dst mask
mask=0
for k in range(4):
if s[0][k]!="_":
mask|=1<<(3-k)
swiz=[0,0,0]
neg=[0,0,0]
for i in range(len(s)-1):
l=s[1+i]
if l[0]=='-':
neg[i]=1
l=l[1:]
for k in range(4):
swiz[i]=((swiz[i]<<2)|swizVal[l[k]])
dvlp.addOpdesc(((1<<31)|(swiz[2]<<23)|(neg[2]<<22)|(swiz[1]<<14)|(neg[1]<<13)|(swiz[0]<<5)|(neg[0]<<4)|(mask),0x0000000F))
def parseUniform(dvlp, dvle, s):
s=s.split(",")
for k in range(len(s)):
s[k]=s[k].replace(" ", "")
type=s[0][0]
if type!=s[1][0]:
print("inconsistent uniform register assignment !")
return
if type=="c":
offset=0x10
elif type=="i":
offset=0x70
elif type=="b":
offset=0x78
dvle.addInput((int(s[0][1:],0)+offset,int(s[1][1:],0)+offset,s[2]))
def parseVsh(dvlp, dvle, s):
global vshMain, vshEndmain
s=s.split(",")
for k in range(len(s)):
s[k]=s[k].replace(" ", "")
vshMain, vshEndmain = s[0], s[1]
def parseGsh(dvlp, dvle, s):
global gshMain, gshEndmain
s=s.split(",")
for k in range(len(s)):
s[k]=s[k].replace(" ", "")
gshMain, gshEndmain = s[0], s[1]
dirList={}
dirList["const"]=(parseConst)
dirList["out"]=(parseOut)
dirList["opdesc"]=(parseOpdesc)
dirList["uniform"]=(parseUniform)
dirList["vsh"]=(parseVsh)
dirList["gsh"]=(parseGsh)
def parseInstruction(dvle, s):
s=s.lower()
p=re.compile("^\s*([^\s]*)(.*)")
r=p.match(s)
if r:
name=r.group(1)
if name in instList:
fmt=instList[name]["format"]
out=fmtList[fmt][0](dvle, r.group(2))
out["opcode"]=instList[name]["opcode"]
v=fmtList[fmt][1](out)
return v
else:
print(name+" : no such instruction")
return None
def parseLabel(s):
s=s.lower()
p=re.compile("^\s*([a-z_0-9]*):")
r=p.match(s)
if r:
return r.group(1)
return None
def parseLine(dvlp, dvle, l, mode):
l=l.split(";")[0] #remove comments
k=0
while (k<len(l) and (l[k]==" " or l[k]==" ")):
k+=1
l=l[k:]
if len(l)>1:
if l[0]==".": #directive
if not(mode):
p=re.compile("^\s*\.([^\s]*)(.*)")
r=p.match(l)
if r:
name=r.group(1)
if name in dirList:
dirList[name](dvlp, dvle, r.group(2))
else:
print(name+" : no such directive")
else:
v=parseLabel(l)
if v: #label
if not(mode):
dvle.addLabel((dvlp.getCodelength(), v))
else: #instruction
v=parseInstruction(dvle, l)
if v:
dvlp.addInstruction(v)
if len(sys.argv)<3:
print("AEMSTRO AS :")
print(" aemstro_as.py <input.vsh> <output.shbin>")
else:
dvlb=DVLB()
vsh_dvle=DVLE(0x0)
with open(sys.argv[1], "r") as f:
for line in f:
parseLine(dvlb.getDVLP(), vsh_dvle, line, False)
dvlb.getDVLP().clearCode()
with open(sys.argv[1], "r") as f:
for line in f:
parseLine(dvlb.getDVLP(), vsh_dvle, line, True)
vsh_dvle.setMain(vsh_dvle.getLabelAddress(vshMain))
vsh_dvle.setEndmain(vsh_dvle.getLabelAddress(vshEndmain))
dvlb.addDVLE(vsh_dvle)
if gshMain!=None and gshEndmain!=None:
gsh_dvle=copy.deepcopy(vsh_dvle)
gsh_dvle._type=0x1
gsh_dvle.setMain(gsh_dvle.getLabelAddress(gshMain))
gsh_dvle.setEndmain(gsh_dvle.getLabelAddress(gshEndmain))
dvlb.addDVLE(gsh_dvle)
open(sys.argv[2],"wb").write(dvlb.toBinary())