<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>
Sometimes you may have a requirement to load assembly code in from disk for execution. It's not really necessary, because TurboForth includes an assembler, which makes writing assembly code as easy (and follows the same process) as writing Forth code. However, in the event that you do wish to load external machine into memory from disk, the EA#3 loader is your friend.
Most TI-99/4A nerds will know that the TI-99/4A Assembler, supplied as part of the Editor/Assembler package, outputs machine code in a format called Tagged Object Code.
Tagged Object Code is a DF80 file that contains the machine code in readable ASCII, though it is in an assembled form; it is not in source-code form. Here's an example of a DF80 Tagged Object Code file:
00000 92000920029200492006B2008B04C0B04C6B020CB0024B30C07F366F 0001
62006KSCAN 62000VBLANK62002KSTAT 7F7E4F 0022
:Asm994a TMS99000 Assembler - v3.010 0023
The contents of the file is interpreted by a loader program. Tags in the file instruct the loader to do things, such as change the address that the next bit of code will be loaded to, etc.
For example, the tag 9 reserves the address following it, so that code is not written there. The tag B writes the following 4 digit hex value to the current loading address. The tag 7 (seen towards the end of the lines above) presents a 4 digit hex check-sum value immediately after it, and so on.
Tagged object code is very versatile. It allows, for example, re-locatable code to be loaded anywhere in memory. It is much more versatile than raw memory-image code, which is generally coded to run from a fixed address, though it is more expensive (i.e. slower) to load.
A simple Tagged Object Code loader is available for TurboForth on block 42 of the companion disk. Load it as follows:
Once loaded, it is invoked as follows:
S" DSKn.filename" #3LOAD
The loader supports the most common tags, such that most assembled source code, assembled with the TI assembler, can be loaded.
At the assembler source code level, the following are supported:
DEF causes the loader to create a dictionary entry for the DEF'd word, so that it can be accessed from the Forth environment. The word produced acts like a variable, returning the address of the DEF'd word, as follows:
AORG >3010 DEF START ; creates a word in the dictionary called START START MOV *R4,R0
If the above code were assembled and loaded via the loader, executing START would not cause the code at START to be executed. Rather, it would return the address of the code beginning at the symbolic label START. So, if one executed the following code in Forth:
START @ $.
It would display the op-code for the MOV instruction.
Using the DEF directive in assembly source, it is possible to call machine code from the Forth side after it has been loaded from the loader. Recall that DEF'd labels cause words to be constructed in the dictionary which return an address. Therefore that address can be supplied to EXECUTE and the machine code will be executed. However, there is a gotcha. TurboForth uses the Indirect Threading Code (ITC) code method, and as such, a pointer to the machine code needs to be assembled, and the address of the pointer is given to EXECUTE.
Here is a complete example of code that can be assembled with the TI Editor/Assembler package, loaded as an option #3 file, and executed from TurboForth:
AORG >2000 DEF DOUBLE DOUBLE DATA MYCODE * _pointer_ to executable code MYCODE A *R4,*R4 * add contents of stack to contents of stack B *R12 * Return to the TurboForth environment
The above code, when assembled and loaded through the loader, will double any value on the stack. It is called via EXECUTE, for example:
99 DOUBLE EXECUTE .
TurboForth will duly display 198. An address should be given (using AORG ("absolute origin")) to tell the loader where to load the code. A good area is in the low memory expansion - 8K of RAM from >2000 to >3FFF. This area is, under normal circumstances, unused by TurboForth unless it is specifically told to compile code there.
An early video is shown below of the loader loading some machine code in from disk, and running that code from the Forth environment.
10th February 2012