HCD65 MACRO ASSEMBLER --------------------- INTRODUCTION HCD65 is powerful macro assembler with a rich set of directives to support the most demanding assembly needs. It supports the full MOS65xx instruction set, and provides facilities for for user customization. The macro capability helps to eliminate some of the tedium associated with assembly language programming. This assembler is similar in nature to the assembler used by Commodore systems software engineers to develop all of the code for our C128 product line. In fact, one benchmark used for testing this assembler was to assemble the C128 source files on the C128. INPUT FILES: HCD65xx accepts sequential type text files as source input. These files must come from disk. OUTPUT FILES: HCD65xx has three types of output files: listing file object file error file Each of these files uses a specific channel specified by a basic startup program. This allows the user to direct the output for these files to which ever output device deemed appropriate. The output for these files may also be inhibited, or all files may be merged so that their output is combined. TEMPORARY FILES: HCD65xx uses a sequential type disk file for holding cross reference information. The user may cause this file to not be used ( therefore no cross reference is generated, or he may specify which disk drive is to be used for this file. HCD65xx contains a rich set of conditional assembly directives. Conditionals may be nested up to 10 deep. HCD65xx has a powerful macro facility which is not just a conventional text expansion macro facility. The macro facility allows macros to redefine opcodes, or even allows macros which define, or redefine other macros. Combined with the conditional assembly features, macros provide a powerful tool for code generation. Macros can be nested to any depth, but are practically limited limited by the amount of memory in the machine. HCD65xx consists of two distinct programs. The first is a user customisable BASIC shell. This program is responsible for setting up the machine language assembler. BASIC is responsible for: Providing the user interface, Setting up the many assembler parameters regarding which information goes where, etc. The BASIC control program runs, sets up communications registers to the machine code, and then passes control to the machine language program. The machine language performs the actual assembly, and returns control to BASIC which then performs some housekeeping. By using BASIC, the user has control over the following: The source file to be assembled. The disk drive(s) to be searched for source files. The output device to send the listing to. The output device to send error reports to. The output device to send the object file to. The disk drive to use for the cross reference temporary file. How many characters wide the listing should be. What to print for the date on each listing page. The BASIC shell program is totally customizable by the user to perform whatever assembly functions are desired. The machine language program runs adapting to the available memory left over by the text for the BASIC program. Because all variables may be overwritten by the assembly, it is neccesary tto execute a CLR statement immediately after the SYS call to the assembler. The assembler's machine code resides from $1700-$3FFF in bank 1. The only memory regions which are guarenteed to be found intact after an assembly are zero page, the basic text, and memory above the top of basic pointer in bank0. MACHINE CODE INTERFACE: The machine code inteface uses a set of memory locations at $1300 to pass paramenters to the machine code. An important thing to remembner is that placeing garbage in these locations can cause the assembler to malfunction. The assembler is a tool to debug your souurce files, and is therefore very forgiving to information found there. It is not a tool to debug the BASIC shell. CHANNELS & SECONDARY ADDRESSES 1) THE USER MAY ONLY USE SECONDARY ADDRESSES FROM 2-7 FOR FILES WHICH ARE OPEN TO DISKS BY THE BASIC PROGRAM. 2) THE USER MAY ONLY USE LOGICAL FILE NUMBERS FROM 2-7 FOR CHANNELS OPENED BY THE BASIC PROGRAM. 3) A channel number of zero inhibits output to that channel. 4) Output channels may be RS232, screen, or serial buss devices. ( I/O to cassette is disallowed because the cassette buffer is raped by the assembler for free memory. ) All that is required of BASIC is to open and close these channels for this assembler. LIST_CHANNEL $1300 The object channel parameter informs the assembler which logical file number to output the list file data too. ERROR_CHANNEL $1301 The object channel parameter informs the assembler which logical file number to output the error file data too. If the error channel is different from the listing channel, The error channel will show all listing lines which errors are detected on, and will also show which files are currently being assembled. If the error channel is the same as the listing channel, then the error channel is effectively inhibited because all errors are reported to the listing channel. Note that information regarding the current include file is inhibited in the listing because this information is displayed in the .INCLUDE statement. OBJECT_CHANNEL $1302 The object channel parameter informs the assembler which logical file number to output the object file data too. SOURCE_DEVICE_LOW $1303 SOURCE_DEVICE_HIGH $1304 HCD65xx can be configured to look for source files on one disk, and if they are not there, search the next disk for the file. These two parameters determine which disks will be searched for source files. The assembler always searchs in order of increasing device number. XREF_DEVICE $1305 The xref device is the device number of the disk drive that the temporary cross reference file is to be created on. The assembler manages this binary file. LIST_CHANNEL_WIDTH $1306 The list channel width is the maximum number of coloumns to print on a listing line. Listing lines greater than this value are truncated. Setting this value too high result in improper paging. SOURCE_FILE_NAME $1307-1317 The source file name is 17 byte area which should contain the null terminated source file name. As with include files, it is not neccesary to append a .SRC to the end of the file as this is done internally. DATE_STRING $1317-$1338 The data string is a 33 byte area which is contain a null terminated section of text. This text is printed in the listing, at the top of every page, in the date feild. INPUT FILE FORMAT: There are four field recognized by the assembler. Each is optional and they typically are delimited by spaces or tabs. Label Field Operator field Argument field Comment field Comment lines are marked with a semicolon as the first non white character. Any characters appearing after a semicolon ( except one that appears in quotes ) are considered to be comments and are ignored. Any text starting in the first column which is non blank and is not a comment is considered to be a label or symbol except in the case where there is a .macro directive on that line in which case the text is considered to be the macro name. The text in the second field defines how the assembler will interpret that line. Mnemonics, assembler directives, and macro calls are all placed here. The third field generally contains arguments to the second field. In cases where the operation does not expect arguments, the third field is considered to be a comment field. Anything after the third field is considered to be a comment. CASE SENSITIVITY: The assembler is case insensitive for all non quoted strings. This includes symbol names, label names, macro names, opcodes, and directives. The list file will show the source statements in whatever case they are presented to the assembler in. The symbol table and cross references will list all symbols in the same case. Subtitles, program names, and other uniquely textual items are not case clamped. CONSTANTS Internally, HCD65xx uses 16 bit values to represent constants. Constants may be expressed in one of four radixs or may be created using literal strings. Hexadecimal Constants: Hexadecimal Constants are represented by up two four hexadecimal characters following a dollar sign ( i.e. $1A7F ). Decimal Constants: Decimal constants are represented by one to five decimal digits. No leading radix character is needed. Octal Constants Octal constants are represented by preceding an octal number with the "@" symbol. ( i.e. @17777 ). Binary Constants Binary constants are represented by preceding a binary number with the "%" symbol. ( i.e. %01010100111 ). Literal Constants Literal constants are represented by one or two ASCII or PETSCII characters enclosed in matching single quote characters. In Certain situations, only the first single quote is neccesary. Certain differences exist in the way the .BYTE directive handles quoted strings. See that directive's explanation. In the case where two literal characters are enclosed in quotes, the assembler places the first character in the low order field in the resulting sixteen bit value. SYMBOLS & LABELS: Three type of symbols are supported by the assembler. Global symbols Global labels Local labels Global symbols and labels represent 16 bit values. A symbol consists of alphanumeric characters. None of the characters can be the characters which the assembler recognizes as an expression delimiter ( i.e. quote marks, spaces, expression operators, radix operators, etc ). In addition, the first character in a symbol name cannot be a digit from 0-9 as those characters are indicative of local labels. Examples of valid symbols the_routine_is_here a3485734583488 periods.are.legal this_symbol_so_long_that_it_is_the_same_as_the_next this_symbol_so_long_that_it_is_the_same_as_the_previous Examples of illegal symbols here+nop ; this is an expression with two symbols 123ksdhjfks ; this starts with a digit blah;blah Global symbols or global labels may be of any length although only the first 32 characters are significant and all other characters are truncated for cross reference and symbol table purposes. Global labels differ from global symbols in the symbols can be redefined many times during assembly, labels can only be defined once. A symbol definition must be made explicitly using the equals sign ('='). Any time a potential symbol appears in the label field, and is not explicitly made a symbol using the equals sign, it becomes a label and further attempts to define it result in assembly error generation. Local labels take the form or one to three decimal digits with the value of 1-255 immediately followed by a dollar sign. Examples of local labels 100$ ; this is legal 001$ ; this is the same as the next 1$ ; this is the same as the previous 999$ ; this is illegal ( 1-255 ). The range over which a local labels is defined is delimited by two things: 1) global labels 2) the .local directive. Example: test jsr 10$ ; ok 10$ bne 20$ ; ok 20$ bpl 30$ ; not ok, 30$ not defined here test2 nop ; the label here delimits the 30$ 30$ bne 10$ ; ok, this 10$ is the one below. 10$ nop ; ok, this is a different 10$ than the ; the one on the second line. .local jmp 30$ ; not ok, the .local directive limits ; the range of the 30$ ASSIGNING VALUES TO SYMBOLS Symbols may given a value in two ways. 1) Appearance in the label field. A symbol which appears in the label field becomes a label except in 2 cases. 1) The symbol is being assigned a value using the '=' sign. ( see below ) 2) The symbol appears on a line with a .MACRO directive. In this case the symbol becomes the name of macro. 2) Explicit assignment using the equals sign. A symbol may be assigned a value using the equals sign. For example: ten = $10 ; assign the hex value 10 to the symbol "ten" SPECIAL SYMBOLS The asterisk "*" is a special symbol. It represents the current program counter. It may both be assigned a value , and it may be evaluated. EXPRESSIONS Expression processing in HCD65xx accepts a large number of operators. Expressions are evaluated left to right except where the below mentioned precedents are relevant. Highest Priority operators: Unary + truth operator Unary - twos complement operator !N ones complement operator < low byte operator ( returns low byte of value ) > high byte operator ( returns high byte of value ( Second Priority operators: * 16 bit multiply, returns low order 16 result / 16 bit divide. returns quotient. !M 16 bit divide. returns modulus. !. logical AND !+ logical OR !X logical Exclusive OR Lowest Priority operators: Binary + 16 bit addition, carry discarded Binary - 16 bit subtraction, borrow ignored. For Example $1234 = $1234 >$1234 = $0012 >$1234+1 = $0013 1+>$1234 = $0013 5-1-1 = $0003 -1 = $FFFF >-1 = $00FF !N$000F = $FFF0 MACROS: The macro facility provides text expansion and substitution capability. Macros are defined by enclosing a block of of text in .MACRO and .ENDM directives. All of the text between the two directives composes the body of the macro. When the .MACRO directive is found, there must be a macro name in the label field. That name is used to call the macro. Whenever the assembler finds text in the operator field which is not preceded by a period ( indicating a directive ), it checks to see if that text is a macro name before checking to see if that text is an opcode mnemonic. When a macro call is encounter in the source file, the text for the body of the macro with that name is substituted into the input stream where the macro call was. Therefore one macro call can result in many lines of code for the rest of the assembler to handle. Example of macro definition: ; the following macro clears the x and a registers. clr_reg .macro lda #0 ldx #0 .endm Example of macro call: label nop clr_reg nop Resulting assembled code: label nop lda #0 ldx #0 nop Macros are expanded in a preprocessor before the input lines are fed to the assembler proper. They work entirely on a text substitution basis. Macros allow arguments to be used. Dummy arguments are declared in as arguments to the .MACRO directive. They are separated by commas. Many arguments are allowed, the upper limit is determined by the maximum length of the input string. When a macro is called, the input text is expanded verbatim except where dummy arguments occur. In this case, the arguments following the call to the macro are substituted into the positions where the dummy arguments were in the macro definition. Example macro for loading a and x with immediate data. definition ldax .macro arg lda #>arg ldx #$1234 ldx #<$1234 Because the macro facility only knows about text streams, and does not know about specific fields, the user must be careful in the selection of of dummy arguments. Using short arguments can lead to unexpected expansions. for example, this following innocent looking source code performs unexpectedly: definition: ; store value in arg into memory at loc. addax .macro a lda #a sat loc .endm call: label nop addax $0F nop expansion: label nop ld$0F #$0F st$0F loc .endm This clearly erroneous expansion occurred because the macro facility blindy substitutes macro args wherever dummy args occur in the macro definition. One solution is to use longer dummy argument names. Another solution preferred by many users is to precede simple dummy argument names with a rarely used character. Percent is a good choice. definition: ; store value in arg into memory at loc. addax .macro %a lda #%a sat loc .endm call: label nop addax $0F nop expansion: label nop lda #$0F sat loc .endm Clearly this works much better. Macros can have many arguments. Blank dummy arguments can occur in macro definitions. Arguments occurring in macro calls which have no corresponding dummy argument in the macro definition are simply ignored. Blank arguments occurring in macro calls evaluate as nothing when the macro is expanded. For example: Definition: ld_chrs .macro %a,%b lda #'%a' ldx #'%b' .endm Call: label nop ld_chrs 1,,3 nop Expansion: label nop lda #'1' ldx #'' .endm Occasionally it is neccesary to pass arguments to macros which cannot be achieved using the previously defined operation of macros. There is a Kludge around this. When a macro is to be expanded, the arguments are scanned for matching sets of angle brackets ( "<",">" ). If these are found then all the text between the angle brackets is passed as a single macro argument after the brackets are stripped away. For example: Definition: ld_chrs .macro %a,%b lda #'%a' ldx #'%b' .endm Call: label nop ld_chrs 1,<,> nop Expansion: label nop lda #'1' ldx #',' .endm nop Many conditionals are supplied expressly for using inside of macros to allow detection of null fields, undefined symbols, etc. Other directives ( .REPT, .IRPC, IRP ) are actually special cases of macros and work using many .MACRO like principles. LISTING FORMAT Many directives are supplied for controlling the format of the list file output. NOTE: The list file output control only applies to normal listing output. If you define the object file as being the same as the list file, then the object file lines will appear in the listing as they are output by the assembler, and independent of the settings imposed by any listing directives. The listing output has many features. The listing is paginated with several lines of information at the top of each page. Here is an example of a portion of a single page. Note that this page shows a call to the macro LD_CHRS used as an example in the previous sections describing macros. -------------------------------------------------------------------------------- MY_PROGRAM HCD65XX V1.0 12-DEC-1985 PAGE 10 UTILITY SUBROUTINES 0:UTILITIES.SRC,S,R ERROR ADDR CODE SEQ SOURCE STATEMENT 8122 EA 7000 LABEL NOP V 8123 A9 02 7001 LDA #$1002 7002+ LD_CHRS 1,<,> 8125 A9 31 7003A LDA #'1' 8127 A2 2C 7004A LDX #',' 8129 EA 7005 NOP -------------------------------------------------------------------------------- The top line contains four things: 1) The program name as defined by the .NAME directive. 2) Information identifying the assembler and version number. 3) The date information as described by the BASIC startup file. 4) The page number. The second line contains two things: 1) The text defined by the last .SUBTTL directive. 2) The current source file being read to generate this page. The third line contains headers for the columns output by the assembler. Source code listing lines have several fields. 1) Error field: The error field is the first one on the page. It is placed there so that lines with error may be easily found. In general, assembly errors are indicated by a single letter in the error field on the line the error occurred on. In a line exhibits multiple errors, then several letters will appear there. One such error is shown in the sample listing indicating that a "VALUE" error occurred. This is because that line is attempting to load the eight bit accumulator with a sixteen bit value. 2) Address field: The address field generally indicates the address of any object code bytes which are listed on that line. 3) Object field: The object field generally indicates any object code bytes which were generated by the current line. It may also contain a 16 bit value preceded by an equals sign. This indicates the value of some expression which was evaluated on the line ( for use in conditional directives, or which a symbol is equated too ). 4) Sequence field: The sequence field indicates the line number of the current source line. If a macro is called on this line then the sequence field is followed by a "+" sign. If the line was generated by a macro then sequence field is followed by a single letter from A-Z. This letter indicates the depth of macro expansion which is generating the current line. 5) The source statement field contains the verbatim source code for the current line. No beatification is performed. Tabs are displayed normally because the sequence field starts on a tab stop. LISTING CONTROL DIRECTIVES Each of the listing control directives is discussed here. Note the all source lines containing the directives are inhibited from the listing. Listing control directives are meant to control the listing, not add too it. .NAME text .NAM text The .NAME directive is used to inform the assembler of the name of the code being assembled. When the .NAME directive is encountered, all text following the .NAME directive is copied to a buffer and is printed on each page header. The source line containing the .NAME directive is not listed. If the name is too long, it is truncated. .SUBTTL text The .SUBTTL directive is used to inform the assembler of a subttile for the current listing pages. When .SUBTTL directive is encountered, all text following the .SUBTTL directive is copied to a buffer and is printed on each page header. The source line containing the .SUBTTL directive is not listed. If the name is too long, it is truncated. .PAGE .PAG The .PAGE directive forces the listing file to the top of a next page is it is not currently there. .SKIP 0 .ELSE lda #0 ; this line is assembled if SYMBOL = 0 .ENDIF The main features of a conditional are the conditional directive itself, and the .ENDIF directive terminating the range of the conditional. In between these two lines is the conditional body. Normally the conditional body is assembled if the question the conditional directive asks is true. The .ELSE directive may be used to toggle the relative "TRUTH" of the conditional assembly thereby allowing the conditional to select between sections of source code to be assembled. All parts of the conditional other than the .ENDIF and the CONDITIONAL line itself are optional. The use of undefined symbols in the expression for the conditional results in an error being generated, and the conditional makes a choice as to whether to evaluate true or false. There are several numeric conditionals. Each of these accepts a single expression as its argument. Numeric evaluation is considered to be 16 bit two complement. .IFE expression evaluates true if expression is 0. .IFN expression evaluates true if expression <> 0. .IFGE expression evaluates true if expression is >= 0. .IFGT expression evaluates true if expression is > 0. .IFLT expression evaluates true if expression is < 0. .IFLE expression evaluates true if expression is =< 0. There are several textual conditionals. These are essentially useless if used alone. However, when combined with macros they can make lots of tasks easier. They can , for example, be used to detect the presence or absence of arguments. .IFB .IFNB The .IFB directive evaluates true if its argument is found to be blank. Because of its nature, it is strongly recommended that is argument is delimited by the enclosing angle brackets as discussed in the section describing MACROS. .IFNB is simply the inverse of .IFB .IFIDN , .IFNIDN , .IFIDN evalauates true if the two argument strings are identical. This operation is case sensitive. .IFNIDN evaluates true if they are not identical. .IFDEF .IFNDEF .IFDEF evaluates true if the argument is both a legal symbol name, and has been previously defined in the source file. .IFNDEF evaluates true if the argument is either not a legal symbol name, or has not previously been defined. MISCELLANEOUS DIRECTIVES .LOCAL The .LOCAL directive is used to delimit the range of local labels. It enables this operation without forcing the unneccesary act of thinking up yet another label name. .MESSG The .MESSG forces the following text to be echoed out the error channel during pass2. Its primary use is inside of conditionals to present error messages for code overflow, etc. .RMB .RMB is functionally identical to "*=*+". It advances the program counter without generating object code. ERROR REPORTING There are three types of errors reported by the assembler: Errors are issued to the error channel and to the listing. FATAL ERRORS Fatal errors are those which prevent the assembler from continuing the assembly. These include running out or macro expansion space, and read errors from disk in the middle of a file. Fatal errors result in assembly termination. Fatal errors are accompanied by error messages. SYSTEM ERRORS System errors include not being able to find an include file, unable to properly access the cross reference file, and other such non fatal errors. ASSEMBLY ERRORS Assembly errors are those related to the source file content. They can usually be associated with a single erroneous line of source code. As such assembly errors are reported in the listing on the same line with the offending source. If the error channel is different from the listing channel, then the offending line is also echoed to the error channel. Assembly errors occur for a variety of reasons. Each one has a specific error code printed in the first few columns of the listing output. The error codes and their reasons are listed below. A Address error. Indicates bad address valued expression was evaluated. May indicate branch out of range. B Balance error. Quotes, or angle brackets are mispaired on this line. E Expression error. Invalid syntax in an expression. This error is more serious than a syntax error. Occurs when invalid expressions are used in critical places ( like * = undefined_symbol ). F Field error. Something is missing on the line. J Indicates that the address space is filled and that the resulting object code has wrapped from $FFFF to $0000 and a byte was created at $0000. M Multiply-defined symbol. A symbol is defined more than once (where this is illegal). All but the first definition are ignored. N Nesting error. Unexpected .ELSE, .ENDIF, .ENDR, or .ENDM detected. O Undefined opcode or macro call used on this line. P Phase error. Indicates the value of label was different in pass 2 than in pass 1. This may indicate a source file ( disk ) problems or some sort of illegal forward reference. The assembler is confused. Q Questionable syntax. Indicates a syntax error which the assembler has resolved by some ( probably incorrect ) assumption. S Syntax error. Generated for all sorts of syntactical errors. U Undefined symbol. The assembler attempted to evaluate an expression which has an undefinde symbol in it. V Value error. An operand value was out of range. Typically generated when an 16 bit value is placed in an eight bit field. Also flags attempts to branch out of range. W Wasted byte warning. Generated when the assembler is forced to use an absolute addressing mode where a zero page addressing mode would suffuce. This warnging is typically created by forward references. Z Division by zero error. Generated when an expression requests the assembler to divide by zero. Shame on you. @ Symbol table overflow. The symbol table is full and A symbol on this line cannot be written to the symbol table. All references to this symbol shall result in undefined symbol errors. ? Internal error checking has conflicting results. This error occurs when the assembler detects an error which by design, should not occur. This is indicative of a bug, however chances are that some construct on the line is questionable. This error can usually be eliminated by rearranging the line. * Too many error codes were generated for this line for the assembler to list them all. APPENDIX I SUPPORTED INSTRUCTION SET This assembler supports the full 65xx instruction set. The following opcode table lists the opcodes, and their associated mnemonics. opcode . immediate . . absolute addressing mode . . . zero page . . . . accumulator . . . . . implied . . . . . . indirect,x . . . . . . . indirect,y . . . . . . . . zero page,x . . . . . . . . . absolute,x . . . . . . . . . . . relative . . . . . . . . . . . . indirect . . . . . . . . . . . . . zero page,y . ADC $69 $6D $65 ... ... $61 $71 $75 $7D $79 ... ... ... AND $29 $2D $25 ... ... $21 $31 $35 $3D $39 ... ... ... ASL ... $0E $06 $0A ... ... ... $16 $1E ... ... ... ... BCC ... ... ... ... ... ... ... ... ... ... $90 ... ... BCS ... ... ... ... ... ... ... ... ... ... $B0 ... ... BEQ ... ... ... ... ... ... ... ... ... ... $F0 ... ... BIT ... $2C $24 ... ... ... ... ... ... ... ... ... ... BMI ... ... ... ... ... ... ... ... ... ... $30 ... ... BNE ... ... ... ... ... ... ... ... ... ... $D0 ... ... BPL ... ... ... ... ... ... ... ... ... ... $10 ... ... BRK ... ... ... ... $00 ... ... ... ... ... ... ... ... BVC ... ... ... ... ... ... ... ... ... ... $50 ... ... BVS ... ... ... ... ... ... ... ... ... ... $70 ... ... CLC ... ... ... ... $18 ... ... ... ... ... ... ... ... CLD ... ... ... ... $D8 ... ... ... ... ... ... ... ... CLI ... ... ... ... $58 ... ... ... ... ... ... ... ... CLV ... ... ... ... $B8 ... ... ... ... ... ... ... ... CMP $C9 $CD $C5 ... ... $C1 $D1 $D5 $DD $D9 ... ... ... CPX $E0 $EC $E4 ... ... ... ... ... ... ... ... ... ... CPY $C0 $CC $C4 ... ... ... ... ... ... ... ... ... ... DEC ... $CE $C6 ... ... ... ... $D6 DE ... ... ... ... DEX ... ... ... ... $CA ... ... ... ... ... ... ... ... DEY ... ... ... ... $88 ... ... ... ... ... ... ... ... EOR $49 i$4D $45 ... ... $41 $51 $55 $5D $59 ... ... ... INC ... $EE $E6 ... ... ... ... $F6 $FE ... ... ... ... INX ... ... ... ... $E8 ... ... ... ... ... ... ... ... INY ... ... ... ... $C8 ... ... ... ... ... ... ... ... JMP ... $4C ... ... ... ... ... ... ... ... ... $6C ... JSR ... $20 ... ... ... ... ... ... ... ... ... ... ... LDA $A9 $AD $A5 ... ... $A1 $B1 $B5 $BD $B9 ... ... ... LDX $A2 $AE $A6 ... ... ... ... ... ... $BE ... ... $B6 LDY $A0 $AC $A4 ... ... ... ... $B4 $BC ... ... ... ... LSR ... $4E $46 $4A ... ... ... $56 $5E ... ... ... ... NOP ... ... ... ... $EA ... ... ... ... ... ... ... ... ORA $09 $0D $05 ... ... $01 $11 $15 $1D $19 ... ... ... PHA ... ... ... ... $48 ... ... ... ... ... ... ... ... PHP ... ... ... ... $08 ... ... ... ... ... ... ... ... PLA ... ... ... ... $68 ... ... ... ... ... ... ... ... PLP ... ... ... ... $28 ... ... ... ... ... ... ... ... ROL ... $2E $26 $2A ... ... ... $36 $3E ... ... ... ... ROR ... $6E $66 $6A ... ... ... $76 $7E ... ... ... ... RTI ... ... ... ... $40 ... ... ... ... ... ... ... ... RTS ... ... ... ... $60 ... ... ... ... ... ... ... ... SBC $E9 $ED $E5 ... ... $E1 $F1 $F5 $FD $F9 ... ... ... SEC ... ... ... ... $38 ... ... ... ... ... ... ... ... SED ... ... ... ... $F8 ... ... ... ... ... ... ... ... SEI ... ... ... ... $78 ... ... ... ... ... ... ... ... STA ... $8D $85 ... ... $81 $91 $95 $9D $99 ... ... ... STX ... $8E $86 ... ... ... ... ... ... ... ... ... $96 STY ... $8C $84 ... ... ... ... $94 ... ... ... ... ... TAX ... ... ... ... $AA ... ... ... ... ... ... ... ... TAY ... ... ... ... $A8 ... ... ... ... ... ... ... ... TSX ... ... ... ... $BA ... ... ... ... ... ... ... ... TXA ... ... ... ... $8A ... ... ... ... ... ... ... ... TXS ... ... ... ... $9A ... ... ... ... ... ... ... ... TYA ... ... ... ... $98 ... ... ... ... ... ... ... ... APPENDIX II Assembler limitations: Symbol table size: The symbol table is stored in bank 1. Its size is 61k bytes. Each symbol requires 8 bytes plus the number of characters in the symbol name. Local symbols always require 11 bytes. Input buffer size. All defined macros, any macro expansions, and the input buffers ( page length per file ), are stored in a heap immediately following the BASIC shell ( which starts at $4000 ) and terminating at $8000. The input buffer is also used for sorting during the cross reference phase. The assembler will perform as many passes through the temporary file as are neccesary to complete the cross reference. Maximum line length The assembler truncates input lines at 132 characters. Internal macro expansion lines are also terminated at 132 characters. No errors are reported for truncation. Discarded control characters The assembler accepts PETSCII or ASCII text. All control characters ($00-$1F) are removed when the file is read in except the tab and carriage return characters. Tabs are treated in the expected fashion. Maximum source file size. Maximum list file size. Maximum object file size. Maximum cross reference file size. Maximum error file size. These things are limited by the available disk capacity, the amount of paper in your printer, and indirectly, by the symbol table size. APPENDIX III LIVING WITHIN THE 1541/1571 DOS. The 15xx series of disk drives have certain limitations which must actively be observed by users of this assembler. Primarily, these relate to specific problems within the drives which cannot, or should not be accounted for within the scope of the assembler proper. These are outlined below. NEVER cause the assembler to attempt to open more than three files on any given drive. If you do, then output files will show a marked tendency to become intermixed thereby confusing both the DOS and the assembler. This means that if you are attempting to perform assemblies on a single drive system, you cannot request two output files to that drive. Note that requesting a cross reference requires a temporary cross reference file to be generated on your drive, and that this counts as a cross reference file. Single drive assembly Single source files with no includes: Legal combos object file and xref file object file and list file object file and error file xref file and list file xref file and error file list file and error file and one output file. Multiple source files ( .INCLUDE used ) Legal combos zero or one output files consisting of xref, object, list or error file. Note: Opening more than two files for simultaneous read access on a given drive is trapped by the drive and results in the third file being ignored. Note that the assembler buffers input files and therefore it may be possible to to do this if the buffering coincidentally works out correctly. Two drive assembly. The most preferred technique for two drive assembly is to have all the source files on one disk, and one or two output files on the other disk. This way, the source file disk is never opened for output and therefore stands very little chance of becoming corrupted. Write protecting the source disk is of course even safer, however we have seen no errors of this type in our testing.