728 lines
31 KiB
Plaintext
728 lines
31 KiB
Plaintext
Path: linear!mv!news.sprintlink.net!howland.reston.ans.net!spool.mu.edu!uwm.edu!caen!linux.reshall.uich.edu!not-for-mail
|
|
From: john@linux.reshall.umich.edu (John Gotts)
|
|
Newsgroups: alt.2600
|
|
Subject: My TI-85 Calculator Hack (LONG)
|
|
Message-ID: <3a9o91$eav@srvr1.engin.umich.edu>
|
|
Date: 15 Nov 1994 07:33:53 GMT
|
|
Organization: Linux in the Baits Residence Hall at the University of Michigan
|
|
Lines: 695
|
|
NNTP-Posting-Host: linux.reshall.umich.edu
|
|
X-Newsreader: TIN [UNIX 1.3 941109BETA PL0]
|
|
|
|
I thought you guys would be interested in this.
|
|
|
|
[ Article reposted from alt.hackers ]
|
|
[ Author was David Boozer ]
|
|
[ Posted on Sat, 12 Nov 1994 18:45:15 GMT ]
|
|
|
|
Several people have been asking for the document I was referring to in my
|
|
previous message, so I decided to post the whole thing to alt.hackers.
|
|
|
|
- David Boozer (adb2y@virginia.edu)
|
|
|
|
ObHack:
|
|
|
|
The following document:
|
|
|
|
+============================================================================
|
|
|
|
|
| Hacking the TI-85 Calculator
|
|
| by
|
|
| David Boozer (adb2y@virginia.edu)
|
|
|
|
|
| September 1, 1994
|
|
|
|
|
+============================================================================
|
|
|
|
This document explains how to do various spiffy things with your TI-85, such
|
|
as dumping the TI-85's ROM and programming the TI-85 in machine language. I
|
|
have included several programs I wrote which are useful for TI hacking, and
|
|
an .85B file containing the first (to my knowledge) machine language program
|
|
ever written for the TI-85 (well, except for the ROM, of course :)). The
|
|
information provided here has been obtained by diddling around with .85B
|
|
produced using the LINK85 package - the basic method is to:
|
|
|
|
(1) Make a backup of the calculator
|
|
|
|
(2) Study the backup
|
|
|
|
(3) Patch the backup
|
|
|
|
(4) Send it back to the calculator
|
|
|
|
Much of the information I have learned about the TI-85 has not made it into
|
|
this document, but I have tried to include the essentials. I am working on a
|
|
more comprehensive version which should be ready in a few weeks. Classes
|
|
have just started, and I figured I should write something up while I still
|
|
have lots of free time on my hands :). Well, have fun tinkering around and
|
|
send questions/comments to adb2y@virginia.edu.
|
|
|
|
* All numbers are in hexadecimal, unless otherwise stated
|
|
|
|
** The procedures outlined here could cause your TI to crash. If this
|
|
happens, remove one of the batteries, hold down the ON key for a few
|
|
seconds, and replace the battery. Also, remember to turn up the contrast
|
|
by doing 2nd up-arrow a few times after you turn the calculator on. If
|
|
you are at all squeamish about crashing your TI, then don't try these
|
|
procedures (but you still might like to read about them).
|
|
|
|
+----------------------------------------------------------------------------
|
|
| The Structure of a .85B File
|
|
+----------------------------------------------------------------------------
|
|
|
|
An .85B file has the following format:
|
|
|
|
File Offset Contents
|
|
|
|
0000 - 0034 Header
|
|
0035 - 0036 Size word (Number of data bytes)
|
|
0037 - XXXX-2 Data bytes (obtained from TI-85)
|
|
XXXX-1 - XXXX Checksum word
|
|
|
|
The header contains the string "**TI85**", and the file comment that you see
|
|
when using LINK85. The size word at offset 0035 is the number of bytes that
|
|
contain data obtained from the TI-85, and is equal to:
|
|
|
|
(Size of .85B file in bytes)
|
|
- (35 bytes for the header)
|
|
- (2 bytes for the size word)
|
|
- (2 bytes for the checksum)
|
|
------------------------------
|
|
(# of data bytes)
|
|
|
|
Thus:
|
|
|
|
(# of data bytes) = (Size of .85B file in bytes) - 39
|
|
|
|
The checksum word is calculated by adding together all the data bytes (but NOT
|
|
bytes from the header, size word, or checksum word) MOD 10000. I wrote a
|
|
little assembly program called FIX.COM to automagically adjust the checksum
|
|
word of a .85B file to the correct value:
|
|
|
|
begin 644 fix.com
|
|
MOX``B@6*R#+M@_D`='E)1XH%/"!T\T&+][^2`?.DN`(]NI(!S2&+V')4M#^Y
|
|
M`("Z,0+-(:.0`7)%OV8"BPTSP#/2B_F!QV@"3XH5`\+B^8L^D`&!QR\"B06X
|
|
M`$(SR3/2S2%R&K1`BPZ0`;HQ`LTA<@VT";H4`LTAM#[-(<T@NN(!M`G-(>OQ
|
|
MNO0!M`G-(<T@````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M`$9I;&4@22]/($5R<F]R+@T*)$EN=F%L:60@;G5M8F5R(&]F('!A<F%M971E
|
|
C<G,N#0HD0VAE8VMS=6T@:&%S(&)E96X@=7!D871E9"X-"B0`
|
|
`
|
|
end
|
|
|
|
To use the program, simply type:
|
|
|
|
FIX [filename]
|
|
|
|
FIX will also work with .85I files, etc.
|
|
|
|
The first 80 bytes of a typical .85B file are shown below:
|
|
|
|
0000 2A 2A 54 49 38 35 2A 2A-1A 0C 00 42 61 63 6B 75 **TI85**...Backu
|
|
0010 70 20 66 69 6C 65 20 64-61 74 65 64 20 30 39 2F p file dated 09/
|
|
0020 30 31 2F 39 34 2C 20 31-39 3A 31 39 00 2E 00 55 01/94, 19:19...U
|
|
0030 27 F5 5D AE 92 0A 11 09-00 B1 08 1D 10 08 38 00 '.]...........8.
|
|
0040 F7 8B B1 08 20 00 10 00-20 00 01 01 0C 08 00 00 .... ... .......
|
|
0050 32 12 00 00 00 00 05 01-00 00 00 00 00 00 00 00 2...............
|
|
0060 00 00 00 20 3F 20 3F 63-84 6D 84 77 84 81 84 8B ... ? ?c.m.w....
|
|
0070 84 95 84 15 00 00 C0 01-FC 10 00 00 00 00 00 00 ................
|
|
|
|
We see that there are 110A data bytes. The size of the .85B file is 1143;
|
|
note that 110A = 1143 - 39.
|
|
|
|
The data bytes from offset 0900 up to the checksum word are a memory image of
|
|
the TI-85's RAM (well, not the entire RAM, but some of it). A byte at offset
|
|
XXXX in the .85B file corresponds to a byte at memory address:
|
|
|
|
8C00 + (XXXX - 0900)
|
|
|
|
in the TI-85. For example, a byte at offset 090B in the .85B file corresponds
|
|
to a byte at address 8C0B in the TI-85.
|
|
|
|
A hex dump of the bytes at offset 0900 from a .85B file is shown below:
|
|
|
|
0900 00 00 00 00 00 0B 00 44-35 00 0B 38 42 6C 65 74 .......D5..8Blet
|
|
0910 63 68 00 00 00 02 FC 12-30 00 00 00 00 00 00 00 ch......0.......
|
|
0920 FC 50 00 00 00 00 00 00-34 00 68 63 74 65 6C 42 .P......4.hctelB
|
|
0930 06 8C 1E 00 6F 6F 46 03-8C 14 00 21 01 8C 12 12 ....ooF....!....
|
|
0940 23 01 8C 05 12 73 6E 41-03 8B FB 00 74 61 74 53 #....snA....tatS
|
|
0950 79 05 8B F9 04 74 61 74-53 78 05 8B F7 04 32 BC y....tatSx....2.
|
|
|
|
When this backup was made, the calculator had two variables defined:
|
|
|
|
123->Foo
|
|
5->Bletch
|
|
|
|
Notice how these variables appear in the RAM image - each variable has an
|
|
entry in a symbol table. This is what the entry for the "Foo" variable means:
|
|
|
|
|
|
+--- The number of characters in the variable name (3)
|
|
|
|
|
| +--+--- The address of the variable in memory (8C14)
|
|
| | |
|
|
6F 6F 46 03-8C 14 00
|
|
| | | |
|
|
| | | +--- The type of the variable (00 => REAL)
|
|
| | |
|
|
+--+--+--- The name of the variable, backwards (Foo)
|
|
|
|
Note that the address of the variable in memory is stored high order byte
|
|
first!
|
|
|
|
Thus, the symbol table from the above hex dump gives us the following
|
|
information:
|
|
|
|
Variable Name Address of Variable Type of Variable
|
|
|
|
xStat 8BF7 04 => LIST
|
|
yStat 8BF9 04 => LIST
|
|
Ans 8BFB 00 => REAL
|
|
Foo 8C14 00 => REAL
|
|
Bletch 8C1E 00 => REAL
|
|
|
|
Variables "xStat", "yStat", and "Ans" were created automatically by the
|
|
calculator.
|
|
|
|
The bytes for different types of variables are given below:
|
|
|
|
Type Byte Variable Type
|
|
|
|
00 REAL
|
|
01 CMPLX
|
|
02 VECTR
|
|
03 VECTR
|
|
04 LIST
|
|
05 LIST
|
|
06 MATRX
|
|
07 MATRX
|
|
08 CONS
|
|
09 CONS
|
|
0A EQU
|
|
0B <blank>
|
|
0C STRNG
|
|
0D GDB
|
|
0E GDB
|
|
0F GDB
|
|
10 GDB
|
|
11 PIC
|
|
12 PRGM
|
|
|
|
Now, remember that a byte at offset XXXX in the .85B file corresponds to
|
|
a byte at address 8C00 + (XXXX - 0900) in the TI-85's RAM. Thus, since
|
|
the variable "Foo" is located at address 8C14 in RAM, it must be located
|
|
at offset
|
|
|
|
(8C14 - 8C00) + 0900 = 0914
|
|
|
|
in our .85B file. If we look at the ten bytes at 0914 in the above hex dump,
|
|
we see the following:
|
|
|
|
00 02 FC 12 30 00 00 00 00 00
|
|
|
|
What it means is this:
|
|
|
|
+--- <Range> (one byte)
|
|
|
|
|
| +--+--+--+--+--+--+--- <Number> (in BCD, 7 bytes)
|
|
| | | | | | | |
|
|
00 02 FC 12 30 00 00 00 00 00
|
|
| |
|
|
+--+--- <Exponent> (in hex, 2 bytes)
|
|
|
|
Thus, for the variable "Foo":
|
|
|
|
<Range> = FC
|
|
<Exponent> = 2
|
|
<Number> = 1.23
|
|
|
|
The value of the variable is given by:
|
|
|
|
Value = <Number>E[<Exponent> + (100)(<Range> - FC)]
|
|
|
|
So for "Foo":
|
|
|
|
Value = (1.23)E[2 - (100)(FC - FC)]
|
|
= (1.23)E(2)
|
|
= 123
|
|
|
|
Note that numbers which are less than one may be represented by using a <Range>
|
|
which is less than FC.
|
|
|
|
We have seen how data in the .85B file corresponds to data in the TI-85. The
|
|
key points are:
|
|
|
|
- We can edit the .85B file
|
|
|
|
- Data in the .85B file is put into RAM when the .85B file is loaded
|
|
|
|
- Hence, by editing the .85B file, we can diddle around with bytes in
|
|
the TI-85's RAM
|
|
|
|
- In particular, we can edit the memory address of a variable - make it
|
|
point to something OTHER than the data it was given when it was
|
|
created. This brings us to...
|
|
|
|
+----------------------------------------------------------------------------
|
|
| Dumping the TI-85's ROM
|
|
+----------------------------------------------------------------------------
|
|
|
|
The method I developed to dump the TI's ROM is the following:
|
|
|
|
(1) Clear the calculator, then use STPIC to make a PIC file - lets call it
|
|
"PIC1"
|
|
|
|
(2) Back up the calculator - we then get a file "BACKUP.85B"
|
|
|
|
(3) Edit "BACKUP.85B" - change the memory address of "PIC1" to point to a
|
|
ROM location
|
|
|
|
(4) Fix up the checksum of "BACKUP.85B"
|
|
|
|
(5) Transfer the hacked version of "BACKUP.85B" to the TI-85
|
|
|
|
(6) Use RCPIC to load "PIC1" into the graphics screen - the stuff you see
|
|
on the screen is ROM data
|
|
|
|
(7) Use STPIC to store this ROM data in a new PIC file - lets call it "Dump"
|
|
|
|
(8) Transfer "Dump" from the TI-85 to your computer
|
|
|
|
(9) Strip of header & other junk from "Dump"
|
|
|
|
You now have a 3F0 byte core dump of the TI-85's ROM. I wrote an assembly
|
|
program called DUMP.COM to automate most of this:
|
|
|
|
begin 644 dump.com
|
|
MM`FZ"0+-(3/;OX``B@TR[8/Y`'0Z24>*!3P@=/-!,N2#^0!T*DD\87P&/'I_
|
|
M`@3@+#`\"GP"+`<*P'P3/`]_#]'CT>/1X]'C`]A'B@7KT8D>Z@&+P^B'`+0)
|
|
MNDT"S2&_%A"AZ@%(2(;@B06_/P.+#3/`,]*+^8''00-/BA4#PN+YOSD-@<<(
|
|
M`XD%M#PSR;KL`<TA<A2+V+1`N3D-N@H#S2%R!K0^S2'-(+KW`;0)S2'K\5!2
|
|
MBM"T`LTA6EC#4%(E#P`%D``G%$`GZ.;_6EC#4;D$`-+(Z.7_TLCHX/]9PX;@
|
|
MZ.O_AN#HYO_#``!"04-+55`N.#5"`$9I;&4@22]/($5R<F]R+@T*)%1H92!B
|
|
M86-K=7`@9FEL92!"04-+55`N.#5"(&ES(&)E:6YG(&-R96%T960@=&\@9'5M
|
|
M<"!M96UO<GD@861D<F5S<R`D+@T*5&\@;V)T86EN('1H92!D=6UP(&9I;&4Z
|
|
M#0H@("`H,2D@5')A;G-F97(@=&AE(&9I;&4@0D%#2U50+C@U0B!T;R!T:&4@
|
|
M5$DM.#4-"B`@("@R*2!';R!T;R!T:&4@1U)!4$@@;65N=2P@86YD(%)#4$E#
|
|
M(")024,Q(@T*("`@*#,I(%-44$E#(")$=6UP(@T*("`@*#0I(%1R86YS9F5R
|
|
M(")$=6UP(B!T;R!Y;W5R(&-O;7!U=&5R#0HD*BI423@U*BH:#`!-96UO<GD@
|
|
M1'5M<"!"86-K=7`@("`@("`@("`@("`@("`@("`@("`@("``#0D`L0@=#@0P
|
|
M`/>+L0@``!``(`````P(```P$@`````%````````````````(#\@/V.$;81W
|
|
MA(&$BX25A!4``(`!_!```````````/P`````````@@```/P```````````#\
|
|
M8H,84P<8``#_^Q,(F6DXF5<``/P```````````#\````````````_&*#&%,'
|
|
M&```__L3")EI.)E7@`'\$``````````!_!```````````/P0````````@`'\
|
|
M$``````````!_!```````````/P0`````````/W[$`````````#[^Q``````
|
|
M`````/Q```````````#\0`````````#_^Q6',!6',!8`__LR)8!D46$I``#\
|
|
M8P``````````_#$```````!1``#``?P0````````0`'\$````````$``_!``
|
|
M``````#``?P0````````0`'\$````````$``_!````````"``?P0````````
|
|
M``'\$````````%L`````_````````````/QB@QA3!Q@``/_[$PB9:3B95X`!
|
|
M_!```````````?P0``````````#\$````````(`!_!```````````?P0````
|
|
M``````#\$````````%L`````_````````````/QB@QA3!Q@``/_[$PB9:3B9
|
|
M5X`!_!```````````?P0``````````#\$````````(`!_!```````````?P0
|
|
M``````````#\$````````'$```#]^Q```````````/P```````````#\````
|
|
M````````_&*#&%,'&```__L3")EI.)E7@`'\$``````````!_!``````````
|
|
M`/P0````````@`'\$``````````!_!```````````/P0`````````!``]_\`
|
|
M`$SZ"8SW_P``````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M```````````````````````````````````````````````````$_!(T4```
|
|
M````!/QGB0````````````````````````````4"`````"`@("`@("`@("`@
|
|
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
|
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
|
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
|
M("`@("`@("`@("`@("`@("`@("`@(`````````F,"8Q"]D+V`````/?_``#F
|
|
M9PX+H6@`!P```````````/\`````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M`````````````````````/?_```%D```````````````````````````````
|
|
M"0\`````````````````````````````````````````.VH`]__W_T?Z]_\%
|
|
MD`60!9`_^C_Z`````#_Z``````````````X$````````_```````````````
|
|
M``#\`````````/`#````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````,``Q0TE0!)Q9$7D!C`D`
|
|
E(0&,!Q(C`8P%$G-N00.+^P!T8713>06+^01T8713>`6+]P3FNP``
|
|
`
|
|
end
|
|
|
|
To use the program, type:
|
|
|
|
DUMP [address, in hex]
|
|
|
|
This will create a file called "BACKUP.85B" with all the necessary
|
|
modifications already made (ie. in effect, it performs steps 1 to 4). Just
|
|
send this to your TI as outlined in steps 5 to 9 in the above list, and you
|
|
will end up with a file called DUMP.85I. Bytes 0000 to 0044 of DUMP.85I are
|
|
the header & can be ignored; bytes from 0045 onward contain the ROM data.
|
|
Here is a dump I made of memory address 33D9:
|
|
|
|
33D0 E3 F5 D5 5E 23 56 23 ...^#V#
|
|
33E0 7E D3 05 EB D1 F1 E3 C9-CD AC 33 38 7D 06 CD AC ~.........38}...
|
|
33F0 33 7B 7D 06 CD AC 33 81-43 07 CD AC 33 12 49 07 3{}...3.C...3.I.
|
|
3400 CD AC 33 65 67 06 CD AC-33 12 69 06 CD AC 33 5C ..3eg...3.i...3\
|
|
3410 69 06 CD AC 33 26 6D 06-CD AC 33 D6 41 07 CD AC i...3&m...3.A...
|
|
3420 33 8B 68 07 CD AC 33 6F-7D 06 CD AC 33 16 52 07 3.h...3o}...3.R.
|
|
3430 CD AC 33 54 54 07 CD AC-33 59 77 06 CD AC 33 1F ..3TT...3Yw...3.
|
|
3440 4B 07 CD AC 33 D6 5D 06-CD AC 33 09 55 06 CD AC K...3.]...3.U...
|
|
3450 33 F9 56 06 CD AC 33 D3-57 3.V...3.W
|
|
|
|
I ran this through a Z80 disassembler to get the following code:
|
|
|
|
33D9: E3 EX (SP),HL
|
|
33DA: F5 PUSH AF
|
|
33DB: D5 PUSH DE
|
|
33DC: 5E LD E,(HL)
|
|
33DD: 23 INC HL
|
|
33DE: 56 LD D,(HL)
|
|
33DF: 23 INC HL
|
|
33E0: 7E LD A,(HL)
|
|
33E1: D3 05 OUT (PORT05H),A
|
|
33E3: EB EX DE,HL
|
|
33E4: D1 POP DE
|
|
33E5: F1 POP AF
|
|
33E6: E3 EX (SP),HL
|
|
33E7: C9 RET
|
|
33E8: CD AC 33 CALL L33AC
|
|
33EB: 38 7D JR C,L346A
|
|
33ED: 06 CD LD B,205
|
|
33EF: AC XOR H
|
|
33F0: 33 INC SP
|
|
33F1: 7B LD A,E
|
|
33F2: 7D LD A,L
|
|
33F3: 06 CD LD B,205
|
|
33F5: AC XOR H
|
|
33F6: 33 INC SP
|
|
33F7: 81 ADD A,C
|
|
33F8: 43 LD B,E
|
|
etc.
|
|
|
|
+----------------------------------------------------------------------------
|
|
| A Few Technical Tidbits about the TI-85
|
|
+----------------------------------------------------------------------------
|
|
|
|
In the next section I will discuss how to write your own machine language
|
|
programs, but before I do, we will need a few facts about the TI-85. First
|
|
of all, we need some information about the video display:
|
|
|
|
Mode Address Dimensions Size (in bytes)
|
|
|
|
Text 80DD 8 x 21 8*21 = 168 bytes
|
|
Graphics 8641 63 x 128 (63*128)/8 = 1008 bytes
|
|
|
|
Next, we need to understand the CUSTOM menu. At offset 08B1 in a .85B file,
|
|
you will see a sequence of 1C bytes, as shown:
|
|
|
|
08B0 9C 59 00 00 A1 59 00-00 00 00 00 00 00 00 00
|
|
08C0 00 00 00 00 00 00 00 00-00 00 00 00 00
|
|
|
|
Each pair of bytes (word) corresponds to menu item in the CUSTOM menu. In the
|
|
above example, we have
|
|
|
|
Item # Name Word
|
|
|
|
Item #1 "abs" 599C
|
|
Item #2 <blank> 0000
|
|
Item #3 "and" 59A1
|
|
Items #4 <blank> 0000
|
|
: :
|
|
: :
|
|
Item #15 <blank> 0000
|
|
|
|
The word associated with a menu item is a memory address - it points to a
|
|
data structure, such as:
|
|
|
|
41 00 07 C3 40 3F 45 44 49 54 00
|
|
|
|
There are actually several possible data structures, but this is the most
|
|
useful.
|
|
|
|
This data structure means the following:
|
|
|
|
+--+--+--+------- ??? (I have some ideas, but no time to explain...)
|
|
| | | |
|
|
| | | | +--+--+--+--- Name of menu item (EDIT)
|
|
| | | | | | | |
|
|
41 00 07 C3 40 3F 45 44 49 54 00
|
|
| | |
|
|
| | +-- Zero termination byte
|
|
| |
|
|
+--+--- Memory address (3F40)
|
|
|
|
When you select a menu item, the code at "Memory address" is executed - in
|
|
this case, the code ad 3F40 is executed. Using my DUMP program, I was able
|
|
to dump this memory location to find:
|
|
|
|
3F40 C3 D9 33
|
|
|
|
Or, in Z80-speak:
|
|
|
|
C3 D9 33 CALL 33D9
|
|
|
|
With this information, we can move on to...
|
|
|
|
+----------------------------------------------------------------------------
|
|
| Writing Machine Language Programs
|
|
+----------------------------------------------------------------------------
|
|
|
|
The basic idea is this:
|
|
|
|
(1) Edit the BACKUP.85B file so that the item #1 of the custom menu
|
|
points to 8641 (the first byte of the graphics display)
|
|
|
|
(2) By editing PIC files (or drawing the bits in manually :)), we can
|
|
diddle around with bytes in the video memory.
|
|
|
|
(3) Put the following bytes in the video memory:
|
|
|
|
41 00 07 C3 50 86 45 00
|
|
|
|
Note that the memory address 8650 is also in the video memory.
|
|
|
|
(4) Put your machine language program at address 8650.
|
|
|
|
Now, when you select item #1 of the custom menu, your program will be
|
|
executed! Just as a demonstration, I created the following .85I file, to
|
|
be loaded into video memory:
|
|
|
|
0000 2A 2A 54 49 38 35 2A 2A-1A 0C 00 50 69 63 74 75 **TI85**...Pictu
|
|
0010 72 65 20 66 69 6C 65 20-64 61 74 65 64 20 30 39 re file dated 09
|
|
0020 2F 30 31 2F 39 34 2C 20-32 31 3A 30 38 00 00 55 /01/94, 21:08..U
|
|
0030 27 F5 5D AE 92 FE 03 08-00 F2 03 11 04 44 75 6D '.]..........Dum
|
|
0040 70 F2 03 F0 03 41 00 07-C3 50 86 45 00 00 00 00 p....A...P.E....
|
|
0050 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
0060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
0070 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
0080 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
0090 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00B0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00D0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00F0 C3 40 3F 00 00 00 00 00-00 00 00 00 00 00 00 00 .F?.............
|
|
<just more zeros>
|
|
|
|
The first 44 bytes are just header info - ignore them. The stuff at offset
|
|
0045 is our menu data structure:
|
|
|
|
41 00 07-C3 50 86 45 00
|
|
| |
|
|
+--+--- Points to 8650
|
|
|
|
The three bytes at 00F0 represent a JP (jump) instruction on the Z80:
|
|
|
|
C3 46 3F JP 3F40
|
|
|
|
Address 3F40 is the code for the "Edit Matrix" menu item. What about all
|
|
the zeros between 004C and 00F0? Well, 00 is a NOP on the Z80, so they do
|
|
nothing.
|
|
|
|
The sequence of events is as follows:
|
|
|
|
(1) The user selects item #1 from the CUSTOM menu
|
|
|
|
(2) The TI looks at memory location 8641, which is the first byte of
|
|
video memory (remember, we changed the CUSTOM menu so that item #1
|
|
would point here)
|
|
|
|
(3) The TI finds the bytes:
|
|
|
|
41 00 07 C3 50 86 45 00
|
|
|
|
which we cleverly placed in the graphics display (and hence at memory
|
|
address 8641)
|
|
|
|
(4) Thus, the calculator executes the instruction at 8650
|
|
|
|
(5) At 8650, it encounters a string of NOPs (zeros), leading up to
|
|
|
|
C3 46 3F JP 3F40
|
|
|
|
The TI takes the jump, which leads to the matrix editor
|
|
|
|
Here is a backup of the TI-85 all set up to demonstrate the above program:
|
|
|
|
begin 644 backup.85b
|
|
M*BI423@U*BH:#`!"86-K=7`@9FEL92!D871E9"`P.2\P,2\Y-"P@,3DZ,3D`
|
|
M+@!5)_5=KI(*$0D`L0@=$`@X`/>+L0@@`!``(``!`0P(```R$@`````%`0``
|
|
M````````````(#\@/V.$;81WA(&$BX25A!4``,`!_!```````````/P`````
|
|
M````@@```/P```````````#\8H,84P<8``#_^Q,(F6DXF5<``/P`````````
|
|
M``#\````````````_&*#&%,'&```__L3")EI.)E7@`'\$``````````!_!``
|
|
M`````````/P0````````@`'\$``````````!_!```````````/P0````````
|
|
M`/W[$`````````#[^Q```````````/Q```````````#\0`````````#_^Q6'
|
|
M,!6',!8`__LR)8!D46$I``#\8P``````````_#$```````!1``#``?P0````
|
|
M````0`'\$````````$``_!````````#``?P0````````0`'\$````````$``
|
|
M_!````````"``?P0``````````'\$````````%L`````_````````````/QB
|
|
M@QA3!Q@``/_[$PB9:3B95X`!_!```````````?P0``````````#\$```````
|
|
M`(`!_!```````````?P0``````````#\$````````%L`````_```````````
|
|
M`/QB@QA3!Q@``/_[$PB9:3B95X`!_!```````````?P0``````````#\$```
|
|
M`````(`!_!```````````?P0``````````#\$````````'$```#]^Q``````
|
|
M`````/P```````````#\````````````_&*#&%,'&```__L3")EI.)E7@`'\
|
|
M$``````````!_!```````````/P0````````@`'\$``````````!_!``````
|
|
M`````/P0`````````!``]_\``$SZ&8SW_P``````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````00`'PU"&10``````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````PT`_````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M```````````````$_!(T4```````!/QGB0``````$@`C,Y4```````>,&(P6
|
|
MC`$``````"`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
|
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
|
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
|
|
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@(```````
|
|
M`!F,&8Q(\DCR`````/?_``#F9PX+H6@`!P#[____`````/\`````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M`````````````````````````````````````````````/?_```'E```````
|
|
M````````````````````````"0]!A@``````````````````````````````
|
|
M````````,68`]__W_UWZ]_\'E`>4!Y0W^C?Z`````#?Z`````````````!`(
|
|
M```````#_#.#```````0`$0-,#`$`&!$,@!@1#,U!```````_`````````#P
|
|
M`P``````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M`````````````````````````/`#00`'PU"&10``````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````PT`_````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````````````
|
|
M````````````````````````````````````````````````````.`!P;75$
|
|
M!)`5$3%#25`$:CD1>0&,&0`A`8P7$B,!C`42<VY!`XO[`'1A=%-Y!8OY!'1A
|
|
)=%-X!8OW!'?1
|
|
`
|
|
end
|
|
|
|
Just transfer it to your TI, go into the CUSTOM menu, and select menu item #1
|
|
(marked "E"). You might also want to take a look at the graphics display, or
|
|
transfer it to your computer to play with. Some other interesting memory
|
|
locations to jump to are:
|
|
|
|
Eqn. Solver 3F28
|
|
Draw Program 3F52
|
|
Program Editor 3F46
|
|
|
|
Well, the three byte program C3 46 3F is admittedly not very impressive, but
|
|
it does demonstrate that programming the TI-85 in machine language is
|
|
possible. More advanced programs are in the works...
|
|
|
|
TO BE CONTINUED
|
|
|
|
--
|
|
John Gotts (jgotts@engin.umich.edu) WWW: http://www.engin.umich.edu/~jgotts
|
|
Student Employee, Computer Aided Engineering Network (CAEN), Sun Support
|
|
GE -d+ H s+: g-- p? !au a-- w+ v C++++ UL++++ P+>++ L++ 3- E--- N+++ K- !W M--
|
|
V-- -po+(---) Y+ t+ 5 j+ R- G? tv b+ D B- e+ u--- h f+ r n- y? <Linux rules!>
|
|
|
|
X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-X
|
|
Another file downloaded from: NIRVANAnet(tm)
|
|
|
|
&TOTSE 510/935-5845 Walnut Creek, CA Taipan Enigma
|
|
Burn This Flag 408/363-9766 San Jose, CA Zardoz
|
|
realitycheck 415/648-9489 San Francisco, CA Poindexter Fortran
|
|
Phallicide 408/899-0235 Monterey, CA Reclinerhead
|
|
Governed Anarchy 510/226-6656 Fremont, CA Eightball
|
|
New Dork Sublime 805/823-1346 Tehachapi, CA Biffnix
|
|
The Ether Room 510/228-1146 Martinez, CA Tiny Little Super Guy
|
|
Lies Unlimited 801/278-2699 Salt Lake City, UT Mick Freen
|
|
The Shrine 206/793-3465 Monroe, WA Rif Raf
|
|
Atomic Books 410/669-4179 Baltimore, MD Baywolf
|
|
Sea of Noise 203/886-1441 Norwich, CT Mr. Noise
|
|
The Floating Pancreas 305/424-0266 Ft. Lauderdale, FL Majestic Cockster
|
|
The Dojo 713/436-1795 Pearland, TX Yojimbo
|
|
Frayed Ends of Sanity 503/965-6747 Cloverdale, OR Flatline
|
|
|
|
"Raw Data for Raw Nerves"
|
|
X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-X
|