Machine Language Stringer
Save 7 seconds on each BASIC subroutine.
By Andy BartonMachine Language Stringer takes machine language object code and converts it into string format for use in your own BASIC programs. This BASIC program works on Atari 8-bit computers with at least 48K memory and disk drive.
Most machine language routines in BASIC programs are in the form of string data. This is done partly because strings take up less space than numerical DATA statements. They frequently don't need to be POKEd into a memory location.
When I tried translating a machine language routine in one of my programs into string format, I discovered the best reason for using strings. The string format virtually eliminated the seven seconds used to READ the 144 bytes of data and POKE them onto page 6. I was sold. I dearly hate to wait for slow computers.
I developed Machine Language Stringer to do the near-impossible manual task of taking the object code file of a machine language program (the executable code) and converting it into a set of BASIC program lines that will produce the proper string data.
GETTING STARTED
Type in Listing 1, STRDAT.BAS, and check it with TYPO II. Be sure to SAVE a copy to disk before you RUN it.
If you have difficulty typing the special characters in Line 460, don't type them in. Instead, type Listing 2, check it with TYPO II and SAVE a copy. When you RUN Listing 2, it creates these hard-to-type lines and stores them in a file called LINES.LST
To merge the two programs, LOAD "D:STRDAT.BAS" and then ENTER "D:LINES.LST." Remember to SAVE the completed program before you RUN it.
When you RUN the program, you will be asked for the object file name. If you forget the "D:" or the name is not found you will be asked again. Next you are asked for a starting line number. Be sure you choose one that will not overlap lines in your BASIC program or in this one.
Finally, you are asked for a name for the machine language string (maximum of 2 characters). The program will add a numerical extender to this name, starting with 1. The program will now go about the business of reading the object file and building the BASIC line(s) that will be incorporated into this program using Atari's forced read mode.
When the program is done, there are three more steps for you to take to incorporate the string into your basic program.
1. LIST the new lines to a disk/cassette file, for example:
LIST "D1YOURPRG.STR";l000, 1005.
2. LOAD your BASIC program and ENTER the string data file, for example:
ENTER "D1:YOURPRG.STR".
3. Make a USR comand to run the ML string.
PROGRAM NOTES
There are two numbers that cannot be displayed in a string-34 and 155. 34 is ASCII for a quotation mark and 155 is ASCII for a carriage return (return key). This program handles this problem by creating a separate line that inserts the number into its proper place in the string, for example:
1001 MLl$(72,72)=CHR$(155).
There are two types of machine language programs, ones that are fully relocatable and ones that are fixed at a particular memory location. Jump (JMP) and jump subroutine (JSR) comands use absolute rather than relative addressing and thus require the program to be at the specific location to which it was assembled.
Machine language Stringer accommodates this by creating a final BASIC line which provides a brief machine language string to move the string data to the memory location indicated by the object file, for example:
1006 X=USR(ADR("hh..."), FROM , TO , NO. BYTES)
This line is provided regardless of which type of machine language program you wrote. If your program is fully relocatable, this line can be deleted.
It is possible to create a program that is loaded into two or more separate memory locations. For example, a section of subroutines could be fixed onto page 6 and the main program could be totally relocatable. Machine language Stringer accomodates this by using the numeric extender mentioned above. Each time a new load address is indicated in the object file, the extender is increased by one, creating a new string name. Each string is provided with its own loader.
As mentioned above, for a program to be relocatable it cannot use absolute addressing with jump instructions. I have found no way around this problem with subroutines other then placing them on Page 6 or some other safe, fixed location.
However, there are two tricks I have discovered for JMP instructions. The problem arises when I would use a branch instruction, but find that its range (126 bytes) was too short so I would be forced to use a JMP instrution. The first crude but effective solution involves setting up intermediate branches to one or more areas within range, but outside the flow of the program. Here is an example:
LOOP LDY #0 PART1 LDA ($D0),Y ... BEQ PART1 BNE PART2 ;BRANCHES OVER BP1 BCS LOOP ;INTER:MEDLATE BRANCH PART2 ASL A ... SEC ;SET CARRY TO BCS BPl ;FORCE A BRANCH
The second solution is more versatile, using the indirect jump instruction JMP(XXXX). It involves passing the address of the relocateable ML string to the ML program in BASIC's USR command. The ML program then figures the relative distance from the start of the program to the targeted instruction, adds this to the starting address of the string and saves the results on page 6 for the JMP(XXXX) to use. Here are two examples, first in BASIC:
X = USR(ADR(ML$),ADR(ML$)) In ML, this would be: IJP1 = $600 ;SAFE STORAGE FOR IJP2 = $602 ;INDIRECT JUMP ADDRESS START * = $5600 PLA PLA ;HI BYTE OF ADDRESS OF ML STRING TAX PLA ;LOW BYTE OF ADDRESS TAY ;SAVE IF MORE THEN ONE JUMP TARGET ;NEEDED CLC ADC #<TARG1-START ;ADD LOW BYTE OF TARGET ADDRESS OFFSET TO ML STRING ADDRESS STA IJP1 TXA ADC #>TARG1-START ;ADD HI BYTES STA IJPl+1 TYA ;GET LOW BYTE ;STRING ADDRESS CLC ;FOR SECOND TARGET ADC #<TARG2-START ... ;etc. TARG1 SEC ;SOMEWHERE IN MAIN PROG. ... ... JMP(IJP1)
You may have to modify the program to get it to work with character set files. This program strips the first two control characters from the file, so you would end up with 1022 instead of 1024 bytes in your character set files.
As always, whenever modifying your programs you should first make backups
of the originals, in case problems arise.
Andy Barton has been a regular contributor to Antic since 1984. His machine language game, Exwall, is this month's Super Disk Bonus.
Listing 1: STRDAT.BAS Download
Listing 2: LINES.BAS (not needed)