|   |
![]() |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Home
|
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 interference 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.
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.
File names and paths are restricted to the normal MS-DOS 8.3 file names.
Sometimes you can use one of several options. These options are separated by a pipe ¦ symbol. 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 calculations. These calculations always result in a 32 bit value. The directive decides how many of the 32 bits are really used.
Syntax: .AS [-]string¦#expression[,string¦#expression[,...]] See also: .AT .AZ .DA .DB .DL .DR .DW .HS .RF Function: The .AS directive converts ASCII strings and/or expressions to hexadecimal bytes. 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\
Syntax: .AT [-]string¦#expression[,string¦#expression[,...]] See also: .AS .AZ .DA .DB .DL .DR .DW .HS .RF 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. Apart from this minor difference the .AT directive works exactly the same as the .AS directive. 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\
Syntax: .AZ [-]string¦#expression[,string¦#expression[,...]] See also: .AS .AT .DA .DB .DL .DR .DW .HS .RF 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. Apart from this minor difference the .AZ directive works exactly the same as the .AS directive. 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\
Syntax: .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. Explanation: The filename may contain drive letter and path name. 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:
In fact 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 remarks. Please Note: 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 omitted.
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. Examples: 0000- BITMAP .BI SAMPLE,INT
Syntax: .BS expression1[,expression2] See also: .DU .ED .EP .NO .OR .PH .RF 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.
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.
Syntax: .CH filename[.ext] Function: With the .CH directive you can CHain include files together without going back to the main source file first. 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.
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.
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
Syntax: .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.
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 semicolon or asterisk. 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.
Syntax: .CP comport,baudrate,parity,databits,stopbits See also: .EF .EJ .LF .LI .LM .PG .SF .TF .TI .TW Function: The .CP directive sets the communication parameters of the select 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. 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.
Syntax: .CR filename[.ext] Function: The .CR directive loads a Cross-Overlay into memory. 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 to switch between different Cross-Overlays in one assembly run to create a program for different processors at same the time.
The .CR directive must be followed by a filename which may be preceded by a drive letter and/or path name.
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.
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 from
; the current directory or from
; the parent directory where the
; sbasm.com program originated
.CR \SBASM\6502 Load the 6502 Cross-Overlay
; from the directory \SBASM\ of the
; current drive.
Syntax: .DA [#¦/¦=¦\]expression[,[#¦/¦=¦\]expression[,...]] See also: .AS .AT .AZ .DB .DL .DR .DW .HS .RF 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. 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 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 000D-34 12 56 .DA $1234,#$56 Mixed words and bytes
Syntax: .DB [expression | string[,[expression | string[,...]] See also: .AS .AT .AZ .DA .DL .DR .DW .HS .RF 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.
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 should 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
Syntax: .DL [#¦/¦=¦\]expression[,[#¦/¦=¦\]expression[,...]] See also: .AS .AT .AZ .DA .DB .DR .DW .HS .RF 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. 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 should 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
Syntax: .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. 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. 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 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. If the .LI COFF mode is selected the skipped lines are not listed at all. 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 .DO is not evaluated
; 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
Syntax: .DR [#¦/¦=¦\]expression[,[#¦/¦=¦\]expression[,...]] See also: .AS .AT .AZ .DA .DB .DL .DW .HS .RF 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.
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 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
Syntax: .DU [expression] See also: .BS .ED .EP .NO .OR .PH .RF Function: The .DU directive is mainly used for defining RAM memory locations. Only the location is important while defining Labels in RAM area. 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 care. 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 equal to 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
Syntax: .DW [expression[,[expression[,...]] See also: .AS .AT .AZ .DA .DB .DL .DR .HS .RF 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.
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 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
Syntax: .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. Explanation: Per default the Error Bell option is switched on, which sounds a beep for every error in your source code. Examples:
.EB ON Switch Error Bell option on
.EB OFF Switch Error Bell option off
Syntax: .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. 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.
Syntax: .ED See also: .BS .DU .EP .NO .OR .PH .RF Function: The .ED directive will end the dummy mode that was started by the .DU directive. 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.
Syntax: .EF filename[.ext] See also: .CP .EJ .LF .LI .LM .PG .SF .TF .TI .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. 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 in 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 drive letter and path.
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 these are 3 separate examples which may not be used together in one single source.
Syntax: .EJ See also: .CP .EF .LF .LI .LM .PG .SF .TF .TI .TW Function:
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.
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.
Syntax: .EL Function: The .EL directive is used together with the conditional assembly directives .DO and .FI. The .EL directive will invert the current condition. 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
Syntax: .EM See also: Macros .DO .EL .FI .MA .XM Function:
This directive ends a Macro definition that was started by the .MA directive unconditionally.
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.
Syntax: .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 the main source file as if the include file was ended in a natural way.
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 assembly will stop immediately.
If we were still in pass 1 the assembler will start pass 2 of the assembly process.
Syntax: .EP See also: .BS .DU .ED .NO .OR .PH .RF Function: With the .EP directive the so called patch mode, that was started by the .PH directive, is switched off . Explanation:
The .EP directive switches off the so-called patch mode.
This effectively 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.
Syntax: label .EQ expression label = expression See also: .SE Function: The .EQ directive is used to assign a value other than the default program counter value to a label. Alternatively the = symbol may be used instead of the .EQ directive. 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 program counter. 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.
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.
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
Syntax: .ER [F[,]][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. 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 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.
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
Syntax: .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. 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.
Syntax: .HS [.]hexbyte[,[.]hexbyte[,.....]] See also: .AS .AT .AZ .DA .DB .DL .DR .DW .RF Function:
The .HS directive accepts a string of hexadecimal encoded bytes.
Each hexadecimal encoded byte must consist of 2 hexadecimal digits.
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
Syntax: .IN filename[.ext] Function: The .IN directive allows you to split the complete source text of your program into different modules. 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. The maximum source file size the SB-Assembler can handle is only limited by your favourite text editor. 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 necessary .INclude files.
The .IN directive requires a filename as parameter.
This filename may be preceded by a drive letter and path name.
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 the include file.
Assembly will then continue in the main source file on the line following the line that opened the include file.
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 stem from an include file. Line numbers are reset to 1 every time a new include file is opened. Examples:
.IN DECLARE Include declaration module
.IN C:\LIB\MACRO.LIB Include Macro library
.IN INIT Include initialization module
Syntax: .LF [filename[.ext][,linelength]] See also: .CP .EF .EJ .LI .LM .PG .SF .TF .TI .TW Function:
With the .LF directive you can divert the listing output from the screen to a file or other output device.
Explanation: Per default the listing is output to the screen with a maximum line length of 254 characters. This means that longer lines are simply broken down at the right end of the screen and continue on the next line. The filename may be preceded by a drive letter and path name. If no extension .ext is given the default extension .LST is used. If you want to send the listing to a device the device name should be followed by a colon like in COM1: PRN: AUX: NUL:.
An already open list file will be closed when the .LF directive is given.
If no filename is given the output will be redirected to the screen again.
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 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 LPT1: Send listing to LPT1
.LF CON: Send listings to the screen
.LF CON:,79 Send listing to screen, max length 79
.LF NUL: Send listing to NUL device
.LF ; Close listing file, output to screen
Syntax: .LI on¦off¦mon¦moff¦con¦coff[,on¦off¦mon¦moff¦con¦coff[,.....]] See also: .CP .EF .EJ .LF .LM .PG .SF .TF .TI .TW Function:
With the .LI directive you can precisely control what is listed to the list file or screen during assembly.
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.
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 a false condition.
Per default all three 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
Syntax: .LM expression See also: .CP .EF .EJ .LF .LI .PG .SF .TF .TI .TW 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. 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 expression may not contain forward referenced labels.
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.
Syntax:
macroname .MA [comment]
.MA macroname [comment]
See also: Macros .DO .EL .EM .FI .XM Function: The .MA directive starts the definition of a Macro. 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 as for Global label names apply to macroname, with the only exception that a macroname is only remembered up to 31 characters.
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 New Local label definitions are not allowed after a Macro definition until at least one new Global label is declared. 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
Please note that I deliberately included the semicolon in the comment field.
Usually this semicolon is optional in the SB-Assembler.
But during a Macro definition it prohibits the comments from being saved to the symbol table.
You can simply omit the use of the semicolon if you want the comments to be repeated every time you expand the Macro at the penalty of using more space in the symbol table.
Syntax: .NO expression1[,expression2] See also: .BS .DU .ED .EP .OR .PH .RF Function: The .NO directive is very similar to the .OR directive, yet has some significant differences. 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
Syntax: .OR expression See also: .BS .DU .ED .EP .NO .PH .RF 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. 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. 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
;
;
;
Syntax: .PG [expression] See also: .CP .EF .EJ .LF .LI .LM .SF .TF .TI .TW 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. 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.
Syntax: .PH expression See also: .BS .DU .ED .EP .NO .OR .RF 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 of the patch mode and replaces the temporary program counter with the original one again. Explanation: The expression may not contain forward referenced labels otherwise a fatal "Undefined label error" will be reported. A possible 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.
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 address $0000 to $07FF (2 kb) is always available. The memory 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.
Syntax: .RF expression1,[expression2] See also: .AS .AT .AZ .DA .DB .DL .DR .DW .HS Function: The .RF directive can fill a portion of memory with randomly generated bytes. This can be useful for software security. Explanation: The expression1 indicates the number of bytes that should be filled with randomly generated values. Expression1 may not contain any forward referenced labels. 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. The exact value of the seed is not important and may range from $0000 to $FFFF. Larger values will be truncated to 16 bit values. 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. 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
|