This lesson will teach you something about how a shell exactly works.
Why a backup file? |
What is a shell?
Everyone has become so used to the assembly shells that a lot people forgot the real purpose of a shell:
A shell provides an easy, user-friendly and safe way to run assembly programs on you're calculator.
It IS possible to run assembly programs without the use of a shell, BUT it's a lot more complicated.
You could compare a shell to a GUI on a PC. It IS possible to run graphical programs for DOS, but it is far more complicated than writing a graphical program for Windows. Try writing Office for DOS :-)
Please remember, this lesson is not intended to tell you how to easily write a shell. The last thing we want is dozens of shells (compatible or incompatible) shells laying around. I guess that two shells (ASH and CrASH) is already more than enough.
Why a backup file?
First question: why do you always have to send a backup file to your calculator when you want to install a shell?
Why can't you just load one program or program group to your calculator to install the shell?
The answer is pretty simple: without messing with the backup file, assembly would never be possible on the TI-82
(unless there is still another backdoor in the TI-OS of which we don't know yet, but this is pretty unlikely).
If the TI-82 wouldn't have got link possibilities, we would still be programming in TI-BASIC :-)
Another problem is that the normal TI-OS is always moving around the programs and variables in the RAM so everything
forms one big block starting at $8D24.
In order to start a shell, which is of course written in assembly language (most of it), this assembly code needs to be at a fixed memory address.
With a backup, it is possible to get the shell program loaded at $8D24. This way, the program will never have to be moved by TI-OS (because there are no programs/vars earlier in the memory).
Without using a backup, it would be very difficult, if not impossible, to get the shell program at the very beginning of the user ram.
How does the shell starts itsself?
A shell is written in assembly, but of course, there's no shell to start a shell :)
A shell needs to be started 'The hard way'. I'm not going to explain everything here, just some basic things.
For a more technical explication, you should read 82HACK.TXT by Mattias Lindqvist.
When sending over the backup file with the shell, you also send over two variables.
It aren't real variables of course, there has been messed with them too.
You can't use those vars in TI-OS and when you delete them, your calc crashes.
These vars are set up in this way that when you copy the first var to the second, some memory locations around $8114 are overwritten.
And $8114 contains the address of the code to be executed after the next keypress.
Guess which address is put in $8114 when copying the first var to the second? If you guessed $8D24, you're almost correct.
Actually, it's about 20 bytes further in memory.
Why? Well, the first two bytes of each program contain the length of it.
And for a shell program or an assembly program, there is no difference.
For a shell program, The first 20 bytes or so contain a real basic program.
Purpose is to copy the two special vars in order to start the shell.
Now you might ask how it is possible to copy those special vars in a basic program, when I just sais that you can't use those vars in the normal TI-OS?
Well, naturally, there has also been messed with that BASIC program :)
Tasks of the shell
OK, what jobs does the shell do once running ? A short list:
- Reset the key press pointer ($8114)
- Find out ROM version and adapt the shell code to this
- Reset some shell vars
- Search the VAT for assembly programs and show a menu on screen
- Let the user choose a program
- Prepare to run the program (relocate, set/res system flags, clear regs/mem areas)
- Execute the user program (Call $9104)
- De-relocate and go re-create the programs menu
Next to this code, the shell also contains some functions for use in assembly programs.
The most important function is the ROM_CALL function.
This function is used to call functions in the ROM without having to concern which ROM version is running in the users calculator.
ROM_CALL($addr) is actually a macro which is translated into call shell_func_romcall \ .dw $addr
What the rom_call function does is:
- Get the $addr using the return address on the stack
- Update the return address on the stack (+2)
- Calculate the correct address depending on the used ROM version (+$1A on ROM 19)
- Call the correct address
Next to all this, the rom_call function also has to make sure that NO registers are destroyed at all and that the code can be executed very fast (to reduce the time you lose by not using a normal call). A hard task...
CrASH has, next to the ROM_CALL function, a full arsenal of other useful functions: a fast graphics routine, a random number generator, a safe KEY_HAND routine (which does not crash the calc when you press the ON key) and CP_HL_BC.
Quiting the shell
When getting out of the shell, the big responsibility of the shell is to leave the calculator in a safe state that can be handled by the TI-OS.
Some things that get done:
- Clear TEXT_MEM, TEXT_MEM2, GRAPH_MEM, ...
- Reset the current calc function byte to $40 (Home Screen)
- Reset the stack pointer
- Reset/Set some system flags
- Return to the TI-OS using a rom function
Most shell also put some publicity (credits) on the screen when you quit ;-)
Previous lesson |