Skip to content

Instantly share code, notes, and snippets.

@CoolOppo
Last active March 7, 2022 06:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CoolOppo/e22f35ac2f7b7856349e to your computer and use it in GitHub Desktop.
Save CoolOppo/e22f35ac2f7b7856349e to your computer and use it in GitHub Desktop.
BinPac8x converts a bin file to a file for use on Texas Instruments calculators, such as a '.8xp' file for the TI-83+ and TI-84+. Created by Kerm Martian: http://goo.gl/rmgmze
#!/usr/bin/env python
import sys
import os
import time
import platform
import struct
import math
def disphelp():
print(
"""Usage: binpac8x [OPTION]... BIN [DESTINATION]
Convert bin file to a file for use on Texas Instruments calculators
OPTIONS:
DESTINATION Filename of output. If omitted, output name derived from input
-O Specify optional on-calculator name - should be <=8 chars
A .8xp file is produced by default.
To build for calculators other than the TI-83+ and TI-84+, use one of the following:
-2 TI-82 program (.82p)
-3 TI-83 program (.83p)
-5 TI-85 string (.85s)
-6 TI-86 program (.86p)
-7 TI-86 string (.86s)""")
sys.exit(0)
t_start = time.localtime()
def parsefile(fnamein, fnameout, abspath, calctype, oncalcname):
fullpathin = os.path.join(abspath, fnamein)
if not(os.path.exists(fullpathin)):
print("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):
print(
"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' '))
# 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
print("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 is for Python 2 and 3 compatibility
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__":
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:
print("\nUnknown switch: ", sys.argv[i])
disphelp()
else:
if prefix == "":
if (fnamein == ''):
fnamein = sys.argv[i]
else:
fnmeout = sys.argv[i]
else:
print("\nUnknown switch: -", prefix, "\n")
else:
skipiter = 0
if fnamein == "":
disphelp()
basepath = os.path.dirname(fnamein)
parsefile(fnamein, fnameout, basepath, calc, oncalcname)
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment