Atari's Assembler Editor cartridge is extremely slow. Time spent just waiting for it to assemble a program could be put to much better use programming and debugging, or thinking of new program ideas. For any programmer who spends much time at all using the Atari cartridge assembler, the accumulation of wasted time could be so substantial it might actually be worthwhile for the programmer to rewrite the assembler to make it faster.
Improving The Assembler
Suppose a programmer did decide to improve the Assembler Editor cartridge. For one thing, he would have the editor tokenize each source line, instead of storing it in AT ASCII format. This change alone would significantly increase the assembly speed, and would have three bonus side effects as well. First, with a tokenized format it would be possible to LOAD and SAVE source programs just as fast as Atari BASIC can LOAD and SAVE programs; there would no longer be any need to wait for the slower ENTER and LIST commands.
Second, through tokenization, the source file could be compacted to almost half the size of the AT ASCII equivalent. The shorter, compacted files would LOAD in even less time, and take up even less disk space. And a condensed program size would make it possible to hold longer files in memory.
Finally, tokenization would allow error detection upon line entry. With the addition of other improvements such as a faster symbol table search, the revised assembler would be extremely fast. If the programmer added some other features like powerful conditional logic, an alphabetized printing of the symbol table, local labels, and macro support, he would have created the best assembler available for the Atari.
A Dream Come True
Stephen Lawrow has made all of these improvements and more, and his MAC/65 macro assembler is the answer to every machine language programmer's dreams. MAC/65 is currently available on the Atari for $80 from OSS, and Apple and Commodore 64 versions are expected soon. This offers users of MAC/65 the added advantage of being able to use the same assembler on three of the most popular personal computers.
Let's take a closer look at two of MAC/65's best features. The first is conditional assembly through the use of the directives .IF, .ELSE, and .ENDIF. The .IF directive evaluates an expression and controls how the following code is assembled. If the value is true (nonzero), only the code between the .IF and the .ELSE or .ENDIF is assembled. Should there exist a . ELSE (it is optional), the code between it and the .ENDIF will be assembled if the value is false. It is possible to nest these conditional constructs. One use of conditional assembly is to let the same source listing produce both cassette and disk versions of a program. This feature is even more powerful when used with the operators .DEF and .REF, which tell whether or not a label has been defined or referenced.
Macro Assembly With Numeric And String Parameters
Macros are defined by the directives .MACRO and .ENDM, and consist of a sequence of frequently used source lines that are given a label. Whenever this label appears at any point in the source listing, the corresponding source lines will be inserted into the assembly. It's like a collection of automatic, prewritten subroutines. Here is an example.
1000 .MACRO SAVEREGS ;save registers on stack 1010 PHA 1020 TXA 1030 PHA 1040 TYA 1050 PHA 1060 .ENDM .... .... .... 5000 SAVEREGS 5010 JSR SOMEPLACE
The one call of SAVEREGS in line 5000 will cause five source lines to be assembled in its place. Note, however, that a macro differs in some ways from a subroutine; a macro only affects assembly, and since this example used the stack, SAVEREGS could certainly not be made into a subroutine (which stores a return address on the stack) without a stack conflict.
A macro can also be defined so that different parameters can be specified each time the macro is called. One good example is the macro defined here to increment a 16-bit memory location.
1000 .MACRO INC16 ;increment a 16-bit number 1010 INC %1 ;increment lo byte 1020 BNE SKIP 1030 INC %l + 1 ;increment hi byte 1040 SKIP 1050 .ENDM .... .... .... 5000 INC16$600
At assembly time, the value $600 is substituted for the symbol %1, and the assembler will generate the code to increment the 16-bit number at $600. Another good example is the macro definition for OPEN, provided in the MAC/65 manual. Once this macro has been defined, it is possible to have a source line which reads OPEN 3,4,0, "D: FILENAME". This one source line will generate all the code necessary to perform an OPEN operation using channel 3, auxiliary bytes 4 and 0, and the specified filename. This takes a lot of the drudgery out of the tasks of writing in machine language.
In the definition of OPEN (not reprinted here), the symbol %1 would represent the first parameter, in this case a 3. The second parameter corresponds to %2, and so on. String parameters are indicated using a dollar sign, as in %$1. The symbol %0 is reserved to tell how many parameters were included in a macro call. Combine this with the conditional logic described earlier and you have some very powerful tools.
MAC/65 can handle a nesting level of 14 macros, with up to 63 parameters at any given instant.
The advantages of macros are that they reduce source file size, speed up the development of machine language programs, and reduce the number of programming mistakes. Typing the same code several times increases the risk of error, but a macro is defined only once. Also, a carefully chosen macro name can communicate more information to the reader of a source listing than a bunch of sparsely commented source lines.
Other Features And Limitations Of MAC/65
A local label is one which has a value in only one part of an assembly source. Another label, possibly of the same name but with a different value, can be used in another local section without conflict. This is especially useful when several programmers are each writing sections of a large machine language project. Through the use of local labels, each programmer can use whichever label names he wants, without fear of causing "duplicate label" errors by using label names already chosen by the other programmers. Local labels are possible in MAC/65 with the .LOCAL directive.
The directive .BYTE will print up to four byte values per assembly line, which can save a lot of paper. The .ERROR directive can be used to report errors, such as the illegal use of a macro call. There is an .INCLUDE directive, which allows access to macro libraries, equate files, and multiple source files. There are also bitwise .AND, .OR, and .NOT operators. The operators > and <, when used before an expression, return high and low byte values. This is an improvement over the common, but error prone, usage of /256 and &255.
The RENumber, FIND and REPlace commands of the editor are usually satisfactory, but it would be nice to have a MOVE command. MAC/65 will work only on a 48K machine and is available only on disk, but these two problems will be solved if OSS releases MAC/65 on a cartridge.
It should be noted that MAC/65 comes with OS/A +, the no-nonsense DOS from OSS. OS/A 4- is completely compatible with DOS II because the disk routines are the same, but the DUP portion of DOS II has been replaced with a monitor that is always resident and takes up very little additional memory. You can quickly read a disk directory or unlock a file without erasing your program, and there is no need for the questionable MEM.SAVfile.
Atarl Assembler Editor Cartridge And MAC/65 Comparison
The test file contained 962 lines of nicely formatted, commented code, and made extensive use of labels but no macros. Macros will slow down MAC/65. The object file was about 2500 bytes. All assembly times are with listing turned off. EASMD is OSS's disk version of Atari's ASM/ED, and is nearly identical to the cartridge.
|DISK FILE SIZE (SECTORS)|
|TIME TO ENTER (SECONDS)||96||82|
|TIME TO LOAD||–||0:15|
|FREEMEM WITH PROGRAM||02389||11489|
|ASM MEMORY TO MEMORY||323||less than 5 seconds|
|ASM DISK TO DISK||444||50|
MAC/65 is amazingly fast. For relatively small programs, no sooner do you type ASM and press the RETURN key than the assembler starts printing the second pass.
The incredible speed of this MAC/65 has greatly increased my productivity as a programmer, not just because it assembles programs faster, but also because while waiting for the old cartridge, I would often switch the television channel and become interested in a show. Now with MAC/65 there's no time to get distracted.
MAC/65 can assemble source files so fast (for memory to memory with no listing, it takes just a few seconds at the most) that the actual assembly speed becomes almost irrelevant. When assembling from disk, the only thing holding MAC/65 back is the slowness of the disk drive. For a comparison between the Atari cartridge and MAC/65, see the chart.
The Apple version of MAC/65 assembles from disk to disk at twice the speed of the Atari, due to the faster speed of the Apple disk drive.
MAC/65 comes with a reference manual which gives complete descriptions of all commands, operators, directives, and errors. It is not a tutorial and does not teach machine language. A small macro library is also provided to get the user started. The manual could stand improvement, but it is a good manual, covers all necessary topics, and contains examples.
Compatibility With The Atari Assembler Editor Cartridge
Here is a list of all the differences between MAC/65 and the Atari cartridge.
- Source files are completely upward compatible with one exception. MAC/65 uses an algebraic operating system with different precedences for different operators (like BASIC), while the cartridge performs all operations from left to right. Expressions like LABEL + 2/256 will have to be rewritten using brackets, such as [LABEL + 2]/256.
- MAC/65 has a TEXT mode which turns off the error checking upon line entry, so the editor can still be used to do things like renumbering Atari BASIC programs.
- There is no DEBUG mode. Only the commands C and D (change and display memory) have been kept. All the other debugging features, including memory manipulation, breakpoints, the instant assembler and the disassembler, are available in BUG/65, an interactive debugging tool which comes with MAC/65.
- The .INCLUDE files must be in SAVE format.
- The directive .PAGE now prints at the bottom of a page, not at the top.
- Bulk line deleting is faster.
- FIND and REPlace are slower, because the source is not stored in straight ATASCII.
- Although MAC/65 still does not print a total error count at the end of an assembly, it does at least list all errors to the screen, even if the output is directed to another device such as the printer.
- Automatic page numbering.
Optimized Systems Software, Inc.
1173 Saratoga-Sunnyvale Rd.
San Jose, CA 95129