Skip to content

Instantly share code, notes, and snippets.

@CoolOppo
Created September 16, 2014 02:38
Show Gist options
  • Save CoolOppo/77183b4a499af719ab97 to your computer and use it in GitHub Desktop.
Save CoolOppo/77183b4a499af719ab97 to your computer and use it in GitHub Desktop.
Convert .bin files to .8xp files for the TI-83+ and TI-84+ with Python - not by me
#!/usr/bin/env python
import sys
import os
import time
import platform
import struct
import 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
# byte 60, length 08
fho.write((mybytes(oncalcname, encoding='ascii')))
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
# byte 61, length varies
fho.write((mybytes(oncalcname, encoding='ascii')))
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
# byte 61, length 08
fho.write((mybytes(oncalcname, encoding='ascii')))
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
# byte 61, length 08
fho.write((mybytes(oncalcname, encoding='ascii')))
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
# byte 60, length 08
fho.write((mybytes(oncalcname, encoding='ascii')))
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)
# this stunningly awkward hack is for 2.x/3.x compat
def mybytearray(thisblist):
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()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment