239 lines
8.4 KiB
Python
239 lines
8.4 KiB
Python
|
#!/usr/bin/env python
|
||
|
import sys, os, time, platform, struct, math;
|
||
|
|
||
|
def safeprint(*args):
|
||
|
print(" ".join([str(arg) for arg in args]))
|
||
|
|
||
|
def disphelp():
|
||
|
safeprint("\n BinPac8x Help Menu:\n======================\n",\
|
||
|
"binpac8x.py [<type>] [-O <oncalcname>] <source bin> [<destination .8*p>]\n",\
|
||
|
"-h: Display this help menu\n",\
|
||
|
"source bin: A .bin file to process\n",\
|
||
|
"destination: Filename of output. If omitted, output name derived from input\n",\
|
||
|
"-O: Specify optional oncalcname, should be <=8 chars and ALL UPPERCASE\n\n",\
|
||
|
"By default produces a .8xp file. To build for a different calculator than\n",\
|
||
|
"the TI-83+/TI-84+ series, use ONE of these <type> flags:\n",\
|
||
|
"-2: TI-82 program (.82p)\n",\
|
||
|
"-3: TI-83 program (.83p)\n",\
|
||
|
"-5: TI-85 string (.85s)\n",\
|
||
|
"-6: TI-86 program (.86p)\n",\
|
||
|
"-7: TI-86 string (.86s)\n")
|
||
|
sys.exit(0)
|
||
|
return
|
||
|
|
||
|
t_start = time.localtime()
|
||
|
|
||
|
def parsefile(fnamein,fnameout,abspath,calctype,oncalcname):
|
||
|
|
||
|
fullpathin = os.path.join(abspath,fnamein)
|
||
|
if not(os.path.exists(fullpathin)):
|
||
|
safeprint("Error: Input file "+fullpathin+" was not found!")
|
||
|
return
|
||
|
if fnameout == "":
|
||
|
if 1 > fnamein.find("."):
|
||
|
fnameout = fnamein + ".bin"
|
||
|
else:
|
||
|
if calctype!="7" and calctype!="5":
|
||
|
fnameout = fnamein[:fnamein.find(".")+1] + "8" + calctype + "p"
|
||
|
elif calctype=="5":
|
||
|
fnameout = fnamein[:fnamein.find(".")+1] + "85s"
|
||
|
elif calctype=="7":
|
||
|
fnameout = fnamein[:fnamein.find(".")+1] + "86s"
|
||
|
|
||
|
fullpathout = os.path.join(abspath,fnameout)
|
||
|
if os.path.exists(fullpathout):
|
||
|
safeprint("Warning: Input file "+fullpathout+" exists, overwriting.")
|
||
|
|
||
|
fhi = open(fullpathin,'rb')
|
||
|
fho = open(fullpathout,'wb')
|
||
|
|
||
|
if calctype=="2":
|
||
|
fho.write(bytearray(b'**TI82**')) #byte 00, length 08
|
||
|
fho.write(mybytearray([26,10,0])) #byte 08, length 03
|
||
|
elif calctype=="3":
|
||
|
fho.write(bytearray(b'**TI83**')) #byte 00, length 08
|
||
|
fho.write(mybytearray([26,10,0])) #byte 08, length 03
|
||
|
elif calctype=="5":
|
||
|
fho.write(bytearray(b'**TI85**')) #byte 00, length 08
|
||
|
fho.write(mybytearray([26,12,0])) #byte 08, length 03
|
||
|
elif calctype=="6" or calctype=="7":
|
||
|
fho.write(bytearray(b'**TI86**')) #byte 00, length 08
|
||
|
fho.write(mybytearray([26,10,0])) #byte 08, length 03
|
||
|
else: #case "x"
|
||
|
fho.write(bytearray(b'**TI83F*')) #byte 00, length 08
|
||
|
fho.write(mybytearray([26,10,0])) #byte 08, length 03
|
||
|
|
||
|
fho.write(bytearray(b'BinPac8x (c)2010 Cemetech.net&Kerm Martian'))
|
||
|
#byte 11, length 42
|
||
|
|
||
|
bincontents = fhi.read();
|
||
|
fhi.close();
|
||
|
binsize = len(bincontents);
|
||
|
bbsize_hb = math.floor(binsize/256)
|
||
|
bbsize_lb = binsize - 256*bbsize_hb
|
||
|
binsize = binsize + 2
|
||
|
bincontents = mybytearray([bbsize_lb,bbsize_hb]) + bincontents
|
||
|
|
||
|
if oncalcname == "":
|
||
|
oncalcname = fnameout[:fnameout.find(".")].upper();
|
||
|
else:
|
||
|
oncalcname = oncalcname.upper()
|
||
|
if len(oncalcname) >=8 or calctype != "5": #TI-85 has variable-len name
|
||
|
while len(oncalcname) != 8:
|
||
|
if len(oncalcname) > 8:
|
||
|
oncalcname = oncalcname[:8]
|
||
|
else:
|
||
|
if calctype != "6" and calctype != "7":
|
||
|
oncalcname = oncalcname + chr(0);
|
||
|
else:
|
||
|
oncalcname = oncalcname + " "; #TI-86 uses space-padded name
|
||
|
|
||
|
if calctype=="2":
|
||
|
headersize = 15
|
||
|
elif calctype=="3":
|
||
|
headersize = 15
|
||
|
elif calctype=="5":
|
||
|
headersize = 8+len(oncalcname)
|
||
|
elif calctype=="6" or calctype=="7":
|
||
|
headersize = 16
|
||
|
else: #case "x"
|
||
|
headersize = 17 # 17-byte header
|
||
|
|
||
|
datasize = binsize + headersize
|
||
|
size_hb = math.floor(datasize/256);
|
||
|
size_lb = datasize - 256*size_hb;
|
||
|
fho.write(mybytearray([size_lb,size_hb])); #byte 53, length 02
|
||
|
safeprint("On-calc name: "+oncalcname)
|
||
|
oncalcname.encode()
|
||
|
bsize_hb = math.floor(binsize/256);
|
||
|
bsize_lb = binsize - 256*bsize_hb;
|
||
|
|
||
|
# Construct the header in the data field
|
||
|
if calctype=="2" or calctype=="3":
|
||
|
fho.write(mybytearray([11,0])); #byte 55, length 02
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02
|
||
|
fho.write(mybytearray([6])); #byte 59, length 01
|
||
|
fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 60, length 08
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 68, length 02
|
||
|
elif calctype=="5":
|
||
|
fho.write(mybytearray([headersize-2,0])) #byte 55, length 02
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])) #byte 57, length 02
|
||
|
fho.write(mybytearray([12])) #byte 59, length 01
|
||
|
fho.write(mybytearray([len(oncalcname)])) #byte 60, length 01
|
||
|
fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 61, length varies
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])) #byte 62-69, length 02
|
||
|
elif calctype=="6":
|
||
|
fho.write(mybytearray([12,0])); #byte 55, length 02
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02
|
||
|
fho.write(mybytearray([18])); #byte 59, length 01
|
||
|
fho.write(mybytearray([8])) #byte 60, length 01
|
||
|
fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 61, length 08
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 69, length 02
|
||
|
elif calctype=="7":
|
||
|
fho.write(mybytearray([12,0])); #byte 55, length 02
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02
|
||
|
fho.write(mybytearray([12])); #byte 59, length 01
|
||
|
fho.write(mybytearray([8])) #byte 60, length 01
|
||
|
fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 61, length 08
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 69, length 02
|
||
|
else:
|
||
|
fho.write(mybytearray([13,0])); #byte 55, length 02
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 57, length 02
|
||
|
fho.write(mybytearray([6])); #byte 59, length 01
|
||
|
fho.write((mybytes(oncalcname, encoding='ascii'))) #byte 60, length 08
|
||
|
fho.write(mybytearray([0])); #byte 68, length 01
|
||
|
fho.write(mybytearray([0])); #byte 69, length 01
|
||
|
fho.write(mybytearray([bsize_lb,bsize_hb])); #byte 70, length 02
|
||
|
|
||
|
fho.write(bincontents); #byte 72, length binsize
|
||
|
|
||
|
if calctype=="2" or calctype=="3":
|
||
|
chksum = 2*bsize_lb + 2*bsize_hb + 11 + 0 + 6;
|
||
|
elif calctype=="5":
|
||
|
chksum = 2*bsize_lb + 2*bsize_hb + (headersize - 2) + 0 + 12 + len(oncalcname);
|
||
|
elif calctype=="6":
|
||
|
chksum = 2*bsize_lb + 2*bsize_hb + 12 + 0 + 18 + 8;
|
||
|
elif calctype=="7":
|
||
|
chksum = 2*bsize_lb + 2*bsize_hb + 12 + 0 + 12 + 8;
|
||
|
else:
|
||
|
chksum = 2*bsize_lb + 2*bsize_hb + 6 + 0 + 0 + 13 + 0; #including [13,0]
|
||
|
|
||
|
for c in oncalcname:
|
||
|
chksum += ord(c);
|
||
|
if sys.version[0] == '2':
|
||
|
for c in bincontents:
|
||
|
chksum += ord(c);
|
||
|
else:
|
||
|
for c in bincontents:
|
||
|
chksum += c;
|
||
|
chksum = chksum % 65536
|
||
|
cs_hb = math.floor(chksum/256);
|
||
|
cs_lb = chksum - 256*cs_hb;
|
||
|
fho.write(mybytearray([cs_lb,cs_hb])); #byte 63, length 02
|
||
|
fho.close();
|
||
|
return
|
||
|
|
||
|
def mybytes(string, encoding):
|
||
|
if sys.version[0] == '2':
|
||
|
return bytes(string);
|
||
|
else:
|
||
|
return bytes(string,encoding)
|
||
|
|
||
|
def mybytearray(thisblist): #this stunningly awkward hack is for 2.x/3.x compat
|
||
|
if sys.version[0] == '2':
|
||
|
mystr = ""
|
||
|
for i in range(0,len(thisblist)):
|
||
|
mystr += chr(int(thisblist[i]));
|
||
|
return mybytes(mystr,encoding="ascii");
|
||
|
else:
|
||
|
return bytearray(thisblist);
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
safeprint(" --+=====================+--")
|
||
|
safeprint(" --| BinPac8x v1.2 |--")
|
||
|
safeprint(" --| by Kerm Martian |--")
|
||
|
safeprint(" --| www.Cemetech.net |--")
|
||
|
safeprint(" --| admin@cemetech.net |--")
|
||
|
safeprint(" --+=====================+--")
|
||
|
fnamein = ""
|
||
|
fnameout = ""
|
||
|
oncalcname = ""
|
||
|
if (len(sys.argv) > 1):
|
||
|
prefix = ""
|
||
|
calc = "x";
|
||
|
skipiter = 0;
|
||
|
for i in range(1,len(sys.argv)):
|
||
|
if skipiter == 0:
|
||
|
if sys.argv[i][0] == "-":
|
||
|
if sys.argv[i][1] == "h":
|
||
|
disphelp()
|
||
|
if sys.argv[i][1]=="2" or sys.argv[i][1]=="3" or sys.argv[i][1]=="5" or sys.argv[i][1]=="6" or sys.argv[i][1]=="x" or sys.argv[i][1]=="7":
|
||
|
calc = sys.argv[i][1]
|
||
|
elif sys.argv[i][1] == "O":
|
||
|
oncalcname = sys.argv[i+1];
|
||
|
skipiter = 1;
|
||
|
else:
|
||
|
safeprint("\nUnknown switch: ",sys.argv[i])
|
||
|
disphelp()
|
||
|
#prefix = sys.argv[i][1]
|
||
|
else:
|
||
|
if prefix == "":
|
||
|
if (fnamein == ''):
|
||
|
fnamein = sys.argv[i]
|
||
|
else:
|
||
|
fnmeout = sys.argv[i]
|
||
|
else:
|
||
|
safeprint("\nUnknown switch: -",prefix,"\n")
|
||
|
else:
|
||
|
skipiter = 0;
|
||
|
|
||
|
if fnamein == "":
|
||
|
safeprint("\nPlease enter the relative path to the bincontents file to pack as a .8*p: ")
|
||
|
fnamein = sys.stdin.readline()[:-1]
|
||
|
|
||
|
basepath = os.path.dirname(fnamein)
|
||
|
safeprint("**Pass 1/1: .8"+calc+"p Construction**")
|
||
|
parsefile(fnamein,fnameout,basepath,calc,oncalcname)
|
||
|
safeprint("Total time:",str(time.mktime(time.localtime())-time.mktime(t_start)) + "s")
|
||
|
sys.exit()
|