Navigation
SB-Assembler Control
Data
Conditional
List
Alphabetical
|
Directives
A directive is a command to the assembler and thus it is not an instruction for the target microprocessor.
Directives are often called pseudo instructions because they appear in the instruction field of the source line.
Directives are always placed in the instruction field on program lines and may be followed by one or more operands.
SB-Assembler directives always begin with a dot which is followed by two or more characters.
This makes it easier to distinguish directives from mnemonics and avoids name clashes with future mnemonics on new Crosses.
Some directives must or may be followed by one or more parameters.
Those parameters may not contain space or TAB characters because that will signal the end of the parameter.
Only literal strings may contain spaces as long as they are properly enclosed in delimiters.
Document Conventions
I use some common document conventions in the following description of the directives.
Text printed in Italic font should not be typed literally but indicates the type of the expected parameter.
For example filename should be replaced by the real file name, possibly including drive and path.
In Version 2 of the SB-Assembler file names and paths are restricted to the normal MS-DOS 8.3 file names.
For Version 3 of the SB-Assembler file and path names must follow the rules of your operating system.
Sometimes you can use one of several options. These options are separated by a pipe ¦ symbol in this document. For example on¦off means you may either use on or off. Notice that on and off are not printed in Italic, so they should be typed literally.
Strings should be delimited.
This means that a legal delimiting character must be used to enclose the string.
All characters in between the two delimiters are treated literally, spaces and upper and lower case are retained.
Expressions can be composed of constant values in any of the available radixes, labels and expressions. These expressions always result in a 32 bit value. The directive decides how many of the 32 bits are actually used. Boundary Sync
Version 3 of the SB-Assembler is better prepared for processors which use multi byte instructions.
The problem with multi byte instructions is that the target byte pointer will grow faster than the instruction pointer.
For normal program instructions this is not really a problem because each instruction will generate the same amount of bytes.
A boundary sync, when executed by the directive, is always executed before the actual function of the directive kicks in. With the description of each directive I will metion whether it performs a boundary sync or not. In version 2 of the SB-Assembler there was no such thing as a boundary sync. This caused many problems when using multi-byte processors. Therefore I have redesigned the behaviour of the SB-Assembler in version 3. .AS Ascii StringSyntax: .AS [-]string¦#expression[,string¦#expression[,...]] See also: .AT .AZ .DA .DB .DL .DR .DW .HS .RF .TS Function: The .AS directive converts ASCII strings and/or expressions to hexadecimal bytes. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
The string parameter is a delimited string.
The expression should evaluate to a positive number that is less than 256.
The parameter can consist of more than one string or expression, which all should be separated from each other by commas.
Examples: 0000-54 65 73 74 .AS /Test/ 0004-D4 E5 F3 F4 .AS -/Test/ 0008-0D 54 65 73 000C-74 0A 0D .AS #$0D,/Test/,#$0A,#$0D 000F-8D D4 E5 F3 0013-F4 8A 8D .AS -#$0D,/Test/,#$0A,#$0D 0016-54 65 73 74 001A-0D 54 65 73 001E-74 .AS /Test/,#$0D,\Test\ .AT Ascii string TerminatedSyntax: .AT [-]string¦#expression[,string¦#expression[,...]] See also: .AS .AZ .DA .DB .DL .DR .DW .HS .RF .TS Function: The .AT directive converts ASCII strings and/or expressions to hexadecimal bytes. The last generated byte will have an inverted bit b7 to signal the end of the string. This can be used to signal the end of a character processing loop. Apart from this minor difference the .AT directive works exactly the same as the .AS directive. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
The string parameter is a delimited string.
The expression should evaluate to a positive number that is less than 256.
The parameter can consist of more than one string or expression, which all should be separated from each other by commas.
Examples: 0000-54 65 73 F4 .AT /Test/ 0004-D4 E5 F3 74 .AT -/Test/ 0008-0D 54 65 73 000C-74 0A 8D .AT #$0D,/Test/,#$0A,#$0D 000F-8D D4 E5 F3 0013-F4 8A 0D .AT -#$0D,/Test/,#$0A,#$0D 0016-54 65 73 74 001A-0D 54 65 73 001E-F4 .AT /Test/,#$0D,\Test\ .AZ Ascii string terminated by ZeroSyntax: .AZ [-]string¦#expression[,string¦#expression[,...]] See also: .AS .AT .DA .DB .DL .DR .DW .HS .RF .TS Function: The .AZ directive converts ASCII strings and/or expressions to hexadecimal bytes. The last generated byte will be followed by a byte with the value of $00 to signal the end of the string. This can be used to signal the end of a character processing loop. Apart from this minor difference the .AZ directive works exactly the same as the .AS directive. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
The string parameter is a delimited string.
The expression should evaluate to a positive number that is less than 256.
The parameter can consist of more than one string or expression, which all should be separated from each other by commas.
Examples: 0000-54 65 73 74 0004-00 .AZ /Test/ 0005-D4 E5 F3 F4 000A-00 .AZ -/Test/ 000B-0D 54 65 73 000F-74 0A 0D 00 .AZ #$0D,/Test/,#$0A,#$0D 0013-8D D4 E5 F3 0017-F4 8A 8D 00 .AZ -#$0D,/Test/,#$0A,#$0D 001B-54 65 73 74 001F-0D 54 65 73 0023-74 00 .AZ /Test/,#$0D,\Test\ .BI Binary IncludeSyntax: .BI filename.ext[,format] Function: The .BI directive copies the contents of a binary file to the current target file from the current location. This enables you to include for example sampled speech, HTML pages, or images in your programs. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation: The filename may contain a path name, and a drive letter for Microsoft based operating systems. If no path is given the current directory should hold the file to be included. No default extension is assumed, so if the file has an extension it should be included in the filename.
Binary include files can not be nested.
Binary include files can't open other include files by themselves, but it is also not allowed to include a binary file from within a normal include file.
If no format is specified the binary include file will be treated as a plain binary file. All bytes are copied as they appear in the file. No attempt is made by the SB-Assembler to figure out in what format the file originally was written! The format parameter can have any of the following names:
For Version 2 of the SB-Assemlber only the first character of the format name is sufficient to select a particular file format.
All other characters on the program line following that character will be ignored and treated as comments.
Please Note for Version 2: That the Motorola format is called MOT here, and not S19, S28 or S37 like it is with the .TF directive. Using S19, S28 or S37 as parameter will result in a *** Binary format error messages if you feed a Motorola formatted file because the SB-Assembler is expecting a Signetics formatted file (which starts with an S).
Address fields of all formatted file formats are ignored.
Segment records in Intel HEX files only carry address information and will be ignored too.
All data bytes are copied in the order of appearance in the binary include file.
Formatted files don't have to be terminated with the end of file record. No error is given if the end of file record is missing.
Formatted files may contain remark lines.
An empty line or a line beginning with ! ; * " or ' will be treated as a remark line.
If a label is present in the label field of the source line containing the .BI directive it will be assigned the address of the first byte of the binary include file. A program line that contains a .BI directive can be listed if the list option is switched on. The generated bytes are never listed though. Examples: 0000- BITMAP .BI SAMPLE,INT .BS Block SkipSyntax: .BS expression1[,expression2] See also: .DU .ED .EP .NO .OR .PH .RF .SM Function:
With .BS you can skip a block of memory.
The number of bytes to be skipped is determined by expression1.
The skipped bytes can be filled with the 8 bits value of expression2.
Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation: Expression1 may not contain forward referenced labels, otherwise a fatal "Undefined label error" will be reported.
The value of expression1 can range from 0 to $FFFFFFFF, although it is not very likely that you're going to use the maximum value.
If the value is 0 no bytes are skipped at all.
The .BS directive is often used to declare RAM buffers and RAM variables. Normally it is not very useful to declare buffers in ROM memory because ROM values can not be changed afterwards anyway.
Operation of the .BS directive differs a little between formatted and unformatted target files.
The list file will only contain the first address of the skipped memory block. The filled bytes are not listed in the list file. Examples: 0000- .OR $0000 Define RAM memory 0000- .DU but don't produce any code 0000- PNTR .BS 2 Define a 2 bytes pointer 0002- CNTR .BS 2 Define a 2 bytes counter 0004- TEMP .BS 1 Define a 1 byte temp location 0005- FLAGS .BS 1 Define a flags byte 0006- KEYIN .BS 1 Last pressed key (1 byte) 0007- DSPPNT .BS 1 Display buffer pntr (1 byte) 0008- DSPBUF .BS 6 Define a 6 byte display buffer 000E- .ED End of dummy block 8000- .OR $8000 Begin of the program in ROM 8000- .BS $100,$FF Skip part of ROM memory 8100- ; and fill it with $FF Please note that no code is generated in the .DUmmy block. Only the addresses are assigned to the appropriate labels. .CH CHain fileSyntax: .CH filename[.ext] Function: With the .CH directive you can CHain include files together without going back to the main source file first. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: The .CHain directive works exactly the same as the .INclude directive if it's encountered in the main source file. It remembers where we are in the main source file, opens a new source file and starts assembling from the beginning of that new source file. If the new source file is finished, it is closed and we continue where we left off in the main source file. But if the .CHain directive is encountered inside an include file it will close the current include file immediately, opens the new .CHained file and starts assembling from the top of this new file. This effectively chains the new include file to the previous include file without going back to the main source file first. Please note that all lines that follow the .CH directive in an include file are ignored by the SB-Assembler. They are not even treated as comment lines because they will never be listed in list files. The program line containing .CH, when encountered inside an include file, is always the last line of the file that is interpreted and listed in the list file.
On Version 2 of the SB-Assembler the .CH directive must be followed by a filename, which may be preceded by a drive letter and a path name according to the normal MS-DOS rules.
With Version 3 of the SB-Assembler the filename may be preceded by a path name (and drive letter on Microsoft operating systems) according to the rules of the operatings ystem in use.
Examples:
.IN DECLARE Called from the main source file
LABEL .EQ 10 Imaginary part of the .INclude file
:
:
:
ANOTHER .EQ $FF
.CH C:\LIB\MACRO.LIB Chain to the file MACRO.LIB
MACRO .MA First line of the chained source file
:
:
:
.EM Last line of the chained source file
NOP We're back in the main source file
.CO COmmentSyntax: .CO Function:
The .CO directive starts a comment block which can be filled with any remarks.
It may also be used to temporarily comment out part of your code during debugging.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: The part of your source file that should be ignored by the SB-Assembler can be enclosed between the opening directive .CO and the closing directive .EC. All lines in between will be treated as if they all start with a comment prefix like ; * or #. They will be listed in list files, but the syntax is not checked nor will any code be generated.
It is possible to define a label together with the .CO directive on the same source line.
All text following the .CO directive on the same source line will be ignored.
The .COmment mode will automatically be terminated if the physical end of the source file is reached. Examples:
.CO Beginning of the comment block
Anything is allowed in this comment block.
You don't have to start the line with ; * or #
; Although it won't hurt if you do.
.CO It is not possible to nest comment
blocks. The last .CO directive is treated as a comment itself.
The next .EC directive will end the complete .COmment mode.
LD A,B Is not assembled
.DO A>B Has no effect
.IN FILE Just skipped
.EN Not even this is interpreted
.EC End of comment block, at last.
.CP Com port ParametersSyntax: .CP comport,baudrate,parity,databits,stopbits See also: .EF .LF .LI .SF .TF .TW Function: The .CP directive sets the communication parameters of the selected serial COM port. This is useful if you intend to send the generated object file directly to a programmer or EPROM simulator connected to the COM port. For now this directive only works on Version 2 of the SB-Assembler. Version 3 doesn't know this directive yet because of the differences in the operating systems it can run on. Explanation: I have added this directive to be able to set the communication parameters of the serial port in case you intend to send the target file directly to a device connected to a COM port. All parameters are to be entered in the order indicated under the heading "Syntax".
comport
baudrate
110
parity
databits
stopbits
Please note that the COM port parameters are only set during pass 2 of the assembly process. Examples:
.CP 1,9600,N,8,1 Set COM1 to 9600 baud, No parity,
; 8 data bits and 1 stop bit.
.CR CRoss Overlay loadSyntax: .CR filename[.ext] Function: The .CR directive loads a Cross Overlay into memory. See also: Cross Overlays Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: This is one of the most powerful directives of the SB-Assembler. It loads a Cross Overlay into memory. This allows the SB-Assembler to assemble programs for almost any type of processor. It can even be used more than once in one program to switch between different Cross Overlays in one assembly run to create a program for different processors at same the time.
In Version 2 of the SB-Assembler the .CR directive must be followed by a filename which may be preceded by a drive letter and/or path name.
In Version 3 of the SB-Assembler the .CR directive must be followed by the cross overlay name.
Cross overlays are allways stored in the sbapack directive of the SB-Assembler package.
All cross overlay files have a name like cr*.py, where * is the actual name of the cross overlay to be used by the .CR directive.
So you only specify this * part as cross name behind the .CR directive, like for example .CR Z80 (this will use the file crz80.py).
As soon as the Cross Overlay is loaded into memory it will be initialized.
This means that some default values are set, like the endian model (the order in which multiple byte values are stored in memory).
Also Cross Overlay specific settings are set to their default value, e.g. the .DP value for the 6809 Cross Overlay will be reset to $00.
In Version 3 of the SB-Assembler a previously loaded cross overlay is allowed to clean up first, before the new overlay is loaded. This allows the system to finish pending operations. One example is the AVR assembler, which is able to write bytes to the otherwise word sized memory. Should the last write to code memory end up on an odd location, the clean-up would add a padding byte to make it end on an even location.
It is even possible to have more than one Cross Overlay loaded during one assembly run.
This enables you to create programs for mixed processor types.
Also note that the SB-Assembler doesn't know any mnemonics of any processor type until a Cross Overlay is loaded into memory. The .CR is best used before any code is generated by the assembler because the Cross Overlay determines the endian model, which is the order in which multiple byte values are stored in memory. Examples:
.CR Z80 Load the Z80 Cross Overlay
.CR 6502 Load the 6502 Cross Overlay
The .CR directive has a hidden feature in Version 3 of the SB-Assembler.
This hidden debug feature is enabled when the .CRD directive is used instead of the normal .CR directive.
Normally you would need this hidden feature when you are writing your own cross overlays.
If you don't enable the debug function the assembler will only complain that it can't load the overlay when you make a programming error, whithout telling you where the error occurred.
.DA DAtaSyntax: .DA [#¦/¦=¦\]expression[,[#¦/¦=¦\]expression[,...]] See also: .AS .AT .AZ .DB .DL .DR .DW .HS .RF .TS Function: The .DA directive is used to enter bytes and words of data into the target code. The data is entered as one or more expressions, separated from each other by commas. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
Every expression following the .DA directive will be evaluated and the lower 16 bit value of the result is stored in the target file.
The order in which the bytes are stored depends on the loaded Cross Overlay.
Some processors prefer to have the lowest byte of pair stored first, others want the highest byte stored first.
So please refer to the description of the particular Cross Overlay to see in what order the bytes are stored.
The .DA directive can also be used to store single bytes in the target file. To store single bytes the expression must be preceded by one of the symbols:
The lowest 16 bits are stored if none of these prefixes is used. Data bytes and words can be mixed together on the same .DA directive line. Multiple expressions should be separated by commas. Important: Be sure to load the appropriate Cross Overlay before using the .DA directive! Otherwise the first data words may be saved in the wrong order (wrong endian model). I have included the .DR directive for those cases where you need the opposite endian model. Examples: 0000-09 53 7B 23 0004-61 E1 .DA #%1001,#@123,#123,#$123,#'a',#"a" 0006-78 .DA #$12345678 0007-56 .DA /$12345678 0008-34 .DA =$12345678 0009-12 .DA \$12345678 000A-34 12 .DA $1234 Notice the byte order 000C-7C .DA #5+$80-%1001 Some math can be done too 000D-34 12 56 .DA $1234,#$56 Mixed words and bytes .DB Define ByteSyntax: .DB [expression | string[,[expression | string[,...]] See also: .AS .AT .AZ .DA .DL .DR .DW .HS .RF .TS Function:
The .DB directive is used to enter bytes only and is meant to add some compatibility with other assemblers in the market.
Operation of the .DB directive is almost the same as the DB directive found in most assemblers.
Personally I prefer the use of the more powerful .DA directive.
Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation: Every expression following the .DB directive will be evaluated and only the lower 8 bit value of each result is stored in the target file. If you need other bytes of the 32-bit result you can divide the result by $100, $10000 or $1000000.
Instead of an expression you may also enter a string of characters.
Strings must be surrounded by a pair of single or double quotes.
The string may not be empty and must be terminated with the same type of quote as it was opened.
The opening quote may not be present in the string itself because that would terminate the string prematurely.
Multiple expressions or strings in the operand field must be separated by commas. I have also included the .DW directive to improve the compatibility of word definitions with other assemblers. Examples: 0000-78 .DB $12345678 Only the LSB is used 0001-7C .DB 5+$80-%1001 Complex expression 0002-12 34 .DB $12,$34 Multiple expressions 0004-54 65 73 74 .DB "Test" Only a string 0008-54 65 73 74 000C-0D 0A .DB 'Test',$0D,$0A A string followed by 2 bytes .DL Data Long wordsSyntax: .DL [#¦/¦=¦\]expression[,[#¦/¦=¦\]expression[,...]] See also: .AS .AT .AZ .DA .DB .DR .DW .HS .RF .TS Function: The .DL directive is used to enter words and long words of data in the target code. The data is entered as one or more expressions, separated by commas. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
Every expression following the .DL directive will be evaluated and a 16 bit word or the entire 32 bit long word is stored in the target file.
The order in which the bytes are stored depends on the loaded Cross Overlay.
Some processors prefer to have the lowest byte stored first, others want the highest byte stored first.
So please refer to the description of the particular Cross Overlay to see in what order the bytes are stored.
The .DL directive is usually used to store long words of data, containing 4 bytes each. It can also be used to store words containing 2 bytes each. To store words the expression must be preceded by one of the symbols:
The long word of 4 bytes is stored if none of these prefixes is used. Long words and words can be mixed together in the same .DL directive. Multiple expressions should be separated by commas. Important: Be sure to load the appropriate Cross Overlay before using the .DL directive! Otherwise the first data words may be saved in the wrong order (wrong endian model). Unlike the .DA directive the .DL directive has no reverse endian model equivalent. If you want to store long words in the reverse order you'll have to save the bytes or words separately by using the .DA or .DR directives. Examples: 0000-78 56 34 12 .DL $12345678 0004-78 56 .DL #$12345678 0006-56 34 .DL /$12345678 0008-34 12 .DL =$12345678 000A-12 00 .DL \$12345678 000C-78 56 34 12 0010-78 56 .DL $12345678,#$12345678 .DO DO if condition is trueSyntax: .DO expression Function: The .DO directive is one of the 3 directives used for conditional assembly. It can be used to include or exclude parts of the source code from the assembly processes depending on a test condition. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation: If the expression evaluates to true (if its value is not 0) all following source lines will be assembled normally. If the expression evaluates to false (if its value is 0) the following source lines will not be assembled until the next .EL or .FI directive.
The .FI directive will end the conditional block that was started by the .DO directive, regardless of whether the expression evaluated to true or false.
The .DO .EL and .FI directives can be compared with IF, ELSE and ENDIF in other languages. Remember that the conditional directives control the assembler and not the target processor! They can not be used to let the target system compare values or make other decisions. The target system is unaware of the conditions used during assembly. In fact, only the lines which were surrounded by a true condition will end up in the target file. The target system will never see lines embedded in a false condition. The expression must evaluate completely and may not contain any forward referenced labels. The .DO directive insists on knowing the condition and that is not possible if one of the labels in an expression is not defined yet.
Conditional assembly can be nested.
This means that a .DO .FI block may contain other .DO .FI blocks.
This nesting may go on, up to 255 levels deep.
If that should not be enough for your application I suggest you get your head examined.
The listing of conditionally excluded source lines can be controlled with the .LI directive.
If the .LI CON mode is selected all source lines are listed, regardless of the condition.
Lines that are not assembled are marked with the word SKIP in the line number column.
With Version 3 of the SB-Assembler the letter 'S' is prefixed in front of the line numbers.
The syntax of skipped lines due to a false condition is not checked.
During a false condition the assembler will only look for .DO, .EL and .FI direcitves in the instruction field.
Examples:
.CR Z80 Load the Z80 Cross Overlay
.DO VALUE1>VALUE2
; These lines are assembled if
; VALUE1 is greater than VALUE 2
NOP
.EL Reverse condition
; These lines are not assembled
; if VALUE1 is greater than
; VALUE2
NOP
.FI End of conditional block
.DO VALUE1>VALUE2
.DO ?=0
; Condition nested 2 levels deep
; These lines are assembled if
; VALUE1 is greater than VALUE2
; and if we are in pass 1 of the
; assembly process (?)
.FI End of 2nd condition (pass 1)
; These lines are assembled if
; VALUE1 is greater than VALUE2,
; regardless of the pass we're in.
.FI First conditional is ended
.DO 0 Condition is never true!
; This line will never be
; assembled
.DO 1 This nested .DO is not evaluated
; because the previous .DO is always
; false.
; This line is never assembled
; The value of the expression
; doesn't matter for the .DO
; is not evaluated anyway.
.FI Nested .DO block ended
; This line is still not assembled
.FI Closing outer .DO block
; This line is assembled again
; You can invert the condition using .EL as often as you like.
.DO 1 Condition is true!
NOP This line is assembled
.EL Reverse condition to false!
NOP This line is not assembled
.EL Reverse condition to true again!
NOP This line is assembled again
.FI End of conditonal assembly
.DR Data ReverseSyntax: .DR [#¦/¦=¦\]expression[,[#¦/¦=¦\]expression[,...]] See also: .AS .AT .AZ .DA .DB .DL .DW .HS .RF .TS Function:
The .DR directive is an alternative tool to enter bytes and words of data in the target code.
The data is entered as one or more expressions, separated by commas.
Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
Every expression following the .DR directive will be evaluated and the lower 16 bit value of the result is stored in the target file.
The order in which the bytes of a pair are stored depends on the loaded Cross Overlay.
The order is opposite to the order in which the .DA directive would store the bytes of a 16 bit value.
Therefore the order also depends on the loaded Cross Overlay.
The .DR directive can also be used to store single bytes in the target file. To store single bytes the expression must be preceded by one of the symbols:
Please note that there is no difference with the .DA directive when it comes to handling single bytes. Data bytes and words can be mixed together in the same .DR directive. Multiple expressions should be separated by commas. Important: Be sure to load the appropriate Cross Overlay before using the .DR directive! Otherwise the first data words may be saved in the wrong order (wrong endian model). Examples: 0000-09 53 7B 23 0004-61 E1 .DR #%1001,#@123,#123,#$123,#'a',#"a" 0006-78 .DR #$12345678 0007-56 .DR /$12345678 0008-34 .DR =$12345678 0009-12 .DR \$12345678 000A-12 34 .DR $1234 Notice the byte order 000C-7C .DR #5+$80-%1001 000D-12 34 56 .DR $1234,#$56 Mixed words and bytes .DU DUmmy modeSyntax: .DU [expression] See also: .BS .ED .EP .NO .OR .PH .RF .SM Function:
The .DU directive is mainly used for defining RAM memory locations.
Only the location is important while defining Labels in RAM area.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: Code generated after the .DU directive is simply discarded. No code is saved to the target file what so ever. For the rest nothing has changed in the assembly process. Labels are assigned and addresses are counted as if the code really was saved. Warning: Use the .DU directive with extreme caution. Wrong use of the .DU directive can create a program that will never work. The SB-Assembler won't warn you if you use the .DU directive in the wrong way. The dummy block that is started by the .DU directive ends at the next .ED directive, or when a new dummy block is started. Also the .OR directive will end the current dummy block. However the .NO directive will not end the dummy block! Everything on the source line following the .DU directive will be treated as comments.
Please note that the target address after .ED will be exactly the same as the target address at the time the .DU directive was given.
Even though the current program counter has increased.
Therefore the program counter and target address won't be in sync anymore.
The dummy mode can span across multiple include files.
As from software version 2.07 you may also specify the starting address of the dummy block by using the optional expression.
Effectively this combines a line with the .OR directive and a line with the .DU directive.
Examples:
.OR $8000 Start defining RAM area
.DU But don't save the code anywhere
COUNTER .BS 2 Define a 2 byte location
POINTER .BS 2 Define another 2 byte location
FLAG .BS 1 Define a single byte location
BUFFER .BS 10 Define a 10 byte long buffer
VALUE .BS 2 Define a 2 byte location
.ED End of RAM definition
.OR $0000 The real program starts here
As from software version 2.07 this example may also be written as:
.DU $8000 Start defining RAM area
COUNTER .BS 2 Define a 2 byte location
POINTER .BS 2 Define another 2 byte location
FLAG .BS 1 Define a single byte location
BUFFER .BS 10 Define a 10 byte long buffer
VALUE .BS 2 Define a 2 byte location
.ED End of RAM definition
.OR $0000 The real program starts here
Version 3 of the SB-Assembler has a more sophisticated way of performing RAM declareations, using the .SM directive.
Therefore I recommend to use the .SM directive instead of the error prone .DU directive.
The .DU directive will still work though, for compatibility reasons.
.DW Define WordSyntax: .DW [expression[,[expression[,...]] See also: .AS .AT .AZ .DA .DB .DL .DR .HS .RF .TS Function:
The .DW directive is used to enter words only and is meant to add some compatibility with other assemblers in the market.
Operation of the .DW directive is almost the same as the DW directive found in most assemblers.
Personally I prefer the use of the more powerful .DA directive.
Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
Every expression following the .DW directive will be evaluated and only the lower 16 bit value of the result is stored in the target file.
The order in which the bytes are stored depends on the loaded Cross Overlay.
Some processors prefer to have the lowest byte of a pair stored first, others want the highest byte stored first.
So please refer to the description of the particular Cross Overlay to see in what order the bytes are stored.
Multiple expressions should be separated by commas. Important: Be sure to load the appropriate Cross Overlay before using the .DW directive! Otherwise the first data words may be saved in the wrong order (wrong endian model). I have included the .DB directive to improve the compatibility of byte definitions with other assemblers too. Examples: 0000-34 12 .DW $1234 Notice the byte order 0002-7C 00 .DW 5+$80-%1001 A more complex expression 0004-34 12 78 56 .DW $1234,$5678 Multiple expressions .EB Error BellSyntax: .EB on¦off Function: With this directive you can turn the Error Bell on or off. The Error Bell is the beep that is generated every time the SB-Assembler stumbles over an error in your source code. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: Per default the Error Bell option is switched on, which sounds a beep for every error in your source code. Not all operating systems support the Error Bell. So there's no guarantee that the Error Bell is sounded even if the option is switched on. Examples:
.EB ON Switch Error Bell option on
.EB OFF Switch Error Bell option off
.EC End CommentSyntax: .EC Function: This directive ends the comment block that was started by the .CO directive. Provided that the label field of the source line is empty and the .EC directive appears in the instruction field. Otherwise the comment block is not ended. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: The label field should be empty and the .EC directive must appear in the instruction field to make it effective. Otherwise the comment block won't be terminated. This means that at least one space or TAB character must precede the .EC directive. No other characters are allowed before the .EC directive, otherwise it will simply be part of the comment lines. Everything on the same source line that follows the .EC directive will still be treated as comment. An error message will be reported if the comment block was not activated. The comment mode will also be terminated automatically at the end of the an include file. In version 3 a warning is given if an orphaned .EC directive is found. An orphaned .EC directive is one which doesn't have a previous .CO directive. .ED End Dummy modeSyntax: .ED See also: .BS .DU .EP .NO .OR .PH .RF .SM Function: The .ED directive will end the dummy mode that was started by the .DU directive. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: No error is reported if the dummy mode was not started when the .ED directive is encountered. In that case the .ED directive will simply be ignored. Everything on the source line following the .ED directive will be treated as comment. The SB-Assembler will not warn you if the program ends when no .ED directive ended an active dummy mode. The dummy mode can span across multiple include files. .EF Error FileSyntax: .EF filename[.ext] See also: .CP .LF .LI .SF .TF .TW Function: The .EF directive allows you to send all reported assembling errors to a specific file or device. Opening this file will allow you to quickly locate the locations in your source files which contain the errors. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The SB-Assembler will send all reported errors to the file that was opened with the .EF directive.
Apart from this the errors will still be sent to the normal list file and screen if the listing is switched on.
Errors will always be displayed on the screen and logged in an opened error file, regardless of the selected list options.
If the error file does not exist yet it will be created. If a file with the same name already exists in the given path it will be overwritten without prior notice.
If you want to make use of the .EF directive you should place that directive preferably among the first few lines of the main source file, before potential errors may occur.
Otherwise some errors may not be logged.
As usual, the filename may be preceded by a path name.
On Microsoft systems a drive letter may also preceed the path name.
If no extension .ext is given the SB-Assembler assumes the default extension for error files, which is .err.
Examples:
.EF errors The errors are sent to the
; file ERRORS.ERR
.EF LPT1: The errors are sent to the
; first printer (mind the : )
.EF C:\TEXT\ERRORS.PRN The errors are sent to
; the file ERRORS.PRN on
; drive C:\TEXT
Please note that some operating systems are case sensitive when it comes to path names and file names. .EJ EJectSyntax: .EJ Function:
In Version 2 of the SB-Assembler the .EJ directive sends a Form Feed character to the list file.
When sending the listing to the printer this will cause ejecting of the current page.
At the same time the line counter for the list file is reset to 0 and the page number is incremented.
Version 3 doesn't have any of the page formatting directives because they have become fairly obsolete nowadays. Therefore the .EJ directive is also scrapped from the list of directives. Explanation: This directive acts like the .PG directive. The only difference is that .EJ will not print a new page head above the new page like .PG does. The source line containing the .EJ directive will not be listed in the list file. Everything following .EJ on the source line will be treated as comment. If the listing is set to Single Sheet mode by the .TI directive the assembly process will come to a halt and a message is put on the screen requesting you to insert a new page. Hit any key when a new page is inserted to continue the assembly process. .EL ELse conditionSyntax: .EL Function: The .EL directive is used together with the conditional assembly directives .DO and .FI. The .EL directive will invert the current condition. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation: The .EL directive inverts the current test condition. If the current condition was true it will become false. And if it was false it will become true. The following program lines are only assembled if the condition is true until the next .EL directive or until the .FI directive is encountered. The .EL directive may be used as often as you want to invert the condition between the .DO and .FI directives. The condition is inverted every time the .EL directive is used. The label field of the source line on which the .EL directive is used must be empty. So it's not possible to declare a label on a source line that contains the .EL directive. Examples:
.DO 1 Condition is always true (<>0)
; These lines are interpreted by
; the SB-Assembler
.EL Reverse condition
; This line is not interpreted
.EL Reverse condition
; This line is again interpreted
.EL Reverse condition
; This line is again not interpreted
.FI End of conditional block
.EM End Macro definitionSyntax: .EM See also: Macros .DO .EL .FI .MA .XM Function:
This directive ends a Macro definition that was started by the .MA directive unconditionally.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The label field of the source line containing the .EM directive should be empty.
It is not possible to define a label on the same line.
In version 3 the user is warned if an orphaned .EM directive is found. An orphaned .EM is one which does not have matching .MA directive. .EN ENdSyntax: .EN Function:
This directive signals the end of the current source file.
The source line containing the .EN directive will be the last line that is assembled of the current source file, regardless of what ever follows it.
The current source file is closed and in case it was an include file the SB-Assembler will continue to process it's parent file as if the include file ended in a natural way.
In version 2 this will always be the main source file because include files can't be nested there.
In version 3 include files can be nested.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The .EN directive can be used to end a source file prematurely.
This could be useful for debugging purposes or if the rest of the source file contains only comments which don't have to be listed in the list file.
If the .EN directive is encountered in the main source file the current pass will end immediately.
If we were still in pass 1 the assembler will start pass 2 of the assembly process.
.EP End PatchSyntax: .EP See also: .BS .DU .ED .NO .OR .PH .RF .SM Function: With the .EP directive the so called patch mode, that was started by the .PH directive, is switched off . Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The .EP directive switches off the so-called patch mode.
In effect this means that the program counter gets the same value as the target pointer again.
A possible label in the label field of the source line still gets the value of the last patch address. Everything on the source line following the .EP directive is ignored and therefore will be treated as comment. Please refer to the .PH directive for more details about the patch mode. In version 3 of the assembler the .PH patch mode is only allowed in code memory. If the .EP directive is found in any of the other memory modes an error is generated. .EQ EQuateSyntax: label .EQ expression label = expression See also: .SE Function: The .EQ directive is used to assign a value other than the default current memory location value to a label. Alternatively the = symbol may be used instead of the .EQ directive. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: The .EQ directive is used to assign a constant value to a label. Per default a new label will get the value of the current memory location. If you want the new label to get a different value than its default value you should use the .EQ directive. The = symbol is equivalent to the .EQ directive and has exactly the same effect.
A label that was assigned using the .EQ directive can be considered a constant value because its value can not be changed anymore in this assembly run.
Please note that the .EQ directive does not generate any code for the target system. It only assigns the expression's value to a label which helps us humans to cope better with meaningless numbers. Forward referenced labels in the expression are not allowed. This means that all labels in the expression should be completely resolved. The SB-Assembler will stop parsing the source line immediately after it has evaluated the expression. Everything following the expression is treated as a comment. This will allow you to let the expression be followed by a second expression to indicate that the label's value is the beginning of multiple addresses. It will have no effect on the value that is assigned to the label though and is only meant for documentary purposes.
Like all labels used with the SB-Assembler, labels declared with the .EQ directive may be redefined, as long as the new definition gives the label the same value as it already had.
This is useful if labels are declared in libraries.
Linking multiple libraries may cause some labels to be redefined.
This is no problem as long as the definition results in the same value every time.
For this redefinition it doesn't matter whether the label gets its value automatically or by using the .EQ directive.
It is even allowed to assign a value to Local labels using the .EQ directive. The SB-Assembler won't protest if you do. But remember that Local labels only "live" until the definition of the next Global label. Legal Examples: 1234- LABEL .EQ $1234 Assign a constant value to LABEL 000D- CR .EQ $0D Assign the Carriage Return to CR 0050- POINTER .EQ $50,$51 Assign the value $50 to POINTER, 0000- ; the rest is treated as comment 1236- NEW .EQ LABEL+2 LABEL is already defined ABCD- ALT = $ABCD = symbol is equivalent to .EQ 123456- BIG .EQ $123456 Number larger than 16-bits 12345678- VERYBIG .EQ $12345678 And even larger (up to 32 bits) Illegal Examples:
TEST .EQ FORWARD Forward referenced!
ERROR .EQ #$0D # prefix not allowed here
.EQ %1001 Label field is empty
MISSING .EQ ; The expression is missing
.ER forced ERrorSyntax: .ER [F|W[,]][errormessage] See also: .DO .EL .FI .CO .EB .EC .EN .ST Function: The .ER directive can force the SB-Assembler to report an error message. Such an error message can either be a normal error or a fatal error. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Example:
You can force an error message to be reported with the use of the .ER directive.
This may be useful if you want to be warned if the program you're writing exceeds a certain memory range, or if a memory page boundary is crossed.
The parameter following the .ER directive is the text of the error message that is to be reported. It is not possible to place comments on the same source line. All text is considered to be the error message, including spaces. Even the case of the characters of the message is retained. The parameter doesn't have to be enclosed in delimiters, like it would have been for other literal strings. If no parameter is given the standard text "User error" is reported.
If the parameter is a single character F or an F followed by a comma a fatal error will be reported.
A fatal error will terminate the assembly process immediately.
In version 3 of the SB-Assembler you may also generate warnings, in stead of the errors. A user generated warning is reported if the first character of the error text is a single W or an W follwed by a comma. Examples:
; Generate a standard non-fatal error
.ER
; Generate a standard fatal error
.ER F
; Generate a custom non-fatal error
.ER *** This is the error message
; Generate a custom fatal error
.ER F,*** This is the error message
; Generate a standard warning (version 3 only)
.ER W
; Generate a custom warning (version 3 only)
.ER W,*** This is the warning message
.FI FInished conditionalSyntax: .FI Function: The .FI directive is used in co-operation with .DO and .EL for conditional assembly. The .FI directive will close a condition that was opened by the last .DO directive. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
The .FI directive will close the condition that was opened by the last .DO directive and at the same time it will decrement the nesting counter.
The label field of the source line containing the .FI directive must be empty. So it's not possible to declare a label on a source line that contains the .FI directive. Examples:
.DO 1 Condition always true (<>0)
; This line is assembled
.EL Reverse condition
; This line will not be assembled
.FI End of conditional assembly
; This line and following lines
; are assembled unconditionally.
.HS Hex StringSyntax: .HS [.]hexbyte[,[.]hexbyte[,.....]] See also: .AS .AT .AZ .DA .DB .DL .DR .DW .RF .TS Function:
The .HS directive accepts a string of hexadecimal encoded bytes.
Each hexadecimal encoded byte must consist of 2 hexadecimal digits.
Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
The Hex String consists of a number of hexadecimal digit pairs.
Every digit pair may be separated from the next pair with a dot.
This dot serves no purpose other than improving the readability for us humans.
Digit pairs belonging to the same byte may not be separated by a dot!
The bytes are saved to the target file in the order of appearance.
All data entered are plain hexadecimal bytes.
No expressions are allowed here.
Examples: 0000-01 23 45 67 0004-89 AB CD EF .HS .01.23.45.67.89.AB.CD.EF 0008-01 23 45 67 000C-89 AB CD EF .HS 0123456789ABCDEF 0010-01 23 45 67 0014-89 AB CD EF .HS 0123.4567.89AB.CDEF .IN INclude source fileSyntax: .IN filename[.ext] Function: The .IN directive allows you to split the complete source text of your program into different modules, which are loaded and interpreted one by one to form the total source of your assembly program. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: Splitting a large job into smaller sub-jobs makes program management and total overview a lot easier. This is also true for creating programs in assembly. In DOS the maximum source file size the SB-Assembler can handle is only limited by your favourite text editor and free memory. The maximum source file size in other operating systems is sheer unlimited. However shorter files, each dedicated to a specific task, are much easier to maintain. The main source file is opened when you start the SB-Assembler. This main source file may open as many include files as you like. Preferably the main source file should only contain some initialization directives like .CR and .OR and all references to the required .INclude files.
The .IN directive requires a filename as parameter.
This filename may be preceded by a path name, and possibly a drive letter for Microsoft systems.
The extension .ext is optional.
If the extension is omitted the default extension .asm is used.
An include file will be closed when the assembler reaches the end of that include file.
Assembly will then continue in the main source file on the line following the line that opened the include file.
With Version 2 of the SB-Assembler it is not possible to nest include files.
This means that you can not open another include file from within an include file.
Line numbers in list files are preceded with an 'I' to indicate that they originate from an include file. Line numbers are reset to 1 every time a new include file is opened. Examples:
.IN declare Include declaration module (extension .asm)
.IN C:\LIB\MACRO.LIB Include Macro library (extesion .lib)
.IN INIT Include initialization module (extension .asm)
.LF List FileSyntax: .LF [filename[.ext][,linelength]] See also: .CP .EF .LI .SF .TF .TW Function:
With the .LF directive you can divert the listing output from the screen to a file or other output device.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: Per default the listing is output to the screen with a maximum line length of 254 characters (Version 3 has nog length limit). This means that longer lines are simply broken down at the right end of the screen and continue on the next line. The .LF directive allows you to send the listing elsewhere. The filename may be preceded by a path name, and a drive letter if you're using a Microsoft operating system. If no extension .ext is given the default extension .lst is used.
An already open list file will be closed when the .LF directive is encountered.
If no filename is given the output will be redirected to the screen again.
If a filename is given behind the .LF directive a new file will be created if the filename does not exist yet. If the filename does already exist its length is reduced to 0, effectively overwriting the existing file irreversible without prior warning.
The filename may be followed by the maximum line length to be used in the listing.
A comma should separate the filename from the linelength expression.
Source lines containing the .LF directive will only be interpreted during pass 2 of the assembly process. Any errors in the parameters will be detected in pass 2. Source lines containing the .LF directive will never be listed in a list file themselves. Please note that you are still able to exclude parts of the program from being sent to the list file by using options of the .LI directive. Examples:
.LF list Send listing to list.lst
.LF C:\ASSEMBLE\TEST.PRN Send listing to TEST.PRN
; on drive C: in directory \ASSEMBLE\
.LF ; Close listing file, output to screen
.LI LIst optionsSyntax: .LI on¦off¦mon¦moff¦con¦coff¦ton¦toff[,on¦off¦mon¦moff¦con¦coff¦ton¦toff[,.....]] See also: .CP .EF .LF .SF .TF .TW Function:
With the .LI directive you can precisely control what is listed to the list file or screen during assembly.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: At least one list option should be present in the parameter field. Multiple list options should be separated by commas.
With the option on¦off you can switch the listing completely on or off.
Nothing will be sent to the list file or screen if the listing is switched off.
Please note that error messages will always be listed, regardless of the settings of the list options.
With the mon¦moff option you can switch the listing of expanding Macros on or off.
Expanding Macros will not be listed if this option is switched off (moff).
The line calling the Macro to expand will be listed however.
With the con¦coff option you can control the listing of source lines that are not assembled due to conditional assembly when the condition is false.
Only version 3 of the SB-Assembler has a fourth list option, ton¦toff.
This option controls the listing of instruction timing information.
If this option is switched on (ton) it will print the timing information in between paranteses just behind the line number on lines containig mnemonics.
Lines containing comments only or directives won't have timing information printed.
Per default all three/four list options are switched on. This means that all source lines will be sent to the list file or screen.
It is allowed to have multiple list options in the parameter field after the .LI directive, as long as they are separated from each other by commas.
It is even allowed to switch any of the list options on and off repeatedly on the same line, although only the last option will be remembered.
.LI OFF,MON,COFF,ON,CON,MOFF
Source lines containing a .LI directive will never be listed in the list file them selves. Except when an error in such a line is detected. Examples:
.LI ON Switch main list option on
.LI OFF Switch main list option off
.LI MON Switch macro list option on
.LI MOFF Switch macro list option off
.LI CON Switch conditional list option on
.LI COFF Switch conditional list option off
.LI ON,MON,CON Switch all options on
.LI OFF,MOFF,COFF Switch all options off
.LI ON,MOFF,CON Only macro option off
.LI ON,OFF,ON,OFF Results in main list option on
; Only for Version 3
.LI TON Turn timing information on
.LI TOFF Turn timing informaiton off
.LM Left MarginSyntax: .LM expression Function: With the .LM directive you can set the width of the left margin of the list file. This is useful if you plan to send the listing to a printer. Version 3 doesn't have any of the page formatting directives because they have become fairly obsolete nowadays. Therefore the .LM directive is also scrapped from the list of directives. Explanation:
Usually the lines of a list file begin in the left most column.
With the .LM directive you can let each line begin with a number of spaces to create a left margin.
The number of spaces used as a margin is determined by the expression that follows the .LM directive.
The expression may have a value in the range from 0 to 16.
The .LM directive will only be evaluated during pass 2 of the assembly process. Any errors in the parameter will be detected in pass 2. .MA MAcro definitionSyntax:
macroname .MA [comment]
.MA macroname [comment]
See also: Macros .DO .EL .EM .FI .XM Function: The .MA directive starts the definition of a Macro. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The syntax of the .MA directive has 2 appearances.
There is a special reason why I explicitly say that comments are allowed behind the .MA directive.
Most directives may be followed by comments, so that's not so special by itself.
But here it is particularly useful to add comments to indicate what parameters are expected by the Macro that you're going to define.
The same rules apply to macroname as for Global label names, with the only exception that a macroname is only remembered up to 31 characters (Version 3 of the SB-Assembler has no length limit).
The macroname must start with a character from A to Z, an may contain other characters from A to Z, digits from 0 to 9, the underscore _ and a dot .
The following directives are not allowed during the definition of a Macro (from the opening .MA directive until the closing .EM directive): .MA, .IN, .CH, .BI, .EN, .CO and .EC In Version 3 of the SB-Assembler the .EN directive is allowed inside a macro definition. When the .EN direcitve is encountered inside an expanding macro it will end all currently expanding macros and the current list file, all at the same time. With Version 2 of the SB-Assembler new Local label definitions are not allowed after a Macro definition until at least one new Global label is declared.
With Version 2 of the SB-Assembler a fatal error will be reported if the end of a source file is reached while in the middle of defining a Macro with the .MA directive.
A detailed description of the Macro capabilities of the SB-Assembler can be found in a separate chapter. Examples: Let's define a Macro that exchanges 2 bytes in memory without altering any of the processor's registers on a 6502.
XCHNG .MA memory1,memory2
PHP ; Save flags register
PHA ; Save Accu
LDA ]1 ; Get the 1st byte from memory
PHA ; and put it on the stack
LDA ]2 ; Copy the 2nd byte to the
STA ]1 ; 1st memory location
PLA ; Save the 1st byte to
STA ]2 ; the 2nd memory location
PLA ; Restore Accu
PLP ; Restore the flags register
.EM ; Done
All parameters in the Macro definition have the notation ]x , where x is the parameter number. This parameter number is determined by the location in the operand field of the Macro call. In the example above the parameter ]1 will be replaced by the first parameter memory1. The parameter ]2 will be replaced by the second parameter memory2. .NO New OriginSyntax: .NO expression1[,expression2] See also: .BS .DU .ED .EP .OR .PH .RF .SM Function: The .NO directive is very similar to the .OR directive, yet it has some significant differences. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: The effect of this directive is that the program counter is set to the value of expression1. The way that this is done differs significantly from the way the .OR directive would do that. In principle the .NO directive works identical to the .BS directive, with the only difference being the way the block size is defined. With the .BS directive you say how big the skipped block should be in terms of the number of bytes. The .NO directive expects you to specify where the skipped block will end by providing the end address in expression1. Expression1 may not contain forward referenced labels otherwise a fatal "Undefined label error" will be reported. The two following program lines will have exactly the same effect:
.NO newpc
.BS newpc-$
You can determine what should be done with the skipped bytes by supplying the fill value in expression2, just like with the .BS directive.
The value of expression1 may not be less than the current program counter.
Values less than the current program counter would otherwise result in very large blocks to be skipped.
Operation of the .NO directive differs a little between formatted and unformatted target files.
The list file will only contain the first address of the skipped memory block. The filled bytes are not listed in the list file. Please note that unformatted files rely on the .NO directive to change the program counter because using the .OR directive would close an unformatted file immediately. Examples: This is a typical 6502 program to be burned into EPROM. First comes the program together with interrupt routines. Interrupt and reset vectors must be placed at the end of the address space.
.OR $F800 Start address of the ROM
NMI NOP The NMI routine
;
;
;
RTI
IRQ NOP The interrupt request routine
;
;
;
RTI
RESET NOP The initialization routine
;
;
;
JMP AGAIN End of the program
.NO $FFFA,$FF Skip all unused memory until
; the vector space. All skipped
; bytes are filled with $FF
.DA NMI The NMI vector
.DA RESET The Reset vector
.DA IRQ The IRQ vector
.OR ORiginSyntax: .OR expression See also: .BS .DU .ED .EP .NO .PH .RF .SM Function: The .OR directive is used to set the starting address of a program, a part of the program, or a data block. All following bytes are stored in consecutive addresses, starting at the address specified by expression. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The .OR directive sets both the program counter and target address to the value of the expression.
The expression may not contain forward referenced labels otherwise a fatal "Undefined label error" will be reported.
One single assemble run may contain several .OR directives.
But some additional rules exist when sending the generated code to an unformatted target file like BIN or HEX.
Due to several questions from users I decided to change (read: improve) the behaviour of the .OR directive in combination with unformatted files.
As from software version 2.07 it is now allowed to start an unformatted file before setting the .OR address, but only if the unformatted file is still empty when the .OR directive is encountered.
However if the .OR directive is used when the unformatted file is not empty it will still close the target file, there is no way to prevent that!
It goes without saying that the programmer is responsible to prevent overlapping of memory spaces when multiple .OR directives are used in one assembly run.
The SB-Assembler will not protest if you reset the target address to an already used location of memory.
Examples:
.OR $1000 Store program from $1000 upwards
;
;
;
.OR $2000 Continue from address $2000
;
;
;
.OR $0000 You can also continue at lower addresses
;
;
;
.PG PaGeSyntax: .PG [expression] Function: The .PG directive will force the listing to start on a new page in the list file or list device. The title, set by the .TI directive, will be printed on top of that new page along with the page number. The printing of the title and page number on top of the new page is the only difference with the .EJ directive. Version 3 of the SB-Assembler no longer supports page formatting. Therefore the .PG directive has been omitted there. Explanation: If a title is defined by a .TI directive it will be printed on the first line of the new page, along with the page number.
If expression is given the new page will be numbered with the value of the expression.
The expression should not be more than 9 spaces away from the .PG directive to be evaluated, otherwise it will be treated as a comment.
A source line containing the .PG directive will never be listed in the list file itself, unless an error is encountered on that line.
.PH PatcHSyntax: .PH expression See also: .BS .DU .ED .EP .NO .OR .RF .SM Function: The .PH directive will switch over to the patch mode. The current program counter is saved during patch mode. The saved program counter will still count up for every byte that is saved to the target file in the background. At the same time a new, temporary, program counter is selected. The .EP directive switches off the patch mode and replaces the temporary program counter with the original one again. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: The expression may not contain forward referenced labels otherwise a fatal "Undefined label error" will be reported. A previous patch mode will be automatically closed when a new patch mode is initiated. This allows you to write multiple patch routines in a row, where each patch routine gets its own address space. Please note that the .OR directive also terminates an active patch mode automatically. The patch mode is typically used to generate pieces of code that are moved to a different memory location by the processor before it is used as code. All labels that are defined during the patch mode automatically get the appropriate values as if the code really was generated at the intended address. In the mean time the code is saved to the target file in a consecutive order as if the program counter was not changed. Originally the patch mode was intended to write some patch routines that should be copied into an existing program by a simple move routine, hence it's name.
Another useful application for the patch mode is writing code that is supposed to start at e.g. address $8000 of the target system, but should be burned to an EPROM starting at address $0000.
You can't simply use .OR $0000 because that would produce erratic destination addresses for jumps, calls and memory access instructions.
The patch mode can also be used to write programs that should run in bank switched memory.
A label declared on the line cotaining the .PH directive will get the value of the real program counter, not the modified program counter.
This simplifies calculation of the beginning and the length of the piece of patch code.
Version 3 of the SB-Assembler has the more convenient .TA directive which can be used for mapping code to the appropriate ROM locations. Example 1: Imagine a piece of 6502 program that should be copied to RAM memory to allow direct changing of addresses used by instructions. 8000- .OR $8000 Begin of program 8000-A0 0A INSTALL LDY #NEXT-PATCH1 Calc. length of patch 8002-B9 0C 80 .LOOP LDA PATCH,Y Get byte from ROM 8005-99 00 20 STA RAM,Y and put it in RAM 8008-88 DEY Decrement length counter 8009-10 F7 BPL .LOOP Repeat while Y>=0 800B-60 RTS 800C- 800C- PATCH .PH $2000 Destination of patch routine 2000-48 RAM PHA Save Accu on stack 2001-AD 00 00 LDA $0000 Address may be changed ; dynamically because it's ; stored in RAM now 2004-38 .LOOP NOP Any other code goes here 2005-68 PLA Restore Accu 2006-60 RTS 2007- .EP End of patch routine 8013- 8013-EA NEXT NOP The rest of ROM code
Explanation: The INSTALL routine copies the patch routine to RAM location starting at address $2000.
In this case the patch routine may not be longer than 127 bytes to simplify the copy loop.
The first thing that's done is calculating the length of the routine that has to be moved by subtracting the end address of the patch routine in ROM ($8013) from the begin address of the patch routine in ROM ($800C, and not $2000!).
Then the patch routine is copied to RAM byte by byte.
Example 2: Imagine you want to create a program for the 8048 processor which can address only 4 kb of ROM memory. But you want to increase to ROM addressing range to 8 kb by using bank switching. The memory range $0000 to $07FF (2 kb) is always available. The memory range from $0800 to $0FFF is available 3 times in 3 different banks. Two I/O lines control what bank is selected.
0000- .OR $000 Begin of bank 0
; Here come universal
; routines, the interrupt
; service routines and bank
; switch routines.
.NO $800,$FF Fill bank 0 with $FF
0800- NOP Bank 1.1 starts at $0800,
; No special attention is
; required yet to do that.
; Here comes the code
; of bank 1.1
.NO $FFF,$FF Fill bank 1.1 with $FF
1000- .PH $800 Bank 1.2 again starts at
0800- ; address $0800. But this time
; the target address in the
; object file continues normally
; from $1000 where we are now.
; Here comes the code of bank 1.2
.NO $FFF,$FF Fill bank 1.2 with $FF
1000- .EP (.EP is optional here)
1800- .PH $800 Bank 1.3 also starts at
0800- ; address $0800. The target
; address still continues which
; is $1800 now.
; Here comes the code of bank 1.3
.NO $FFF,$FF Fill bank 1.3 with $FF
.EP End of bank 1.3
Explanation: Bank 0 of the program is nothing special from the SB-Assembler's point of view.
Bank 0 contains some universal routines, interrupt service routines and bank switch routines.
Bank 0 is always available to the target processor.
Please note that switching from bank 1.2 to bank 1.3 does not necessarily require the .EP directive.
The .PH directive would have automatically executed an .EP directive.
This example works for formatted and unformatted target files because all banks are filled completely by using the .NO directives at the end of every bank.
.RF Random FillSyntax: .RF expression1,[expression2] See also: .AS .AT .AZ .DA .DB .DL .DR .DW .HS .TS Function: The .RF directive can fill a portion of memory with randomly generated bytes. This can be useful for software security. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation: The expression1 indicates the number of bytes that should be filled with randomly generated values. Expression1 may not contain any forward referenced labels. Expression1 may not be a negative number. The optional expression2 can be used as a seed value for the pseudo random number generator. If expression2 is not used the pseudo random bytes generated are different every time the source file is assembled. By specifying the seed you can generate the same pseudo random sequence time after time. In Version 2 of the SB-Assemble the seed value is truncated to the lower 16 bits. In Version 3 the entire value is used as seed value.
In Version 2 of the SB-Assembler the pseudo random sequence will repeat itself after 65536 generated bytes.
This is not a big problem for I can't think of an application that would require more random bytes than that.
Because of the totally different pseudo random number generators of Version 2 and 3 of the SB-Assembler, they will not generate the same pseudo random number sequences when both seeded with the same seed. Examples:
For example the single chip processor 8051 (or its relatives) provide a few security levels to prevent software piracy.
One of these levels of security encrypt the ROM contents when read by a programmer.
Without the correct encryption key sequence this information is useless.
Examples:
.RF $1000-$ Fill up to 4kb with random numbers
.SE SEt variableSyntax: label .SE expression See also: .EQ Function: With the .SE directive you can declare and change a variable value to a label. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
Normally only constant values are assigned to labels.
Once a particular value is assigned to a label it can not be changed anymore.
The syntax for the .SE directive is almost identical to the syntax for the .EQ directive.
The only difference is that the .SE directive only allows you to use Global labels.
This means that the label name should start with a letter from A to Z.
After the definition of a variable label it is not possible to declare or use Local or Macro labels until the next declaration of a normal Global label. Subsequent changes to the value using the .SE directive are transparent to the use of Local and Macro labels. The values of variable labels are not printed in the Symbol table because their value is not necessarily constant throughout the entire program. See to it that a variable is declared during pass 1 of the assembly process, because new labels can't be added to the Symbol table in pass 2 anymore. A variable can not be used as a forward referenced value. This means that the current value is always used, not the value that the variable may have in the future. Examples:
The 8048 processor does not allow lookup tables to cross a memory page boundary.
This means that the most significant byte of the address must remain the same for the beginning of the table and the last byte in the table.
Two Macros are working together to see if a table does not cross a page boundary.
OPEN .MA
BEGIN .SE $/256 ; Remember the page
.EM
CLOSE .MA
.XM $/256=BEGIN ; Quit macro if page is equal
.DO $*$1000000*? ; Do only if LSB<>0 and pass 2
.ER *** Table page error
.FI
.EM
I agree that the second Macro calls for some extra explanation.
The .XM directive will terminate the Macro's expansion immediately if the current memory page is equal to the value stored in the variable label BEGIN.
If the pages are different we'll continue with the Macro.
Please note that these two Macros may be used as often as you like because the value of BEGIN may be changed over and over again.
This would not have been possible using the .EQ directive.
PS: This is only an example to demonstrate the use of variables. The problem presented here is so common for the 8048 that I have included 2 dedicated directives in 8048 family Cross Overlays to replace these 2 Macros (.OT and .CT). .SF Symbol FileSyntax: .SF filename[.ext] See also: .CP .EF .LF .LI .TF .TW Function: The .SF directive allows you to create a Symbol file at the end of the assembly process. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The symbol file lists all Global constant labels followed by .EQ directives and their value.
Such a Symbol file could be used to transfer all constants from one program into another program for linking purposes.
The Symbol table is opened by the .SF directive in pass 2 of the assembly process and will only be filled with the symbols at the end of pass 2. Therefore errors are only recognized in pass 2.
As usual drive letter (on DOS/Windwos machines) and path are allowed together with the filename.
The extension .ext is optional. The default extension is .sym .
The .SF directive may only be used once in a program. In version 3 local labels are also listed to the symbol file, grouped together with their parrent global label. Macro labels are not listed though. The comment field in the symbol file will hold the number of references to the particular label and the source file it was declared in. .SM Select MemorySyntax: .SM code¦ram¦eeprom See also: .BS .DU .ED .EP .NO .OR .PH .RF Function:
Version 3 of the SB-Assembler allows you to split memory into 3 major segments.
Per default you are using CODE memory, just like version 2 would have known it.
However now you can also select RAM or EEPROM memory.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: A total of 3 different memory segments are supported as of version 3 of the SB-Assembler.
Each of the 3 memory segments has its own address space. This means that you can setup 3 different .OR addresses, one for each memory segment. Now you can switch back and forth between these three memory segments as often as you want. Declare some RAM, write some code, declare some more RAM, save some pre-set values to EEPROM memory, write some more code, declare some memory space to EEPROM memory, etc, etc. A line containing the .SM directive must have an empty label field. An error is reported if the label field is not empty. Please note that you can not write CODE memory and EEPROM memory to the same target file. If you use CODE and EEPROM segments you will always have to use (at least) 2 different target files. Example:
The following piece of code demonstrates the use of memory segments.
First a piece of RAM memory is defined.
RAM starts at $8000 here and 2 labels are defined in RAM space, the first one spanning 2 bytes, the second one only one byte.
You don't have to, or better yet, you can't open a target file while in the RAM memory segment.
You can switch back and forth between the different segments as often as you want. And each time the appropriate address space and target file is automatically selected.
.SM RAM
.OR $8000
POINTER .BS 2 Declare a 2 byte pointer in RAM
COUNTER .BS 1 Declare a 1 byte counter in RAM
.SM EEPROM
.TF EEPROMFILE.HEX,INT Write EEPROM data here
.OR $1000 Begin of EEPROM memory
.TA $0000 Write data from address $0000
IP_ADDR .DA #192,#168,#1,#200 Set default IP address
IP_MASK .DA #255,#255,#255,#0 Set default net mask
.SM CODE
.TF CODEFILE.HEX,INT Write Code data here
.OR $0000 Begin of Code memory
RESET JMP INIT Get the system started
NMI JMP DO_NMI Handle non maskable interrupts
:
:
:
RET End of some code
.SM EEPROM Write some more data to EEPROM
SERVER .AZ /www.sbprojects.com/
NV_BUF .BS 40 Reserve a 40 byte block of memory
URL .AZ \www.sbprojects.com/sbasm\
.SM RAM Define some more RAM bytes
BUFFER .BS 40 Reserve a 40 byte block of memory
BUFPNTR .BS 1 Reserve 1 byte buffer pointer
.SM CODE Continue code memory
INIT NOP Get the system started
:
:
RET End of some code
.ST STopSyntax: .ST [stopmessage] Function:
The .ST directive is used to stop the assembly process temporarily.
A message is displayed on the screen and the SB-Assembler waits until the operator presses almost any key.
The function of this directive has become fairly obsolete now adays. Therefore the .ST directive is no longer available in Version 3 of the SB-Assembler. Explanation: If no stopmessage is given the assembler will display the default stop message "Press almost any key to continue". Otherwise the text following the .ST directive will be displayed up to a maximum length of 79 characters. This limits the maximum length of the stop message to one line on the screen.
The stopmessage will be erased from the screen when the operator presses almost any key and then the assembly process will resume.
Source lines that contain the .ST directive will never be listed in the list file and can not hold comments. All text following the .ST directive is considered to be the stopmessage. Examples: Prompt the operator for a new disk:
.ST Insert disk 2 and press any key
Warning! Don't use the drive that must hold different disks for writing target files, error files, or what ever other generated files to! This could even destroy the contents of the diskette written to. .TA Target AddressSyntax: .TA expression Function:
In Version 2 of the SB-Assembler this is an obsolete directive, originating from the Apple version of the SB-Assembler.
Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: This directive was used on the Apple ][ version of the SB-Assembler to send generated code directly to memory, where it could be started directly. This is never possible on the PC however. In Version 2 of the SB-Assembler this directive will always report the "Not implemented in MS-DOS version error" message.
In Version 3 of the SB-Assembler this directive is reinstated and will set the target address of the formatted target file.
Normally the current program counter is equal to the addresses in the target file.
Some processors however don't start their programs at address $0000.
For the 6502 for instance ROM memory is mapped somewhere at the end of the address space.
Thus the program may start at $C000 for instance.
However the EPROM address spaces always starts at address $0000.
In Version 3 of the SB-Assembler you may now solve the above problem in a more natural way. Simply set the .OR to the real starting address of your program ($C000 in the example above), and then change the target address to $0000. Now the assembler will still generate code for the intended address range, while the target file is correctly written from address $0000 and upwards.
Each time a byte is written to the target file, the target address is incremented.
Therefore the program counter and the target address counter will remain in sync with each other.
The .OR directive will set the target address to the new program counter multiplied with the number of bytes stored per instruction. This is normally exactly what you want, unless you want to change the target address to reflect propper ROM alignment. .TF Target FileSyntax: .TF [filename.ext[,format[,expression]]] See also: .CP .EF .LF .LI .SF .TW Function: With the .TF directive you can open a target file in any of the available formats. This target file will be filled with the generated object code of your program. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation:
The .TF directive, without parameters, will close an already open target file.
Nothing will happen if no target file is open at that time.
If a filename does follow the .TF directive an already open target file will also be closed.
Then a new target file is created with the name filename.
If that file already exists its length will be reduced to zero, effectively overwriting the file without prior notice!
TIP: To avoid problems with other MS-DOS programs I advise you not to use the extensions .COM, .BAT, .EXE or .OBJ for your target files. The use of the extension .ASM for your target files will also cause confusion you clearly can do without. It could cause your source file to be overwritten accidentally.
Some target file formats won't allow you to create programs that are larger than 64 k bytes, provided that the maximum address used is not greater than $FFFF.
So if you start your program at $F000 your program can't be any bigger than 4 k bytes!
Other target file formats allow you to create programs up to 4 G bytes, which will be sufficient for the next few years from now ;-)
Please note that all bytes generated by the program will be lost when no target file is open yet. Warning: If the file filename already exists its contents will be erased and overwritten without prior notice. In Version 2 of the SB-Assembler it is also possible to send the target file to a device, instead of to a file. That way you can send your object code directly to a programmer or EPROM simulator. A device name should always end in a colon. All MS-DOS device names are allowed like PRN:, LPT1:, COM1:, NUL:. Avoid sending the object file to the screen (CON:) however, it will only cause a lot of gibberish to be displayed there. The file format following the filename is optional. If it is not provided the default BIN format is used.
Please note: The .OR directive will close the unformatted file types BIN and plain HEX immediately because they don't support an address field.
Please specify the start of the program before opening the target file if you intend to use one of these two file formats.
If, for any reason, you do have to change the start address of the next code you can always use the .NO directive.
These are the possible file format names:
What format you can use best depends on the capabilities of your EPROM programming device.
I prefer the FPC format because it produces the most compact formatted target files.
Unfortunately not many EPROM programmers support that code though.
The format identifier may also be followed by an expression, separated by an other comma.
This expression defines the maximum number of data bytes you want to have on each line in your target file.
Only BIN files don't provide for this because they don't consist of lines.
The syntax of the .TF directive will only be checked during pass 2 of the assembling process. An existing file with the name filename will not be erased and overwritten before pass 2. So if any errors are encountered during pass 1 the old target file(s) will still exist unchanged. All errors that occur in the parameter field of the .TF directive will result in a fatal error message to be reported. This will stop the assembly process immediately. Examples:
.TF C:\OBJ\TARGET.BIN Open BIN file (BIN is default)
.TF C:\OBJ\TARGET Open BIN file (no extension)
.TF TARGET.BIN,BIN Open BIN file
.TF TARGET.TXT,AP1,8 Open Apple 1 format
.TF TARGET.HEX,E52 Open EMON52 file
.TF TARGET.HEX,HEX Open HEX file
.TF TARGET.INT,INT,32 Open INT file (32 bytes/line)
.TF TARGET.INT,INS Open INS file
.TF TARGET.MOT,S19,8 Open S19 file (8 bytes/line)
.TF TARGET.MOT,S28 Open S28 file
.TF TARGET.MOT,S37 Open S37 file
.TF TARGET.SIG,SIG,0 Open SIG file (8 bytes/line)
.TF TARGET.TEK,TEK,100 Open TEK file (32 bytes/line)
.TF TARGET.FPC,FPC Open FPC file
.TF TARGET.MOT,INT Confusing, but legal
.TF TARGET.BIN,BIN,10 Legal, but length irrelevant
.TF ; Close previous target file
.TF COM1:,INT,32 Send object to COM1:
Note on the Apple 1 format:
Vince Briel started some sort of Apple 1 fever around the 30th anniversary of this legendarily computer.
The original Apple 1 has only the cassette recorder as mass storage.
However it is possible to expand the original Apple 1 with a serial interface and several replica versions are standard equipped with a similar serial interface.
.TI TItleSyntax: TI [S],[expression[,title]] Function:
In Verison 2 of the SB-Assembler the .TI directive is used to set the page length and title for each page in the list file.
Explanation:
If only the .TI directive is given on a source line, or when the text following the .TI directive is more than 9 spaces away from it, all default parameters are set.
This means that the Single Sheet mode is switched off, the page length is set to infinite and the title is erased.
The infinite page length implies that no form feeds are inserted after a certain number of lines.
The Single Sheet mode is selected if the first character of the operand field is a single S, or an S followed by a comma.
This means that the SB-Assembler will wait for the operator to insert a new page in the printer when the previous page is full.
The user is prompted to press almost any key when the new page is loaded in the printer with the message: "Insert new sheet and press any key".
The expression defines the number of lines that are to be printed on a page in the list file.
The minimum number of lines is 8, the maximum number is 254.
All other values result in a "range error" to be reported.
The title can be any piece of text, up to 127 characters in length.
The title is treated as literal text, where case and spaces are not changed.
The title is always printed above each new page in the list file.
It does not matter if that page is started automatically or was forced by the .PG directive.
The title may be changed as often as you want during the assembly. Every time you change the title, using the .TI directive, a new page is started with the new title above it. The .TI directive is never listed in a listing file itself. Therefore it does not accept comments. Everything following the title will be treated as part of the title itself. The .TI directive is only parsed during pass 2 of the assembly process. Errors will not be discovered during pass 1. Examples:
; Set the list page length to 55 lines, without a title
.TI 55
; Set the page length to 55 lines, with title
.TI 55,This is the title
; Set the page length to 40 lines, with title and
; Single Sheet mode
.TI S,40,New title
; Switch off auto page mode and titles.
.TI
.TS Time StampSyntax: .TS See also: .AS .AT .AZ .DA .DB .DL .DR .DW .HS .RF Function: This directive is new to version 3. It write a time stamp string to the target file. Boundary Sync: In Version 3 of the SB-Assembler this directive will not perform a boundary sync. Explanation:
A time stamp string can be written to your target file by using the .TS directive.
The system time at the start of the current assembly run is taken as time stamp.
This means that you can use .TS as often as you want, generating the same time stamp throughout the entire program.
.TW Target WriteSyntax: TW string¦#expression[,string¦#expression[,...]] See also: .CP .EF .LF .LI .SF .TF Function: This directive allows you to write strings of text directly to the target file. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: This command will flush the current target file's line buffer and then it writes a string directly to the file. The string can be anything, but usually holds some remarks or programming device commands.
I can think of two main reasons why you would want to write to the target file directly.
The syntax of the .TW directive is somewhat comparable with that of the .AS directive, with the only exception that it is not possible to create strings with a negative ASCII polarity.
You may use either a delimited string, or a separate byte per parameter.
Multiple parameters must be separated by commas.
Please note that strings are not terminated with a CR or LF automatically in version 2!
If you do want to end the string with a CR/LF pair you will have to enter them as normal byte parameters.
This directive should be used with some care because you can make the target file useless if you write something to it that your programming device doesn't understand. Also be very careful not to write directly to a binary formatted file because they rarely allow comments or other commands.
Strings may not be empty and must be terminated by the same delimiter that was used to start the string, otherwise an error will reported.
The .TW directive is only parsed during pass 2 of the assembly process. Errors will not be discovered during pass 1.
Please note that it is not possible to put comments or commands at the absolute end of the target file, unless the target file is a binary or HEX unformatted file.
The reason for this is very simple.
The "end of file" line is only written just before the target file is closed.
Therefore the "end of file" line is always the last line to be written to the target file, simply because the file is closed immediately afterwards.
And you can't write to an already closed file anymore.
With version 3 it is no longer possible for .TW to write to onformatted binary files. Examples:
.TF TWTEST.HEX,INT
.AS /Test/
.TW /'Remark line/,#$0D,#$0A
.AS /Test/
The program above generates the target file below: :04000000546573745C 'Remark Line :040004005465737458 :00000001FF Omitting the #$0D,#$0A part of the .TW directive in the example above would result in the probably useless file below: :04000000546573745C 'Remark Line:040004005465737458 :00000001FF Please note that the program below will generate a remark line just before the "end of file" record in the target file. The "end of file" line is always the last line of the target file!
.TF TWTEST.HEX,INT
.AS /Test/
.AS /Test/
.TW /'Remark line/,#$0D,#$0A
:04000000546573745C :040004005465737458 'Remark Line :00000001FF .XM eXit MacroSyntax: .XM [expression] See also: Macros .DO .EL .EM .FI .MA Function: The .XM directive prematurely exits an expanding Macro. This premature exit can be caused conditionally or unconditionally. Boundary Sync: In Version 3 of the SB-Assembler this directive will perform a boundary sync. Explanation: If the optional expression is omitted the .XM directive will prematurely exit the expanding Macro. If the expression is given the expanding Macro will be terminated when the expression evaluates to be true, i.e. unequal to 0. The expression may not contain any forward referenced labels. The expression must follow the .XM directive within 9 or 10 spaces, otherwise it is treated as comment.
The unconditional exit is normally only used in co-operation with conditional assembly directives .DO, .EL and .FI.
Without any of these conditional directives the use of an unconditional .XM does not make much sense.
A detailed description of the Macro capabilities of the SB-Assembler can be found in a separate chapter. Examples: The following example shows us a Macro that can push up to 3 registers on the processors stack. You can expand the Macro to handle even more than 3 registers yourself. 1 PUSH .MA reg1,reg2,reg3 2 PUSH ]1 ; Push register 1 on the stack 3 .XM ]#=1 ; Done if only 1 parameter 4 PUSH ]2 ; Push register 2 on the stack 5 .XM ]#=2 ; Done if only 2 parameters 6 PUSH ]3 ; Push register 3 on the stack 7 .EM 8 9 TEST >PUSH ACC,PCL,PCH M1 PUSH ACC M2 .XM 3=1 M3 PUSH PCL M4 .XM 3=2 M5 PUSH PCH 10 11 >PUSH ACC M1 PUSH ACC M2 .XM 1=1 12 13 >PUSH B,ACC M1 PUSH B M2 .XM 2=1 M3 PUSH ACC M4 .XM 2=2 14 NOP Rest of the program |