
Having discovered in my regular control a certain amount of computational errors, the physics teacher said several most polite phrases, which would loosely translate into a living Great Russian language like this:
So that next time there was a normal graphing calculator!
As a result of the raid on the nearest bookstore (there were no more relevant ones in the district),
TI-84 Plus was acquired. After all the controls were written, the question arose: what, strictly speaking, does this animal know how? By Google, it turned out that TI-84 Plus is not only a valuable square root extractor, but also:
- Legendary Zilog Z80,
- 24 Kb of RAM and 480 Kb of Flash available to the user,
- A bunch of useful (and not so) programs written by enthusiasts.
Under the cut there is a small review of the calculator and a rather clumsy game
“robots” of my writing. I apologize in advance to the lovers of nudity - I could not make out the calculator, and I was afraid.
The TI-84 + is a 96x64 programmable graphic calculator with a black and white screen. "Says and understands" mathematical notation (fractions of the form a above ba, square roots with an argument under the line, and so on):

Able to a bunch of useful mathematical pieces, but its programmability from the point of view of Habr is more interesting.
Programming
TI-84 + can be programmed out of the box either on TI BASIC or in machine codes. TI BASIC is a dialect of BASICa. This is a “structural”, not a “macaroni” dialect. Instead of keywords - tokens (in my opinion something like this was in Spectrum). Optimized for mathematical operations, for games and other applications it is suitable for itself, although of course you can write anything with skill. Of the minuses very slow, because in addition to the interpretation, all the floating point math. Of the benefits - the programs take up very little space.
')
Another possibility is machine codes. Usually assembler assembled on a computer. Accordingly, the programs are obtained by several orders of magnitude faster and two times more than the corresponding program in BASIC. They can also kill the calculator.
Enthusiasts have created other ways to program the TI-84 +. Perhaps the most significant is AX. This is an analogue of C for calculators: a language with a Basic-like syntax translated into machine codes. It does not require a computer to write and compile a program (although, writing a large program on a calculator is a pleasure for an amateur). Uses sixteen bit arithmetic, which of course is slower than native eight bit.
Programs for TI-84 +
Here there is an archive with a bunch of programs - how useful, yatak and gaming. Also, there are many useful programs on the
official TI website. On a calculator out of the box, the memory is crammed to capacity, but most of the programs in the standard package are useless, they can be safely removed.
A few words about the organization of memory: the calculator has RAM and FLASH (Archive in TI terminology). Both are organized in a kind of file system. Programs and data can be stored both in RAM and in FLASH. FLASH is slower, but more. In addition to “programs” and data, “applications” are stored in FLASH — they differ from “programs” in that they are distributed over the pages of FLASH-memory and can take up more memory than the processor is able to address.
A useful thing worth having on a calculator is a shell, an application containing libraries, a binary program loader, and a graphical interface. I personally use
Doors CS . Its plus is that it contains libraries of all popular shells, and minus - in large size. The creators of Doors CS tried to make the interface look like Windows, for which TI-84 + fits, in my opinion, badly. However, using the GUI Door CS is optional, it is automatically integrated into the OS.
Some interesting programs for TI-84 +:
"Robots" on AX
After chasing the bird and jumping through the portals, I decided to write something myself. I chose AX as the language and BSD robots as the task. It turned out clumsily: most of the memory is occupied by arrays. But how to make more compact, I have not thought up.
The program consists of five "parts": initialization, drawing, creating a new level, "intelligence" of robots and the main loop. Differences from the original: the playing field is 23x15 (each 4x4 sprite + border), fewer robots due to a smaller playing field, no scoring.
Initialization
Hidden text.ROBOTS .IMAGES .EMPTY .ROBOT .JUNK .PLAYER .STONE .STONE [000000000000000020702000000000007070700000000000702070000000000020707000000000002070700000000000]->Pic1 .FIELD Buff(23*15)->Str1 Buff(23*15)->Str2 Buff(23*15)->Str3 1->L
Everything is simple here. First comes the title with the name of the program, then the hexadecimal string with sprites. AX supports 8x8 sprites, and I have 4x4 sprites, so most of this drains are zeros. Also, I used an “empty” sprite and repeated the sprite with the grave two times to simplify the rendering.
Further the arrays with the playing field are initialized. Str1 - the main playing field, Str2 - auxiliary, Str3 - a copy of the old playing field to prevent player errors. Variable L - level.
Notice the syntax for AX (and TI-BASICa): assignment takes place from right to left.
Creating a new level
Hidden text Lbl NEWLVL Fill(Str1,15*23,0) L*5->R For(R) rand^15->I rand^23->J I*23+J+Str1->P 1->{P} End rand^23->X rand^15->Y 3->{Y*23+X+Str1} Return
First, the playing field is reset to zero, then robots are placed on it (sprite numbered 1). In the original, ten robots appeared on each level, my playing field is smaller, so I chose five. Robots may be less than L * 5 because of the overlap, I decided to consider it a fitchey. Then the position of the player is selected (sprite number 3), again: unlike the original, where you can die on a zero move, my player “kills” the robot if it lands on him at the beginning of the game.
Drawing
Hidden text Lbl DRAW ClrDraw VLine(0,0,62) VLine(94,0,62) HLine(0,0,94) HLine(62,0,94) For(I,0,22) For(J,0,14) Pt-On(I*4+1,J*4+2,{J*23+I+Str1}*8+Pic1) End:End DispGraph Return
Here, again, everything is simple. It’s probably worth saying that the colon is the operator separator, and Pt-On is the drawing of the sprite. Lbl - label from LaBeL. Braces in AX - the value of the byte at a given address.
Robots movement
Hidden text Lbl STEP 0->R Fill(Str2,23*15,0) For(I,0,22):For(J,0,14) J*23+I->A {A+Str1}->B If B=2 2->{A+Str2}:End If B=1: R+1->R (J+SIGN(J,Y))*23+I+SIGN(I,X)+Str2->A {A}+({A}<2)->{A} End End:End Copy(Str2,Str1,23*15) Y*23+X+Str1->A {A}+3->{A} Return Lbl SIGN ([r1]<[r2])-([r1]>[r2]) Return
This is where the dirty hacks begin. The program scans the playing field, looking for robots, and moves them towards the player. Comparison operations in AX return one, therefore {A} + ({A} <2) -> {A} increments A if and only if A is less than two. Then the player’s position is marked.
Main loop
Hidden text While 1 0->G NEWLVL() DRAW() While R>0 X->M:Y->N Copy(Str1,Str3,23*15) If G<200 getKey^^r->G ReturnIf G=9 G^100->K End If K=47 rand^23->X rand^15->Y STEP() DRAW() If {A}!=3 getKey^^r:Return End Else (K=51)+(K=48)+(K=45)-(K=49)-(K=46)-(K=43)->I ((K>=43) and (K<=45))-((K>=49) and (K<=51))->J If ((J+Y)<15) and ((J+Y)>=0) and ((I+X)<23) and ((I+X)>=0) X+I->X:Y+J->Y Else:0->G End STEP() If {A}!=3 M->X:N->Y Copy(Str3,Str1,23*15) 0->G End End
Actually, you can observe the deterioration of the code quality: I had to rewrite the main cycle three times (the commandment “make backups” for TI-84 + is more relevant than ever), and by the end I was tired. The result is what turned out.
Explanations:
R - the number of robots on the playing field. If there are no more robots, then the level is passed.
getKey ^^ r waits for the key to be pressed, then returns the scan code. Realizing my criminal intent, I used the fact that the 2nd modifier adds a hundred to the scan codes of the number keys. Thus, the new key is not readable if the 2nd one was pressed - thus the repetition is realized. The true scan code is stored in the variable G, and if G is greater than 200, the new command is not read.
Scan code 147 - key "5". In the game, this is a teleportation team. Teleportation is the only move in which the game can end, so it is processed separately.
The scan codes 43 ... 45, 49 ... 51, 46 and 48 are the numeric keys, the player moves along them. It is impossible to kill a player while moving, so the state of the game is saved until the turn and is restored if the player collides with someone. At the same time, G is reset.
How it all looks assembled:
Hidden text .ROBOTS .IMAGES .EMPTY .ROBOT .JUNK .PLAYER .STONE .STONE [000000000000000020702000000000007070700000000000702070000000000020707000000000002070700000000000]->Pic1 .FIELD Buff(23*15)->Str1 Buff(23*15)->Str2 Buff(23*15)->Str3 1->L While 1 0->G NEWLVL() DRAW() While R>0 X->M:Y->N Copy(Str1,Str3,23*15) If G<200 getKey^^r->G ReturnIf G=9 G^100->K End If K=47 rand^23->X rand^15->Y STEP() DRAW() If {A}!=3 getKey^^r:Return End Else (K=51)+(K=48)+(K=45)-(K=49)-(K=46)-(K=43)->I ((K>=43) and (K<=45))-((K>=49) and (K<=51))->J If ((J+Y)<15) and ((J+Y)>=0) and ((I+X)<23) and ((I+X)>=0) X+I->X:Y+J->Y Else:0->G End STEP() If {A}!=3 M->X:N->Y Copy(Str3,Str1,23*15) 0->G End End DRAW() End L+1->L End Return Lbl DRAW ClrDraw VLine(0,0,62) VLine(94,0,62) HLine(0,0,94) HLine(62,0,94) For(I,0,22) For(J,0,14) Pt-On(I*4+1,J*4+2,{J*23+I+Str1}*8+Pic1) End:End DispGraph Return Lbl NEWLVL Fill(Str1,15*23,0) L*5->R For(R) rand^15->I rand^23->J I*23+J+Str1->P 1->{P} End rand^23->X rand^15->Y 3->{Y*23+X+Str1} Return Lbl STEP 0->R Fill(Str2,23*15,0) For(I,0,22):For(J,0,14) J*23+I->A {A+Str1}->B If B=2 2->{A+Str2}:End If B=1: R+1->R (J+SIGN(J,Y))*23+I+SIGN(I,X)+Str2->A {A}+({A}<2)->{A} End End:End Copy(Str2,Str1,23*15) Y*23+X+Str1->A {A}+3->{A} Return Lbl SIGN ([r1]<[r2])-([r1]>[r2]) Return
Thanks for attention!
References:
Especially for those who read: