II The actual FAQ
III To do / Questions without answser
The purpose of this FAQ is to help programmers who program only for TI-82, TI-83 or TI-83+ to program for these 3 calculators at the same time.
When ION was released, making easy the development on both TI-83 and TI-83+, it was the first time people could almost transparently program for two (quite) different calculator models. But unfortunately nothing has evolved since then.
You may be wondering why I don't include the TI-85 and TI-86 in this FAQ. The answer is : it's only a matter of time. If you really want the clues to do it, just get "Phoenix" by Patrick Davidson at http://pad.calc.org, and see how the author manages to build a program for every TI-z80 calc with almost the same source code.
Last, you may have already noticed that English is not my mother language, so you can e-mail me to report spell and grammar errors :)
1. Which shell should I program for on each calc?
* the way I use the word "shell" is sometimes abusive (in example, Venus is rather a plug-in than a shell)
* I don't always use the right names for each built-in functions, I prefer to use names that give you an immediate idea of what it does. And sometimes functions to which I give the same name are a little different :)
* I don't mention outdated shells
The choice of the shell depends on several points:
1) amount of RAM it leaves once loaded (FBLOI: free bytes left once installed)
2) built-in functions
4) compatibility with other shells
1) Very important because the user will be more comfortable when they can put more (or bigger) programs on their calc. It may be important also if the programmer wants to make a full use of the calculator's memory.
2) It can be good and bad at the same time, because if a program uses a lot of shell functions, it will certainly be bigger once ported to another calc, because the shell will be different and may not have all the functions used; on the other hand, if a there are many shell functions that aren't used by a majority of programs, there functions are useless and still take your calc's precious memory. The best compromise is a shell that has only really useful functions.
3) Most of the shells are stable, but some of them are no longer maintained or still under development. It is seldom a real issue.
4) It can be useful if you don't want to force the user to forsake their beloved programs that work with an older shell. But, obviously, this can interfere with the 1st point, beware!
So the most important points you should look at are the first two ones. I'm going to make my own research on this topic :
On TI-82 :
The choice is hard, because, to me, there isn't really a "best ti-82 shell", they all have drawbacks.
Random, Exit2TIOS, CP_HL_BC
||CrASH ones + Pause, Fill
(hl) with a, HL_DECI, DirectKey...
||ACE ones + Greyscale, Beep,
|For which ROMs ?||all but 19.006
||All known ROMs
to compile two different versions, one for CrASH, another one for
||Beta, no longer maintained.
Uses TEXT_MEM2. Has an inner 2 kB buffer.
Has "emulators" to run CRASH, ASH, ACE and ION programs.
My choice : CrASH/CrASH19006Remark : if you don't use any ROM call and no link routine, you can compile a single program for any TI-82 ROM versions, than can be run with CrASH and CrASH19006. For the link issue, you can find more info here (in French).
On TI-83 :
||FastCopy, Random, Putsprite,
Putlargesprite, Getpixel, Detectprogram, Unpackdata
|Comments||Allows to lauch program directly
from the TI-OS. It is just a single program that you can sent and
at wish. Can run ION and SOS programs with an external module.
My choice : Venus
On TI-83+ :
||FastCopy, Random, Putsprite,
Putlargesprite, Getpixel, Detectprogram, Unpackdata
||ION ones + lots|
||It's a Flash APP, so it leaves
all RAM free.
Handles ION programs.
My choice : I make ION programs and I use MirageOS
I've chosen ION because it has fewer features, so I prevent myself from using extra features of MirageOS that will be hard to let down on other calcs. Plus, a ION program can be run with MirageOS, while the contrary is impossible.
There is also the possibility to make flash APPs, but you won't be able to use self-modifying code, and you'll have to create APP vars to store things like highscore, saves, etc. Plus, your programs must fit in one or several 16 kB Flash APPS, that means that a 5 kB program will use a whole 16 kB Flash APP, and that a 24 kB program will use two 16 kB Flash Apps (that you will have to link together...).
2. Are there already headers to do so, or will I have to do it all by myself?
It depends on which compiler you use.
The most widespread one is TASM. It works under DOS (thus Windows). You can also launch TASM under Linux with DOSEMU or WINE. But you have to know that it is a shareware, it is not free, though propably noone and nothing will prevent you from using it for years, like almost the whole ti-community does :)
The less known one is TPASM. It works under Unix (and Linux). It's under the GNU/GPL. TPASM requires a source code syntax that is a little different from TASM's, i.e. the MACROs are defined differently, you must use "db", "dw", "ds", "org", etc. instead of ".db", ".dw", ".ds", .org"... Another important thing is that TPASM is case sensitive, including for the labels, while TASM isn't.
In case you use TASM, the header you may use is "dwedit.inc", by Dan "Dwedit" Weiss. You can find it at http://home.comcast.net/~alanweiss3/dwedit/ti/. With this header, you will be able to program for TI-82, TI-83(+) and even TI-73 ! You will also be able to make Flash Apps for ti-83+. It's really a huge header, and it handles almost all known shells.
If you use TPASM, I've made a header called "vion.inc". You can find it at http://etrange.paxl.org/. This header handles CrASH and CrASH19006 for the TI-82, Venus for the Ti-83 and ION for the Ti-83+. That's all! It is just my own little header, but then you can add what you want for yourself.
Saferams are really useful, but sometimes you can't do what you want with them.
The most useful one is the APD Buffer, which is 768 bytes big. On TI-83(+) there's no problem, they are only used if the calc shuts down after a few minutes of inactivity (Auto Power Down) so it won't happen in your programs (unless you use the rom call _getkey, that is NOT recommended !)
But on TI-82 it's a little more difficult; actually it depends on the shell you are using. I don't really know how it works for ACE and SNG... CrASH(19006) has a disturbing feature ; it allows to install an interrupt routine in the APD_BUF, that stays even when another program is launched... So, as I don't care about what the others' interrupt routines will do, I merely disable them as I start my program, like this (replace the # by a space for TPASM) :
im 1 ; tells to the z80 processor to stop executing "custom interrupt", and to execute the "normal interrupt" instead
ld (INT_STATE),a ; tells CrASH that there is no more interrupt routine installed (not really useful I think)
Now you have the whole APD_BUF for you alone.
There is another useful saferam: TXT_BUF (128 bytes big). This one is usable on TI-82,83(+) without problem, just remember to reset it before leaving your program, if you don't want remaining weird characters on the TI-OS screen.
And last, the OPs (the area where are stored the Floating Points values) that is 66 bytes big. You can use it as long as you don't use any rom call concerning FP operations (that is a wise decision because they are sluggish, unless you really need to do FP maths).
We also have the PlotsScreen area (768 bytes) on every calc model. It is almost always used as a buffer for the display, but you can use it as a saferam.
There are other saferams, but for compatibility's sake, we can't use them :
* StatRam (531 bytes) is on TI-83(+) but not on TI-82. Moreover, on TI-83+, MirageOS has its own interrupt that uses the first bytes of StatRam, as says the doc :
( By default, there will be an interrupt running during your program. This interrupt is located in the StatRam location. If you wish to use StatRam for variable storage, you must disable interrupts or set IM 1 before doing so.
So, for the TI-83+ version of your program, if you really want to use StatRam, put im 1 at the beginning of your program, to be sure it's wot mess everything up.
* On TI-83+ there are appBackupScreen (768 bytes) and tempSwapArea (323 bytes), but they aren't on TI-82/83 as they are related to Flash RAM.
* On TI-83(+) we have imathptrs (10 bytes), I don't know what it's for, but as it isn't on TI-82 we won't use it.
* The TI-83(+) have a ram place called cmdShadow, that is 128 bytes big. It is not free when you use ION or MirageOS, but with Venus there's no problem. This area is called TEXT_MEM2 on TI-82, and gets reseted each time you call the CR_HAND routine under CrASH (but you shouldn't use CR_HAND = _getkey).
Summary table :
||cmdShadow / TEXT_MEM2
|TI-82 status, address
||Available (with CrASH, after
|Available (reseted when you call CR_HAND;
Available with ACE)
|Non Available (doesn't exist)|
|TI-83 status, address
|Available (with Venus only)
|Non Available (doesn't exist)|
|TI-83+ status, address
|Non Available (used by shells)
|Available (disable interrupts)
|Available (unless during
|Use it ?
We can use 3 saferams, but look at the grey cells : the smallest among them is TEXT_MEM2 on TI-82 (and cmdShadow on TI-83), so in the source code of your programs you can refer to these 3 different saferam as a single one that is 128 bytes big like this :
Thus, later in your program, you will be able to use these 128 bytes to store temporary data :
ship_y = ship_x+1
life = ship_y+1
Now we can say that we have 4 common saferams on TI-82, TI-83 and TI-83+ ! THIS is useful !
4. How do I manage ROM Calls on these different calcs ?
First of all, read carefully the following sentence, and copy it a hundred times on a sheet of paper :
I SHALL NOT USE ROM CALLS
You're certainly wondering why. "They're handy and they make my programs smaller!", I hear you say. Sure. It is also true that, since we program in ASM, we are used to heavily depend on the hardware our programs will run on, so for certain things very hardware-related (i.e. for all that concerns the VAT) we just can't avoid using ROM calls.
But from an "unification" point of view, you must remind that the more your program is machine-independent, the better it is.
One thing for sure is that you won't always find the same ROM Calls on different calc models (and I'm not yet considering the possibility to port your program to other z80-based systems). It will not really kill the porting process, but I'm sure that the amount of time you want to give for TI-programming is not so big. So, take the good way since the beginning, and use ROM call as less as possible.
Plus, you will see further in this part that dealing with bcall, icall, bjp and ijp are a pain...
Moreover, ROM calls on the TI-8X+ series are slow, this is because the bcall thingy looks for the right ROM page before calling the routine. So it is also a speed issue.
Oh, I was about to forget mention this reason ! :)
Now, here are some explanations if you really want or have to use ROM calls :
If you already program for TI-83 and TI-83+, you are already used to
"bcall" instead of "call" for calling ROM Calls. This is a command that is equated by the compiler, differently in function of the calc :
* for the TI-83 is is replaced by a mere "call"
* for the TI-83+ it is replaced by a slow code that handles different rom pages to find the ROM Call (don't ask me how the TI-83+ memory works...)
But when you program also for the TI-82 you have to take in account 2 categories of TI-82 ROM Calls : those that you can directly call with a mere "call", and those you can't (that's where the shell is useful).
Here is a table to visualise how it works (the ????
address is the address of the routine used by CrASH(19006) to
handle ROM Calls) :
|TI-83 transcription||call xxxx
|TI-83+ transcription||rst 28h
Hopefully, the ROM Calls that require icall aren't too numerous. (reminder : this is for CrASH(19006) programming) :
_ldhlind ( LD_HL_MHL )
_cphlde (CP_HL_DE )
_divhlby10 ( UNPACK_HL )
_divhlbya ( DIV_HL_A )
_getcsc ( GET_KEY )
_lcdbusy ( DISP_DELAY )
The faster you'll memorize them, the fewer bugs you'll experience in your developpements, because confusing an icall/ijp with a bcall/bjp always leads to a crash on TI-82.
Replacing ROM calls
Here is an explanation of how I do to avoid using ROM calls.
For the following rom calls, I merely paste their code into my programs (it's small) :
For _clrlcdf, I first clear the graph buffer and then I update the screen with a FastCopy routine. Quite dirty, but for now I realize that I don't need speed when I use _clrlcdf.
When I need speed for a _clrlcdf routine, I'll make one based on the FastCopy.
Now the most controversial part :
_puts (and its derivates) : I use only small fonts, so I don't need these :)
_vputs (and its derivates) : here comes the one that can make your programs noticeably bigger... I think the best replacement for this routine is the one made by Dan "Dwedit" Weiss for Bubble Bobble 85. This routine draws the most useful characters jsut like the _vputs routine and it's 334 bytes big. I've also made a 4x4 version or this routine that is 220 bytes big. There are also (not as good) routines like it at http://void.ticalc.org, just look at the file font.h or into the program TxtView.
Using a replacement for _vputs also allows to develop TI-85 versions of your programs, because on this calc you can't write in the graph buffer in small fonts. It also allows to have a personnalised font, and some extra characters you may want to insert that are not in TI's "ASCII".
Other explanations will come ... Feel free to send to me your remarks and suggestiosn about this.
*to do : _getcsc replacement*
5. How do I use the free RAM ?
Sometime, you need a BIG temporary buffer for your games. You can put it inside your program, but it would be a waste because it will take space even if your program isn't running. So the best solution is to use the free RAM of your calc.
On TI-83 and TI-83+, it's easy to do so. Put these equates in the header you're using (if they aren't already there) :
FREE_MEM_START = $930D
FREE_MEM_END = $9311
_enoughmem = 443Ah
FREE_MEM_START = $9824
FREE_MEM_END = $9828
_enoughmem = 42FDh
|ld hl,(FREE_MEM_START) ; now HL has the address of the buffer|
On TI-82 :
Marc Plouhinec, the author of the TI-82 shell SNG v 1.0, has included these macros in the file SNG.inc :
;Creates a buffer if there is enough memory, leaves if not (ret)
;Creates a buffer if there is enough memory, jumps at the label NotEnoughMem else.
;Destroys the buffer
#Define DELBUFFER(Size, BufferAddress)
When you "call a macro" to create a temporary buffer, you have to specify the address of the buffer. A solution that works well is simply to choose the adress of the byte right after the end of the current program. You merely need to define a label at the very end of your program, and use this label as the address of the temporary buffer. The romcalls INSERT_MEM and CREATE_TMP take care of moving the other programs, so in theory you can choose any adress, but choosing the previous solution works fine.
CoBB says : "These macros work only with those shells that leave the VAT consistent with the memory. That means no CrASH." So for the moment you'd better stick to SNG 1.0 if you want to use free ram on TI-82.
CoBB also has an easy way to make this "83(+) compatible", by introducing the 2 FREE_MEM_START and FREE_MEM_END variables :
; These equates are in the OPs, but they could be anywhere (only 4 bytes needed)
FREE_MEM_START = $8028
FREE_MEM_END = $802A
LD HL,BufferAddress+Size; These are constant anyway
6. What about other z80-based devices ?
Game BoyLearning that the GameBoy has a z80 processor is quite mouthwatering, but the bad news is that it is a modified version. The GB processor has :
This text file explains more deeply the differences between the GB's processor and a regular z80 processor.
So, you get the idea, it is almost impossible to have similar source codes that run on both GB and TI z80.
III To do/Questions without answer
How do I replace the rom call _getcsc ?
How do I handle external programs ?
Is a TI-z80 program easily portable on z80-based Sinclair computers ?
If you have any suggestion, comment or question about this FAQ, contact me!
E-mail : guillaume.h (a) ifrance dot com
Thanks to (in no particular order):
Pat Fagan (who made the GB's z80 comparsion)
and anyone acting for the ti-community :)
revision 9 : 05/05/2005
Some minor corrections.
revision 8 : 28/10/2004
Added the info about using the free RAM on TI82 with SNG. BIG thanks to Marc Plouhinec, pacHa and CoBB for this.
revision 7 : 01/07/2004
Complete the "don't use rom calls" stuff with _vputs replacement.
Used neutral pronouns ;)
revision 6 : 06/06/2004
Added the "don't use rom calls" and Game Boy stuff.
revision 5 : 01/03/2004
Added the incomplete "free RAM" part.
revision 4 : 28/10/2003
Added several precisions
revision 3 : 07/10/2003
Added the saferam addresses.
revision 2 : 06/10/2003
Added the icall/bcall/ijp/bjp part.
revision 1 : 05/10/2003
I realised that cmdShadow and TEXT_MEM2 were the same thing...
Mentionned the PlotsScreen in the saferam part.
Corrected several things
revision 0 : 04/10/2003