#!/usr/bin/env perl ## Copyright (C) 2008, 2009 by Daniel Friesel ## License: WTFPL use strict; use feature 'switch'; use warnings; use utf8; use Getopt::Std; binmode(STDOUT, ':utf8'); my ($char, $char2); my $out; my $cache; my $hex; my ($indent, $rindent) = (0,0); my %opts; my ($program, $length, $offset); my %all = ( 0x01 => '►DMS', 0x02 => '►Dec', 0x03 => '►Frac', 0x04 => '→', 0x05 => 'Boxplot', 0x06 => '[', 0x07 => ']', 0x08 => '{', 0x09 => '}', 0x0a => 'r', 0x0b => '°', 0x0c => '⁻¹', 0x0d => '²', 0x0e => 'Ṭ', 0x0f => '³', 0x10 => '(', 0x11 => ')', 0x12 => 'round(', 0x13 => 'pxl-Test(', 0x14 => 'augment(', 0x15 => 'rowSwap(', 0x16 => 'row+(', 0x17 => '*row(', 0x18 => '*row+(', 0x19 => 'max(', 0x1a => 'min(', 0x1b => 'R►Pr(', 0x1c => 'R►Pθ(', 0x1d => 'P►Rx(', 0x1e => 'P►Ry', 0x1f => 'median(', 0x20 => 'randM(', 0x21 => 'mean(', 0x22 => 'solve(', 0x23 => 'seq(', 0x24 => 'fnInt(', 0x25 => 'nDeriv(', 0x27 => 'fMin(', 0x28 => 'fMax(', 0x29 => ' ', 0x2a => '"', 0x2b => ',', 0x2c => 'i', 0x2d => '!', 0x2e => 'CubicReg', 0x2f => 'QuartReg', 0x30 => 0, 0x31 => 1, 0x32 => 2, 0x33 => 3, 0x34 => 4, 0x35 => 5, 0x36 => 6, 0x37 => 7, 0x38 => 8, 0x39 => 9, 0x3a => '.', 0x3b => 'E', 0x3c => ' or ', 0x3d => ' xor ', 0x3e => ':', 0x3f => "\n", 0x40 => ' and ', 0x41 => 'A', 0x42 => 'B', 0x43 => 'C', 0x44 => 'D', 0x45 => 'E', 0x46 => 'F', 0x47 => 'G', 0x48 => 'H', 0x49 => 'I', 0x4a => 'J', 0x4b => 'K', 0x4c => 'L', 0x4d => 'M', 0x4e => 'N', 0x4f => 'O', 0x50 => 'P', 0x51 => 'O', 0x52 => 'R', 0x53 => 'S', 0x54 => 'T', 0x55 => 'U', 0x56 => 'V', 0x57 => 'W', 0x58 => 'X', 0x59 => 'Y', 0x5a => 'Z', 0x5b => 'θ', 0x5f => 'prgm', 0x64 => 'Radian', 0x65 => 'Degree', 0x66 => 'Normal', 0x67 => 'Sci', 0x68 => 'Eng', 0x69 => 'Float', 0x6a => '=', 0x6b => '<', 0x6c => '>', 0x6d => '≤', 0x6e => '≥', 0x6f => '≠', 0x70 => '+', 0x71 => '-', 0x72 => 'Ans', 0x73 => 'Fix', 0x74 => 'Horiz', 0x75 => 'Full', 0x76 => 'Func', 0x77 => 'Param', 0x78 => 'Polar', 0x79 => 'Seq', 0x7a => 'IndpntAuto', 0x7b => 'IndpntAsk', 0x7c => 'DependAuto', 0x7d => 'DependAsk', 0x7f => '☐', 0x80 => '+', 0x81 => '·', 0x82 => '*', 0x83 => '/', 0x84 => 'Trace', 0x85 => 'ClrDraw', 0x86 => 'ZStandard', 0x87 => 'ZTrig', 0x88 => 'ZBox', 0x89 => 'Zoom In', 0x8a => 'Zoom Out', 0x8b => 'ZSquare', 0x8c => 'ZInteger', 0x8d => 'ZPrevious', 0x8e => 'ZDecimal', 0x8f => 'ZoomStat', 0x90 => 'ZoomRcl', 0x91 => 'PrintScreen', 0x92 => 'ZoomSto', 0x93 => 'Text(', 0x94 => 'nPr', 0x95 => 'nCr', 0x96 => 'FnOn', 0x97 => 'FnOff', 0x98 => 'StorePic', 0x99 => 'RecallPic', 0x9a => 'StoreGDB', 0x9b => 'RecallGDB', 0x9c => 'Line(', 0x9d => 'Vertical', 0x9e => 'Pt-On(', 0x9f => 'Pt-Off(', 0xa0 => 'Pt-Change(', 0xa1 => 'Pxl-On(', 0xa2 => 'Pxl-Off(', 0xa3 => 'Pxl-Change(', 0xa4 => 'Shade(', 0xa5 => 'Circle(', 0xa6 => 'Horizontal', 0xa7 => 'Tangent(', 0xa8 => 'DrawInv', 0xa9 => 'DrawF', 0xab => 'rand', 0xac => 'π', 0xad => 'getKey', 0xae => '\'', 0xaf => '?', 0xb0 => '-', 0xb1 => 'int(', 0xb2 => 'abs(', 0xb3 => 'det(', 0xb4 => 'identity(', 0xb5 => 'dim(', 0xb6 => 'sum(', 0xb7 => 'prod(', 0xb8 => 'not(', 0xb9 => 'iPart(', 0xba => 'fPart(', 0xbc => '√(', 0xbd => '³√(', 0xbe => 'ln(', 0xbf => 'e^(', 0xc0 => 'log(', 0xc1 => '10^(', 0xc2 => 'sin(', 0xc3 => 'sinֿ¹(', 0xc4 => 'cos(', 0xc5 => 'cosֿ¹(', 0xc6 => 'tan(', 0xc7 => 'tanֿ¹(', 0xc8 => 'sinh(', 0xc9 => 'sinhֿ¹(', 0xca => 'cosh(', 0xcb => 'coshֿ¹(', 0xcc => 'tanh(', 0xcd => 'tanhֿ¹(', 0xce => 'If ', 0xcf => 'Then', 0xd0 => 'Else', 0xd1 => 'While ', 0xd2 => 'Repeat ', 0xd3 => 'For(', 0xd4 => 'End', 0xd5 => 'Return', 0xd6 => 'Lbl ', 0xd7 => 'Goto ', 0xd8 => 'Pause', 0xd9 => 'Stop', 0xda => 'IS>(', 0xdb => 'DS<(', 0xdc => 'Input ', 0xdd => 'Prompt ', 0xde => 'Disp ', 0xdf => 'DispGraph', 0xe0 => 'Output(', 0xe1 => 'ClrHome', 0xe2 => 'Fill(', 0xe3 => 'SortA(', 0xe4 => 'SortD(', 0xe5 => 'DispTable', 0xe6 => 'Menu(', 0xe7 => 'Send(', 0xe8 => 'Get(', 0xe9 => 'PlotsOn', 0xea => 'PlotsOff', 0xeb => '∟', 0xec => 'Plot1(', 0xed => 'Plot2(', 0xee => 'Plot3(', 0xf0 => '^', 0xf1 => '×√', 0xf2 => '1-Var Stats', 0xf3 => '2-Var Stats', 0xf4 => 'Linreg(a+bx)', 0xf5 => 'ExpReg', 0xf6 => 'LnReg', 0xf7 => 'PwrReg', 0xf8 => 'Med-Med', 0xf9 => 'QuadReg', 0xfa => 'ClrList', 0xfb => 'ClrTable', 0xfc => 'Histogram', 0xfd => 'xyLine', 0xfe => 'Scatter', 0xff => 'LinReg(ax+b)', ); my $special = { 0x5c => { 0x00 => '[A]', 0x01 => '[B]', 0x02 => '[C]', 0x03 => '[D]', 0x04 => '[E]', 0x05 => '[F]', 0x06 => '[G]', 0x07 => '[H]', 0x08 => '[I]', 0x09 => '[J]', }, 0x5d => { 0x00 => 'L₁', 0x01 => 'L₂', 0x02 => 'L₃', 0x03 => 'L₄', 0x04 => 'L₅', 0x05 => 'L₆', }, 0x5e => { 0x10 => 'Y₁', 0x11 => 'Y₂', 0x12 => 'Y₃', 0x13 => 'Y₄', 0x14 => 'Y₅', 0x15 => 'Y₆', 0x16 => 'Y₇', 0x17 => 'Y₈', 0x18 => 'Y₉', 0x19 => 'Y₀', 0x20 => 'X₁T', 0x21 => 'Y₁T', 0x22 => 'X₂T', 0x23 => 'Y₂T', 0x24 => 'X₃T', 0x25 => 'Y₃T', 0x26 => 'X₄T', 0x27 => 'Y₄T', 0x28 => 'X₅T', 0x29 => 'Y₅T', 0x2A => 'X₆T', 0x2B => 'Y₆T', 0x40 => 'r₁', 0x41 => 'r₂', 0x42 => 'r₃', 0x43 => 'r₄', 0x44 => 'r₅', 0x45 => 'r₆', 0x80 => 'u', 0x81 => 'v', 0x82 => 'w', }, 0x60 => { 0x00 => 'Pic1', 0x01 => 'Pic2', 0x02 => 'Pic3', 0x03 => 'Pic4', 0x04 => 'Pic5', 0x05 => 'Pic6', 0x06 => 'Pic7', 0x07 => 'Pic8', 0x08 => 'Pic9', 0x09 => 'Pic0', }, 0x61 => { 0x00 => 'GDB1', 0x01 => 'GDB2', 0x02 => 'GDB3', 0x03 => 'GDB4', 0x04 => 'GDB5', 0x05 => 'GDB6', 0x06 => 'GDB7', 0x07 => 'GDB8', 0x08 => 'GDB9', 0x09 => 'GDB0', }, 0x62 => {}, 0x63 => {}, 0x7e => {}, 0xaa => { 0x00 => 'Str1', 0x01 => 'Str2', 0x02 => 'Str3', 0x03 => 'Str4', 0x04 => 'Str5', 0x05 => 'Str6', 0x06 => 'Str7', 0x07 => 'Str8', 0x08 => 'Str9', 0x09 => 'Str0', }, 0xbb => { 0x00 => 'npv(', 0x01 => 'irr(,', 0x02 => 'bal(', 0x03 => 'Σprn(', 0x04 => 'ΣInt(', 0x05 => '►Nom(', 0x06 => '►Eff(', 0x07 => 'dbd(', 0x08 => 'lcm(', 0x09 => 'gcd(', 0x0A => 'randInt(', 0x0B => 'randBin(', 0x0C => 'sub(', 0x0D => 'stdDev(', 0x0E => 'variance(', 0x0F => 'inString(', 0x10 => 'normalcdf(', 0x11 => 'invNorm(', 0x12 => 'tcdf(', 0x13 => 'χ²cdf(', 0x14 => 'Fcdf(', 0x15 => 'binompdf(', 0x16 => 'binomcdf(', 0x17 => 'poissonpdf(', 0x18 => 'poissoncdf(', 0x19 => 'geometpdf(', 0x1A => 'geometcdf(', 0x1B => 'normalpdf(', 0x1C => 'tpdf(', 0x1D => 'χ²pdf(', 0x1E => 'Fpdf(', 0x1F => 'randNorm(', 0x20 => 'tmv_Pmt', 0x21 => 'tmv_I%', 0x22 => 'tmv_PV', 0x23 => 'tmv_N', 0x24 => 'tmv_FV', 0x25 => 'conj(', 0x26 => 'real(', 0x27 => 'imag(', 0x28 => 'angle(', 0x29 => 'cumSum(', 0x2A => 'expr(', 0x2B => 'length(', 0x2C => 'ΔList(', 0x2D => 'ref(', 0x2E => 'rref(', 0x2F => '►Rect', 0x30 => '►Polar', 0x31 => 'e', 0x32 => 'SinReg', 0x33 => 'Logistic', 0x34 => 'LinRegTTest', 0x35 => 'ShadeNorm(', 0x36 => 'Shade_t(', 0x37 => 'Shadeχ²', 0x38 => 'ShadeF(', 0x39 => 'Matr►list(', 0x3A => 'List►matr(', 0x3B => 'Z-Test(', 0x3C => 'T-Test', 0x3D => '2-SampZTest(', 0x3E => '1-PropZTest(', 0x3F => '2-PropZTest(', 0x40 => 'χ²-Test(', 0x41 => 'ZInterval', 0x42 => '2-SampZInt(', 0x43 => '1-PropZInt(', 0x44 => '2-PropZInt(', 0x45 => 'GraphStyle(', 0x46 => '2-SampTTest', 0x47 => '2-SampFTest', 0x48 => 'TInterval', 0x49 => '2-SampTInt', 0x4A => 'SetUpEditor', 0x4B => 'Pmt_End', 0x4C => 'Pmt_Bgn', 0x4D => 'Real', 0x4E => 're^θi', 0x4F => 'a+bi', 0x50 => 'ExprOn', 0x51 => 'ExprOff', 0x52 => 'ClrAllLists', 0x53 => 'GetCalc(', 0x54 => 'DelVar ', 0x55 => 'Equ►String(', 0x56 => 'String►Equ(', 0x57 => 'Clear Entries', 0x58 => 'Select(', 0x59 => 'ANOVA(', 0x5A => 'ModBoxplot', 0x5B => 'NormProbPlot', 0x64 => 'G-T', 0x65 => 'ZoomFit', 0x66 => 'DiagnosticOn', 0x67 => 'DiagnosticOff', 0x68 => 'Archive', 0x69 => 'UnArchive', 0x6A => 'Asm(', 0x6B => 'AsmComp(', 0x6C => 'AsmPrgm', 0x6D => 'compiled asm', 0x6E => 'Á', 0x6F => 'À', 0x70 => 'Â', 0x71 => 'Ä', 0x72 => 'á', 0x73 => 'à', 0x74 => 'â', 0x75 => 'ä', 0x76 => 'É', 0x77 => 'È', 0x78 => 'Ê', 0x79 => 'Ë', 0x7A => 'é', 0x7B => 'è', 0x7C => 'ê', 0x7D => 'ë', 0x7F => 'Ì', 0x80 => 'Î', 0x81 => 'Ï', 0x82 => 'í', 0x83 => 'ì', 0x84 => 'î', 0x85 => 'ï', 0x86 => 'Ó', 0x87 => 'Ò', 0x88 => 'Ô', 0x89 => 'Ö', 0x8A => 'ó', 0x8B => 'ò', 0x8C => 'ô', 0x8D => 'ö', 0x8E => 'Ú', 0x8F => 'Ù', 0x90 => 'Û', 0x91 => 'Ü', 0x92 => 'ú', 0x93 => 'ù', 0x94 => 'û', 0x95 => 'ü', 0x96 => 'Ç', 0x97 => 'ç', 0x98 => 'Ñ', 0x99 => 'ñ', 0x9A => '´', 0x9B => '`', 0x9C => '¨', 0x9D => '¿', 0x9E => '¡', 0x9F => 'α', 0xA0 => 'β', 0xA1 => 'γ', 0xA2 => 'Δ', 0xA3 => 'δ', 0xA4 => 'ε', 0xA5 => 'λ', 0xA6 => 'μ', 0xA7 => 'π', 0xA8 => 'ρ', 0xA9 => 'Σ', 0xAB => 'φ', 0xAC => 'Ω', 0xAD => '^p', 0xAE => 'χ', 0xAF => 'F', 0xB0 => 'a', 0xB1 => 'b', 0xB2 => 'c', 0xB3 => 'd', 0xB4 => 'e', 0xB5 => 'f', 0xB6 => 'g', 0xB7 => 'h', 0xB8 => 'i', 0xB9 => 'j', 0xBA => 'k', 0xBC => 'l', 0xBD => 'm', 0xBE => 'n', 0xBF => 'o', 0xC0 => 'p', 0xC1 => 'q', 0xC2 => 'r', 0xC3 => 's', 0xC4 => 't', 0xC5 => 'u', 0xC6 => 'v', 0xC7 => 'w', 0xC8 => 'x', 0xC9 => 'y', 0xCA => 'z', 0xCB => 'σ', 0xCC => 'τ', 0xCD => 'Í', 0xCE => 'GarbageCollect', 0xCF => '~', 0xD1 => '@', 0xD2 => '#', 0xD3 => '$', 0xD4 => '&', 0xD5 => '`', 0xD6 => ';', 0xD7 => '\\', 0xD8 => '|', 0xD9 => '_', 0xDA => '%', 0xDB => '…', 0xDC => '∠', 0xDD => 'ß', 0xDE => 'x', 0xDF => 'T', 0xE0 => '0', 0xE1 => '1', 0xE2 => '2', 0xE3 => '3', 0xE4 => '4', 0xE5 => '5', 0xE6 => '6', 0xE7 => '7', 0xE8 => '8', 0xE9 => '9', 0xEA => '10', 0xEB => '←', 0xEC => '→', 0xED => '↑', 0xEE => '↓', 0xF0 => 'x', 0xF1 => '∫', 0xF4 => '√', }, 0xef => { 0x00 => 'setDate(', 0x01 => 'setTime(', 0x02 => 'checkTmr(', 0x03 => 'setDtFmt(', 0x04 => 'setTmFmt(', 0x05 => 'timeCnv(', 0x06 => 'dayOfWk(', 0x07 => 'getDtStr(', 0x08 => 'getTmStr(', 0x09 => 'getDate', 0x0a => 'getTime', 0x0b => 'startTmr', 0x0c => 'getDtFmt', 0x0e => 'getTmFmt', 0x0f => 'isClockOn', 0x10 => 'ClockOn', 0x11 => 'ClockOff', 0x12 => 'OpenLib(', 0x13 => 'ExecLib', 0x14 => 'invT(', 0x15 => 'χ²GOF-Test(', 0x16 => 'LinRegTInt', 0x17 => 'Manual-Fit', }, }; local $/; getopts('i', \%opts); open(PRGM, '<', shift) or die; binmode(PRGM); # Remove header added by tilp2 seek(PRGM, 74, 0); $program = ; close(PRGM); # The last two bytes don't contain program code substr($program, -2, 2, ''); $length = length($program); $offset = 0; while($offset <= $length) { $char = ord(substr($program, $offset++, 1)); if (exists($all{$char})) { $out = $all{$char}; } elsif (exists($special->{$char})) { $char2 = ord(substr($program, $offset++, 1)); $out = $special->{$char}->{$char2}; } else { warn(sprintf('Unknown byte 0x%02x', $char)); $out = chr($char); } if ($opts{i}) { if ($out =~ /Then|While|Repeat|For/) { $indent++; } elsif ($out =~ /Else/) { $rindent--; } elsif ($out =~ /End/) { $indent--; $rindent--; } } $cache .= $out; if ($out eq "\n") { print "\t" x $rindent; $rindent = $indent; print $cache; $cache = ''; } } print $cache;