D A65.DOC => A65.DOC +0 -1262
@@ 1,1262 0,0 @@
-/*
- HEADER: CUG129;
- TITLE: 6502/65C02 Cross-Assemblers;
- FILENAME: A65.DOC;
- VERSION: 0.1;
- DATE: 08/27/1988;
-
- DESCRIPTION: "These programs let you use your computer to assemble
- code for the MOS Technology 6502 and Rockwell 65C02
- microprocessors. The program is written in portable
- C rather than BDS C. All assembler features are
- supported except relocation, linkage, and macros.";
-
- KEYWORDS: Software Development, Assemblers, Cross-Assemblers,
- MOS Technology, Rockwell, 6502, 65C02;
-
- SYSTEM: CP/M-80, CP/M-86, HP-UX, MSDOS, PCDOS, QNIX;
- COMPILERS: Aztec C86, Aztec CII, Eco-C, HP-UX, Microsoft C,
- QNIX C;
-
- WARNINGS: "HP-UX is a Berkeley 4.2 UNIX look-alike, so the port
- to UNIX should be trivial. So far, the program
- compiles under two different MSDOS/PCDOS compilers, so
- the port to other MSDOS/PCDOS compilers should be
- easy.";
-
- AUTHORS: William C. Colley III;
-*/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 6502/65C02 Cross-Assemblers
-
-
- Version 0.1
-
-
- Copyright (c) 1986 William C. Colley, III
-
-
-
-
-
-
- The manual such as it is.
-
-
-
-
-
-
-
-
-
-
-
- Legal Note: This package may be used for any commercial or
- non-commercial purpose. It may be copied and
- distributed freely provided that any fee charged
- by the distributor of the copy does not exceed the
- sum of: 1) the cost of the media the copy is
- written on, 2) any required costs of shipping the
- copy, and 3) a nominal handling fee. Any other
- distribution requires the written permission of
- the author. Also, the author's copyright notices
- shall not be removed from the program source, the
- program object, or the program documentation.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Table of Contents
-
- 1.0 How to Use the Cross-Assembler Package .................. 3
- 2.0 Format of Cross-Assembler Source Lines .................. 4
- 2.1 Labels ............................................. 5
- 2.2 Numeric Constants .................................. 5
- 2.3 String Constants ................................... 6
- 2.4 Expressions ........................................ 6
- 3.0 Machine Opcodes ......................................... 7
- 4.0 Pseudo Opcodes .......................................... 9
- 4.1 Pseudo-ops -- END .................................. 9
- 4.2 Pseudo-ops -- EQU .................................. 10
- 4.3 Pseudo-ops -- FCB .................................. 10
- 4.4 Pseudo-ops -- FCC .................................. 10
- 4.5 Pseudo-ops -- FDB .................................. 11
- 4.6 Pseudo-ops -- IF, ELSE, ENDI ....................... 11
- 4.7 Pseudo-ops -- INCL ................................. 12
- 4.8 Pseudo-ops -- ORG .................................. 12
- 4.9 Pseudo-ops -- PAGE ................................. 12
- 4.10 Pseudo-ops -- RMB .................................. 13
- 4.11 Pseudo-ops -- SET .................................. 13
- 4.12 Pseudo-ops -- TITL ................................. 13
- 5.0 Assembly Errors ......................................... 13
- 5.1 Error * -- Illegal or Missing Statement ............ 14
- 5.2 Error ( -- Parenthesis Imbalance ................... 14
- 5.3 Error " -- Missing Quotation Mark .................. 14
- 5.4 Error A -- Illegal Addressing Mode ................. 14
- 5.5 Error B -- Branch Target Too Distant ............... 14
- 5.6 Error D -- Illegal Digit ........................... 14
- 5.7 Error E -- Illegal Expression ...................... 15
- 5.8 Error I -- IF-ENDI Imbalance ....................... 15
- 5.9 Error L -- Illegal Label ........................... 15
- 5.10 Error M -- Multiply Defined Label .................. 15
- 5.11 Error O -- Illegal Opcode .......................... 15
- 5.12 Error P -- Phasing Error ........................... 16
- 5.13 Error R -- Illegal Register ........................ 16
- 5.14 Error S -- Illegal Syntax .......................... 16
- 5.15 Error T -- Too Many Arguments ...................... 16
- 5.16 Error U -- Undefined Label ......................... 16
- 5.17 Error V -- Illegal Value ........................... 16
- 6.0 Warning Messages ........................................ 17
- 6.1 Warning -- Illegal Option Ignored .................. 17
- 6.2 Warning -- -l Option Ignored -- No File Name ....... 17
- 6.3 Warning -- -o Option Ignored -- No File Name ....... 17
- 6.4 Warning -- Extra Source File Ignored ............... 17
- 6.5 Warning -- Extra Listing File Ignored .............. 17
- 6.6 Warning -- Extra Object File Ignored ............... 17
- 7.0 Fatal Error Messages .................................... 17
- 7.1 Fatal Error -- No Source File Specified ............ 17
- 7.2 Fatal Error -- Source File Did Not Open ............ 18
- 7.3 Fatal Error -- Listing File Did Not Open ........... 18
- 7.4 Fatal Error -- Object File Did Not Open ............ 18
- 7.5 Fatal Error -- Error Reading Source File ........... 18
- 7.6 Fatal Error -- Disk or Directory Full .............. 18
- 7.7 Fatal Error -- File Stack Overflow ................. 18
-
-
-
- 1
-
-
-
- 7.8 Fatal Error -- If Stack Overflow ................... 18
- 7.9 Fatal Error -- Too Many Symbols .................... 18
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
- 1.0 How to Use the Cross-Assembler Package
-
- First, the question, "What does a cross-assembler do?" needs
- to be addressed as there is considerable confusion on this point.
- A cross-assembler is just like any other assembler except that it
- runs on some CPU other than the one for which it assembles code.
- For example, this package assembles 6502 or 65C02 source code
- into 6502 or 65C02 object code, but it runs on an 8080, a Z-80,
- an 8088, or whatever other CPU you happen to have a C compiler
- for. The reason that cross-assemblers are useful is that you
- probably already have a CPU with memory, disk drives, a text
- editor, an operating system, and all sorts of hard-to-build or
- expensive facilities on hand. A cross-assembler allows you to
- use these facilites to develop code for a 6502 or 65C02.
-
- This program requires one input file (your 6502 or 65C02 source
- code) and zero to two output files (the listing and the object).
- The input file MUST be specified, or the assembler will bomb on a
- fatal error. The listing and object files are optional. If no
- listing file is specified, no listing is generated, and if no
- object file is specified, no object is generated. If the object
- file is specified, the object is written to this file in "Intel
- hexadecimal" format.
-
- The command line for the 6502 cross-assembler looks like
- this:
-
- A65 source_file { -l list_file } { -o object_file }
-
- where the { } indicates that the specified item is optional.
-
- Some examples are in order:
-
- a65 test65.asm source: test65.asm
- listing: none
- object: none
-
- a65 test65.asm -l test65.prn source: test65.asm
- listing: test65.prn
- object: none
-
- a65 test65.asm -o test65.hex source: test65.asm
- listing: none
- object: test65.hex
-
- a65 test65.asm -l test65.prn -o test65.hex
- source: test65.asm
- listing: test65.prn
- object: test65.hex
-
- The order in which the source, listing, and object files are
- specified does not matter. Note that no default file name exten-
- sions are supplied by the assembler as this gives rise to porta-
- bility problems.
-
-
-
-
- 3
-
-
-
- The 65C02 cross assembler works the same way except that the
- command is "a65c" instead of "a65".
-
-
- 2.0 Format of Cross-Assembler Source Lines
-
- The source file that the cross-assembler processes into a
- listing and an object is an ASCII text file that you can prepare
- with whatever editor you have at hand. The most-significant
- (parity) bit of each character is cleared as the character is
- read from disk by the cross-assembler, so editors that set this
- bit (such as WordStar's document mode) should not bother this
- program. All printing characters, the ASCII TAB character ($09),
- and newline character(s) are processed by the assembler. All
- other characters are passed through to the listing file, but are
- otherwise ignored.
-
- The source file is divided into lines by newline char-
- acter(s). The internal buffers of the cross-assembler will
- accommodate lines of up to 255 characters which should be more
- than ample for almost any job. If you must use longer lines,
- change the constant MAXLINE in file A65.H or A65C.H and recompile
- the cross-assembler. Otherwise, you will overflow the buffers,
- and the program will mysteriously crash.
-
- Each source line is made up of three fields: the label
- field, the opcode field, and the argument field. The label field
- is optional, but if it is present, it must begin in column 1.
- The opcode field is optional, but if it is present, it must not
- begin in column 1. If both a label and an opcode are present,
- one or more spaces and/or TAB characters must separate the two.
- If the opcode requires arguments, they are placed in the argument
- field which is separated from the opcode field by one or more
- spaces and/or TAB characters. Finally, an optional comment can
- be added to the end of the line. This comment must begin with a
- semicolon which signals the assembler to pass the rest of the
- line to the listing and otherwise ignore it. Thus, the source
- line looks like this:
-
- {label}{ opcode{ arguments}}{;commentary}
-
- where the { } indicates that the specified item is optional.
-
- Some examples are in order:
-
- column 1
- |
- v
- GRONK LDA OFFSET, X ; This line has everything.
- STA MAILBOX ; This line has no label.
- BEEP ; This line has no opcode.
- ; This line has no label and no opcode.
-
- ; The previous line has nothing at all.
- END ; This line has no argument.
-
-
-
- 4
-
-
-
- 2.1 Labels
-
- A label is any sequence of alphabetic or numeric characters
- starting with an alphabetic. The legal alphabetics are:
-
- ! & , . : ? [ \ ] ^ _ ` { | } ~ A-Z a-z
-
- The numeric characters are the digits 0-9. Note that "A" is not
- the same as "a" in a label. This can explain mysterious U
- (undefined label) errors occurring when a label appears to be
- defined.
-
- A label is permitted on any line except a line where the
- opcode is IF, ELSE, or ENDIF. The label is assigned the value of
- the assembly program counter before any of the rest of the line
- is processed except when the opcode is EQU, ORG, or SET.
-
- Labels can have the same name as opcodes, but they cannot
- have the same name as operators or registers. The reserved
- (operator and register) names are:
-
- A AND EQ GE GT HIGH
- LE LT LOW MOD NE NOT
- OR SHL SHR X XOR Y
-
- If a label is used in an expression before it is assigned a
- value, the label is said to be "forward-referenced." For
- example:
-
- L1 EQU L2 + 1 ; L2 is forward-referenced here.
- L2
- L3 EQU L2 + 1 ; L2 is not forward-referenced here.
-
-
- 2.2 Numeric Constants
-
- Numeric constants can be formed in two ways: the Intel
- convention or the Motorola convention. The cross-assembler
- supports both.
-
- An Intel-type numeric constant starts with a numeric
- character (0-9), continues with zero or more digits (0-9, A-F),
- and ends with an optional base designator. The base designators
- are H for hexadecimal, none or D for decimal, O or Q for octal,
- and B for binary. The hex digits a-f are converted to upper case
- by the assembler. Note that an Intel-type numeric constant
- cannot begin with A-F as it would be indistinguishable from a
- label. Thus, all of the following evaluate to 255 (decimal):
-
- 0ffH 255 255D 377O 377Q 11111111B
-
- A Motorola-type numeric constant starts with a base
- designator and continues with a string of one or more digits.
- The base designators are $ for hexadecimal, none for decimal, @
- for octal, and % for binary. As with Intel-type numeric
-
-
-
- 5
-
-
-
- constants, a-f are converted to upper case by the assembler.
- Thus, all of the following evaluate to 255 (decimal):
-
- $ff 255 @377 %11111111
-
- If a numeric constant has a value that is too large to fit
- into a 16-bit word, it will be truncated on the left to make it
- fit. Thus, for example, $123456 is truncated to $3456.
-
-
- 2.3 String Constants
-
- A string constant is zero or more characters enclosed in
- either single quotes (' ') or double quotes (" "). Single quotes
- only match single quotes, and double quotes only match double
- quotes, so if you want to put a single quote in a string, you can
- do it like this: "'". In all contexts except the FCC statement,
- the first character or two of the string constant are all that
- are used. The rest is ignored. Noting that the ASCII codes for
- "A" and "B" are $41 and $42, respectively, will explain the
- following examples:
-
- "" and '' evaluate to $0000
- "A" and 'A' evaluate to $0041
- "AB" evaluates to $4142
-
- Note that the null string "" is legal and evaluates to $0000.
-
-
- 2.4 Expressions
-
- An expression is made up of labels, numeric constants, and
- string constants glued together with arithmetic operators,
- logical operators, and parentheses in the usual way that
- algebraic expressions are made. Operators have the following
- fairly natural order of precedence:
-
- Highest anything in parentheses
- unary +, unary -
- *, /, MOD, SHL, SHR
- binary +, binary -
- LT, LE, EQ, GE, GT, NE
- NOT
- AND
- OR, XOR
- Lowest HIGH, LOW
-
- A few notes about the various operators are in order:
-
- 1) The remainder operator MOD yields the remainder from
- dividing its left operand by its right operand.
-
- 2) The shifting operators SHL and SHR shift their left
- operand to the left or right the number of bits
- specified by their right operand.
-
-
-
- 6
-
-
-
-
- 3) The relational operators LT, LE, EQ, GE, GT, and NE can
- also be written as <, <= or =<, =, >= or =>, and <> or
- ><, respectively. They evaluate to $FFFF if the
- statement is true, 0 otherwise.
-
- 4) The logical opeators NOT, AND, OR, and XOR do bitwise
- operations on their operand(s).
-
- 5) HIGH and LOW extract the high or low byte, of an
- expression.
-
- 6) The special symbol * can be used in place of a label or
- constant to represent the value of the program counter
- before any of the current line has been processed.
-
- Some examples are in order at this point:
-
- 2 + 3 * 4 evaluates to 14
- (2 + 3) * 4 evaluates to 20
- NOT %11110000 XOR %00001010 evaluates to %00000101
- HIGH $1234 SHL 1 evaluates to $0024
- @001 EQ 0 evaluates to 0
- @001 = 2 SHR 1 evaluates to $FFFF
-
- All arithmetic is unsigned with overflow from the 16-bit
- word ignored. Thus:
-
- 32768 * 2 evaluates to 0
-
-
- 3.0 Machine Opcodes
-
- The opcodes of the 6502 and 65C02 processors are listed in
- the following table along with the various legal argument field
- formats. An X in the table indicates that the argument format is
- legal with the opcode on both processors. A * in the table
- indicates that the argument is legal only on the 65C02 processor.
- Opcodes that are unique to the 65C02 are flagged with a *.
-
- Opcode Argument Format
- 1 2 3 4 5 6 7 8 9 10 11
- ADC X * X X X X X
- AND X * X X X X X
- ASL X X X
- BBR * X
- BBS * X
- BCC X
- BCS X
- BEQ X
- BIT X * *
- BMI X
- BNE X
- BPL X
- BRA * X
-
-
-
- 7
-
-
-
- Opcode Argument Format
- 1 2 3 4 5 6 7 8 9 10 11
- BRK
- BVC X
- BVS X
- CLC
- CLD
- CLI
- CLV
- CMP X * X X X X X
- CPX X X
- CPY X X
- DEC X * X
- INC X * X
- INX
- INY
- JMP X X *
- JSR X
- LDA X * X X X X X
- LDX X X X
- LDY X X X
- LSR X X X
- NOP
- ORA X * X X X X X
- PHA
- PHP
- PHX *
- PHY *
- PLA
- PLP
- PLX *
- PLY *
- RMB * X
- ROL X X X
- ROR X X X
- RTI
- RTS
- SBC X * X X X X X
- SEC
- SED
- SEI
- SMB * X
- STA X * X X X X
- STX X X
- STY X X
- STZ * X X
- TAX
- TAY
- TRB * X
- TSB * X
- TSX
- TXA
- TXS
- TYA
-
-
-
-
- 8
-
-
-
- The argument field formats are:
-
- 1) expression where expression arbitrary is
- (except RMB and SMB where
- expression is 0 thru 255)
-
- 2) expression where the difference between
- expression and the beginning of the
- next instruction must be -128 thru
- 127
-
- 3) (expression) where expression is arbitrary
-
- 4) #expression where expression is -128 thru 255
-
- 5) A Note that the A may be attached to
- the opcode. Thus "LSR A" and
- "LSRA" are the same.
-
- 6) expression, X where expression is arbitrary
- (except STY where expression is 0
- thru 255)
-
- 7) expression, Y where expression is 0 thru 255
- (except LDX and STX where
- expression is arbitrary)
-
- 8) (expression, X) where expression is 0 thru 255
- (except JMP where expression is
- arbitrary)
-
- 9) (expression), Y where expression is 0 thru 255
-
- 10) bit, expression where bit is 0 thru 7 and
- expression is 0 thru 255
-
- 11) bit, expr1, expr2 where bit is 0 thru 7, expr1 is 0
- thru 255, and expr2 follows the
- same rule as 2) above
-
-
- 4.0 Pseudo Opcodes
-
- Unlike 6502/65C02 opcodes, pseudo opcodes (pseudo ops) do not
- represent machine instructions. They are, rather, directives to
- the assembler. These directives require various numbers and
- types of arguments. They will be listed individually below.
-
-
- 4.1 Pseudo-ops -- END
-
- The END pseudo-op tells the assembler that the source
- program is over. Any further lines of the source file are
- ignored and not passed on to the listing. If an argument is
- added to the END statement, the value of the argument will be
-
-
-
- 9
-
-
-
- placed in the execution address slot in the Intel hex object
- file. The execution address defaults to the program counter
- value at the point where the END was encountered. Thus, to
- specify that the program starts at label START, the END statement
- would be:
-
- END START
-
- If end-of-file is encountered on the source file before an
- END statement is reached, the assembler will add an END statement
- to the listing and flag it with a * (missing statement) error.
-
-
- 4.2 Pseudo-ops -- EQU
-
- The EQU pseudo-op is used to assign a specific value to a
- label, thus the label on this line is REQUIRED. Once the value
- is assigned, it cannot be reassigned by writing the label in
- column 1, by another EQU statement, or by a SET statement. Thus,
- for example, the following statement assigns the value 2 to the
- label TWO:
-
- TWO EQU 1 + 1
-
- The expression in the argument field must contain no forward
- references.
-
-
- 4.3 Pseudo-ops -- FCB
-
- The FCB (Form Constant Bytes) pseudo-op allows arbitrary
- bytes to be spliced into the object code. Its argument is a
- chain of one or more expressions that evaluate to -128 thru 255
- separated by commas. The sequence of bytes $FE $FF, $00, $01, $02
- could be spliced into the code with the following statement:
-
- FCB -2, -1, 0, 1, 2
-
-
- 4.4 Pseudo-ops -- FCC
-
- The FCC (Form Constant Characters) pseudo-op allows
- character strings to be spliced into the object code. Its
- argument is a chain of zero or more string constants separated by
- blanks, tabs, or commas. If a comma occurs with no preceding
- string constant, an S (syntax) error results. The string
- contants are not truncated to two bytes, but are instead copied
- verbatim into the object code. Null strings result in no bytes
- of code. The message "Kaboom!!" could be spliced into the code
- with the following statement:
-
- FCC "Kaboom!!" ;This is 8 bytes of code.
-
-
-
-
- 10
-
-
-
-
- 4.5 Pseudo-ops -- FDB
-
- The FDB (Form Double Bytes) pseudo-op allows 16-bit words to
- be spliced into the object code. Its argument is a chain of zero
- or more expressions separated by commas. If a comma occurs with
- no preceding expression, a word of $0000 is spliced into the
- code. The word is placed into memory low byte in low address,
- high byte in high address as per standard MOS Technology order.
- The sequence of bytes $FE $FF $00 $00 $01 $02 could be spliced
- into the code with the following statement:
-
- FDB $FFFE, , $0201
-
-
- 4.6 Pseudo-ops -- IF, ELSE, ENDI
-
- These three pseudo-ops allow the assembler to choose whether
- or not to assemble certain blocks of code based on the result of
- an expression. Code that is not assembled is passed through to
- the listing but otherwise ignored by the assembler. The IF
- pseudo-op signals the beginning of a conditionally assembled
- block. It requires one argument that may contain no forward
- references. If the value of the argument is non-zero, the block
- is assembled. Otherwise, the block is ignored. The ENDI pseudo-
- op signals the end of the conditionally assembled block. For
- example:
-
- IF EXPRESSION ;This whole thing generates
- FCB $01, $02, $03 ; no code whatsoever if
- ENDI ; EXPRESSION is zero.
-
- The ELSE pseudo-op allows the assembly of either one of two
- blocks, but not both. The following two sequences are
- equivalent:
-
- IF EXPRESSION
- ... some stuff ...
- ELSE
- ... some more stuff ...
- ENDI
-
- TEMP_LAB SET EXPRESSION
- IF TEMP_LAB NE 0
- ... some stuff ...
- ENDI
- IF TEMP_LAB EQ 0
- ... some more stuff ...
- ENDI
-
- The pseudo-ops in this group do NOT permit labels to exist
- on the same line as the status of the label (ignored or not)
- would be ambiguous.
-
-
-
-
- 11
-
-
-
- All IF statements (even those in ignored conditionally
- assembled blocks) must have corresponding ENDI statements and all
- ELSE and ENDI statements must have a corresponding IF statement.
-
- IF blocks can be nested up to 16 levels deep before the
- assembler dies of a fatal error. This should be adequate for any
- conceivable job, but if you need more, change the constant
- IFDEPTH in file A65.H and recompile the assembler.
-
-
- 4.7 Pseudo-ops -- INCL
-
- The INCL pseudo-op is used to splice the contents of another
- file into the current file at assembly time. The name of the
- file to be INCLuded is specified as a normal string constant, so
- the following line would splice the contents of file "const.def"
- into the source code stream:
-
- INCL "const.def"
-
- INCLuded files may, in turn, INCLude other files until four
- files are open simultaneously. This limit should be enough for
- any conceivable job, but if you need more, change the constant
- FILES in file A65.H or A65C.H and recompile the assembler.
-
-
- 4.8 Pseudo-ops -- ORG
-
- The ORG pseudo-op is used to set the assembly program
- counter to a particular value. The expression that defines this
- value may contain no forward references. The default initial
- value of the assembly program counter is $0000. The following
- statement would change the assembly program counter to $F000:
-
- ORG $F000
-
- If a label is present on the same line as an ORG statement,
- it is assigned the new value of the assembly program counter.
-
-
- 4.9 Pseudo-ops -- PAGE
-
- The PAGE pseudo-op always causes an immediate page ejection
- in the listing by inserting a form feed ('\f') character before
- the next line. If an argument is specified, the argument
- expression specifies the number of lines per page in the listing.
- Legal values for the expression are any number except 1 and 2. A
- value of 0 turns the listing pagination off. Thus, the following
- statement cause a page ejection and would divide the listing into
- 60-line pages:
-
- PAGE 60
-
-
-
-
-
- 12
-
-
-
- 4.10 Pseudo-ops -- RMB
-
- The RMB (Reserve Memory Bytes) pseudo-op is used to reserve
- a block of storage for program variables, or whatever. This
- storage is not initialized in any way, so its value at run time
- will usually be random. The argument expression (which may
- contain no forward references) is added to the assembly program
- counter. The following statement would reserve 10 bytes of
- storage called "STORAGE":
-
- STORAGE RMB 10
-
-
- 4.11 Pseudo-ops -- SET
-
- The SET pseudo-op functions like the EQU pseudo-op except
- that the SET statement can reassign the value of a label that has
- already been assigned by another SET statement. Like the EQU
- statement, the argument expression may contain no forward
- references. A label defined by a SET statement cannot be
- redefined by writing it in column 1 or with an EQU statement.
- The following series of statements would set the value of label
- "COUNT" to 1, 2, then 3:
-
- COUNT SET 1
- COUNT SET 2
- COUNT SET 3
-
-
- 4.12 Pseudo-ops -- TITL
-
- The TITL pseudo-op sets the running title for the listing.
- The argument field is required and must be a string constant,
- though the null string ("") is legal. This title is printed
- after every page ejection in the listing, therefore, if page
- ejections have not been forced by the PAGE pseudo-op, the title
- will never be printed. The following statement would print the
- title "Random Bug Generator -- Ver 3.14159" at the top of every
- page of the listing:
-
- TITL "Random Bug Generator -- Ver 3.14159"
-
-
- 5.0 Assembly Errors
-
- When a source line contains an illegal construct, the line
- is flagged in the listing with a single-letter code describing
- the error. The meaning of each code is listed below. In
- addition, a count of the number of lines with errors is kept and
- printed on the C "stderr" device (by default, the console) after
- the END statement is processed. If more than one error occurs in
- a given line, only the first is reported. For example, the
- illegal label "=$#*'(" would generate the following listing line:
-
- L 0000 FF 00 00 =$#*'( CPX #0
-
-
-
- 13
-
-
-
-
-
- 5.1 Error * -- Illegal or Missing Statement
-
- This error occurs when either:
-
- 1) the assembler reaches the end of the source file
- without seeing an END statement, or
-
- 2) an END statement is encountered in an INCLude file.
-
- If you are "sure" that the END statement is present when the
- assembler thinks that it is missing, it probably is in the
- ignored section of an IF block. If the END statement is missing,
- supply it. If the END statement is in an INCLude file, delete
- it.
-
-
- 5.2 Error ( -- Parenthesis Imbalance
-
- For every left parenthesis, there must be a right paren-
- thesis. Count them.
-
-
- 5.3 Error " -- Missing Quotation Mark
-
- Strings have to begin and end with either " or '. Remember
- that " only matches " while ' only matches '.
-
-
- 5.4 Error A -- Illegal Addressing Mode
-
- This error occurs if an addressing mode is specified in the
- argument field that is not legal with the opcode in the opcode
- field. See the table in section 3.0 for the list of legal
- combinations.
-
-
- 5.5 Error B -- Branch Target Too Distant
-
- The 6502 relative branch instructions will only reach -128
- to +127 bytes from the first byte of the instruction following
- the branch instruction. If this error occurs, the source code
- will have to be rearranged to shorten the distance to the branch
- target address or a long branch instruction that will reach
- anywhere (JMP) will have to be used.
-
-
- 5.6 Error D -- Illegal Digit
-
- This error occurs if a digit greater than or equal to the
- base of a numeric constant is found. For example, a 2 in a
- binary number would cause a D error. Especially, watch for 8 or
- 9 in an octal number.
-
-
-
-
- 14
-
-
-
-
- 5.7 Error E -- Illegal Expression
-
- This error occurs because of:
-
- 1) a missing expression where one is required
-
- 2) a unary operator used as a binary operator or vice-
- versa
-
- 3) a missing binary operator
-
- 4) a SHL or SHR count that is not 0 thru 15
-
-
- 5.8 Error I -- IF-ENDI Imbalance
-
- For every IF there must be a corresponding ENDI. If this
- error occurs on an ELSE or ENDI statement, the corresponding IF
- is missing. If this error occurs on an END statement, one or
- more ENDI statements are missing.
-
-
- 5.9 Error L -- Illegal Label
-
- This error occurs because of:
-
- 1) a non-alphabetic in column 1
-
- 2) a reserved word used as a label
-
- 3) a missing label on an EQU or SET statement
-
- 4) a label on an IF, ELSE, or ENDI statement
-
-
- 5.10 Error M -- Multiply Defined Label
-
- This error occurs because of:
-
- 1) a label defined in column 1 or with the EQU statement
- being redefined
-
- 2) a label defined by a SET statement being redefined
- either in column 1 or with the EQU statement
-
- 3) the value of the label changing between assembly passes
-
-
- 5.11 Error O -- Illegal Opcode
-
- The opcode field of a source line may contain only a valid
- machine opcode, a valid pseudo-op, or nothing at all. Anything
- else causes this error.
-
-
-
-
- 15
-
-
-
-
- 5.12 Error P -- Phasing Error
-
- This error occurs because of:
-
- 1) a forward reference in a EQU, ORG, RMB, or SET
- statement
-
- 2) a label disappearing between assembly passes
-
-
- 5.13 Error R -- Illegal Register
-
- This error occurs either when the register designator A or B
- is used with a machine opcode that does not permit it, or when
- the register designator is missing with a machine opcode that
- requires it.
-
-
- 5.14 Error S -- Illegal Syntax
-
- This error means that an argument field is scrambled. Sort
- the mess out and reassemble.
-
-
- 5.15 Error T -- Too Many Arguments
-
- This error occurs if there are more items (expressions,
- register designators, etc.) in the argument field than the opcode
- or pseudo-op requires. The assembler ignores the extra items but
- issues this error in case something is really mangled.
-
-
- 5.16 Error U -- Undefined Label
-
- This error occurs if a label is referenced in an expression
- but not defined anywhere in the source program. If you are
- "sure" you have defined the label, note that upper and lower case
- letters in labels are different. Defining "LABEL" does not
- define "Label."
-
-
- 5.17 Error V -- Illegal Value
-
- This error occurs because:
-
- 1) an index offset is not 0 thru 255, or
-
- 2) an 8-bit immediate value is not -128 thru 255, or
-
- 3) an FCB argument is not -128 thru 255, or
-
- 4) an INCL argument refers to a file that does not exist.
-
-
-
-
-
- 16
-
-
-
- 6.0 Warning Messages
-
- Some errors that occur during the parsing of the cross-
- assembler command line are non-fatal. The cross-assembler flags
- these with a message on the C "stdout" device (by default, the
- console) beginning with the word "Warning." The messages are
- listed below:
-
-
- 6.1 Warning -- Illegal Option Ignored
-
- The only options that the cross-assembler knows are -l and
- -o. Any other command line argument beginning with - will draw
- this error.
-
-
- 6.2 Warning -- -l Option Ignored -- No File Name
- 6.3 Warning -- -o Option Ignored -- No File Name
-
- The -l and -o options require a file name to tell the
- assembler where to put the listing file or object file. If this
- file name is missing, the option is ignored.
-
-
- 6.4 Warning -- Extra Source File Ignored
-
- The cross-assembler will only assemble one file at a time,
- so source file names after the first are ignored. To assemble a
- second file, invoke the assembler again. Note that under CP/M-
- 80, the old trick of reexecuting a core image will NOT work as
- the initialized data areas are not reinitialized prior to the
- second run.
-
-
- 6.5 Warning -- Extra Listing File Ignored
- 6.6 Warning -- Extra Object File Ignored
-
- The cross-assembler will only generate one listing and one
- object file per assembly run, so -l and -o options after the
- first are ignored.
-
-
- 7.0 Fatal Error Messages
-
- Several errors that occur during the parsing of the cross-
- assembler command line or during the assembly run are fatal. The
- cross-assembler flags these with a message on the C "stdout"
- device (by default, the console) beginning with the words "Fatal
- Error." The messages are explained below:
-
-
- 7.1 Fatal Error -- No Source File Specified
-
- This one is self-explanatory. The assembler does not know
- what to assemble.
-
-
-
- 17
-
-
-
-
-
- 7.2 Fatal Error -- Source File Did Not Open
-
- The assembler could not open the source file. The most
- likely cause is that the source file as specified on the command
- line does not exist. On larger systems, there could also be
- priviledge violations. Rarely, a read error in the disk
- directory could cause this error.
-
-
- 7.3 Fatal Error -- Listing File Did Not Open
- 7.4 Fatal Error -- Object File Did Not Open
-
- This error indicates either a defective listing or object
- file name or a full disk directory. Correct the file name or
- make more room on the disk.
-
-
- 7.5 Fatal Error -- Error Reading Source File
-
- This error generally indicates a read error in the disk data
- space. Use your backup copy of the source file (You do have one,
- don't you?) to recreate the mangled file and reassemble.
-
-
- 7.6 Fatal Error -- Disk or Directory Full
-
- This one is self-explanatory. Some more space must be found
- either by deleting files or by using a disk with more room on it.
-
-
- 7.7 Fatal Error -- File Stack Overflow
-
- This error occurs if you exceed the INCLude file limit of
- four files open simultaneously. This limit can be increased by
- increasing the constant FILES in file A65.H or A65C.H and
- recompiling the cross-assembler.
-
-
- 7.8 Fatal Error -- If Stack Overflow
-
- This error occurs if you exceed the nesting limit of 16 IF
- blocks. This limit can be increased by increasing the constant
- IFDEPTH in file A65.H or A65C.H and recompiling the cross-
- assembler.
-
-
- 7.9 Fatal Error -- Too Many Symbols
-
- Congratulations! You have run out of memory. The space for
- the cross-assembler's symbol table is allocated at run-time using
- the C library function alloc(), so the cross-assembler will use
- all available memory. The only solutions to this problem are to
- lessen the number of labels in the source program, to use a
-
-
-
- 18
-
-
-
- larger memory model (MSDOS/PCDOS systems only), or to add more
- memory to your machine.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 19
->
\ No newline at end of file
A a65.html => a65.html +654 -0
@@ 0,0 1,654 @@
+<!doctype html>
+<html lang="en">
+<head>
+<style>
+body {
+ line-height: 140%;
+ margin: auto;
+ width: 800px;
+}
+
+p {
+ text-indent: 2em;
+}
+
+p.no-indent {
+ text-indent: 0em;
+}
+
+code {
+ font-family: monospace, monospace;
+}
+
+
+pre code {
+ background-color: #eee;
+ border: 1px solid #999;
+ display: block;
+ padding: 20px;
+}
+</style>
+<meta charset="utf-8">
+<title>A65 Manual</title>
+</head>
+<body>
+<div style="text-align:center">
+<h1>A65 6502 Cross-Assembler</h1>
+<h3>Version 0.2n</h3>
+<h3>Copyright (c) 1986 William C. Colley, III</h3>
+<h3>Modifications by Nathan Misner</h3>
+</div>
+<h3>Legal Note</h3>
+<p>This package may be used for any commercial or
+non-commercial purpose. It may be copied and
+distributed freely provided that any fee charged
+by the distributor of the copy does not exceed the
+sum of: 1) the cost of the media the copy is
+written on, 2) any required costs of shipping the
+copy, and 3) a nominal handling fee. Any other
+distribution requires the written permission of
+the author. Also, the author's copyright notices
+shall not be removed from the program source, the
+program object, or the program documentation.</p>
+
+<h3>1.0 - How to Use the Cross-Assembler Package</h3>
+<p>First, the question, "What does a cross-assembler do?" needs
+to be addressed as there is considerable confusion on this point.
+A cross-assembler is just like any other assembler except that it
+runs on some CPU other than the one for which it assembles code.
+For example, this package assembles 6502 source code
+into 6502 object code, but it runs on an 8080, a Z-80,
+an 8088, or whatever other CPU you happen to have a C compiler
+for. The reason that cross-assemblers are useful is that you
+probably already have a CPU with memory, disk drives, a text
+editor, an operating system, and all sorts of hard-to-build or
+expensive facilities on hand. A cross-assembler allows you to
+use these facilites to develop code for a 6502.</p>
+
+<p>This program requires one input file (your 6502 source
+code) and zero to two output files (the listing and the object).
+The input file MUST be specified, or the assembler will bomb on a
+fatal error. The listing and object files are optional. If no
+listing file is specified, no listing is generated, and if no
+object file is specified, no object is generated. If the object
+file is specified, the object is written to this file in absolute
+binary format.</p>
+
+<p>The command line for the 6502 cross-assembler looks like this:</p>
+<pre><code>a65 source_file { -l list_file } { -o object_file }</code></pre>
+<p class="no-indent">where the { } indicates that the specified item is optional.
+Some examples are in order:</p>
+<pre><code>a65 test65.asm source: test65.asm
+ listing: none
+ object: none
+
+a65 test65.asm -l test65.prn source: test65.asm
+ listing: test65.prn
+ object: none
+
+a65 test65.asm -o test65.bin source: test65.asm
+ listing: none
+ object: test65.bin
+
+a65 test65.asm -l test65.prn -o test65.bin
+ source: test65.asm
+ listing: test65.prn
+ object: test65.bin</code></pre>
+
+<p>The order in which the source, listing, and object files are
+specified does not matter. Note that no default file name extensions are supplied by the assembler as this gives rise to portability problems.</p>
+
+<h3>2.0 - Format of Cross-Assembler Source Lines</h3>
+<p>The source file that the cross-assembler processes into a
+listing and an object is an ASCII text file that you can prepare
+with whatever editor you have at hand. The most-significant
+(parity) bit of each character is cleared as the character is
+read from disk by the cross-assembler, so editors that set this
+bit (such as WordStar's document mode) should not bother this
+program. All printing characters, the ASCII TAB character ($09),
+and newline character(s) are processed by the assembler. All
+other characters are passed through to the listing file, but are
+otherwise ignored.</p>
+
+<p>The source file is divided into lines by newline character(s). The internal buffers of the cross-assembler will
+accommodate lines of up to 255 characters which should be more
+than ample for almost any job. If you must use longer lines,
+change the constant MAXLINE in file a65.h and recompile
+the cross-assembler. Otherwise, you will overflow the buffers,
+and the program will mysteriously crash.</p>
+
+<p>Each source line is made up of three fields: the label
+field, the opcode field, and the argument field. The label field
+is optional, but if it is present, it must begin in column 1. It may
+optionally be terminated with a colon character.
+The opcode field is optional, but if it is present, it must not
+begin in column 1. If both a label and an opcode are present,
+one or more spaces and/or TAB characters must separate the two.
+If the opcode requires arguments, they are placed in the argument
+field which is separated from the opcode field by one or more
+spaces and/or TAB characters. Finally, an optional comment can
+be added to the end of the line. This comment must begin with a
+semicolon which signals the assembler to pass the rest of the
+line to the listing and otherwise ignore it. Thus, the source
+line looks like this:</p>
+<pre><code>{label}{ opcode{ arguments}}{;commentary}</code></pre>
+<p class="no-indent">where the { } indicates that the specified item is optional.
+Some examples are in order:</p>
+<pre><code>column 1
+ |
+ v
+ GRONK LDA OFFSET, X ; This line has everything.
+ STA MAILBOX ; This line has no label.
+ BEEP: ; This line has no opcode.
+ ; This line has no label and no opcode.
+
+ ; The previous line has nothing at all.
+ END ; This line has no argument.</code></pre>
+
+<h3>2.1 - Labels</h3>
+<p>A label is any sequence of alphabetic or numeric characters
+starting with an alphabetic. The legal alphabetics are:</p>
+<pre><code>& , . ? [ \ ] ^ _ ` { | } ~ A-Z a-z</code></pre>
+<p>The numeric characters are the digits 0-9. Note that "A" is not
+the same as "a" in a label. This can explain mysterious U
+(undefined label) errors occurring when a label appears to be
+defined.</p>
+
+<p>A label is permitted on any line except a line where the
+opcode is IF, ELSE, or ENDIF. The label is assigned the value of
+the assembly program counter before any of the rest of the line
+is processed except when the opcode is EQU, ORG, or SET.</p>
+
+<p>Labels can have the same name as opcodes, but they cannot
+have the same name as operators or registers. The reserved
+(operator and register) names are:</p>
+<pre><code>A AND EQ GE GT HIGH
+LE LT LOW MOD NE NOT
+OR SHL SHR X XOR Y</pre></code>
+
+<p>If a label is used in an expression before it is assigned a
+value, the label is said to be "forward-referenced." For
+example:</p>
+<pre><code>L1 EQU L2 + 1 ; L2 is forward-referenced here.
+L2
+L3 EQU L2 + 1 ; L2 is not forward-referenced here.</code></pre>
+
+<h3>2.2 - Numeric Constants</h3>
+
+<p>Numeric constants can be formed in two ways: the Intel
+convention or the Motorola convention. The cross-assembler
+supports both.</p>
+
+<p>An Intel-type numeric constant starts with a numeric
+character (0-9), continues with zero or more digits (0-9, A-F),
+and ends with an optional base designator. The base designators
+are H for hexadecimal, none or D for decimal, O or Q for octal,
+and B for binary. The hex digits a-f are converted to upper case
+by the assembler. Note that an Intel-type numeric constant
+cannot begin with A-F as it would be indistinguishable from a
+label. Thus, all of the following evaluate to 255 (decimal):</p>
+<pre><code>0ffH 255 255D 377O 377Q 11111111B</code></pre>
+
+<p>A Motorola-type numeric constant starts with a base
+designator and continues with a string of one or more digits.
+The base designators are $ for hexadecimal, none for decimal, @
+for octal, and % for binary. As with Intel-type numeric constants,
+a-f are converted to upper case by the assembler.
+Thus, all of the following evaluate to 255 (decimal):</p>
+<pre><code>$ff 255 @377 %11111111</code></pre>
+
+<p>If a numeric constant has a value that is too large to fit
+into a 16-bit word, it will be truncated on the left to make it
+fit. Thus, for example, $123456 is truncated to $3456.</p>
+
+<h3>2.3 - String Constants</h3>
+<p>A string constant is zero or more characters enclosed in
+either single quotes (' ') or double quotes (" "). Single quotes
+only match single quotes, and double quotes only match double
+quotes, so if you want to put a single quote in a string, you can
+do it like this: "'". In all contexts except the DB and DS statements,
+the first character or two of the string constant are all that
+are used. The rest is ignored. Noting that the ASCII codes for
+"A" and "B" are $41 and $42, respectively, will explain the
+following examples:</p>
+<pre><code>"" and '' evaluate to $0000
+"A" and 'A' evaluate to $0041
+"AB" evaluates to $4142</code></pre>
+<p class="no-indent">Note that the null string "" is legal and evaluates to $0000.</p>
+
+<h3>2.4 - Expressions</h3>
+<p>An expression is made up of labels, numeric constants, and
+string constants glued together with arithmetic operators,
+logical operators, and parentheses in the usual way that
+algebraic expressions are made. Operators have the following
+fairly natural order of precedence:</p>
+<pre><code>Highest anything in parentheses
+ unary +, unary -
+ *, /, MOD, SHL, SHR
+ binary +, binary -
+ LT, LE, EQ, GE, GT, NE
+ NOT
+ AND
+ OR, XOR
+Lowest HIGH, LOW</code></pre>
+<p class="no-indent">A few notes about the various operators are in order:</p>
+<ol>
+<li>The remainder operator MOD yields the remainder from dividing its left operand by its right operand.</li>
+<li>The shifting operators SHL and SHR shift their left
+operand to the left or right the number of bits
+specified by their right operand.</li>
+<li>The relational operators LT, LE, EQ, GE, GT, and NE can
+also be written as <, <= or =<, =, >= or =>, and <> or
+><, respectively. They evaluate to $FFFF if the
+statement is true, 0 otherwise.</li>
+<li>The logical opeators NOT, AND, OR, and XOR do bitwise
+operations on their operand(s).</li>
+<li>HIGH and LOW extract the high or low byte, of an
+expression.</li>
+<li>The special symbol * can be used in place of a label or
+constant to represent the value of the program counter
+before any of the current line has been processed.</li></ol>
+<p class="no-indent">Some examples are in order at this point:</p>
+<pre><code>2 + 3 * 4 evaluates to 14
+(2 + 3) * 4 evaluates to 20
+NOT %11110000 XOR %00001010 evaluates to %00000101
+HIGH $1234 SHL 1 evaluates to $0024
+@001 EQ 0 evaluates to 0
+@001 = 2 SHR 1 evaluates to $FFFF</code></pre>
+<p class="no-indent">All arithmetic is unsigned with overflow from the 16-bit
+word ignored. Thus:</p>
+<pre><code>32768 * 2 evaluates to 0</code></pre>
+
+<h3>3.0 - Pseudo Opcodes</h3>
+<p>Unlike 6502 opcodes, pseudo opcodes (pseudo ops) do not
+represent machine instructions. They are, rather, directives to
+the assembler. These directives require various numbers and
+types of arguments. They will be listed individually below.</p>
+
+<h3>3.1 - Pseudo-ops -- END</h3>
+<p>The END pseudo-op tells the assembler that the source
+program is over. Any further lines of the source file are
+ignored and not passed on to the listing. If end-of-file
+is encountered on the source file before an
+END statement is reached, the assembler will add an END statement
+to the listing and flag it with a * (missing statement) error.</p>
+
+<h3>3.2 - Pseudo-ops -- EQU</h3>
+<p>The EQU pseudo-op is used to assign a specific value to a
+label, thus the label on this line is REQUIRED. Once the value
+is assigned, it cannot be reassigned by writing the label in
+column 1, by another EQU statement, or by a SET statement. Thus,
+for example, the following statement assigns the value 2 to the
+label TWO:</p>
+<pre><code>TWO EQU 1 + 1</code></pre>
+<p>The expression in the argument field must contain no forward
+references.</p>
+
+<h3>3.3 - Pseudo-ops -- DB</h3>
+<p>The DB (Define Bytes) pseudo-op allows arbitrary
+bytes to be spliced into the object code. Its argument is a
+chain of one or more expressions or string constants
+separated by commas. Any expressions must evaluate to -128 thru 255.
+The sequence of bytes $FE, $FF, $00, $01, $02
+could be spliced into the code with the following statement:</p>
+<pre><code>DB -2, -1, 0, 1, 2</code></pre>
+<p class="no-indent">The NUL-terminated string "nyaa~" could be spliced into the code
+with the following statement:</p>
+<pre><code>DB "nyaa~",0 ; This is 6 bytes of code.</code></pre>
+
+<h3>3.4 - Pseudo-ops -- DS</h3>
+<p>The DS (Define String) pseudo-op allows
+character strings to be spliced into the object code. Its
+argument is a chain of zero or more string constants separated by
+blanks, tabs, or commas. If a comma occurs with no preceding
+string constant, an S (syntax) error results. The string
+contants are not truncated to two bytes, but are instead copied
+verbatim into the object code. Null strings result in no bytes
+of code. The message "Kaboom!!" could be spliced into the code
+with the following statement:</p>
+<pre><code>DS "Kaboom!!" ;This is 8 bytes of code.</code></pre>
+
+<h3>3.5 - Pseudo-ops -- DW</h3>
+<p>The FDB (Form Double Bytes) pseudo-op allows 16-bit words to
+be spliced into the object code. Its argument is a chain of zero
+or more expressions separated by commas. The word is placed into
+memory low byte in low address, high byte in high address as per
+standard MOS Technology order. The sequence of bytes $FE $FF $00
+$00 $01 $02 could be spliced into the code with the following statement:</p>
+<pre><code>DW $FFFE, $0000, $0201</code></pre>
+
+<h3>3.6 - Pseudo-ops -- IF, ELSE, ENDI</h3>
+<p>These three pseudo-ops allow the assembler to choose whether
+or not to assemble certain blocks of code based on the result of
+an expression. Code that is not assembled is passed through to
+the listing but otherwise ignored by the assembler. The IF
+pseudo-op signals the beginning of a conditionally assembled
+block. It requires one argument that may contain no forward
+references. If the value of the argument is non-zero, the block
+is assembled. Otherwise, the block is ignored. The ENDI pseudo-
+op signals the end of the conditionally assembled block. For
+example:</p>
+<pre><code>IF EXPRESSION ;This whole thing generates
+FCB $01, $02, $03 ; no code whatsoever if
+ENDI ; EXPRESSION is zero.</code></pre>
+
+<p>The ELSE pseudo-op allows the assembly of either one of two
+blocks, but not both. The following two sequences are
+equivalent:</p>
+<pre><code> IF EXPRESSION
+ ... some stuff ...
+ ELSE
+ ... some more stuff ...
+ ENDI
+
+TEMP_LAB SET EXPRESSION
+ IF TEMP_LAB NE 0
+ ... some stuff ...
+ ENDI
+ IF TEMP_LAB EQ 0
+ ... some more stuff ...
+ ENDI</code></pre>
+<p>The pseudo-ops in this group do NOT permit labels to exist
+on the same line as the status of the label (ignored or not)
+would be ambiguous.</p>
+<p>All IF statements (even those in ignored conditionally
+assembled blocks) must have corresponding ENDI statements and all
+ELSE and ENDI statements must have a corresponding IF statement.</p>
+<p>IF blocks can be nested up to 16 levels deep before the
+assembler dies of a fatal error. This should be adequate for any
+conceivable job, but if you need more, change the constant
+IFDEPTH in file a65.h and recompile the assembler.</p>
+
+<h3>3.7 - Pseudo-ops -- INCL</h3>
+<p>The INCL pseudo-op is used to splice the contents of another
+file into the current file at assembly time. The name of the
+file to be INCLuded is specified as a normal string constant, so
+the following line would splice the contents of file "const.def"
+into the source code stream:</p>
+<pre><code>INCL "const.def"</code></pre>
+
+<p>INCLuded files may, in turn, INCLude other files until four
+files are open simultaneously. This limit should be enough for
+any conceivable job, but if you need more, change the constant
+FILES in file a65.h and recompile the assembler.</p>
+
+<h3>3.8 - Pseudo-ops -- MSG</h3>
+<p>The MSG pseudo-op is used to print arbitrary strings and/or
+expression results to the console at assembly time. For example,
+adding the following line at the end of the program would print
+out the amount of free ROM space (assuming the labels are inserted
+at the correct spots):
+<pre><code>MSG "Free bytes: ", VectorTable-EndCode</code></pre>
+
+<h3>3.9 - Pseudo-ops -- ORG</h3>
+<p>The ORG pseudo-op is used to set the assembly program
+counter to a particular value. The expression that defines this
+value may contain no forward references. The default initial
+value of the assembly program counter is $0000. The following
+statement would change the assembly program counter to $F000:</p>
+<pre><code>ORG $F000</code></pre>
+<p>The first ORG statement will specify the starting address of the
+binary file (e.g. where it's mapped in memory). Any subsequent ORG
+statements will pad the binary file up to the given address. Attempting
+to ORG "backwards" (to an address before the program counter) will
+cause an error.</p>
+<p>If a label is present on the same line as an ORG statement,
+it is assigned the new value of the assembly program counter.</p>
+
+<h3>3.10 - Pseudo-ops -- PAGE</h3>
+<p>The PAGE pseudo-op always causes an immediate page ejection
+in the listing by inserting a form feed ('\f') character before
+the next line. If an argument is specified, the argument
+expression specifies the number of lines per page in the listing.
+Legal values for the expression are any number except 1 and 2. A
+value of 0 turns the listing pagination off. Thus, the following
+statement cause a page ejection and would divide the listing into
+60-line pages:</p>
+<pre><code>PAGE 60</code></pre>
+
+<h3>3.11 - Pseudo-ops -- RMB</h3>
+<p>The RMB (Reserve Memory Bytes) pseudo-op is used to reserve
+a block of storage for program variables, or whatever. This
+storage is not initialized in any way, so its value at run time
+will usually be random. The argument expression (which may
+contain no forward references) is added to the assembly program
+counter. The following statement would reserve 10 bytes of
+storage called "STORAGE":</p>
+<pre><code>STORAGE RMB 10</code></pre>
+
+<h3>3.12 - Pseudo-ops -- SET</h3>
+<p>The SET pseudo-op functions like the EQU pseudo-op except
+that the SET statement can reassign the value of a label that has
+already been assigned by another SET statement. Like the EQU
+statement, the argument expression may contain no forward
+references. A label defined by a SET statement cannot be
+redefined by writing it in column 1 or with an EQU statement.
+The following series of statements would set the value of label
+"COUNT" to 1, 2, then 3:</p>
+<pre><code>COUNT SET 1
+COUNT SET 2
+COUNT SET 3</code></pre>
+
+<h3>3.13 - Pseudo-ops -- TITL</h3>
+<p>The TITL pseudo-op sets the running title for the listing.
+The argument field is required and must be a string constant,
+though the null string ("") is legal. This title is printed
+after every page ejection in the listing, therefore, if page
+ejections have not been forced by the PAGE pseudo-op, the title
+will never be printed. The following statement would print the
+title "Random Bug Generator -- Ver 3.14159" at the top of every
+page of the listing:</p>
+<pre><code>TITL "Random Bug Generator -- Ver 3.14159"</code></pre>
+
+<h3>4.0 - Assembly Errors</h3>
+<p>When a source line contains an illegal construct, the offending filename
+and line number are printed to stderr. The line
+is also flagged in the listing with a single-letter code describing
+the error. The meaning of each code is listed below. In
+addition, a count of the number of lines with errors is kept and
+printed on the C "stderr" device (by default, the console) after
+the END statement is processed. If more than one error occurs in
+a given line, only the first is reported. For example, the
+illegal label "=$#*'(" would generate the following listing line:</p>
+<pre><code>L 0000 FF 00 00 =$#*'( CPX #0</code></pre>
+
+<h3>4.1 - Error * -- Illegal or Missing Statement</h3>
+<p>This error occurs when either:</p>
+<ol>
+<li>the assembler reaches the end of the source file without seeing an END statement, or</li>
+<li>an END statement is encountered in an INCLude file.</li>
+</ol>
+<p>If you are "sure" that the END statement is present when the
+assembler thinks that it is missing, it probably is in the
+ignored section of an IF block. If the END statement is missing,
+supply it. If the END statement is in an INCLude file, delete
+it.</p>
+
+<h3>4.2 - Error ( -- Parenthesis Imbalance</h3>
+<p>For every left parenthesis, there must be a right parenthesis. Count them.</p>
+
+<h3>4.3 - Error " -- Missing Quotation Mark</h3>
+<p>Strings have to begin and end with either " or '. Remember that " only matches " while ' only matches '.</p>
+
+<h3>4.4 - Error A -- Illegal Addressing Mode</h3>
+<p>This error occurs if an addressing mode is specified in the
+argument field that is not legal with the opcode in the opcode
+field.</p>
+
+<h3>4.5 - Error B -- Branch Target Too Distant</h3>
+<p>The 6502 relative branch instructions will only reach -128
+to +127 bytes from the first byte of the instruction following
+the branch instruction. If this error occurs, the source code
+will have to be rearranged to shorten the distance to the branch
+target address or a long branch instruction that will reach
+anywhere (JMP) will have to be used.</p>
+
+<h3>4.6 - Error D -- Illegal Digit</h3>
+<p>This error occurs if a digit greater than or equal to the
+base of a numeric constant is found. For example, a 2 in a
+binary number would cause a D error. Especially, watch for 8 or
+9 in an octal number.</p>
+
+<h3>4.7 - Error E -- Illegal Expression</h3>
+<p>This error occurs because of:</p>
+<ol>
+<li>a missing expression where one is required</li>
+<li>a unary operator used as a binary operator or vice-versa</li>
+<li>a missing binary operator</li>
+<li>a SHL or SHR count that is not 0 thru 15</li>
+</ol>
+
+<h3>4.8 - Error I -- IF-ENDI Imbalance</h3>
+<p>For every IF there must be a corresponding ENDI. If this
+error occurs on an ELSE or ENDI statement, the corresponding IF
+is missing. If this error occurs on an END statement, one or
+more ENDI statements are missing.</p>
+
+<h3>4.9 - Error L -- Illegal Label</h3>
+<p>This error occurs because of:</p>
+<ol>
+<li>a non-alphabetic in column 1</li>
+<li>a reserved word used as a label</li>
+<li>a missing label on an EQU or SET statement</li>
+<li>a label on an IF, ELSE, or ENDI statement</li>
+</ol>
+
+<h3>4.10 - Error M -- Multiply Defined Label</h3>
+<p>This error occurs because of:</p>
+<ol>
+<li>a label defined in column 1 or with the EQU statement being redefined</li>
+<li>a label defined by a SET statement being redefined either in column 1 or with the EQU statement</li>
+<li>the value of the label changing between assembly passes</li>
+</ol>
+
+<h3>4.11 - Error O -- Illegal Opcode</h3>
+<p>The opcode field of a source line may contain only a valid
+machine opcode, a valid pseudo-op, or nothing at all. Anything
+else causes this error.</p>
+
+<h3>4.12 - Error P -- Phasing Error</h3>
+<p>This error occurs because of:</p>
+<ol>
+<li>a forward reference in a EQU, ORG, RMB, or SET statement</li>
+<li>a label disappearing between assembly passes</li>
+</ol>
+
+<h3>4.13 - Error R -- Illegal Register</h3>
+<p>This error occurs either when the register designator A or B
+is used with a machine opcode that does not permit it, or when
+the register designator is missing with a machine opcode that
+requires it.</p>
+
+<h3>4.14 - Error S -- Illegal Syntax</h3>
+<p>This error means that an argument field is scrambled. Sort the mess out and reassemble.</p>
+
+<h3>4.15 - Error T -- Too Many Arguments</h3>
+<p>This error occurs if there are more items (expressions,
+register designators, etc.) in the argument field than the opcode
+or pseudo-op requires. The assembler ignores the extra items but
+issues this error in case something is really mangled.</p>
+
+<h3>4.16 - Error U -- Undefined Label</h3>
+<p>This error occurs if a label is referenced in an expression
+but not defined anywhere in the source program. If you are
+"sure" you have defined the label, note that upper and lower case
+letters in labels are different. Defining "LABEL" does not
+define "Label."</p>
+
+<h3>4.17 - Error V -- Illegal Value</h3>
+<p>This error occurs because:</p>
+<ol>
+<li>an index offset is not 0 thru 255</li>
+<li>an 8-bit immediate value is not -128 thru 255</li>
+<li>a DB argument is not -128 thru 255</li>
+<li>an ORG statement is attempting to seek backwards in the file</li>
+<li>an INCL argument refers to a file that does not exist</li>
+</ol>
+
+<h3>5.0 - Warning Messages</h3>
+<p>Some errors that occur during the parsing of the cross-
+assembler command line are non-fatal. The cross-assembler flags
+these with a message on the C "stdout" device (by default, the
+console) beginning with the word "Warning." The messages are
+listed below:</p>
+
+<h3>5.1 - Warning -- Illegal Option Ignored</h3>
+<p>The only options that the cross-assembler knows are -l and
+-o. Any other command line argument beginning with - will draw
+this error.</p>
+
+<h3>5.2 - Warning -- -l Option Ignored -- No File Name</h3>
+<h3>5.3 - Warning -- -o Option Ignored -- No File Name</h3>
+<p>The -l and -o options require a file name to tell the
+assembler where to put the listing file or object file. If this
+file name is missing, the option is ignored.</p>
+
+<h3>5.4 - Warning -- Extra Source File Ignored</h3>
+<p>The cross-assembler will only assemble one file at a time,
+so source file names after the first are ignored. To assemble a
+second file, invoke the assembler again. Note that under CP/M-80,
+the old trick of reexecuting a core image will NOT work as
+the initialized data areas are not reinitialized prior to the
+second run.</p>
+
+<h3>5.5 Warning -- Extra Listing File Ignored</h3>
+<h3>5.6 Warning -- Extra Object File Ignored</h3>
+<p>The cross-assembler will only generate one listing and one
+object file per assembly run, so -l and -o options after the
+first are ignored.</p>
+
+<h3>6.0 - Fatal Error Messages</h3>
+<p>Several errors that occur during the parsing of the cross-
+assembler command line or during the assembly run are fatal. The
+cross-assembler flags these with a message on the C "stdout"
+device (by default, the console) beginning with the words "Fatal
+Error." The messages are explained below:</p>
+
+<h3>6.1 - Fatal Error -- No Source File Specified</h3>
+<p>This one is self-explanatory. The assembler does not know what to assemble.</p>
+
+<h3>6.2 - Fatal Error -- Source File Did Not Open</h3>
+<p>The assembler could not open the source file. The most
+likely cause is that the source file as specified on the command
+line does not exist. On larger systems, there could also be
+privilege violations. Rarely, a read error in the disk
+directory could cause this error.</p>
+
+<h3>6.3 - Fatal Error -- Listing File Did Not Open</h3>
+<h3>6.4 - Fatal Error -- Object File Did Not Open</h3>
+<p>This error indicates either a defective listing or object
+file name or a full disk directory. Correct the file name or
+make more room on the disk.</p>
+
+<h3>6.5 - Fatal Error -- Error Reading Source File</h3>
+<p>This error generally indicates a read error in the disk data
+space. Use your backup copy of the source file (You do have one,
+don't you?) to recreate the mangled file and reassemble.</p>
+
+<h3>6.6 - Fatal Error -- Disk or Directory Full</h3>
+<p>This one is self-explanatory. Some more space must be found
+either by deleting files or by using a disk with more room on it.</p>
+
+<h3>6.7 - Fatal Error -- File Stack Overflow</h3>
+<p>This error occurs if you exceed the INCLude file limit of
+four files open simultaneously. This limit can be increased by
+increasing the constant FILES in file A65.H or A65C.H and
+recompiling the cross-assembler.</p>
+
+<h3>6.8 - Fatal Error -- If Stack Overflow</h3>
+<p>This error occurs if you exceed the nesting limit of 16 IF
+blocks. This limit can be increased by increasing the constant
+IFDEPTH in file A65.H or A65C.H and recompiling the cross-
+assembler.</p>
+
+<h3>6.9 - Fatal Error -- Too Many Symbols</h3>
+<p>Congratulations! You have run out of memory. The space for
+the cross-assembler's symbol table is allocated at run-time using
+the C library function alloc(), so the cross-assembler will use
+all available memory. The only solutions to this problem are to
+lessen the number of labels in the source program, to use a
+larger memory model (MSDOS/PCDOS systems only), or to add more
+memory to your machine.</p>
+
+</body>
+</html><
\ No newline at end of file
M a65util.c => a65util.c +2 -2
@@ 389,7 389,7 @@ void bseek(unsigned a) {
}
/* don't allow seeking backwards */
else if (cursor > a) {
- error('S');
+ error('V');
}
/* pad the file to make up the difference */
else {
@@ 452,7 452,7 @@ void error(char code) {
default: description = ERR_UNKNOWN; break;
}
- printf("%s:%d: %c -- %s\n", filestk[filesp].filename, filestk[filesp].linenum, code, description);
+ fprintf(stderr, "%s:%d: %c -- %s\n", filestk[filesp].filename, filestk[filesp].linenum, code, description);
}
}
return;
M readme.txt => readme.txt +1 -2
@@ 14,8 14,7 @@ your workflow.
"dialects" like all the popular assemblers do
- It's an absolute assembler, so no linking
- No macro support
-- I'm like 90% sure that it won't like Unicode characters (but who knows, it
- might...)
+- It clears the upper bit when reading input files, so no UTF-8 support
=====Why to use this assembler=====
- The code is well laid out and easy to understand and modify in case you want