[A85] Re: Programming for the Ti85


[Prev][Next][Index][Thread]

[A85] Re: Programming for the Ti85





On Sat, 22 Sep 2001, Henk Poley wrote:

Before saying anything else, I would like to point out a way to go around
all the problems with Rigel:  You could just write programs for ZShell,
but fix them at an absolute address, and use a brief section of code at
the beginning of the program to move it there.  This way you would easily
have compatibility with all shells, not just one obscure one, and you
wouldn't need to figure out anyone's relocation table format.  This would
of course leave variables mostly inaccessible throughtou most of your
program, but the same problem exists under CrASH.

> > > > 1) Static:
> > >
> > > The one I like to have. All other Ti's behave like this.
> >
> > Actually, dynamic relocation is standard on the TI-89, TI-92, and TI-92
> > Plus.  Not to mention that the state of assembly programming on the other
> > Z80 calculators at the time Usgard was released was not to great.
>
> Okay, all Z80 Ti's... M68k asm is automaticaly 'relocatable' (as far as I
> know). Since this processor is "more grown up", it has all kind of stuff
> like the higher processors we use nowadays in our PC's.

I'm not sure what you mean by 'automatic' in this context, but if you mean
that the processor has the ability to access addresses relative to the
program counter, making relocation unnecessary, it does do that, but only
to a limited extent.  The TI-89 OS (as well as TI-89 kernels, if used) do
contain code to relocate absolute references similar to what Usgard does.
However, the assemblers and linkers are not quite as stupid as TASM, so
they can tell when you are referencing something that needs to be
relocated and do the appropriate thing automatically.  The same is at
least the situation on the 68K-based Amiga computer.

For a "modern" x86 PC the situation is of course a bit different with
segmented memory and such...

> >  Even though Rigel does use both
> > methods of relocation, it isn't compatible because it doesn't have the
> > exact same format as the others (not to mention that the addresses are
> > probably different).
>
> Adresses? What adresses?
> (and what format? The header-format?)

For the format, I meant mainly that of the header, as everything else
couldn't practically be different.  And for "address" I was referring to
the address the program is run from.

> >  I also think that PhatOS doesn't allow calling ROM
> > routines by just calling into its jump table (as Usgard does, and ZShell
> > allows but doesn't document) which might make a few ZShell programs fail.
>
> Indeed PhatOS (says it) doesn't have the ROM_CALL() feature. This thing is
> basicaly the same as on the Ti82, I hope? There they just add an offset
> value to the ROM-adress, so it actually points to get right stuff, and then
> calls/jumps to it.

For TI-85 ROM versions up to 8.0 (and ZShell versions up to 3.1), it was
indeed as simple as that.  However, ROM version 9.0 rearranged things
quite a bit, requiring a new method.  Dealing with this problem was a main
reason for the releases of ZShell 4.0 (as well as the earlier UShell) and
unfortunately was incompatible with older programs.  Under this method,
each ROM function has a single byte identifying it, so

   ROM_CALL(D_ZT_STR)

   expands to

   call _ADDRESS_IN_ZSHELL_FOR_ROM_CALL
   .db D_ZT_STR

Then that code inside ZShell gets the byte out of your program, and uses
it as an index into a table which looks something like

   jp TX_CHARPUT_IN_ROM
   jp D_ZT_STR_IN_ROM
   ...

and then call the right address in that table, which transfers control to
the ROM.  This is just to show the idea, I'm not sure of the exact
arrangement.  If you used the macro, your program would work fine in any
shell.  However, some 'clever' people replaced uses of the macro with
calls directly into the table, which worked fine as long as the table was
implemented in this way, and at the same address.  Under Usgard, such
direct calls are actually documented and approved of, unlike in ZShell.
The problem with PhatOS is that it doesn't have the table done the same
way, making some such programs fail.  But most ZShell programs use the
'official' method and thus have no problems.

> > As far as frequency of use, I don't think any TI-85 shell is used often
> > these days.  However, I would think that neither Rigel nor PhatOS is
> among
> > the most used.  Most older TI-85 programs were written for ZShell, and
> > many newer ones were written for Usgard, with very few programs for Rigel
> > or PhatOS, almost all of which had versions for ZShell or Usgard.  So I
> > would tend to guess that the most common shells would be ZShell (and
> > similar ones like OShell, CShell-NT, etc. that don't have separate
> > formats) and Usgard.
>
> Yes, ZShell seemed like 'the grandfather of all Ti85 shells' to me. Every
> shellmaker references to it.

It is certainly the oldest one; the first version was released in late
1994, only a few months after assembly programming for the TI-85 was first
discovered.  Since it was the first, and for a long time the only, shell,
a new shell that didn't run its programs probably wouldn't be well-liked.
In the 1997 shell wars on this very list, it was directly and indirectly
argued a good number of times that people owe respect to ZShell for having
this place.

And if you look at shells like CrASH on other calculators, you may notice
their interfaces are also quite a lot like ZShell.

> It's not my choise...

Maybe not, but you could always hack the compiler to make TASM-compatible
code, and probably make a portable assembler by extracting pieces of the
code of Assembly Studio 8x.

> And the format isn't that different that it would be
> impossible to overcome, I guess SRCWIZ only searches for the @ or & and
> changes it to R_.

Actually, it has a few other features, like handling #incbin to include a
binary file, but I guess that's irrelevant here...

> The main problem is linking... Which would basicaly mean
> that it would be easier to hack the assembler to generate a
> relocation-table. Ss far as I know Z80ASM has already a built-in option to
> generate a auto-relocational-executable for the Z88.
> Basicly it's just collection the position all JP's and CALL's and making a
> table that points to them (oh, and don't forget adress-tables)...

Since it already does that, all you really need to do is get your linker
to understand the format it generates.  Though I don't know what the
"address-tables" are; all you need is a list of every JP/CALL/LD/etc.
to be relocated, and not another list of where they need to point (since
relocating is essentially just adding/subtracting from the base value
which is already there).

> >  However, if the
> > assembly source is generated by a compiler, it would probably be just as
> > easy to put in the R_ directly as to put the &.
>
> Uhm, do you know that 'the compiler itself' isn't the major part of 'a
> compiler'? Libs (can be handwritten assembly) are much more important...
> Normaly the 'compiler itself' doesn't even touch the libraries.

No, I actually didn't know that, and in fact I still don't know it.

Even if one does assume that the library is a part of the compiler, I
can't see why it would be more important than the compiler itself.  Which
is at best questionable; while proprietary compilers for PCs usually have
the libraries included, many other systems (like GNU/Linux) have the C
library and C compiler in separate packages (where the C library is needed
to run the system, but the compiler isn't).  While you can't run anything
generated by the compiler if you don't have the library (with a few
exceptions) you certainly can't use the library very effectively with no
compiler to generate programs that use it.  If you were referring to
libraries other than the standard library, they're even less necessary as
complete program can be made wihout using them.

To see a similar example, look at TI-GCC on the 68K calculators.  It does
include the library, which is nearly a complete standard C library and
also has numerous calculator functions.  It is sophisticated and the
result of hard work by skilled programmers.  But then try comparing the
source of that to the source of GCC itself (the compiler used), which has
been worked on for many years by numerous experts, and you will see a much
more advanced product.  And of course don't neglect to note the most of
that library itself (as with many libraries on PCs) was written in C.

On things like the TI-82 or TI-85, you can't have a huge library nomatter
what, as there isn't much memory to put it.  While having efficient
routines to do various tasks would be nice, if 'the compiler itself' isn't
very good, any program original enough to do more than just a few calls to
those routines would not turn out very well.

Of course, it may be that your idea of the purpose of a compiler is quite
different than mine.

> BTW, It does (incorrectly dissasembled) show the relocation-pointer, and
> relocationtable itself. Only the 'real-header' (header bytes/word and
> description-size) are removed. The rest stays. I think that IS confusing...

Though not terribly surprising, since I don't see why someone making a
generic z80 disassembler would be terribly concerned about the format of
such an obscure shell.

> > > String85 is for WinDOwS... So no: Linux, Amiga, Unix, Solaris (the
> Z88DK
> > > can run one of these 'giants'), Sparc, etc.
> >
> > OK, I suppose that is a good reason.  Though string85 could be run under
> > emulation on most, if not all, of those systems.  And I'd think that the
> > number of people who want to develop TI-85 programs on those is quite
> > small, to say the least.  Ports of at least the ZShell string85 are out
> > there.
>
> Oh, yes and we could also use Perl and Tcl/Tk scripts or reprogram the
> compiler in Java. That would make everybody use it (..not..), since they
> would need to download 'hunderds' of megabytes of libs and executables to
> get the thing to work.

I'm not quite sure what the original point of this was, but I did say it
was a good idea to have a more portable tool.  However, I actually have
managed to do TI-85 and TI-86 development under Linux with DOSEmu (which
is not that huge of a program).  While I had first tried to use the Unix
tools on ticalc.org, after a little while of being unable to get them to
work, I switched to the emulated tools instead.

No doubt it probably would be a good idea for everyone to switch to
Z80ASM, but I don't feel like doing it since I'm already used to the TASM
syntax, and TASM isn't really that bad.

> The entier Z88DK (source included) is now about 6MB. A fully working
> binary-distribution would be aprox. 2.5MB. It is already irritating
> that they use 'make' to compile the libs. I know I can get this to
> work on my Windows (don't bother me about that) machine by downloading
> a 30MB CygWin distro. I won't download it, it far to big for that bit
> of support I get, I can also just wait a week till someone puts newely
> compiled libs into CVS.

Of course if you want to edit the libs, I don't see how you can avoid
compiling them at some time or other.  The building tools of DJGPP might
also work and be a little smaller.

> > > Okay, the 'problem' is, from a binary you can't see "what it is", so it
> > > would be nice if you can pump "as much as possible" data about shell
> into
> > > the binaries. So you can see lateron what shell it compiled was for...
> >
> > I don't really understand what this problem is.  Clearly, the string
> files
> > do have information identifying the shell, in the form of the initial 2
> > bytes that come before the code itself.
>
> Now the difference between binaries (the *.BIN or *.OBJ files) and
> strings/programs/executables (in this case *.85S)???

The .BIN or .OBJ is probably the output of the assembler, which is simply
the assembled machine code corresponding to the source code you gave it.
For more advanced assemblers, the .OBJ file probably has a header
identifying object file type, section(s) of the program (probably one in
front of each section), and has relocation information as well as external
symbol information for linkers to link to libraries.  But for TASM (and
probably Z80ASM in non-reloc mode) it is just the machine code which can
run only at the absolute location you had as the origin.  The "string"
would be what is on the caclulator (excluding the VAT table and the size
byte); more or less, what you see if you try to use the basic Disp or
something to show the string.  This would be the BIN file with the three
header bytes added (and more in the case of Usgard).  The .85S file is
something that has the string, but also has other junk in it, like
**TI85** at the beginning, a 'description' for the Graph-Link software,
the string name (that it will have on the calculator) and other stuff
imbedded.  There are files on ticalc.org that describe the .85S (and
other) formats in great detail.

> >  Also, this source looks
> > kind of worrying to me that you used 'defb' for the distance from fixup
> > to the beginning of the program, as that seems to me like something to
> > define a byte, when a distance within the program would be stored as a
> > word value.
>
> Uhm, yes...
> But how could it then possibly work (it does work)?

I certainly don't know, but perhaps you should find out.  For all I know,
the assembler might automatically change to a word if it is too big for a
byte, or maybe it really is wrong but it just happens to go to a wrong
address that has 0s in it, so it looks like an empty table.

> > While I'm not sure what the $E6 is sure, I have to wonder if it is really
> > a part of the string data itself, or something that is just part of the
> > various data outside the string itself that the .85s file format uses.
>
> I'll check around...
>
> BTW: I still haven't seen anything like some decent header description(s).

I'm not sure what it takes to be 'decent' although the headers of the
strings are just two bytes followed by a length, so you can get a decent
description yourself rather easily.  As far as the .85S headers go, the
informational files on ticalc.org include documents that explain this
somewhere.





References: