Extending MAE
Dr. Harold Lindner
Krefeld, West Germany
Carl Moser's MAE Assembler for the Apple and PET has proven popular with machine language programmers. Here, Dr. Lindner demonstrates how you can add your own, custom pseudo op's.
Carl Moser's excellent MAE macroassembler and text editor for the PET and the Apple is a very powerful program, but it can still be improved. I should like to describe how two new pseudo operation codes ".SL" and ".SH" can be added. These pseudo op's .SL "store low byte of a two byte address" and .SH "store high byte of a two byte address" may be used to generate jump-tables (e.g. the TOOLKIT, Commodore's BASIC-interpreter, and machine language monitor).
MAE's pseudo op's are contained in the table from 57C3 to 5834 (all addresses in hexadecimal). Each entry consists of four bytes. The first two bytes contain the ASCII-codes of the pseudo opcode name, and the last two bytes contain the address of the corresponding subroutine in the usual 6502-format low/high.
Fortunately, eight spare zero bytes (582B-5833) at the end of the table leave room for the addition of two new pseudo opcodes.
The Simple Solution
MAE contains two subroutines, Low at 5E39 and High at 5E4A, to evaluate the expressions "#L," and "#H," as in LDA #L,$B312 and LDY #H,$B312. The simple solution is to replace the eight zeros at 582B-5833 by:
582B 53 4C 39 5E ;SI LOW 582F 53 48 4A 5E ;SH HIGH
MAE will now handle the new pseudo op's .SL and .SH as expected. The only remaining problem is the relocating loader, which doesn't yet like these pseudo op's.
A Better Solution
Let us quickly consider the relocating information in MAE files. Assembler source files are program files, whereas MAE's OUTPUT command generates sequential files. The information for the relocating loader is contained in bytes whose low nibble is F (15 decimal). These bytes do not constitute valid 6502 instructions. After an ordinary machine language instruction such as LDA 4A or STX 6502 the bytes OF to 7F have the following meaning:
OF: fixed address, do not alter. IF: low byte of an address, the high byte follows. 2F: high byte of an address, the low byte follows. 3F: a byte value follows, do not alter. 4F: an address (2 bytes) follows, alter unless OF follows. 5F: pseudo op .RS (resolve info set). 6F: pseudo op .RC (resolve info clear). 7F: pseudo op .DS (define storage).
Our new pseudo ops .SL and .SH will have to provide the following informations to the relocating loader:
a byte value follows (via 3F),
this is the low or high, respectively,
part of an address (via IF, 2F).
This is achieved by the following coding:
75BD SL JSR 6347 LDA 49 JSR 5B67 JMP 5E41 75C8 SH JSR 6347 LDA 4A JSR 5B67 JMP 5E52
This routine may be located conveniently at 75BD-75D2 which area is not occupied by MAE (at least not the PET version). MAE's pseudo op table is to be altered as follows:
582B 53 4C BD 75 582F 53 48 C8 75
Finally, the relocating loader must learn to consider the directives 1F and 2F after a byte value (via 3F). This is easily done by replacing JMP 0584 with JMP 0639 at location 059A of the relocating loader (1979 version). Your MAE assembler will now handle the new pseudo op's .SL and SH perfectly.