Wednesday, September 29, 2010

A quick summary of some TI-85 emulators

I tried a few TI-85 emulators, hoping that they would be more convenient than testing code on a real calculator. Here are some observations using my version 9 TI-85 ROM:
  • Wabbitemu has a nice user interface. The TI-86 skin looks great, and it's nice how I get visual feedback when I press buttons. I don't mind that it's not a TI-85 skin. However, there doesn't seem to be any way to transfer TI-85 files to the emulator, so it's useless for development.
  • TilEm 0.972 looks kind of ugly due to the scaled up low resolution skin, and the screen standing out too much. Multiple attempts to transfer a backup to the calculator failed, and so I couldn't use it for running assembler programs. I couldn't get 0.973 to display the skin.
  • Virtual TI 2.5 has some problems, but it is usable. In Windows 7, it has to be run as Administrator (or else I get a "Failed to set data for 'LastEmuVersion'" error). I've had some linking failures, but I was generally able to transfer a backup after resetting the calculator. When transferring variables, I got annoying linking errors whenever a variable under that name exist, so I'm forced to delete variables before re-uploading them. The skin looks worse than Wabbitemu, but it is a TI-85 skin which looks like my TI-85, and it looks a lot better than TilEm.

Sunday, September 26, 2010

Usgard relocation table format

Usgard is the most recent and most capable assembly shell for the TI-85 graphing calculator. It can run ZShell programs, but it also offers additional functionality which can be used when writing programs specifically for Usgard. The primary advantages are relocation and functions for accessing TI-85 variables.

On the TI-85, assembler programs are stored in string variables, and they execute in-place. The initial location of the variable depends on the amount of free RAM, and the variable can me moved when other variables are deleted. Because of this ZShell code cannot rely on being at a fixed address. Usgard's relocation almost removes this concern. At the end of a program is a list which shows what locations in the code need to be updated with the current position. The list contains two kinds of entries:
  • a single byte, whose value is the offset of the current relocation position minus the offset of the previous relocation position.
  • a zero byte, followed by a 16 bit little endian absolute offset of the relocation position.
The single byte form is used whenever possible. At the beginning, the previous relocation position is considered to be zero, and the single byte form can be used for relocations at absolute offsets 1 through 255. The file is assembled starting at offset zero (".org 0") and this determines absolute offsets and initial values of locations requiring relocation. All locations requiring relocation contain little endian 16 bit numbers. The list of relocations is followed by a four byte header which consists of two 16 bit little endian values. The first value is zero minus the number of bytes in the relocation table, and the second value is the number of relocation entries.

To perform relocation, Usgard needs to add the current offset of the program to all of the locations requiring relocation. When the program terminates, Usgard undoes these changes by subtracting the current offset from the locations.

The only disadvantage of Usgard relocation is that the relocation table is created via a sort of kludge using an ancient toolchain which runs in MS-DOS. All operands which require relocation need to be prefixed with an ampersand. Before assembly, the code is preprocessed via SRCWIZ.EXE, which removes the ampersands and adds labels of R_ followed by a number, with the number starting at zero. Then, this code is assembled, and STRING85.EXE creates the relocation table based on the listing produced by the assembler. A batch file ties all this together and at the end replaces the files altered by SRCWIZ with the originals.

Several programs in the Usgard directory were compiled with old Borland Pascal compilers. They fail with "Runtime error 200", meaning divide by zero, because modern computers are too fast for Borland Pascal delay loop calibration. Fortunately, this is easy to fix with TPPATCH.

Overall, the toolchain works, but I would prefer something more modern. Maybe I'll try using the GNU assembler or even the Small Device C Compiler (SDCC).