save the whales

Ever since the release of MirageOS 1.0 around 2000, the TI calculator community has strived to find out the purpose of the mysterious "Save the Whales" option in the MirageOS settings.

Save the Whales :)

Finally, the mystery has been solved. The "Save the Whales" option in the settings has no effect whatsoever other than setting/resetting a bit in the MirageOS AppVar so it can remember the setting.

However, there is a "Save the Whales" secret. If you create three folders (in order) called "SAVE", "THE", and "WHALES" (as shown below), a token hook will be installed.

Save the Whales!

This token hook renames some of the built-in commands, as described and shown below:

Andrew instead of GarbageCollect

Original NameNew Name
GarbageCollectAndrew
fnInt(JaSoNiSr33t(
>Dec>JKDE
Circle(Square(

Unfortunately, this "feature" was removed after MirageOS v1.0, so you will have to download it in order to see for yourself, which you can do here.

The complete disassembly of MirageOS 1.0 is downloadable in a couple of different formats as well.


proof

For those unbelievers out there, the code which makes the decision whether or not to install the token hook is shown below, located at address 68DBh:

seg000:68DB SaveTheWhales:
seg000:68DB                 call    getMirageAppVar
seg000:68DE                 ld      a, b
seg000:68DF                 ex      de, hl
seg000:68E0                 ld      de, copyBuffer
seg000:68E3                 ld      bc, 150
seg000:68E6                 rst     28h
seg000:68E7                 dw 5017h                ; _FlashToRam
seg000:68E9                 ld      hl, copyBuffer
seg000:68EC                 ld      de, 9
seg000:68EF                 add     hl, de
seg000:68F0                 ld      e, (hl)
seg000:68F1                 add     hl, de
seg000:68F2                 ld      de, 17h
seg000:68F5                 add     hl, de
seg000:68F6                 push    hl
seg000:68F7                 push    hl
seg000:68F8                 ld      bc, 20
seg000:68FB                 call    getchecksum
seg000:68FE                 ld      de, 4F9h
seg000:6901                 call    cphlde
seg000:6904                 pop     hl
seg000:6905                 jr      nz, loc_691E
seg000:6907                 ld      c, 5
seg000:6909                 add     hl, bc
seg000:690A                 ld      a, (hl)
seg000:690B                 cp      53h ; 'S'
seg000:690D                 jr      nz, loc_691E
seg000:690F                 add     hl, bc
seg000:6910                 ld      a, (hl)
seg000:6911                 cp      54h ; 'T'
seg000:6913                 jr      nz, loc_691E
seg000:6915                 add     hl, bc
seg000:6916                 ld      a, (hl)
seg000:6917                 cp      48h ; 'H'
seg000:6919                 jr      nz, loc_691E
seg000:691B                 call    enableTokenHook
seg000:691E loc_691E:
seg000:691E                 pop     hl
seg000:691F                 ret

You'll notice that this routine calls "getchecksum", which is a routine available in mirage.inc. It simply adds up BC bytes pointed to by HL and returns that number in HL (a checksum, naturally, which in this case is 04F9h). The routine itself, which I've called "SaveTheWhales" here, is called in curfoldname and possibly in other places as well.

An interesting side effect of this routine is that some other folder names besides "SAVE", "THE", and "WHALES" can be used; for example, "SCAR", "THE", "SHOALS", or "SALT", "THE", "PHAGEL."

Anyway, once the check for the three folders succeeds, the hook is installed, which is located at address 7A5Dh:

seg000:7A5D myTokenHook:
seg000:7A5D                 add     a, e
seg000:7A5E                 push    hl
seg000:7A5F                 ld      hl, 2
seg000:7A62                 rst     28h
seg000:7A63                 dw 400Ch                ; _CpHLDE
seg000:7A65                 jr      z, loc_7A90
seg000:7A67                 ld      hl, 546h
seg000:7A6A                 rst     28h
seg000:7A6B                 dw 400Ch                ; _cphlde
seg000:7A6D                 jr      z, loc_7A8B
seg000:7A6F                 ld      hl, 48h ; 'H'
seg000:7A72                 rst     28h
seg000:7A73                 dw 400Ch                ; _cphlde
seg000:7A75                 jr      z, loc_7A86
seg000:7A77                 ld      hl, 14Ah
seg000:7A7A                 rst     28h
seg000:7A7B                 dw 400Ch                ; _cphlde
seg000:7A7D                 jr      z, loc_7A81
seg000:7A7F                 pop     hl
seg000:7A80                 ret     nz
seg000:7A81 loc_7A81:
seg000:7A81                 ld      hl, aSquare     ; "\aSquare("
seg000:7A84                 jr      loc_7A93
seg000:7A86 loc_7A86:
seg000:7A86                 ld      hl, aJasonisr33t ; "\fJaSoNiSr33t("
seg000:7A89                 jr      loc_7A93
seg000:7A8B loc_7A8B:
seg000:7A8B                 ld      hl, aAndrew     ; "\x06Andrew"
seg000:7A8E                 jr      loc_7A93
seg000:7A90 loc_7A90:
seg000:7A90                 ld      hl, aJkde       ; "\x05\x05JKDE"
seg000:7A93
seg000:7A93 loc_7A93:
seg000:7A93                 ld      de, localTokStr+1
seg000:7A96                 ld      bc, 16
seg000:7A99                 ldir
seg000:7A9B                 ld      hl, localTokStr
seg000:7A9E                 pop     bc
seg000:7A9F                 ret
seg000:7AA0 aJkde:          .ascii '\x05\x05JKDE'
seg000:7AA6 aAndrew:        .ascii '\x06Andrew'
seg000:7AAD aJasonisr33t:   .ascii '\fJaSoNiSr33t('
seg000:7ABA aSquare:        .ascii '\aSquare('

There it is, staring at us right in the face for over 6 years.