ROM dumping tools for TI-81 --------------------------- This is a collection of programs that may be useful when attempting to dump the ROM of a TI-81 calculator. It's not very well organized at the moment. Using these tools will require some technical skill, a lot of patience, and the willingness to crash your calculator a few times. There may even be bugs. With that out of the way: 0. Materials Required --------------------- 1. A TI-81 graphing calculator (hopefully, any ROM version will do.) 2. A good set of batteries. 3. A digital camera capable of recording at least an hour of video. Resolution is important; frame rate, not so much. I used 640x480 at 10 fps. 4. A tripod. 5. Appropriate lighting. 6. A PC, with the following installed: - a C compiler - GTK+ - Perl - ffmpeg 1. Compiling the tools ---------------------- Run 'make'. 2. Setting up the calculator ---------------------------- Enter the following as prgm1: as shown on calc screen spaces added for clarity ------------------------------------------------------ :"77777777777777 " 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7≠DispGraphPT-On 7 ≠ DispGraph PT-On( (ю^All-On6≤ln Xm 10^ All-On 6 ≤ ln Xmax axDispGraphClrDr DispGraph ClrDraw aw≤All-OnPT-Chg( ≤ All-On PT-Chg( ConnectedOW7777T Connected O W 7 7 7 7 Tstep stepY₂-On1PT-Off Y₂-On 1 PT-Off( (XminY₂-On1PT-Of Xmin Y₂-On 1 PT-Off( f(sinh Xres[B]An sinh Xres [B] Ans sXmax≤Y₂-On1PT-O Xmax ≤ Y₂-On 1 PT-Off( ff(5=ln 6√Brow5= 5 = ln 6 √ Brow 5 = ⁻8DispGraph7777¹ (-) 8 DispGraph 7 7 7 7 ⁻¹ ((((Y₂-On.PT-Off ( ( ( ( Y₂-On . PT-Off( (CrowY₂-Off,0)Hi Crow Y₂-Off , 0 ) Hist stY₁┬/G6PT-Off(. Y₁┬ / G 6 PT-Off( . X₂┬-OnY₃=Ymin°Ro X₂┬-On Y₃ = Ymin ° Round( und(R▸P(P▸R(RowS R▸P( P▸R( RowSwap( wap(Row+(*Row+(N Row+( *Row+( NDeriv( Deriv(RandGHIQSW Rand G H I Q S W θ8Y₂8Y₃┬"→Y₂ θ 8 Y₂ 8 Y₃┬ " → Y₂ (See 'dump.asm' for the source to this program. The above text was generated by the 'bintotok' program.) Note: The above code had only been tested on 2.0V. It didn't work on 1.6K. On all early TI-81, it should be replaced by the following code: as shown on calc screen spaces added for clarity assembly code ------------------------------------------------------------------------------- :"77777777777777 " 7 7 7 7 7 7 7 7 7 7 7 7 7 7 1717171717171717171717171717 7≠DispGraphPT-On 7 ≠ DispGraph PT-On( 1721E4DC (ю^All-On6≤ln Xm 10^ All-On 6 ≤ ln Xmax 37CB1623347E axDispGraphClrDr DispGraph ClrDraw E4E1 aw≤All-OnPT-Chg( ≤ All-On PT-Chg( 23CBDE Y₂-Ontan¹ PT-Off Y₂-On tan⁻¹ PT-Off( CD3DDD (7777TstepY₂-On1 7 7 7 7 Tstep Y₂-On 1 171717177CCD11 PT-Off(XminY₂-On PT-Off( Xmin Y₂-On DD7DCD 1PT-Off(sinh Xre 1 PT-Off( sinh Xres 11DD3E83 s[B]AnsXmax≤Y₂-O [B] Ans Xmax ≤ Y₂-On 87577E23CD n1PT-Off(5=ln 6√ 1 PT-Off( 5 = ln 6 √ 11DD1520341632 Brow5=⁻8DispGrap Brow 5 = (-) 8 DispGraph 7615203018E4 h7777¹((((Y₂-On. 7 7 7 7 ⁻¹ ( ( ( ( Y₂-On . 17171717471F1F1F1FCD1A PT-Off(CrowY₂-Of PT-Off( Crow Y₂-Off DD78D5 f,0)HistY₁┬/G6PT , 0 ) Hist Y₁┬ / G 6 PT-Off( 1E101DA3C6295F16DD -Off(.X₂┬-OnY₃=Y . X₂┬-On Y₃ = Ymin 1AD1C32080 min°Round(R▸P(P▸ ° Round( R▸P( P▸R( 4D4E4F50 R(RowSwap(Row+(* RowSwap( Row+( *Row+( 515254 Row+(NDeriv(Rand NDeriv( Rand 5558 GHIQSWθ8Y₂8Y₃┬Co G H I Q S W θ 8 Y₂ 8 Y₃┬ Connected 5F6061696B6F7318C218CAAF nnectedOW1JPT-Of O W 1 J PT-Off( 676F1162DD f(sinh Prgm¹.Y₃- sinh Prgm ⁻¹ . Y₃-Off 3E07471AD6 Offcosh If 3≤Y₂c cosh If 3 ≤ Y₂ cosh 40BE1323C240 osh PT-Off(Crowt PT-Off( Crow tan⁻¹ DD783D an¹ Y₂?PT-Off( n Y₂ ? PT-Off( nPr C245DD2B Pr XmaxY₃-OffX₃┬ Xmax Y₃-Off X₃┬ 7ED6C9 Y₂*Row+(PT-Off(≤ Y₂ *Row+( PT-Off( ≤ C254DD23 <-PT-Off(OWX₃┬I* < - PT-Off( O W X₃┬ I *Row( 2227DD676FC96153 Row(≤ArowIf sinh ≤ Arow If sinh 2374BE3E P▸R(" P▸R( " 50 This should be identical to the older program, except that near the beginning, 'Connected O W' is replaced by 'Y₂-On tan⁻¹ PT-Off(', and there's extra code added to the end (beginning with 'Connected O W'.) This extra code searches for the PutC routine in the OS; if all goes well, it should then proceed to dump the ROM as usual. If the PutC routine can't be identified, this code will probably just go into an infinite loop and display nothing (you should still be able to halt it by pressing On.) Enter the following as prgm2: :X+1→X :If X<9 :prgm2 :0→X :Input X Enter the following as prgm3: :"PT-On(PT-On(PT -On(PT-On(PT-On( PT-On(PT-On(PT-O n(PT-On(PT-On(PT -On(PT-On(PT-On( PT-On(PT-On(PT-O n(PT-On(PT-On(PT -On(PT-On(PT-On( PT-On(PT-On(PT-O n(PT-On(PT-On(PT -On(PT-On(PT-On( PT-On(PT-On(PT-O n(PT-On(PT-On(PT -On(PT-On(PT-On( PT-On(PT-On(PT-O n(PT-On(PT-On(PT -On(PT-On(PT-On( PT-On(PT-On(PT-O n(PT-On(PT-On(++ ++++++++++++++++ ++++++++++++"→Y4 (The precise number isn't important, just be sure to include a LOT of PT-On( commands.) Go to the Y= screen. Clear ALL equations (including the parametric ones.) Enter the following as Y₁: :Y₁=(⁻1)^π Execute the following: Prgm1 Prgm3 0→{x}(1 π→{y}(1 1→{x}(2 1→{y}(2 LinReg (the last part is just used to store a nice long expression in RegEQ.) Go back to the Y= screen and scroll down to Y₃. Type RegEQ over and over until it won't let you type anything more. 3. Running the ROM dumper ------------------------- 3a. Turn the calculator off and back on. 3b. Do the following FIVE times: - Run prgm2. - At the prompt, type Y₁. - An error message will be displayed. Press Enter to "Goto Error." - Press 2nd, CLEAR to exit the Y= screen. 3c. Run prgm3. If you typed everything correctly, the calculator will start printing out the contents of ROM. If you typed anything wrong, it will most likely either crash or do nothing. (If it does nothing, then immediately turn the calculator off and back on. Then clear the equations and start over.) The ROM contents are printed in hexadecimal, but not using normal digits. The "digits" are as follows: A = 0 B = 1 C = 2 D = 3 E = 4 F = 5 H = 6 I = 7 L = 8 S = 9 T = A U = B b = C d = D h = E n = F When you're done, press ON to exit the ROM dumper and turn the calculator off. 4. Recording the screen contents -------------------------------- To get a good ROM dump, you'll need to record the screen output very precisely. Use a tripod, and put both the camera and calculator somewhere where you're not likely to bump them by accident. Make sure the screen is well lit, and position the camera so that there is no glare, and the entire screen is (mostly) in focus. Start recording before you run prgm3, and continue recording until you've gotten well past the point you want to stop (e.g., "LAAA".) 5. Dumping at different offsets ------------------------------- I found that despite my best efforts, some parts of the screen were simply harder to see than others. In particular, the rightmost column is at a disadvantage because the top-right corner is blocked by the run indicator. My way around this was to dump the ROM twice: once starting at address 0000, and once starting at address 0015 (which happens to be 3 mod 6.) To do this, go to Y₁, find the 'OW7777TStep' bit, and replace it with 'OWInt 577Tstep'. ('Int 5' stands for the opcode 'LD L,15h'. The '7's, in this case, are placeholders.) You could, of course, use a different address if you wanted. 6. Defining video coordinates ----------------------------- Once you have a video file, you need to identify the screen coordinates. This is done using the 'coordedit' program. Extract a single frame from the video: ffmpeg -ss 30 -i video.mov -an -vframes 1 -vcodec ppm sample.ppm Then run './coordedit sample.ppm'. coordedit displays the image you specify, with a grid overlaid on top. Click and drag points along the boundary of the grid, until the grid is aligned with the empty pixels between characters on the screen. The text box at the top of the window contains the grid parameters. Test that you have a good fit by copying those parameters and passing them to 'xchr', e.g. ./xchr sample.ppm 138.0000 105.1772 445.0000 111.3641 147.0000 305.2202 \ 458.0000 293.3620 0.0682 0.1347 0.2029 0.2679 0.3344 0.3977 0.4610 \ 0.5244 0.5860 0.6477 0.7062 0.7679 0.8263 0.8847 0.9446 0.1429 0.2857 \ 0.4258 0.5714 0.7143 0.8571 (You can also use 'xchrv' instead of 'xchr' if you want a lot of detailed debugging information.) 7. Extracting the data ---------------------- Open extr.pl using your favorite text editor. Set $VIDEOFILE to the path to your video file; $LOGFILE to the location where output should be written; $COORDS to the list of grid coordinates you found in the previous step. Run extr.pl with two arguments (the starting and ending time, in seconds.) It will extract one frame every 1/10 of a second, run it through xchr, and write the result to the designated $LOGFILE. You can combine results from multiple video files into a single log file; remember that each video file will need a different set of grid coordinates. 8. Combining the data --------------------- Once you have a complete log file (possibly after processing several video files), you can use the 'collect' program to combine the results. Run './collect my-log-file' to analyze the contents of 'my-log-file' and display the program's best guess of the value of each of the 65,536 hexadecimal digits in the ROM. For instance: 0000 (3) 2223333333333333333333333333333333333 0000 (E) EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE indicates that for the first byte of ROM, 3 video frames appear to contain the value "2E", while 34 appear to contain "3E". If the program is unsure about a particular digit, '???' will be displayed. Run './collect my-log-file output.bin' to write the results to output.bin. collect will manually prompt you for the value of each digit it is unsure about.