DOCUMENTATION FOR LISA V3.2 =========================== copyright 1983, Randall Hyde copyright 1983, LazerWare All Rights Reserved Here it is -- LISA v3.2 addendum documentation. This doc file assumes that you've got access to a LISA v2.6 manual. If you don't, call HAL Labs to get one. Since this file was uploaded from an Apple Lisa running the 7/7 office system, it has some peculiar characters in it. When you see the following, make the appropriate changes: G --> "<<" H --> ">>" I --> "..." There may be other weird characters, but these three are used all over the place. Note, the copyright notice in this documentation can be ignored. Feel free to (non-commercially) distribute this program to your friends. Ignore notices of support provided by Lazerware or Randy Hyde in this doc. Support for the product can be obtained from HAL Labs at (714) 780-3328. So, without futher ado... LAZER'S INTERACTIVE SYMBOLIC ASSEMBLER VERSION 3.2 A PRIMER FOR ADVANCED LISA V2.6 USERS This short manual is intended to describe the additional features of the LISA v3.2 assembler and the ALE (Advanced LISA Editor) program over the LISA v2.6 interactive assembler. This manual is not intended for beginning or even intermediate LISA users. It assumes that the reader is quite familiar with the features of LISA v2.6 and has mastered most of the features of that product. If you've just begun learning 6502 assembly language or this is your first experience with the LISA interactive assembler, please take the time to master the use of the LISA v2.6 assembler before attempting to use the v3.2 release. This release includes several versions of the LISA macro assembler. Versions for the standard NMOS 6502, CMOS 65C02, and CMOS 65C802 chips are provided. These three assemblers are further broken down into three additional versions, one for 64K Apple // systems, one for 128K (minimum) Apple //e and Apple //c systems, and one for (older) Apple systems with a minimum of 80K installed. Unlike most other assemblers now available for the Apple, LISA v3.2 is capable of running on any Apple which supports ProDOS. MEMORY REQUIREMENTS Since ProDOS occupies the primary 16K language card bank, LISA v3.2 had to be relocated elsewhere. For 128K (or larger) Apple //e and Apple //c systems, LISA v3.2 and the ALE programs reside in the auxilliary memory bank. On the older Apple ][ systems which do not support the auxiliary memory bank, two 16K language cards, a 32K card, a 64K card, or a 128K card (available from various manufacturers) is required for proper operation of the LISA v3.2 assembler. For smaller systems with only 64K, a special, limited, version of LISA v3.2 is available. The ALE program will not run on a 64K Apple ][ system. For 128K Apple //e and //c systems or Apple ][ systems with 96K or greater, a one key command can be used to quickly switch between the LISA assembler and the ALE editor (context switching is accomplished in about a second). If you are using a standard 128K Apple //e or Apple //c, or the 64K version of the assembler, you will be able to use LISA 'right out of the box'. If you intend to use an 80K (or greater) Apple ][, you will need to run a configuration program to install the assembler on your system; consult the appendices for more details. Backing up LISA v3.2 Unlike many software companies, Lazerware supplies its programs on copyable floppy disks. To protect your investment, you should immediately make a working copy and a backup copy from the diskettes supplied by Lazerware. To keep the cost of this package down we copy information on both sides of the floppy diskette. Although both sides are usually good, only one side is guaranteed by the manufacturer. You should make copies of the disks supplied by Lazerware as quickly as possible and then never again use these diskettes (except in some extreme emergency). This will help avoid the loss of important program files on the diskette. While on the subject of disk copying, we freely encourage you to make as many copies of this program as you feel necessary for yourself. But please, don't make copies for all your friends as well. Treat this software like a book. You can carry it from location to location (machine to machine), but you can only use it in one location at a time. Likewise, you can loan it to your friends, but while they're using you can't (if you loaned your friend a book, you wouldn't be able to read it at the same time s/he was). If you're using this program in a work environment, the same rule applies: anyone can use it on any machine, but only one person can be using it at any time. This package is priced so low that even the smallest companies can afford additional copies if multiple work stations are required. Lazerware provides extremely low-cost multiple station licenses for schools and companies requiring more than five workstations. RUNNING LISA V3.2 If you want to run under the ProDOS operating system, you will use the LISA v3.2 assembler. LISA v3.2 runs under the ANIX v2.x operating system. ANIX v2.x isn't actually a stand-alone operating system, but rather a shell for the ProDOS operating system. Other than the fact that ANIX v2.x reserves memory locations $9400...$BEFF for its own use, ANIX v2.x is ProDOS (plus several enhancements). Since the ANIX v2.x reference manual is quite large (and very expensive to reproduce), a small ANIX primer is supplied at the end of this document. Advanced users, who wish to take advantage of ANIX's power, may purchase a copy of the ANIX manual directly from Lazerware. LISA v3.2 requires a minimum of 64K RAM. For serious development, a minimum of 80K is required. If you are running LISA v3.2 on an Apple //e, you should install the extended memory card to boost that machine's capacity to 128K. Since Apple //c systems are shipped with 128K, LISA v3.2 will run just fine on these systems. If you are using an older Apple ][ or Apple ][ Plus system (or an Apple ][ compatible system) you should install at least 80K of memory before using the LISA v3.2 assembler. LISA v3.2 requires this additional memory because, like LISA v2.6, LISA v3.2 normally sits in the language card area of the Apple //. Unfortunately, ProDOS also resides in this area of memory. To resolve this conflict, LISA v3.2 uses a special set of bank selection routines in page three which allow ProDOS and LISA v3.2 to co-reside in (separate) 16K language card banks. A special relocated version of LISA is available for 64K Apple systems. The 64K LISA sits down in the lower 48K. In addition to reducing the amount of RAM avail- able for source files and symbol tables, the 64K version doesn't provide the LISA debugger/monitor program. You will have to use the Apple monitor with the 64K LISA. Apple ][ and Apple ][ Plus 80K versions require an additional 16K of bank switchable memory to hold the assembler (since ProDOS always loads into the primary 16K card bank). The additional 16K of memory can be installed in a variety of ways. You can install two language cards into your Apple, you can install a 32K card (like the Saturn 32K card manufactured by Titan Systems, the RAMPLUS+ card manufactured by Mountain Computer, or the 32K cards manufactured by Microtek and MPC), or you can install certain high-capacity 64K and 128K cards manufactured by various companies including Titan Systems, Legend Industries, Prometheus, STB, and Omega. Note: any high-capacity card which is addressed like multiple 16K cards can be used. Certain high-capacity boards (like Apple's Megabyte memory expansion card, the SVA 256K card, and the Synetix semiconductor RAM disk) do not meet this criterion. With a high-capacity memory card, ProDOS loads into the standard 16K bank and LISA loads into (one of) the alternate 16K bank(s). Since there are several different bank selection schemes used by various manufacturers, LISA v3.2 must be customized for the particular card you are using (in extremely rare situations, you may be required to write your own short bank selection routine). Installation details are covered in an appendix at the end of this manual. Once LISA v3.2 is loaded into an alternate language card bank (be it the auxiliary memory bank on an Apple //e or Apple //c, or into an alternate 16K bank on an Apple ][ or Apple ][ Plus), the assembler almost behaves the same regardless of which machine is executing the program. Since most LISA v3.2 users will be using a 128K Apple //e or Apple //c, this document will assume such is the case. To run LISA v3.2, boot the LISA master disk type one of the following program names after the ANIX "=" prompt: If you wish to run the 64K version, type: LISA.64K -To execute the LISA program. LISAC02.64K -To execute the 65C02 version of LISA. LISAC802.64K -To execute the 65C802 version of LISA. ALE is not currently available for 64K users. If you wish to run the full version, You must first install the appropriate memory manager code by running SETUP.LISA (on the LISA.CONFIG disk). After configuring LISA for your machine, you can execute LISA using one of the ANIX commands: LISA -To execute the LISA program. LISAC02 -To execute the 65C02 version of LISA. LISAC802 -To execute the 65C802 version of LISA. ALE -To execute the Advanced LISA Editor program. ALEC02 -To execute ALE for the 65C02. ALEC802 -To execute ALE for the 65C802. If your Apple has 96K (or more) RAM installed, the SETUP.LISA program will merge LISA and ALE into a single file (LISA, LISAC02, or LISAC802). CREATING A WORKING DISK Due to the wide variety of Apple systems, there are a large number of files provided on the LISA release disk. To create a working disk for your system, only a few files are required. For 64K systems, you only need: PRODOS, ANIX.SYSTEM, LISA.64K (or LISAC02.64k/LISAC802.64k), and, optionally, SETUP.LISA64K and DS. For 80K, or greater, systems you will need: PRODOS, ANIX.SYSTEM, LISA (or LISAC02/C802), ALE (or ALEC02/C802), SETUP.LISA, and, optionally, DS. SETUP.LISA will be required to configure your LISA system. If you have installed more than 80K in your Apple II (e.g., a 128K Apple //e or Apple //c) ALE and LISA will be merged into a single file. THE LISA V3.2 EDITOR With a few minor differences and three omissions (the FIND, APPEND, and LOB commands), the LISA v3.x editor is used identically to the LISA v2.6 editor. There's also an additional program, ALE (advanced LISA editor), which provides several new editing commands including find, search and replace, several new listing options (including listing forwards and backwards in the file), block move and copy commands, a built-in hex calculator, several reference charts (including the ASCII character set and all of the ProDOS equates), plus other features. On 128K Apple //e and Apple //c systems and on 96K (or greater) Apple ][ systems, a single keystroke command will automatically switch between the assembler and ALE programs so that the extended editor will always be available. For major editing tasks, the ALE program is a big improvement over the LISA v2.6 editor. One of the major differences between the LISA v2.6 editor and the LISA v3.2 editor is how screen editing is handled. Screen editing under LISA v3.x is handled by the ANIX operating system. If you want to change the screen editing keys for LISA v3.2/ANIX v2.x, the ANIX v2.x SETUP.ANIX program is used. ANIX v2.x is shipped prepared for an Apple //e or Apple //c keyboard. If you own an older Apple ][ system you will probably want to change a few of the screen editing assignments with the SETUP.ANIX program. Once you run the LISA v3.x program, you will be greeted with a LISA v3.x sign-on message and the exclamation mark prompt. At this point, all of the LISA v2.6 editor commands except Append, LOB, Find, control-P, Read, and Write operate almost exactly as before. Append, LOB, and Find are not implemented in LISA v3.x (Find has been moved into the ALE program, there's no need for LOB, and Append can be simulated with Read and Write); control-P (the user command) is implemented with the LISA v3.x "U" command; and Read and Write are implemented a little differently. Finally a new command, "SYS", has been added which will return control to the ANIX operating system. Within the LISA v3.x assembler/editor, the following commandls concerning these commands. The following commands have (very) minor differences between the LISA v2.6 command and the corresponding LISA v3.x command: LOad Syntactically, the LISA v3.x LOad command is used exactly like LISA v2.6 LOad command. The only difference is the syntax for the filename accepted by the operating system. LISA v3.2 allows only ProDOS/ANIX v2.x filenames after the load command. SAve Same filename restrictions as LOad. LEn The length command displays some additional information in addition to the length of the file. CTRL-D In LISA v2.6, control-D is used to preface a DOS 3.3 command. In LISA v3.2, CTRL-D marks an ANIX v2.x command. Consult the appro- priate ANIX reference document for more details. The Read, Write, and CTRL-P commands perform the same functions as before, they're just implemented a little differently. CTRL-P behaves exactly like its LISA v2.6 counterpart, it jumps to location $E009 ($5C09 on 64K systems) where a JMP instruction which transfers control to a user-written command. The difference between the LISA v2.6 and LISA v3.x user commands is that LISA v3.x uses the "U" symbol to execute the user command rather than CTRL-P. The Read and Write commands are used exactly like their LISA v2.6 counterparts, except the syntax for the filenames has changed a little. First of all, the filename must be a valid ProDOS filename, secondly, the ">" symbol must pre- cede the filename in the Write command and the "<" symbol must precede the filename in the Read command. E.g.: R YOURFILE.TXT R 65 TEXT.VERSION Two new commands, which don't have a LISA v2.6 counterpart, have been added to the LISA v3.x assembler: CTRL-P (actually an ANIX command) and SYS. Whenever control-P is encountered at the beginning of a line, ANIX will turn on the printer device (which is usually the interface card in slot one). The printer will remain on until control-P is once again pressed at the beginning of an input line. The SYS command jumps into ANIX (at the warmstart entry point). SYS should be used to quit the assembler. The "RUN 300" (warmstart) and "RUN 303" (coldstart) commands can be used to restart LISA v3.2 from the ANIX "=" prompt. THE ASSEMBLER While the current editor is actually inferior to the LISA v2.6 editor (it doesn't support the Find, LOB, or Append commands), the assembler is another story. The LISA v3.x assembler is three times faster, contains tons of new features, and LISA v3.x uses a much better tokenizing scheme which reduces the amount of memory required to hold the source file by 25%. If you don't go crazy with comments in your source file, you can easily enter over 3,000 lines of text into the LISA v3.x default source file buffer. LISA v3.x supports several new instructions, assembler directives, and pseudo-opcodes. A list of the new instructions includes: .ME .WE IF1 IF2 EXP NOX NLC CND ADD SUB WHL .MD FZR LCL RLS INP CON SET ANX SBT CHN RVS MSG ZRO Gone are the Sweet-16 instructions (you can use macros to emulate Sweet-16 if you really need these instructions), LET (replaced by SET), DCM (replaced by ANX), ICL (replaced by CHN), ASC (substitute BYT), and ENZ instructions. The 65C02 version of LISA v3.x does not support the Rockwell-only BBS, BBR, SMB, and RMB instructions found in the LISA v2.6 XPO assembler. A couple of instructions behave a little differently. The "=" assembler directive is identical to the SET (LET) directive. In LISA v2.6 the "=" directive was the same as EQU. The HEX pseudo-opcode, although still functional, is converted on input to a BYT pseudo-opcode by the editor. This makes the listing easier to read. PHS and DPH work properly in this version of the assembler. All zero page variables (defined with the EPZ directive) must be declared before they are used; see the description of FZR. Finally, as promised in the LISA v2.6 manual, symbols may only contain alphanumerics, periods, and underscores; and the order of evaluation for expressions has been changed. All expression are evaluated from left to right. Also, many of the LISA v2.6 operators and constant formats have changed; see the section on address expressions for more details. MACROS A macro is a single assembly command used to replace several LISA instructions. A single macro, for example, can replace several 6502 instructions and LISA pseudo-opcodes. In certain circumstances, a macro definition can help you create a program with fewer bugs since the number of bugs in a program is proportional to the number of lines of code. Unfortunately, the overzealous use of macros can actually introduce several new bugs since macros tend to hide several instructions and their possible side effects from the programmer. Macros were included with LISA for two reasons: to make LISA v3.x a more marketable product (few people will purchase an assembler without macros, even if they really have no use for macros) and to ease the task of converting assembly language source listings from other assemblers to LISA. Expert assembly language programmers rarely use macros since they tend to make programs harder to read and less efficient. Macros are defined with the .MD (macro definition) and .ME (macro end) directives. .MD must be followed with a single LISA symbolic name limited to seven characters in length. All of the assembler statements between the MD statement and the .ME statement will be stored in the LISA symbol table and recalled as necessary for the macro definition. Since the macros are stored in the symbol table, avoid placing comments in macro definitions since comments will quickly eat up available memory. An example of a macro definition is: .MD SAVEREGS PHA TXA PHA TYA PHA .ME This macro, when invoked, outputs the five instructions: PHA TXA PHA TYA PHA Since LISA checks the validity of all mnemonics entered into the system, a special character must be used to mark a macro. Currently, all macro calls must be prefaced with a slash character ("/"). For example, a subroutine which uses the previously defined macro to save all the registers is: SUBRTN /SAVEREGS LDX #0 LOOP DEX TXA STA $1000,X TAY STA $2000,Y BNE LOOP /RESTREG ;Complement to SAVREGS RTS The macro lead-in character is user definable. The ASCII code for this character can be changed with the SETUP.LISA program. While almost any character can be used, you should not use an alphanumeric or a period. A macro may have up to ten optional parameters. Currently LISA v3.x only allows address expressions as parameters. String parameters will be allowed in a later version. Parameters for a macro appear in the operand field of the macro invocation separated by commas. The ten parameters are accessed within the macro definition using the symbols "?0", "?1", "?2", I, "?9". The "?0" symbol returns the value of the first parameter, the "?1" symbol returns the value of the second parameter, etc. As an example, consider the macro definition: .MD MOVWORD LDA ?0 STA ?1 LDA ?0+1 STA ?1+1 .ME An invocation of the form: "/MOVWORD LOC1,LOC2" generates the code to copy the 16-bit value at location LOC1 to the two bytes starting at location LOC2. This invocation of the macro would expand into the instruction sequence: LDA LOC1 STA LOC2 LDA LOC1+1 STA LOC2+2 Each occurrence of ?0 is replaced by "LOC1" and each occurrence of ?1 is replaced by "LOC2". Two additional macro parameter values, "? " and "?:GexprH", may be of interest to you. The "? " symbol returns the number of parameters actually present. You can use this token to test for an exact number of parameters. In the previous macro definition, the macro is expecting exactly two parameters. You could rewrite the macro to test for exactly two parameters with the code: .MD MOVWORD .IF ?# <> 2 PAU .EL LDA ?0 STA ?1 LDA ?0+1 STA ?1+1 .FI .ME The ".IF" directive compares the actual number of parameters passed to MOVWORD with two, if the number of parameters is not equal to two, then the assembler encounters the PAU instruction and stops, printing the pause error message. If the number of parameters is exactly equal to two, then the LDA/STA instructions are assembled (also see MSG below). With certain macro definitions, you may want to allow a variable number of parameters. If a variable number of parameters are desired, you will need some method of accessing the individual parameters using a variable index. The "?:GexprH" token can be used to access a parameter using an expression to select the desired parameter. For example, "?:2" selects the third parameter. "?:5" selects the sixth parameter (remember, the first parameter is ?0). Note that these two usages perform the same operations as "?2" and "?5". The real advantage of this form of parameter passing is that the value following the colon can be any expression. If X is a label declared as a value between zero and nine, "?:X" returns the value of the Xth parameter. If X was declared with the SET or "=" pseudo-opcode, the value of X can be changed during program assembly. A parameter of the form "?:GexprH" uses the complete expression following the colon to select the parameter. For example, if the label X is currently equal to zero, the expression "?:X" returlus one. Therefore, if you wish to modify the parameter's value, the "?:" token must appear as the last token in the address expression. E.g., If X=1 and the second parameter is $1000, then "1+?:X" returns $1001 while "?:X+1" returns the value of the third parameter (if it is present). The "?:GexprH" and "? " operands are extremely useful in conjunction with while loops. The while loops can be used to easily process a variable number of parameters within a macro. See the explanation of WHL below. During assembly, LISA v3.x, by default, will expand the macro and list all of the lines which compose the macro. Such lines are prefaced with a plus sign ("+") to denote a macro expansion. To disable macro expansion listing, the NOX (for NO eXpand) can be used. To turn macro expansion back on, the EXP (for EXPand) pseudo-opcode is used. All macros between an NOX directive and a EXP (for EXPand) will not be expanded. While on the subject of macros, LISA v3.x has a couple of built-in macros not found in LISA v2.6. The ADD macro is an ADC instruction which emits a CLC opcode prior to outputting the ADC instruction code. The SUB macro is a SBC instruction which emits a SEC instruction prior to outputting the SBC opcode. Local Labels Consider for a moment the macro definition: .MD INC16 INC ?0 BNE >0 INC ?0+1 ^0: .ME This looks like a very straight-forward macro used to increment a sixteen-bit memory location. Unfortunately, there is a big problem with this macro. Consider the code segment: LDA TSTINC BEQ >0 /INC16 POINTER LDA #0 STA TSTINC ^0: If TSTINC is zero, control will be transferred to the first "^0" label in the file. The first "^0" label encountered will be the "^0" label inside the INC16 macro. Therefore, the program will jump to the LDA 0 instruction rather than past the STA TSTINC instruction. This, of course, can create some very hard to find bugs. To alleviate this problem, LISA v3.x supports a special form of local label: the symbolic local label. Local symbolic labels are allocated and deallocated with the LCL (local) and RLS (release) assembler directives. Whenever "LCL GlabelH" is encountered in the source file during assembly, LISA v3.x "temporarily" forgets that the specified label was already defined. The label is marked as undefined in the symbol table and assembly continues. When "RLS GlabelH" is encountered, the current definition is lost and the original definition is restored. There is a current restriction to LCL/RLS pairs with the same symbolic label: they may not be nested. If a nested LCL is encountered, LISA v3.x terminates the previous local definition before beginning the current one. The INC16 macro definition, recoded to take advantage of symbolic local labels, is: .MD INC16 LCL I16LBL INC ?0 BNE I16LBL INC ?0+1 I16LBL: RLS I16LBL .ME This macro definition will work fine as long as you do not include the /INC16 macro invocation inside another piece of program code which redefines the I16LBL label using LCL and RLS. Should this occur, the value of I16LBL would revert to its original value and an error would be given when the next RLS pseudo-opcode was encountered. The following is an example of such a situation: I16LBL: EQU 5 LCL I16LBL I16LBL EQU 4 /INC16 WORDVAL BYT I16LBL ;Uses the value 5 rather than 4. RLS I16LBL ;Generates an error. An error is generated because the local label I16LBL is automatically released by the occurrence of the LCL pseudo-op in the INC16 macro, then the RLS pseudo-opcode in the macro releases the label to its original value. The RLS pseudo-op in this program segment attempts to release a label which isn't currently a local label, hence an error is generated. In practice, this situation rarely occurs, but you should look out for it. Note that you are not restricted to defining local labels within macros, you can also define local labels within your main program code. This lets you define blocks of local labels in a fashion similar to the Pascal or "C" programming languages. Keep in mind, you are limited to one level of nested local labels. Conditional Assembly and the While Loop LISA v3.x supports nested ".IF" statements. This lets you include ".IF" directives within macros without having to worry about the macro invocation appearing inside an ".IF" directive somewhere else. Nested ".IFs" are also useful within the body of your programs. The severe limitation of one level ".IF" statements in LISA v2.x has been removed from LISA v3.x. LISA v3.x also supports two new conditional assembly instructions: IF1 and IF2. The code between "IF1" and the corresponding .EL or .FI is assduring pass two. WARNING! Do not include any instructions which modify the program counter (i.e., that generate object code) inside these directives. Doing so will generate a "phase error". A phase error occurs when more or less bytes of code are generated in one pass of an assembly than in the other pass. For example, consider: ORG $800 IF2 BYT 0,1,2,3,4,5,6,7 .FI LABEL JMP LABEL The BYT pseudo opcode is ignored during pass one since it is surrounded by the "IF2" and ".FI" pseudo-opcodes. Since, during pass one the BYT statement is totally ignored, LISA thinks that the LABEL symbol is encountered at address $800. Without the "IF2/.FI" directives, LISA would encounter eight bytes of data before the occurrence of "LABEL" and would have assigned the value $808 to it. Since the "IF2" pseudo-op is present, the JMP instruction assembles into a JMP $800 instruction rather than a JMP $808 instruction. The assembler will print an error message if a phase error occurs during assembly. The WHL assembler directive can be used to set up loops within the assembling code. This feature can be used to repeat certain sections of code or to process macro parameters when you have an unknown number of parameters. The WHL directive expects a single address expression in the operand field. The code between the WHL and the corresponding .WE (While End) is repeatedly assembled until the address expression after the WHL directive is zero. A short macro which generates a split address list for up to ten addresses is: .MD SPLITADR X=0 WHL X < ?# BYT ?:X X=X+1 .WE ; X=0 WHL X < ?# HBY ?:X X=X+1 .WE .ME This macro generates a table of bytes for each parameter present, and then it generates a table of high-bytes for each parameter present. WARNING! The WHL loop can get you into a lot of trouble if you're not careful. In particular, you can generate some nasty infinite loops if you omit code which tweaks the address expression following the WHL mnemonic or if the expression never evaluates to false. Such a situation will cause the system to hang during assembly. If an assembly appears to take an abnormally long time, perhaps you've created an infinite WHL loop somewhere. The WHL directive should be used only by expert programmers with extreme caution. Normally, LISA v3.x lists the code between .IF, IF1, or IF2 and the .EL or .FI regardless of whether the code was assembled or not. Likewise, when the WHL expression evaluates to zero, LISA v3.x will list the code between the WHL and the .WE even though it isn't assembled. To shorten the assembly listing down a little bit, the NLC (No List Conditionals) and CND (list CoNDitionals) assembler directives can be used. These directives (respectively) disable and enable the listing of unassembled code within the .IF, IF1, IF2, and WHL conditional directives. NEW STRING DIRECTIVES LISA v3.x supports two new string directives: RVS and ZRO. Both directives must be followed by a single string. These directives handle special requirements of certain programs. The RVS pseudo-opcode emits the characters in the string in the reverse order that they appear within the string. This directive is useful if you want to access the data within a string using a loop counter which decrements to zero (or to minus one). Simply load an index register with the length of the string minus one and index into the string, this will access the first character of the string following the RVS pseudo-op: RVS "ABC" ..generates the code $C3, $C2, $C1 (C, B, A). The ZRO pseudo-opcode emits the specified string followed by a zero byte. This directive is quite useful when working with zero terminated strings. MISC. ASSEMBLER DIRECTIVES The CON (constant) directive is currently a synonym for EQU. However, in future versions of LISA v3.x, a label defined with the CON directive will only be allowed within immediate expressions or within an address expression for a pseudo-opcode. You should not use CON to define variable names. The intent of the CON directive is to help make your programs more readable. The CON directive instantly identifies a label as a constant, not a variable in memory or the entry point of some subroutine. By using CON for constants and EPZ/EQU for variables and entry points, you can make your programs much easier to read and understand. Most 6502 assembly language programmers define all of their zero page labels at the beginning of the program before they are encountered within an address expression. This geography is considered good programming style. Although there is probably no reason why you cannot always define a zero page label (using the EPZ pseudo-opcode) before the label is encountered within a program, a special pseudo-opcode, FZR, is included in LISA v3.x's repertoire to allow you to state that a symbol is zero page without defining its value before it is used. This pseudo-opcode is especially useful when converting certain LISA v2.6 programs to LISA v3.x. The FZR (Forward Zero page Reference) assembler directive is used to define a zero page label without assigning a value to it. LISA v3.x is a two-pass assembler (LISA v2.6 was a three pass assembler) and it assumes that undefined labels are absolute. If a zero page label is defined with the EPZ directive after that label was already encountered in the source file, LISA v3.x will give you an error. To correct this problem, either move the zero page definition to the beginning of the source file (if practical or possible) or use the FZR assembler directive to define the label as zero page before the label is used. The syntax for the FZR directive is: FZR