A Trip Down Memory Lane: Programming On An Old Casio Calculator

  |   Source   |   18 min read

Young people today grow up surrounded by computers. Children are given smartphones and tablets pretty much from birth, and in the rare case they are not, their primary school will make sure to supply them a cheap laptop as soon as possible. Whether that abundance is an unqualified good or not is a question I’ll happily leave to the reader, but more than 15 years ago, my own first "computer" looked very different. While my classmates already had early smart-ish phones and Nintendo DS consoles (the luckier ones got the upgraded Lite version, and I was extremely jealous), my pride and joy was a Casio graphing calculator, more precisely a Casio Graph 25+.

I recently stumbled upon it again while sorting through old boxes at home, and out of curiosity, I put in a fresh set of batteries. It surprisingly still worked, but even more surprising to me is that its memory was still intact. So I figured I'd take a look and share it with the world here! If not very insightful, it still might be amusing to some to check out what a seventh-grade kid, with no programming knowledge but quite a lot of free time during recess, had managed to come up with.

1. How It Became Mine

This part is a bit of personal backstory. I enjoy reminiscing, but feel free to skip ahead if you’re somehow here for the technical bits.

Before the Graph 25+, I used a more modest machine: a Casio College fx-92. It did everything I needed to follow maths lessons throughout my late elementary and early junior high years, but all of that changed when my older sister started high school.

Even though she was going for the literary program, she was told she needed a graphing calculator. Not at all convinced, our parents reluctantly bought her the cheapest one they could find: the humble Casio Graph 25+, and predictably, she hated it. The menu system felt unintuitive to her, there was no natural fraction notation, she never had any use for the graphing features... Maths in general had never really been her thing. She struggled with it for a few month, then she and I struck a deal: she got my fx-92, and I inherited the thick green slab.

My access to the internet was extremely limited at the time; at home, just like at school, it was mostly reserved for homework, under adult supervision and in short sessions. So my only real resource was the user manual, a 236 pages long pink-ish booklet printed in a comically small format (A6, I think). I unfortunately must have thrown it away at some point, but you can still find it online if you look for it well enough. Most of it is insanely dry as you'd expect, but the chapter on programming did catch my eye at the time.

I was never the popular kid on the playground, so during recess, while others played, I got into the habit of sitting in the same quiet corner, calculator in hand, tinkering and trying things I barely understood.

Beauty Shot of a Graph 25+

2.Programming Like It's the 80's - A Primer on Casio BASIC

The Graph 25+ (known as the fx-7400G+ in the US) was already a bit outdated when I got my hands on it. It's first release was actually in the very late 20th century, and it absolutely felt like it. Most parents at the time bought newer, more capable models like the Casio’s Graph 35, or Texas Instruments’ TI-83, or even the TI-84 if they wanted to future-proof.

Mine, by comparison, isn't sleek. The plastic is very thick and very green. The keyboard is fine, but the true letdown is the screen. We are talking about an 80×48 pixels monochrome, blue LCD dot matrix on a green-ish background with pretty atrocious contrast and heat death of the universe style response time. It can make use of that amazing screen resolution to display exactly six lines of thirteen characters each, but the first and last line are not available when programming, leaving exactly 52 characters split on four lines to display your code. Finally, you get some roomy 20 kB of non-volatile memory to store programs and data combined; the OS is mercifully installed somewhere else.

The programming language is a distant cousin of the original BASIC, modified for Casio calculators, and the code is interpreted at run time by an already very slow chip. An empty for loop from 0 to 1000 (and no output to the screen) will take around 4 whole seconds (not milliseconds, this is not a typo) to execute.

You get exactly 26 numeric variables, and you do not get to choose their names. They’re simply called after letters in the alphabet, A to Z. Assigning a value to a variable looks like this: 10→A. You also get the equivalent of BASIC's INPUT command through the question mark command: ?→A.

The Atrocious Programming Experience

Instructions can be separated either by : or by . The latter represents an actual line break in the code listing. This distinction matters, because long lines are automatically wrapped by the editor, and not at word boundaries. Keywords will happily be split in half across lines, making the code even more painful to read.

Outputting to the screen is a bit weird too. You need to use the symbol after whatever you want to display ("HELLO"◢ will print HELLO, and A◢ will display the value of the variable A). It will print to the screen, and then halt the code execution, waiting for a keypress. For strings and numbers, you don't need the . When by themselves, they are interpreted as display instruction by default and will perform a non blocking display. Unfortunately that does not work in loops.

Conditionals are pretty much standard BASIC, that is:

If <condition>
Then <instruction>
Else <instruction>
IfEnd

There is, however, a delightful quirk: if you omit IfEnd and there is no Else clause, then when the condition is false, execution jumps back to the start of the program.

Surprisingly you also get a ternary operator, which the documentation bizarrely classifies as a "jump command":

<condition>  <instruction_if_true> : <instruction_if_false>

The Dreaded Error Message

Loops are standard BASIC, that is a While / WhileEnd, a Do / LpWhile and a For. But if structured programming isn’t your thing, Casio BASIC has you covered. You can label parts of your code using the Lbl command. There are unfortunately only 36 labels available: 0 to 9 and A to Z, but once labeled, you can jump there using Goto. Mercifully, Goto expects a label, preventing you from jumping to an arbitrary line number.

Finally, the language includes shortcuts like Dsz, Isz, commands to clear the screen, and functions to interact with the calculator plotting and tabular capabilities. There is also a way to interact with exernal sensors, but unfortunately for aspiring game developers, no addressing individual pixels. I believe the latter was added later on the 35+, but this one is a serious calculator, made for serious people, doing serious maths.

One word on code input. You don’t type keywords using the Alpha letters of the keyboard as you might have expected. Instead, you navigate menus that insert the entire word at once. Each keyword is a sequence of 4 to 5 keypresses. For exemple, getting an If statement is done this way:

  1. Shift → Vars (to open the PGRM menu)
  2. F1 (COM submenu)
  3. F1 again (the If keyword)

And finally, let's talk debugging. There is no help coming your way. At run time, you are given a few different error messages, like Ma Error for divisions by 0, and synError for syntax errors, but no line numbers and no hint of what is actually wrong. Better start printf() debugging!

3. Code Review of My Thirteen Years Old Self

Now that you’re up to speed, let’s take a look at what a thirteen-year-old kid actually coded.

But before you judge my past self, remember that this was my first real exposure to programming. At the time, I had no idea what a variable or a loop was. As I mentioned, my sole source of information was the calculator’s user manual. And it is not programming tutorial by a long shot. I learned by carefully studying the few snippets and examples it contained, and by experimenting until something somewhat worked. Please be kind.

I’ve also copied the listings here using somewhat natural line breaks, and you get syntax highlighting for free. As a reminder, on the original calculator screen, the characters were monochomes and the display was limited to 4 lines of 13 characters each. I’ve also translated all the strings from their original French into English.

A Very Simple Start

One of the earliest and simplest programs I wrote looked like this:

"SALARY/YEAR"?A
A÷12A
A

If you’ve been following so far, this one should be easy to understand: it asks the user for a yearly salary, divides the number by twelve, and prints the corresponding monthly income. In retrospect, it’s a little depressing that the very first test program I ever wrote was about money...

Quadratic Equations

Next up is the following listing:

"AX²+BX+C"
"A:":?A
"B:":?B
"C:":?C
-4xAxCD
"DELTA =":D
If D<0:Then "NO SOLUTION":Goto 0:IfEnd
If D=0:Then -B÷2AS:"SOLUTION =":S
Goto 0:IfEnd
If D>0:Then (-B-D)÷2AS:(-B+D)÷2AT
"SOLUTIONS =":S
T
Goto 0:IfEnd
Lbl 0

This is, unsurprisingly, a solver for second-degree polynomials:

$$\text{Given } ax^2 + bx + c = 0,\quad a \neq 0$$ $$\Delta = b^2 - 4ac$$ $$ x = \begin{cases} \dfrac{-b \pm \sqrt{\Delta}}{2a} & \text{if } \Delta > 0 \newline \dfrac{-b}{2a} & \text{if } \Delta = 0 \newline \text{no real solution} & \text{if } \Delta < 0 \end{cases} $$

It’s a solid implementation. If I really wanted to nitpick, I would point out the usage of labels and gotos to exit gracefully instead of using the Stop command, but other than that, I think it holds up pretty well.

Utility Programs and Not-Cheats

Beyond that, I found a handful of small programs solving very specific problems, along with several listings copied straight from the documentation. I also discovered a significant number of password-protected cheat sheets which were never meant to be run, but to store formulas and reminders. The password is obviously long forgotten, but you can easily imagine the contents. And before you accuse me of cheating: this was (and to my knowledge still is) extremely common practice among students.

The Big Game

I want to end this chapter with the most ambitious program I wrote, the implementation of which I found interesting. Below is the original Casio BASIC code, as well as a faithful Python equivalent:

' The Original Casio BASIC

0V                                    
0W
"PLAYER 1, INPUT A NUMBER"
?X
ClrText
If X<0:Then Goto Z:IfEnd
If X>10000:Then Goto Z:IfEnd
Intg XX
Lbl 1
"PLAYER 2, INPUT A NUMBER"
?Q
If Q>X:Then "IT'S LESS":IfEnd
If Q<X:Then "IT'S MORE":IfEnd
V+1V
If Q=X:Then Goto 2:IfEnd
"PLAYER 3, INPUT A NUMBER"
?R
If R>X:Then "IT'S LESS":IfEnd
If R<X:Then "IT'S MORE":IfEnd
W+1W
If R=X:Then Goto 2:IfEnd
Goto 1
Lbl 2
If V>W:Then "PLAYER 1 WINNER"
Else "PLAYER 2 WINNER"
IfEnd
"RESULTS"
"-------"
"J1→":V
"J2→":W
Goto 9
Lbl Z
"THIS IS NOT ALLOWED"
Lbl 9
Stop
# Almost line for line Python version

v = 0
w = 0
print("Player 1, input a number")
x = float(input())
os.system('clear')
if x < 0 or x > 10000: 
    not_allowed()
x = int(x)
while True:
    print("Player 2, input a number")
    q = float(input())
    if q > x: print("It's less")
    if q < x: print("It's more")
    v += 1
    if q == x: break
    print("Player 3, input a number")
    r = float(input())
    if r > x: print("It's less")
    if r < x: print("It's more")
    w += 1
    if r == x: break


if v > w: print("Player 1 winner")
else: print("Player 2 winner")

print("Results")
print("-------")
print(f"J1->{v}")
print(f"J2->{w}")

def not_allowed():
    print("This is not allowed")
    exit()  

So what’s going on here?

This is a three-player game. Player 1 chooses a secret number between 1 and 9999, and Players 2 and 3 then take turns trying to guess it before the other does. The concept is not very creative, but there are a few implementation quirks. For example, I like how seriously I took input sanitation. The ? command will only allows real numbers, but on top of that I limited the range of allowed numbers and explicitly truncated the value to an integer. I must already have been burned by a few particularly cheeky classmates. There is also an obvious mistake hidden in there: I mixed up the player numbers in the result strings. Players 2 and 3 are the ones actually guessing, yet the program can declare Player 1 as the possible winner.

But the biggest problem is more structural and subtle. If Player 2 guesses the number correctly, the program immediately jumps out of the loop and declares a winner, leaving no chance for Player 3 to guess during that round and making ties impossible, even if Player 3 would have guessed correctly on the same turn. Ironically, it is this very unfairness that allows the program to determine a winner at all, since the winner is inferred after exiting the loop by comparing the number of guesses each player made. If both players have the same number of attempts, Player 2 is declared the winner!

A much cleaner approach would have been to explicitly track the winner using a dedicated variable defined outside the loop, and to set it before exiting. Conceptually, something like this:

winner = None
i = 0
while not winner:
    print("Player 2, input a number")
    q = float(input())
    if q > x: print("It's less")
    if q < x: print("It's more")
    print("Player 3, input a number")
    r = float(input())
    if r > x: print("It's less")
    if r < x: print("It's more")

    if q == x: winner = "Player 2"
    if r == x: winner = "Player 3"
    if q == x and r == x: winner = "Tied"
    i += 1

print(f"Winner : {winner}\nNumber of guesses : {i}")

Obviously this would need to be adapted to Casio BASIC, but the logic would have been much saner. And, finally, I just can't remember why we needed a Player 1 in the first place. A random number would probably have been enough.

Conclusion - Fifteen Years Later

The New Replaced The Old

I was born too late to take part in the glory days computing in the 1970s and early 1980s and in a way, the humble Graph 25+ was my Commodore 64. The performance and the limitations are surprisingly comparable, and programming like this is an experience I probably would never have had otherwise. The struggle really makes you appreciate the large screens, fast processors and high level programming languages that are taken for granted today.

Not long after, I was given an already old at the time Pentium III based PC, running Windows Millennium Edition (!). My father, who was always very attentive to his children, noticed my growing interest in programmation and bought me a French translation of Stephen Davis' C++ For Dummies. I installed the recommended Dev-C++ IDE, wrote my first programs with a real keyboard, and never really went back to Casio BASIC.

And this is where this story ends and an other starts. Let me thank you for traveling with me through this personal detour! I hope it brought back a few memories of your own, and maybe even made you look for the old calculator of yours, hidden somewhere in a drawer. Power it up from time to time, and I'll make sure that the batteries don't leak!

But what happened to the old girl, you ask?

During my second year of high school, I managed to convince my parents that I needed a more powerful calculator (which was somewhat true) and that it had to be an early TI-Nspire model (which was a huge exaggeration). But I had heard that beyond the larger screen and faster processor, it had been jailbroken a few years earlier, and that an open source toolchain was written to compile C code that could run natively...

The Casio was retired and put into storage, where it has remained until now. Let me conclude by indulging my amateur photographer’s urge and give her the few minutes in the spotlight she deserves.