A one-word tutorial on what shouldn’t be your first programming project - read this post if you read anything on this blog

December 8th, 2008

RPGs.

Strangeness with interrupts

November 26th, 2008

Apparently, the TI-84+ and TI-84+ SE tend to run assembly programs with interrupts disabled. What’s up with that?

I came across this problem when I found out that a hex code (from my earlier post) didn’t work. The code, which was supposed to turn off the screen and wait for the ON key to be pressed, was:

ld a, 1
out (3), a
halt
res OnInterrupt, (iy+OnFlags)
ret

On the TI-83+ it still works fine. On the TI-84+ and TI-84+ SE it freezes the calculator. The solution turned out to be to add an “ei” instruction before the “halt.” It might also be in the spirit of good programming to write $0B to the port at the end of the program, but as far as I know any OS version will do that for you anyway, so there’s no need to do it.

The updated “hex-code” version, which works on all TI-83+/84+ calculator models, is:

AsmPrgm3E01D303FB76FDCB09A6C9

Screenshots

November 18th, 2008

A milestone: 200 (actually, 201) screenshots for the 68k section of TI-Basic Developer. I still have newMat() through ZoomTrig to go.

I’ll probably have more to say about this later

August 5th, 2008

Here’s an idea for displaying images quickly, potentially to nearly the whole screen (obviously, nothing can beat RecallPic, but that has the disadvantage of using picture variables).

Like text sprites, this technique uses part of the pixels displayed by Text(, except this time it’s the bottom row. The advantage of this method is that by displaying multiple characters at a time, you can draw a whole row of pixels at once - filling the screen that much more quickly.

The good news that I only came up with today is that it’s actually possible to come up with any combination of pixels this way: the key is the list L and finance N characters, which don’t have a padding of blank pixels on the sides. In fact, using only four characters: space, period, [, and the list L, any image can be drawn.

I haven’t had the opportunity to experiment further, because my calculator is critically low on batteries. But in fact, this isn’t the way to draw characters, because filling a row with fewer wider tokens is more efficient in terms of speed and memory. Ideally, you’d be using all (or nearly all) of the possible tokens.

One limitation is that the top five rows of pixels (and an additional column on the right) are off-limits. You could probably add regular text at the top of the screen to get around this (that is, to pretend that it’s a feature, not a limitation).

Results hopefully to come: screenshots, a program to save the screen to a string, and an attempt to use this method for tilemaps.

How TI-68k Basic solves the Goto problem

July 19th, 2008

As always, I bring you the very best in meaningless trivia about internal workings of the TI-Basic parser.

TI-83 Basic’s “memory leaks” are caused by the way loops and If:Then blocks were parsed — each time such a beast is encountered, the parser pushes relevant data to a stack and waits for an End. A Goto that skips over a few Ends will wreak havoc with this process because the top of the stack will never get cleared.

TI-68k Basic deals with this problem by not allocating any memory for blocks in the first place. Instead, each End command (such as EndWhile, EndFor, EndLoop, etc.) stores an offset to its parent While, For, Loop instruction — the math is done during tokenization. If the End is encountered, the parser uses this offset to look at the head of the loop and see if it’s time to stop looping. But if some Goto happens to exit the loop in the middle, no harm done.

I guess this is a lesson to people planning to write interpreted languages. A preliminary “tokenization” step can really save a lot of trouble.

What one can do without a link cable

July 13th, 2008

#include "ti83plus.inc" .db tFullScreen, tColon, tYOff, tColon, tPlotOff, tColon
.db tGFormat, tGridOff, tColon, tGFormat, tAxisOff, tColon
.db tZoomStd, tColon, tZInt, tEnter

.db tDelVar, tO, tChs, t1, t4, tStore, tA, tEnter
.db tChs, t2, t6, tStore, tB, tEnter
.db t2, t9, tStore, tC, tEnter

.db tRepeat, t0, tEnter
...

Using “rand” as a one-way function

May 9th, 2008

Wikipedia is defines a one-way function as a “function that is easy to compute but hard to invert.” There are multiple well-known cryptographic functions reputed to be one-way, but they’re usually annoying to compute on a TI-83 series calculator, because they tend to rely on modular arithmetic with very long integers. So with the admission that I’m not really creating anything new, here is an idea for a somewhat weaker one-way function that’s easily computable on a calculator.

The idea is that storing a number N to rand, and then generating a random number, is very easy. But given the random number, you’d have to do a brute-force search using something like this code (on a computer) to find out what N must have been. This is basically impossible to do on a calculator.

Here is an example of using this method as a hash function for a password program.

New password:

randInt(1,E9→X
Input “New password?”,N
N→rand
DelVar N
{rand→LPASS
X→rand

Input password:

randInt(1,E9→X
Input “Password?”,N
N→rand
DelVar N
If min(rand=LPASS
Then
Disp “Correct!
Else
Disp “Wrong password!
End
X→rand

This method isn’t perfect because it ignores some digits of a too-long password, and passwords should be allowed to have letters anyway. You could write a getKey routine to fix that, though. As a side note, the first and last lines of code preserve randomness (if you didn’t do that, and used this in a game that depends on random numbers, they’d come out the same every time you entered the same password).

Optimizing Lists on the TI-68k

April 13th, 2008

I’ve already pointed out (maybe not on this blog) that the TI-68k calculators have a quirky way of storing lists: since they’re stored as an expression, they can only be accessed sequentially (much like a linked list in “real” programming languages). There’s some consequences to this. For example, consider the following two routines:

:For i,1,dim(list)
: If list[i]=value
: Return true
:EndFor
:Return false

and

:Return product(list-value)=0

While the second routine is smaller, in no sane programming language would it be faster. In TI-68k Basic, it is: 3 times faster for only a 10-element list, and 12 times faster for a 100-element list (on average)! This is explained by the quirk in list access. In big-oh terms, the first routine is O(n2) whereas the second is O(n), since the product() command can go through the list just once and multiply everything together.

Moral: avoid For loops. Yeesh.

Continued Fraction Factorization

April 10th, 2008

A discussion of factoring methods in my number theory class led me to believe that the continued fraction factorization method might be ideally suited to a number factoring program on the TI calculator. Consider: floating-point math and square roots are much more natural operations on a TI-83+ than the modular arithmetic heavily involved in most other factoring algorithms. And the numbers that can be represented in a floating point number aren’t going to require heavier machinery anyway.

Link to Wikipedia’s article on continued fraction factorization. Maybe, code to come?

Recent TI Programming

March 11th, 2008