home *** CD-ROM | disk | FTP | other *** search
/ Brotikasten / BROTCD01.iso / texte / asm65816.txt next >
Text File  |  1995-08-20  |  97KB  |  2,254 lines

  1.                 A Proposed Assembly Language Syntax For 65c816 Assemblers
  2.                                                         by Randall Hyde
  3.                                                         
  4.  
  5.         This is a proposed standard for 65c816 assembly language.  The
  6. proposed standard comes in three levels: subset, full, and extended.  The
  7. subset standard is intended for simple (or inexpensive) products,
  8. particularly those aimed at beginning 65c816 assembly language programmers.
  9. The full standard is the focus of this proposal.  An assembler meeting the
  10. full level adopts all of the requirements outlined in this paper.  The
  11. extended level is a mechanism whereby a vendor can claim full compliance
  12. with the standard and point out that there are extensions as well.  An
  13. assembler cannot claim extended level compliance unless it also complies with
  14. the full standard.  An assembler, no matter how many extensions are
  15. incorporated, will have to claim subset level unless the full standard is
  16. supported.  This ensures that programmers who do not use any assembler
  17. extensions can assemble their programs on any assembler meeting the full or
  18. extended compliance levels.  
  19.  
  20.         In addition to the items required for compliance, this proposal 
  21. suggests several extensions in the interests of compatibility with existing
  22. 65c816 assemblers.  These recommendations are not required for full
  23. compliance with the standard, they're included in this proposal as suggestions
  24. to help make conversion of existing programs easier.  The suggestions are
  25. presented in two levels: recommended and optional.  Recommended items should
  26. be present in any decent 65c816 package.  Inclusion of the optional items
  27. is discouraged (since there are other ways to accomplish the same operation
  28. within the confines of the standard) but may be included in the assembler
  29. at the vendor's discretion to help alleviate conversion problems.
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.                         65c816 Instruction Mnemonics 
  40.                         ----------------------------
  41.  
  42.  
  43.         All of the following mnemonics are required at the subset, full,
  44. and extended standard levels.
  45.  
  46.         The following mnemonics handle the basic 65c816 instruction set:
  47.  
  48. ADC - add with carry
  49. AND - logical AND
  50. BCC - branch if carry clear
  51. BCS - branch if carry set
  52. BEQ - branch if equal
  53. BIT - bit test
  54. BMI - branch if minus
  55. BNE - branch if not equal
  56. BPL - branch if plus
  57. BRA - branch always
  58. BRK - break point instruction
  59. BVC - branch if overflow clear
  60. BVS - branch if overflow set
  61. CLC - clear the carry flag
  62. CLD - clear the decimal flag
  63. CLI - clear the interrupt flag
  64. CLP - clear bits in P
  65. CLR - store a zero into memory
  66. CMP - compare accumulator
  67. CPX - compare x register
  68. CPY - compare y register
  69. CSP - call system procedure
  70. DEC - decrement acc or memory
  71. DEX - decrement x register
  72. DEY - decrement y register
  73. EOR - exclusive-or accumulator
  74. HLT - halt (stop) the clock
  75. INC - increment acc or memory
  76. INX - increment x register
  77. INY - increment y register
  78. JMP - jump to new location
  79. JSR - jump to subroutine
  80. LDA - load accumulator
  81. LDX - load x register
  82. LDY - load y register
  83. MVN - block move (decrement)
  84. MVP - block move (increment)
  85. NOP - no operation
  86. ORA - logical or accumulator
  87. PHA - push accumulator
  88. PHP - push p
  89. PHX - push x register
  90. PHY - push y register
  91. PLA - pop accumulator
  92. PLP - pop p
  93. PLX - pop x register
  94. PLY - pop y register
  95. PSH - push operand
  96. PUL - pop operand
  97. RET - return from subroutine
  98. ROL - rotate left acc/mem
  99. ROR - rotate right acc/mem
  100. RTI - return from interrupt
  101. RTL - return from long subroutine
  102. RTS - return from short subroutine
  103. SBC - subtract with carry
  104. SED - set decimal flag
  105. SEI - set interrupt flag
  106. SEP - set bits in P
  107. SHL - shift left acc/mem
  108. SHR - shift right acc/mem
  109. STA - store accumulator
  110. STX - store x register
  111. STY - store y register
  112. SWA - swap accumulator halves
  113. TAD - transfer acc to D
  114. TAS - transfer acc to S
  115. TAX - transfer acc to x
  116. TAY - transfer acc to y
  117. TCB - test and clear bit
  118. TDA - transfer D to acc
  119. TSA - transfer S to acc
  120. TSB - test and set bit
  121. TSX - transfer S to X
  122. TXA - transfer x to acc
  123. TXS - transfer x to S
  124. TXY - transfer x to y
  125. TYA - transfer y to acc
  126. TYX - transfer y to x
  127. WAI - wait for interrupt
  128. XCE - exchange carry with emulation bit
  129.  
  130. Comments:
  131.  
  132.         CLP replaces REP in the original 65c816 instruction set, since CLP
  133. is a tad more consistent with the original 6502 instruction set.  See 
  134. "recommended options" for the status of REP.  CLR replaces the STZ
  135. instruction.  Since STA, STX, and STY are used to store 65c816 registers,
  136. STZ seems to imply that there is a Z register.  Using CLR (clear) eliminates
  137. any confusion.  CSP (call system procedure) replaces the COP mnemonic.  COP
  138. was little more than a software interrupt in both intent and implementation.
  139. CSP helps make this usage a little clearer.  HLT replaces the STP mnemonic.
  140. STP, like the STZ mnemonic, implies that the P register is being stored
  141. somewhere.  HLT (for halt) is just as obvious as "stop the clock" yet it
  142. doesn't have the same "look and feel" as a store instruction.   JML and JSL
  143. are not really required by the new standard;  but see recommended options
  144. concerning these two instructions.  Most of the new 65c816 push and pull
  145. instructions have been collapsed into two instructions: PSH and PUL.
  146.  
  147.         PEA label   becomes  PSH #label
  148.         PEI (label) becomes  PSH label
  149.         PER label   becomes  PSH @label
  150.         PHB         becomes  PSH DBR
  151.         PHD         becomes  PSH D
  152.         PHK         becomes  PSH PBR
  153.  
  154.         PLB         becomes  PUL DBR
  155.         PLD         becomes  PUL D
  156.         
  157. These mnemonics are more in line with the original design of the 6502
  158. instruction set whereby the mnemonic specifies the operation and the operand
  159. specifies the addressing mode and address.  The RET instruction gets converted
  160. to RTS or RTL, depending on the type of subroutine being declared.  RTS and 
  161. RTL still exist in order to force a short or long return.  SHL and SHR (shift
  162. left and shift right) are used instead of ASL and LSR.  The 6500 family has
  163. NEVER supported an arithmetic shift left instruction.  The operation performed
  164. by the ASL mnemonic is really a logical shift left. To simplify matters, SHL
  165. and SHR are used to specify shift left and shift right.  SWA (swap accumulator
  166. halves) is used instead of XBA.  Since this is the only instruction that
  167. references the "B" accumulator, there's no valid reason for even treating
  168. the accumulator as two distinct entities (this is just a carry-over from the
  169. 6800 MPU).  Likewise, since the eight-bit accumulator cannot be distinguished
  170. from the 16-bit accumulator on an instruction by instruction basis (it depends
  171. on the setting of the M bit in the P register), the accumulator should always
  172. be referred to as A, regardless of whether the CPU is in the eight or sixteen
  173. bit mode.  Therefore, instructions like TCD, TCS, TDC, and TSC should be
  174. replaced by TAD, TAS, TDA, and TSA.  For more info on these new mnemonics,
  175. see the section on "recommended options".
  176.  
  177.  
  178.                         Built-in Macros
  179.                         ---------------
  180.  
  181.         The following instructions actually generate one or more instructions.
  182. They are not required at the subset level, but are required at the full and
  183. extended levels.
  184.  
  185.  
  186. ADD - emits CLC then ADC
  187. BFL - emits BEQ (branch if false)
  188. BGE - emits BCS
  189. BLT - emits BCC
  190. BTR - emits BNE (branch if true)
  191. BSR - emits PER *+2 then BRA (short) or PER *+3 then BRL (long)
  192. SUB - emits SEC then SBC
  193.  
  194.  
  195.                         Recommended Options
  196.                         -------------------
  197.  
  198.         The following mnemonics are aliases of existing instructions.  The
  199. (proposed) standard recommends that the assembler support these mnemonics,
  200. mainly to provide compatibility with older source code, but does not
  201. recommend their use in new programs.  Some (or all) of these items may be
  202. removed from the recommended list in future revisions of the standard.  None
  203. of these recommended items need be present at the subset level.  If these
  204. are the only extensions over and above the full syntax, the assembler
  205. CANNOT claim to be an extended level assembler.
  206.  
  207. ASL     BRL     COP     JML     JSL     LSR     PEA     PEI     PER
  208. PHB     PHK     PHK     PLB     PLD     REP     TCD     TCS     TDC
  209. TSC     TRB     WDM     XBA
  210.  
  211.  
  212.  
  213.  
  214.                 Symbols, Constants, and Other Items
  215.                 -----------------------------------
  216.  
  217.         Symbols may contain any reasonable number of characters at the full
  218. level.  At the subset compliance level, at least 16 characters should be
  219. supported and 32 is recommeded.  A "reasonable" number of characters should
  220. be at least 64 if the implementor needs a maximum value.
  221.  
  222.         Symbols must begin with an alphabetic character and may contain
  223. (only) the following symbols:  A-Z, a-z, 0-9, "_", "$", and "!".  The
  224. assembler must be capable of treating upper and lower case alphabetic
  225. characters identically.  Note that this does not disallow an assembler from
  226. allowing the programmer to choose that upper and lower case be distinct, it
  227. simply requires that in the default case, upper and lower case characters
  228. are treated identically.  Note that the standard does not require case
  229. sensitivity in the assembler (and, in fact, recommends against it).
  230. Therefore, anyone foolish enough (for many, many reasons) to create variables
  231. that differ only in the case of the letters they contain is risking port-
  232. ability problems (as well as maintenence, readability, and other problems).
  233.  
  234.         The following symbols are reserved and may not be redefined within
  235. the program:
  236.  
  237.                 A, X, Y, S, DBR, PBR, D, M, P
  238.  
  239. Nor may these symbol appear as fields to a record or type definition (which
  240. will be described later).
  241.  
  242.  
  243.         Constants take six different forms: character constants, string
  244. constants, binary constants, decimal constants, hexadecimal constants and
  245. set constants.
  246.  
  247.         Character constants are created by surrounding a single character by 
  248. a pair of apostrophes or quotation marks, e.g., "s", "a", '$', and 'p'.  If 
  249. the character is surrounded by apostrophes, then the ASCII code for that 
  250. character WITH THE H.O. BIT CLEAR will be used.  If the quotation marks are 
  251. used, then the ASCII code for the character WITH THE H.O. BIT SET will be 
  252. used.  If you need to represent the apostrophe with the H.O. bit clear or a
  253. quotation mark with the H.O. bit set, simply double up the characters, e.g.,
  254.  
  255.                 ''''    - emits a single apostrophe.
  256.                 """"    - emits a single quotation mark.
  257.  
  258.         String constants are generated by placing a sequence of two or more
  259. characters within a pair of apostrophes or quotation marks.  The choice of
  260. apostrophe or quotation mark controls the H.O. bit, as for character
  261. constants.  Likewise, to place an apostrophe or quote within a string
  262. delimited by the same character, just double up the apostrophe or quotation
  263. mark:
  264.  
  265.         'This isn''t bad!'  - generates  --This isn't bad--
  266.         "He said ""Hello""" - generates  --He said "Hello"--
  267.  
  268.  
  269.         Binary integer constants consist of a sequence of 1 through 32 zeros
  270. or ones preceded by a percent sign ("%").  Examples:
  271.  
  272.                         %10110010
  273.                         %001011101
  274.                         %10
  275.                         %1100
  276.  
  277.         Decimal integer constants consist of strings of decimal digits without
  278. any preceding characters.  E.g.,  25,  235,  8325, etc.  Decimal constants
  279. may be (optionally) preceded by a minus sign.
  280.  
  281.         Hexadecimal constants consist of a dollar sign ("$") followed by
  282. a string of hexadecimal digits (0..9 and A..F).  Values in the range $0 
  283. through $FFFFFFFF are allowed.
  284.  
  285.         Set constants are only required at the full and  extended compliance
  286. levels.  A set constant consists of a list of items surrounded by braces,
  287. e.g., {0,3,5}.  For more information, see the .SET directive.
  288.  
  289.  
  290.  
  291.                         Address Expressions
  292.                         -------------------
  293.                         
  294.         Most instructions and many pseudo-opcode/assembler directives require
  295. operands of some sort.  Often these operands contain some sort of address
  296. expression (some, ultimately, numeric or string value).  This proposed 
  297. standard defines the operands, precision, accuracy, and available operations 
  298. that constitutes an address expression.
  299.  
  300. Precision: all integer expressions are computed using 32 bits.  All string
  301. expressions are computed with strings up to 255 characters in length.  All
  302. floating point operations are performed using IEEE 80-bit extended floating
  303. point values (i.e., Apple SANE routines).  All set operations are performed
  304. using 32 bits of precision.
  305.  
  306. Accuracy: all integer operations (consisting of two 32-bit operands and an
  307. operator on those operands) must produce the correct result if the actual
  308. result can fit within 32 bits.  If an overflow occurs, the value is truncated
  309. and only the low order 32 bits are retained.  If an underflow occurs, zero
  310. is used as the result.  If an overflow or underflow occurs, a special bit will
  311. be set (until the next value is computed) that can be tested by the ".IFOVR"
  312. and ".IFUNDR" directives.  Other than that, such errors are ignored.  All
  313. arithmetic is performed using unsigned arithmetic operations. All
  314. floating point operations follow the IEEE (and Apple SANE) suggestions, and
  315. are otherwise ignored by the assembler.  Any string operation producing a
  316. string longer than 255 characters produces an assembly time error.  All set
  317. operations must be exact.
  318.  
  319. Integer operations: The following integer operations must be provided at all
  320. compliance levels:
  321.  
  322. + (binary) adds the two operands.
  323. - (binary) subracts second operand from the first.
  324. * multiplies the two operands.
  325. / divides the first operand by the second.
  326. \ divides the first operand by the second and returns the remainder.
  327. & logically ANDs the two operands.
  328. | logically ORs the two operands.
  329. ^ logically XORs the two operands.
  330.  
  331.  
  332. =
  333. <> These operators compare the two operands (unsigned comparison) and
  334. <  return 1 if the comparison is true, 0 otherwise.
  335. >
  336. <=
  337. >=
  338.  
  339. - (unary) negates (2's complement) the operand
  340. ~ (unary) complements (inverts - 1's complement) the operand
  341.  
  342.  
  343. The following operators must be provided at the full and extended compliance
  344. levels:
  345.  
  346. <- shifts the first operand to the left the number of bits specified by the
  347.    second operand.
  348. -> shifts the first operand to the right the number of bits specified by the
  349.    second operand.
  350.  
  351. @ (unary) subtracts the location counter at the beginning of the current
  352.           statement from the following address expression.
  353.  
  354. % (ternary, e.g.: X%Y:Z)  This operator extracts bits Y through Z from X and
  355.   returns that result right justified.
  356.  
  357.  
  358. Floating point operations: floating point numbers and operations are required
  359. only at the full and extended levels.  The following operations must be
  360. available as well:
  361.  
  362. + adds the two operands.
  363. - subtracts the second operand from the first.
  364. * multiplies the two operands.
  365. / divides the first operand by the second.
  366. - (unary) negates the operand.
  367.  
  368. =
  369. <> These operators compare the two operands and
  370. <  return 1 if the comparison is true, 0 otherwise.
  371. >
  372. <=
  373. >=
  374.  
  375.  
  376.  
  377. String operations: strings and string operations are not required at the
  378. subset level, but the standard recommends their presence.  The following
  379. string operations must be provided at the full and extended levels:
  380.  
  381. + concatenates two strings
  382. % (ternary, e.g., X%Y:Z) returns the substring composed of the characters in
  383.   X starting at position Y of length Z.  Generate an error if X doesn't
  384.   contain sufficient characters.
  385.  
  386. =
  387. <> These operators compare the two operands and
  388. <  return 1 if the comparison is true, 0 otherwise.
  389. >
  390. <=
  391. >=
  392.  
  393.  
  394. Set operations: sets and set operations are required only at the full and
  395. extended levels.  The following set operations must be provided:
  396.  
  397. +  union of two sets  (logical OR of the bits).
  398. *  intersection of two sets (logical AND of the bits).
  399. -  set difference (set one ANDed with the NOT of the second set)
  400.  
  401. =  returns 1 if the two sets are equal, zero otherwise.
  402. <> returns 1 if the two sets are not equal, zero otherwise.
  403. <  returns 1 if the first set is a proper subset of the second.
  404. <= returns 1 if the first set is a subset of the second.
  405. >  returns 1 if the first set is a proper superset of the second.
  406. >= returns 1 if the first set is a superset of the second.
  407.  
  408. % (ternary, e.g., X % Y:Z) extracts elements Y..Z from X and returns those
  409.   items.
  410.  
  411.  
  412. In addition to the above operators,  several pre-defined functions are also
  413. available.  Note that these functions are not required at the subset
  414. compliance level, only at the full and extended levels:
  415.  
  416. float(i) - Converts integer "i" to a floating point value.
  417. trunc(r) - Converts real "r" to a 32-bit unsigned integer (or generates an 
  418.            error).
  419. valid(r) - returns "1" if r is a valid floating point value, 0 otherwise
  420.            (for example, if r is NaN, infinity, etc.)
  421. length(s)- returns the length of string s.
  422. lookup(s)- returns "1" if s is a valid symbol in the symbol table.
  423. value(s) - returns value of symbol specified by string "s" in the symbol
  424.            table.
  425. type(s)  - returns type of symbol "s" in symbol table.  Actual values
  426.            returned are yet to be defined.
  427. mode(a)  - returns the addressing mode of item "a".  Used mainly in macros.
  428. STR(s)   - returns string s with a prefixed length byte.
  429. ZRO(s)   - returns string s with a suffixed zero byte.
  430. DCI(s)   - returns string s with the H.O. bit of its last char inverted.
  431. RVS(s)   - returns string s with its characters reversed.
  432. FLP(s)   - returns string s with its H.O. bits inverted.
  433. IN(v,s)  - returns one if value v is in set s, zero otherwise.
  434.  
  435.  
  436. The following integer functions must be present at all compliance levels:
  437.  
  438. LB(i),
  439. LBYTE(i),
  440. BYTE(i)  - returns the L.O. byte of i.
  441. HB(i),
  442. HBYTE(i) - returns byte #1 (bits 8-15) of i.
  443. BB(i),
  444. BBYTE(i) - returns bank byte (bits 16-23) of i.
  445. XB,
  446. XBYTE(i) - returns H.O. byte of i.
  447. LW(i),
  448. LWORD(i),
  449. WORD(i)  - returns L.O. word of i.
  450. HW(i),
  451. HWORD(i) - returns H.O. word of i.
  452. WORD(i)
  453.  
  454. Pack(i,j)- returns a 16-bit value whose L.O. byte is the L.O. byte of i and
  455.            whose H.O. byte is the L.O. byte of j.
  456.            
  457. Pack(i,j,k,l)- returns a 32-bit value consisting of (i,j,k,l) where i is the
  458.                L.O. byte and l is the H.O. byte.  Note: l is optional.  If
  459.                it isn't present, substitute zero for l.
  460.  
  461.  
  462.  
  463.  
  464.         The order of evaluation for an expression is strictly left to right
  465. unless parentheses are used to modify the precedence of a sub-expression.
  466. Since parentheses are used to specify certain indirect addressing modes, the
  467. use of paretheses to override the strict left-to-right evaluation order
  468. introduces some ambiguity.  For example, should the following be treated
  469. as jump indirect through location $1001 or jump directly to location $1001?
  470.  
  471.                 JMP ($1000+1)
  472.  
  473. The ambiguity is resolved as follows: if the parenthesis is the first char-
  474. acter in the operand field, then the indirect addressing mode is assumed.
  475. Otherwise, the parentheses are used to override the left-to-right precedence.
  476. The example above would be treated as a jump indirect through location $1001.
  477. If you wanted to jump directly to location $1001 in this fashion, the state-
  478. ment could be modified to
  479.  
  480.                 JMP 0+($1000+1)
  481.  
  482. so that the parenthesis is no longer the first character in the operand
  483. field.
  484.  
  485.         The use of parentheses to override the left-to-right precedence is
  486. only required at the full and extended compliance levels.  It is not
  487. required at the subset compliance level.
  488.  
  489.  
  490.  
  491.  
  492.  
  493.                                 Expression Types
  494.                                 ----------------
  495.  
  496.         Expressions, in addition to having a value associated with
  497. them, also have a specific type.  The three basic types of expressions are
  498. integer, floating point, and string expressions.  Integer expressions can
  499. be broken down into subtypes as well.  A hierarchical diagram is the easiest
  500. way to describe integer expressions:
  501.  
  502.  
  503.  
  504. integers ------ constants ------------ user defined (enumerated) types
  505.             |                   |
  506.             |                   +----- simple numeric constants
  507.             |
  508.             |
  509.             +-- addresses ------------ direct page addresses
  510.                                 |
  511.                                 +----- absolute addresses --- full 16-bit
  512.                                 |                          |
  513.                                 |                          +- relative 8-bit
  514.                                 |
  515.                                 +----- long addresses
  516.  
  517.         This diagram points out that there are two types of integer expres-
  518. sions: constants and addresses.  Further, there are two types of constants
  519. and four types of addresses.  Before discussion operations on these different
  520. types of integer values, their purpose should be presented.
  521.  
  522.         Until now, most 65xxx assembler did little to differentiate between
  523. the different types of integer values.  In this proposed standard, however,
  524. strong type checking is enforced.  Whereas in previous assemblers you could
  525. use the following code:
  526.  
  527.         label   equ     $1000
  528.                 lda     #Label
  529.                 sta     Label
  530.  
  531. such operations are illegal within the confines of the new standard.  The
  532. problem with this short code segment is that the symbol "label" is used as
  533. both an integer constant (in the LDA instruction) and as an address 
  534. expression (in the STA instruction).  To help prevent logical errors from
  535. creeping into a program, the assembler doesn't allow the use of addresses
  536. where constants are expected and vice versa.  To that end, a new assembler
  537. directive, CON, is used to declare constants while EQU is used to declare
  538. an (absolute) address.  Symbols declared by CON cannot be (directly) used
  539. as an address.  Likewise, symbols declared by EQU (and others) cannot be
  540. used where a constant is expected (such as in an immediate operand).
  541.  
  542.         Although this type checking can be quite useful for locating bugs
  543. within the source file, it can also be a source of major annoyance.  Some-
  544. times (quite often, in fact) you may want to treat an address expression
  545. as a constant or a constant expression as an address.  Two functions are
  546. used to coerce these expressions to their desired form: PTR and OFS.
  547. PTR(expr) converts the supplied constant expression to an address expression.
  548. OFS(expr) converts the supplied address expression to a constant expression.
  549. The following is perfectly legal:
  550.  
  551.         Cons1   CON     $5A
  552.         DataLoc EQU     $1000
  553.                 lda     #OFS(DataLoc)
  554.                 sta     PTR(Cons1)
  555.  
  556. For more information, see the section on assembler directives.  PTR and OFS
  557. are required at all compliance levels of this proposed standard.
  558.  
  559.         While any constant value may be used anywhere a constant is allowed,
  560. the 65c816 microprocessor must often differentiate between the various types
  561. of address expressions.  This is particularly true when emitting code since
  562. the length of an instruction depends on the particular address expression.
  563. If an expression contains only constants, direct page values, absolute
  564. values, or long values,  there isn't much of a problem.  The assembler uses
  565. the specified type as the addressing mode.  If the expression contains mixed
  566. types, the resulting type is as follows:
  567.  
  568. Expression contains:                            Result is:
  569.         |            |
  570.         |            |
  571.         +------------+-- Constants              -       Constant
  572.         |            |
  573.         +-- Direct   |                          -       Direct
  574.                      |
  575.                      +--+  Absolute             -       Absolute
  576.                      |
  577.                      +--+- Long                 -       Long
  578.  
  579. Allowable forms:
  580.  
  581.         constant
  582.         direct          constant+direct
  583.         absolute        constant+absolute
  584.         long            constant+long           
  585.                         absolute+long
  586.                         constant+absolute+long
  587.         
  588.  
  589. This says that if you expression contains only constants, then the
  590. result is a constant.  If it contains a mixture of constants and direct
  591. page addresses, the result is a direct page address.  Note that direct page
  592. addresses cannot be mixed with other types of addresses.  An error must be
  593. reported in this situation (although you could get around it with an
  594. expression of the form "abs+OFS(direct)").  Likewise, adding a constant to
  595. an absolute address produces an absolute address.  Adding an absolute and
  596. a long address produces a long address, etc.
  597.  
  598.         Sometimes, you need to force an expression to be a certain type.
  599. For example, the instruction "LDA $200" normally assembles to a load
  600. absolute from location $200 in the current data bank.  If you need to force
  601. this to location $200 in bank zero, regardless of the content of the DBR,
  602. the address expression must be coerced to a long address.  Coercion of this
  603. type is accomplished with the ":D", ":A", ":L", and ":S" expression suffixes.
  604. To force "LDA $200" to be assembled using the long address mode, the in-
  605. struction is modified to be "LDA $200:L".  The coercion suffix must always
  606. follow the full address expression.  The ":S" (for short branches) suffix
  607. is never required, since a short branch (for BRA and BSR) is always assumed,
  608. but it is included for completeness.  For BRA and BSR, the ":L" suffix is
  609. used to imply a long branch (+/- 32K) rather than the long addressing mode.
  610.  
  611.         Caveats: If ":D" or ":A" is used to coerce a large address expression
  612. to direct or absolute, the high order byte(s) of the expression are truncated
  613. and ignored.  The assembler must assume that when a programmer uses these
  614. constructs he knows exactly what he's doing.  Therefore, "LDA $1001:D" will
  615. happily assemble this instruction into a "LDA $01" instruction despite the
  616. actual value of the address expression.
  617.  
  618.  
  619.  
  620.  
  621.  
  622. Addressing Mode Specification
  623. -----------------------------
  624.  
  625.         65c816 addressing modes are specified by certain symbols in the op-
  626. erand field.  A quick rundown follows:
  627.  
  628.         Addressing mode         Format(s)               Example(s)
  629.         ---------------         ------------------      ----------------------
  630.  
  631.         Immediate               #<expression>           LDA #0
  632.                                 =<expression>           CMP =LastValue
  633.  
  634.         Direct Page             <expression>            LDA DPG
  635.                                 <expression>:D          LDA ANY:D
  636.  
  637.         Absolute                <expression>            LDA ABS
  638.                                 <expression>:A          LDA ANY:A
  639.  
  640.         Long                    <expression>            LDA LONG
  641.                                 <expression>:L          LDA ANY:L
  642.  
  643.         Accumulator             {no operand}            ASL
  644.                                                         INC
  645.  
  646.         Implied                 {no operand}            CLC
  647.                                                         SED
  648.  
  649.         Direct, Indirect,
  650.         Indexed by Y            (<direct expr>),Y       LDA (DPG),Y
  651.                                 (<direct expr>).Y       LDA (ANY:D).Y
  652.  
  653.         Direct, Indirect,
  654.         Indexed by Y, Long      [<direct expr>],Y       LDA [DPG],Y
  655.                                 [<direct expr>].Y       LDA [DPG].Y
  656.  
  657.         Direct, Indexed by X,
  658.         Indirect                (<direct expr>,X)       LDA (DPG,X)
  659.                                 (<direct expr>.X)       LDA (ANY:D.X)
  660.  
  661.         Direct, Indexed by X    <direct expr>,X         LDA DPG,X
  662.                                 <direct expr>.X         LDA DPG.X
  663.  
  664.         Direct, Indexed by Y    <direct expr>,Y         LDX DPG,Y
  665.                                 <direct expr>.Y         LDX DPG.Y
  666.  
  667.         Absolute, Indexed by X  <abs expr>,X            LDA ABS,X
  668.                                 <abs expr>.X            LDA ANY:A.X
  669.  
  670.         Long, Indexed by X      <long expr>,X           LDA ANY:L,X
  671.                                 <long expr>.X           LDA LONG.X
  672.  
  673.         Absolute, Indexed by Y  <abs expr>,Y            LDA ANY:A,Y
  674.                                 <abs expr>.Y            LDA ABS.Y
  675.  
  676.         Program Counter
  677.         Relative (branches)     <expression>            BRA ABS
  678.                                 @<expression>           BRA @ABS
  679.  
  680.         PC Relative (PSH)       @<expression>           PSH @ABS
  681.  
  682.         Absolute, Indirect      (<abs expr>)            JMP (ABS)
  683.  
  684.         Absolute, Indexed,
  685.         Indirect                (<abs expr>,X)          JMP (ABS,X)
  686.                                 (<abs expr>.X)          JMP (ABS.X)
  687.  
  688.         Direct, Indirect        (<dpg expr>)            LDA (DPG)
  689.                                                         STA (ANY:D)
  690.  
  691.         Stack Relative          <expr8>,S               LDA 2,S
  692.                                 <expr8>.S               LDA 2.S
  693.  
  694.         Stack Relative,
  695.         Indirect, Indexed       (<expr8>,S),Y           LDA (2,S),Y
  696.                                 (<expr8).S),Y           LDA (2.S),y
  697.                                 (<expr8),S).Y           LDA (2,S).y
  698.                                 (<expr8).S).Y           LDA (2.S).y
  699.  
  700.         Block Move              <long expr>,<long expr> MVN LONG,LONG
  701.                                                         MVP LONG,LONG
  702.  
  703.  
  704.         <dpg expr>, DPG-        Any direct page expression or symbol.
  705.         <abs expr>, ABS-        Any absolute expression or symbol.
  706.         <long expr>, Long-      Any long expression or symbol.
  707.         expr8-                  Any expression evaluating to a value less than
  708.                                 256.
  709.  
  710.  
  711. Note: the only real difference between the existing standard and the proposed 
  712. standard is that the period (".") can be used to form an indexed address ex-
  713. pression.  This is compatible (in practice, as well as philosophy) with the 
  714. record structure mechanism supported by this proposed standard.  This syntax 
  715. for the various addressing modes is required at all compliance levels.
  716.  
  717.         Suggestion: (<dpg expr>):L,  (<dpg expr>):L,Y, and (<dpg expr):L.Y 
  718. should be allowed as substitutes for [<dpg expr>],  [<dpg expr>],Y, and 
  719. [<dpg expr].Y, respectively.  This, however, is not required by this proposed 
  720. standard.
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727. Assembler Directives and Pseudo-Opcodes
  728. ---------------------------------------
  729.  
  730.         An assembler directive is a message to the assembler to change some
  731. status or otherwise affect the assembly operation.  It does not generate any
  732. object code.  A pseudo-opcode, on the other hand, is not a standard 65c816
  733. instruction but does generate object code.  Examples of assembler directives
  734. include instructions that turn the listing on or off, define procedures,
  735. equate labels to values, etc.  Examples of pseudo-opcodes include instructions
  736. like .BYTE which emit bytes of object code based on the instruction's
  737. parameters.
  738.  
  739.  
  740. Equates:
  741. --------
  742.  
  743.         Probably the most important assembler directives are the equates.
  744. The equate directives let you associate a value and a type with a symbol.
  745. The possible equates use the syntax:
  746.  
  747.         <label>         .EQU    <16-bit value>
  748.         <label>         .EDP    <8-bit value>
  749.         <label>         .EQL    <24-bit value>
  750.         <label>         .CON    <32-bit value>
  751.         <label>         .FCON   <SANE floating point value>
  752.  
  753. All except .FCON are required at all compliance levels.  .FCON is required
  754. at the full and extended levels.
  755.  
  756.         .EQU lets you define a absolute symbol; an address whose value is
  757. relative to the DBR.  An error should be generated if the value in the
  758. operand field requires more than 16 bits.  The type of the operand expression
  759. is ignored.  It may be a constant expression, a direct page expression, or
  760. even a long address expression.  As long as it's an integer expression an
  761. can fit into 16 bits, it's quite acceptable.
  762.  
  763.         .EDP (equate to direct page) is used to define direct page symbols.
  764. Again, the operand field may be of any integer type as long as the result
  765. fits into 8 bits.  A recommended synonym for .EDP is .EPZ (equate to page
  766. zero) in deference to the 6502's zero page addressing mode.
  767.  
  768.         .EQL (equate long) defines long address expressions.  As usual, the
  769. operand field may contain any integer expression that fits within 24 bits.
  770.  
  771.         .CON (constant) is used to define integer numeric constants.  Any
  772. 32 bit numeric value may be specified in the operand field.
  773.  
  774.         .FCON (floating point constant) is used to declare symbolic floating
  775. point constants.  Such constants must be stored in the symbol table as
  776. 80-bit SANE extended values.
  777.  
  778.         In addition to the typed equates, this proposed standard also allows
  779. an untyped equate, which takes the form:
  780.  
  781.                 <label>         =       <operand>
  782.  
  783. where "<operand>" is any valid operand that may appear in the operand field
  784. of any instruction.  <operand>'s type may be integer, string, floating point
  785. and may also include an addressing mode.  The following are all legal:
  786.  
  787.                 lbl     =       5
  788.                 lbl     =       5.5
  789.                 lbl     =       "Five"
  790.                 lbl     =       Array,X
  791.                 lbl     =       (dp,s),y
  792.  
  793. Labels defined by "=" may appear anywhere the operand field specified for
  794. that label is allowed.  In general, a simple string substitution should be
  795. performed when a label defined by "=" is used.  Note: a label declared by
  796. "=" can be redefined without error throughout the program.  The "=" directive
  797. is required only at the full and extended compliance levels.
  798.  
  799.  
  800.  
  801. Data Definitions:
  802. -----------------
  803.  
  804.         While the equates are probably the most important assembler 
  805. directives, the data definition instructions are probably the most important
  806. pseudo-opcodes around.  These instructions are classed into four groups
  807. determined by the types of operands they accept.  In the following paragraphs
  808. all optional items are enclosed within braces.
  809.  
  810.         The first group of data reservation instructions accept any integer
  811. type expression as operands.  They are:
  812.  
  813.         {label}         .BYTE   {expr1, expr2, ..., exprn}
  814.         {label}         .WORD   {expr1, expr2, ..., exprn}
  815.         {label}         .LONG   {expr1, expr2, ..., exprn}
  816.         
  817. If a label is present, it is treated as a statement label within the current
  818. segment and assigned the value of the location counter before any bytes are
  819. emitted.  For the .BYTE opcode, one byte of data is emitted for each operand
  820. in the operand field, that byte being the L.O. byte of each expression.  
  821. Operands are purely optional.  If no operand appears, then an indeterminate
  822. value is emitted. The .WORD opcodes outputs two bytes for each expression in 
  823. the operand field (or two indeterminate bytes if no operand is present).  The
  824. .LONG instruction outputs four bytes for each operand.  These three pseudo-
  825. opcodes must be present at all compliance levels.
  826.  
  827.         The next group of pseudo-opcodes are used to create tables of
  828. addresses.  As such, they only allow symbols that have been defined by
  829. .EQU, .EQL, "=" (as applicable), statement labels, procedure labels, and
  830. segment labels in their operand fields.  They are:
  831.  
  832.         {label}         .OFFS   expr1 {,expr2, ..., exprn}
  833.         {label}         .ADRS   expr1 {,expr2, ..., exprn}
  834.         {label}         .PTR    expr1 {,expr2, ..., exprn}
  835.  
  836. .OFFS outputs two bytes for each operand;  .ADRS outputs three bytes for
  837. each operand; and .PTR outputs four bytes for each operand.  These three
  838. pseudo-opcodes are only required at the full and extended compliance levels.
  839.  
  840.         The third group of declarations are used to create constant tables.
  841. As such, they only allow symbols declared by .CON.  They are:
  842.  
  843.         {label}         .SHORT   expr1 {,expr2, ..., exprn}
  844.         {label}         .INTEGER expr1 {,expr2, ..., exprn}
  845.         {label}         .LONGINT expr1 {,expr2, ..., exprn}
  846.  
  847. These pseudo-ops output one, two, and four bytes respectively.  These
  848. pseudo-opcodes are not required at the subset compliance level, they are
  849. required only at the full and extended levels.
  850.  
  851.         Note: non-symbolic constants are allowed in any of the above
  852. pseudo-opcodes.  Only symbols should have their type information checked.
  853.  
  854.         The last group of data declaration pseudo-opcodes are used to
  855. initialize floating point values.  These pseudo-ops are:
  856.  
  857.         {label}         .FLOAT          {item1, item2, ..., itemn}
  858.         {label}         .DOUBLE         {item1, item2, ..., itemn}
  859.         {label}         .EXTENDED       {item1, item2, ..., itemn}
  860.         {label}         .COMP           {item1, item2, ..., itemn}
  861.  
  862. each instruction generates operands of 4, 8, 10, or 8  bytes in length,
  863. respectively.  If the operand field is left blank, the corresponding bytes
  864. contain an indeterminate value, but the assembler should initialize them to
  865. NaN (not a number).  These four pseudo-opcodes are required only at the
  866. full and extended levels.
  867.  
  868.         Although not required by the standard, the following data declaration
  869. directives are recommended and should be supported:
  870.  
  871.         {label}         .HBYTE          expr1 {,expr2, ..., exprn}
  872.         {label}         .BBYTE          expr1 {,expr2, ..., exprn}
  873.         {label}         .XBYTE          expr1 {,expr2, ..., exprn}
  874.         {label}         .HWORD          expr1 {,expr2, ..., exprn}
  875.  
  876. the first three reserve one byte of memory for each operand and store the
  877. H.O (bits 8-15), bank (bits 16-23), or extra byte (bits 24-31) respectively.
  878. .HWORD reserves two bytes composed of bits 16-31 for each operand.
  879.  
  880.  
  881. Arrays:
  882. -------
  883.  
  884.         Space for arrays and data tables can be reserved using the data
  885. declaration statement mentioned above in conjunction with the "DUP" operator.
  886. DUP is a binary operator that takes the form:
  887.  
  888.                 count DUP (list)
  889.  
  890. where count is some constant value and list is a (possibly empty) list of
  891. values.  The items in (list) are repeated "count" times.  For example, the
  892. following .BYTE statement reserves space for an array of 64 bytes and
  893. initializes each byte to zero:
  894.  
  895.         MyArray         .BYTE           64 DUP (0)
  896.  
  897. The following statement reserves 256 bytes consisting of the values 1, 2, 3,
  898. 4, 5, 6, 7, and 8 repeated 32 times:
  899.  
  900.         MyArray         .BYTE           32 DUP (1,2,3,4,5,6,7,8)
  901.  
  902.  
  903.         The DUP operator is fully recursive.  That is, one of the items in
  904. the list may, itself, be a list defined by the DUP operator.  For example,
  905.  
  906.         Example         .BYTE           16 DUP (0,1,2 DUP (3,4,5))
  907.  
  908. reserves 128 bytes consisting of the list "0,1,3,4,5,3,4,5" repeated 16 times.
  909.  
  910.         If the DUP list is empty,  e.g., "16 dup ()", then exactly one item
  911. is reserved for each entry, but it is not initialized.  The following example
  912. reserves space for 128 uninitialized words:
  913.  
  914.         OffsetTable     .WORD           128 DUP ()
  915.  
  916.  
  917.  
  918.  
  919. Type definitions:
  920. -----------------
  921.  
  922.         Enumerated data types can be declared with the ".TYPE" directive.
  923. This directive takes the form:
  924.  
  925.         {label}         .TYPE           item1 {,item2, ..., itemn}
  926.  
  927. The items in the list are assigned consecutive values starting from zero.
  928. For example, in the following .TYPE statement, the symbols red, green, and
  929. blue are assigned the values zero, one, and two, respectively:
  930.  
  931.         colors          .TYPE           red,green,blue
  932.  
  933. The symbols in the operand field of a .TYPE statement must be unique and
  934. undefined elsewhere (within the current scope, more on that later).  The
  935. .TYPE statement above is almost identical to the statements:
  936.  
  937.                 red     .con    0
  938.                 green   .con    1
  939.                 blue    .con    2
  940.  
  941. However, there is one major difference.  The .TYPE statement also defines a
  942. symbol specified in the label field.  This symbol can be used as a pseudo-
  943. opcode to reserve space for values of the specified type.  In the example
  944. above, "colors" could be used as a pseudo-opcode to reserve space for the
  945. values red, green, and blue.  To differentiate type declarations from other
  946. instructions, a special lead-in character is used.  The slash ("/") is
  947. recommended by this standard, but the user should have the option of choosing
  948. this character via a setup program for the assembler.  From the example
  949. above, colors could be used as a pseudo-opcode in the following manner:
  950.  
  951.         Christmas       /colors         red,green
  952.         Ocean           /colors         blue,green
  953.         Sky             /colors         blue
  954.                         /colors         red
  955.         Primaries       /colors         red,blue,green
  956.  
  957. Unlike other data reserving pseudo-opcodes, a "/colors" definition only
  958. allows symbols that appear in the operand field of the associated .TYPE
  959. statement or one of those symbols in a expression that contains a single
  960. such symbol plus or minus a numeric constant, as long as the result is still
  961. within the range of symbols declared for that type.  E.g.,
  962.  
  963.         Okay            /colors         red,green+1,blue
  964.         NotOkay1        /colors         blue+2   ;Outside allowable range
  965.         NotOkay2        /colors         red+blue ;can't add two such symbols
  966.         NotOkay3        /colors         $25      ;Not red, green, or blue
  967.  
  968. If you need to coerce an expression to the proper form, simply use the type
  969. name as a pseudo-function.  E.g.,
  970.  
  971.         ThisIsOkay      /colors         colors(0),blue ;Same as red, blue
  972.  
  973. If the operand is not appropriate, the assembler should generate a warning
  974. and emit the code as though the .BYTE statement were used.
  975.         
  976.  
  977.         If there isn't a label starting in column one of a .TYPE statement
  978. then the symbols defined in the operand field are applied to the previous
  979. .TYPE statement.  This allows you to create .TYPEs where several symbols
  980. (which couldn't possibly fit on a single line) are declared as constants.
  981. E.g.,
  982.  
  983.         colors          .TYPE           red, yellow, blue
  984.                         .TYPE           orange, green violet
  985.                         .TYPE           brown, black, white
  986.  
  987. All of these symbols will be associated with "colors".   A maximum of 256
  988. symbols can be associated with a symbol via the .TYPE statement.  Whenever
  989. the data reservation form is used, exactly one byte is reserved for each
  990. item in the operand field.  If you need to reserve more than a single byte
  991. for each item, use the record declarations described next.
  992.  
  993.         The DUP operator can be used to define enumerated data type arrays,
  994. e.g.,
  995.  
  996.         LotsOfRed       /colors         16 DUP (red)
  997.  
  998.  
  999.  
  1000.         Another form of the .TYPE statement allows you to declare byte
  1001. subrange values.  A definition of this type takes the form:
  1002.  
  1003.         label           .TYPE   start..stop
  1004.  
  1005. where start and stop are constant values in the range 0..255 and 
  1006. start <= stop.   Examples:
  1007.  
  1008.         LessThan10      .TYPE   0..9
  1009.         Nibbles         .TYPE   0..$F
  1010.         PrimaryColors   .TYPE   red..blue   ;From above, is red, yellow, blue
  1011.  
  1012.  
  1013.         Implementation of the .TYPE statement is required only at the full
  1014. and extended compliance levels.
  1015.  
  1016.  
  1017.  
  1018. Records:
  1019. --------
  1020.  
  1021.         A record data structure can be defined with the ".RECORD" and ".ENDR"
  1022. directives using the syntax:
  1023.  
  1024.         label   .RECORD
  1025.               <data declarations>
  1026.                 .ENDR
  1027.  
  1028. This creates a template, but does not generate any code.  An example might
  1029. be:
  1030.  
  1031.         CursorPosn      .RECORD
  1032.         ROW             .BYTE   0
  1033.         COLUMN          .BYTE   0
  1034.                         .ENDR
  1035.  
  1036. This definition creates the type "CursorPosn".  Like the .TYPE definitions,
  1037. the symbol defined by .RECORD can be used as a pseudo-opcode to reserve
  1038. storage for a variable.  For example, to declare a variable of type
  1039. "CursorPosn" the following statement is used:
  1040.  
  1041.         MyCursor        /CursorPosn
  1042.  
  1043. This statement reserves two bytes, initialized to zeros, at the current
  1044. location counter.
  1045.  
  1046.         Access to the fields of the record is accomplished by using the
  1047. "." operator, just like Pascal.   E.g.,
  1048.  
  1049.                         lda     MyCursor.ROW    ;Fetches first byte.
  1050.                         lda     MyCursor.COLUMN ;Fetches the second byte.
  1051.  
  1052.  
  1053.         In the example above, the ROW and COLUMN fields of each variable
  1054. declared with CursorPosn are always initialized to zero.  Any other value
  1055. could have been used by substituting the appropriate value, or an 
  1056. indeterminate value could have been specified by the definition:
  1057.  
  1058.         CursorPosn      .RECORD
  1059.         ROW             .BYTE
  1060.         COLUMN          .BYTE
  1061.                         .ENDR
  1062.  
  1063.  
  1064.         On occasion, you may want each record variable definition to
  1065. specify the initial values.  This can be accomplished by specifying
  1066. parameters in the record definition.  Parameters are specified by the
  1067. symbols:  ?0, ?1, ..., ?9.  ?0 corresponds to the first parameter, ?1 to
  1068. the second, etc.   Consider the following record and variable definitions:
  1069.  
  1070.         CursorPosn      .RECORD
  1071.         ROW             .BYTE   ?0
  1072.         COLUMN          .BYTE   ?1
  1073.                         .ENDR
  1074.  
  1075.         HomePosn        /CursorPosn     0,0
  1076.         LowerRight      /CursorPosn     23,79
  1077.         MyCursor        /CursorPosn     5,10
  1078.  
  1079.  
  1080.         The only problem with this definition form is that each CursorPosn
  1081. variable must supply exactly two operands.  Sometimes you may want to have
  1082. a default value in the event an operand isn't specified.  This is accomplished
  1083. using a record defintion of the form:
  1084.  
  1085.         CursorPosn      .RECORD ?0=0,?1=0
  1086.         ROW             .BYTE   ?0
  1087.         COLUMN          .BYTE   ?1
  1088.                         .ENDR
  1089.  
  1090. This definition instructions the assembler to allow zero or more parameters,
  1091. defaulting ?0 and ?1 to zero if their respective entries aren't present.
  1092. The .DEFAULT directive can also be used, particularly if you run out of
  1093. room on the .RECORD line:
  1094.  
  1095.         OpenRec         .RECORD  ?0=0, ?1=1
  1096.                         .DEFAULT ?2=ZRO('Hello there'), ?3=2
  1097.         FirstItem       .WORD    ?0
  1098.                         .LONG    ?3
  1099.         SecondItem      .BYTE    ?1, ?2
  1100.                         .ENDR
  1101.  
  1102.  
  1103.         Record definitions are required at the full and extended compliance
  1104. levels, they are not required at the subset compliance level.
  1105.  
  1106.  
  1107.  
  1108. Sets:
  1109. -----
  1110.  
  1111.         Bit string types can be declared using the .SET directive.  .SET is
  1112. used in a manner quite similar to .TYPE except the items in the operand field
  1113. can be any constant whose value is less than 32.  Up to 32 items may 
  1114. appear in the operand field of a .SET definition.  The syntax is
  1115.  
  1116.         label           .SET    item1 {,item2, ..., itemn}  ;n <= 32.
  1117.  
  1118. An alternate form is to specify the name of some type variable in the operand
  1119. field.  The following definition creates a set of integers in the range
  1120. 0..9:
  1121.  
  1122.         LessThan10      .TYPE   0..9
  1123.         SetOfDigits     .SET    LessThan10
  1124.  
  1125.  
  1126.         Declaring a set variable is quite similar to declaring an enumerated
  1127. type variable or a record variable: simply use the set name as a pseudo-opcode
  1128. prefaced by a "/":
  1129.  
  1130.         Digits          /SetOfDigits
  1131.  
  1132.  
  1133.         Set constants are specified by placing the items in the set within
  1134. a pair of braces.  E.G.:
  1135.  
  1136.         BitValues       .TYPE           0..7
  1137.         SetOfBitValues  .SET            BitValues
  1138.         Bits            /SetOfBitValues {0,1,2,3}
  1139.         ;
  1140.         ;
  1141.                         lda             #{0,2,7}
  1142.                         sta             Bits
  1143.  
  1144.  
  1145.         The assembler, by default, should allow set constants composed of
  1146. the integer values 0..31.  This allows programmers to easily deal with bits
  1147. by bit numbers rather than the integers those bit patterns represent.  For
  1148. example, to strip all but the H.O. two bits in the (8-bit) accumulator, the
  1149. instruction "AND #{6,7}" makes a lot more sense than "AND #$C0".  All other
  1150. entities appearing within "{" and "}" must appear somewhere in the operand
  1151. field of a .SET statement (or must be a member of a .TYPE definition if that
  1152. type appears in the operand field of a .SET).
  1153.  
  1154.  
  1155.  
  1156. Macros:
  1157. -------
  1158.  
  1159.          Macros are created using the .MACRO and .ENDM directives.  The syntax
  1160. for a macro definition is
  1161.  
  1162.         label           .MACRO          {default parameter values}
  1163.                       <macro body>
  1164.                         .ENDM
  1165.  
  1166. Macros are invoked by placing an underscore, followed by the macro name (the
  1167. label in the .MACRO statement).  The user should be able to change the macro
  1168. lead-in character from underscore to some other character via an assembler
  1169. set up program.
  1170.  
  1171. All labels declared within the macro are local to that definition unless the
  1172. ".GLOBAL" directive is used to extend their scope.  In general, global
  1173. macro labels (except, possibly, those defined by "=") are not useful anyway
  1174. since a duplicate label error might occur on the second invocation of the 
  1175. macro.
  1176.  
  1177.         The macro body consists of a sequence of assembler statements.  Most
  1178. reasonable statements may be included in the macro body.  The standard does
  1179. not required nested macro definitions.  Nor need the macro definitions allow
  1180. .RECORD, .TYPE, or .SET definitions (since labels are local to the macro,
  1181. such definitions are dubious anyway).
  1182.  
  1183.         Macro parameters are specified using ?0, ?1, ..., ?9, just as for
  1184. .RECORD definitions.  "?#" can be used to determine the actual number of
  1185. parameters present.  "?:expr" can be used to select a parameter using a
  1186. numeric expression.  For example, "?:?#-1" returns the value of the last
  1187. parameter specified.  Default values for the parameters can be specified
  1188. in the .MACRO operand field, or in a .DEFAULT statement, just like specifying
  1189. default values for .RECORD parameters.  E.g.,
  1190.  
  1191.                 MyMacro .MACRO   ?0=0, ?1=2
  1192.                         .DEFAULT ?2="Hello there"
  1193.                         .BYTE    ?0
  1194.                         .WORD    ?1
  1195.                         .BYTE    ?2
  1196.                         .ENDM
  1197.  
  1198. then:
  1199.  
  1200.                         _MyMacro 10,20
  1201.  
  1202. generates the bytes:
  1203.                         10, 20, 0, Hello there
  1204.  
  1205.  
  1206.         Macros, by the very nature, allow a variable number of parameters.
  1207. If more parameters are specified than there are references for, the extra
  1208. parameters are ignored.  If fewer parameters are specified than there are
  1209. references for, the additional references will be treated as undefined
  1210. symbols.  If you want to be able to force the user to enter an exact number
  1211. of parameters, then use the ?# in the default field to specify a fixed number
  1212. of parameters.  The following macro definition requires the user to enter
  1213. exactly two parameters whenever TwoParms is invoked:
  1214.  
  1215.         TwoParms        .MACRO  ?#=2
  1216.                         lda     ?0
  1217.                         sta     ?1
  1218.                         .ENDM
  1219.  
  1220. If the number of parameters is fixed at a certain value, default values
  1221. are not allowed in the macro definition.
  1222.  
  1223.         Since macro parameters, in a macro invocation, are separated by
  1224. commas, you cannot directly create a macro of the form:
  1225.  
  1226.         LDAIX           .MACRO  ?#=1
  1227.                         lda     ?0
  1228.                         .ENDM
  1229.  
  1230. and invoke it by:
  1231.  
  1232.                         _LDAIX  LBL,X
  1233.  
  1234. intending the "LDA LBL,X" instruction to be generated.  Instead, the macro
  1235. mechanism will think that LBL and X are two different parameters and generate
  1236. an error since only a single parameter is allowed.  The "<<" and ">>" symbols
  1237. are used as an escape mechanism to parenthesize such operands.  To handle the
  1238. case above, the following statement could be used:
  1239.  
  1240.                         _LDAIX  <<LBL,X>>
  1241.  
  1242. and this would generate the instruction "LDA LBL,X".
  1243.  
  1244.         The lookup, value, type, and mode functions are quite useful for
  1245. dealing with macro parameters.  The exact values returned by these functions
  1246. will be described at a later time.
  1247.  
  1248.         For additional information on macros and dealing with macro para-
  1249. meters, see the sections on conditional assembly and while loops.
  1250.  
  1251.         Macros are required only at the full and extended compliance levels.
  1252.  
  1253.  
  1254.  
  1255. Address Expression Functions:
  1256. -----------------------------
  1257.  
  1258.         Format:
  1259.  
  1260.                 label   .FUNC   {default parameter values}
  1261.                       <function body>
  1262.                         .RETURN expr
  1263.                         .ENDF
  1264.  
  1265.         The .FUNC statement lets programmers define their own address
  1266. expression functions that can be used in operand fields of assembly language
  1267. statements.  The function body typically contains a sequence of equates
  1268. and other value computing statements;  it may not contain any code generating
  1269. statements.
  1270.  
  1271.         Like a macro definition, all symbols defined inside an address
  1272. expression function are local to that function.  Likewise,  default parameters
  1273. may be declared in the operand field of the .FUNC statement or via the
  1274. .DEFAULT statement.  Alternately, you can specify that a fixed number of
  1275. parameters are required by using the "?#=expr" item in the operand field
  1276. of the .FUNC statement.
  1277.  
  1278.         The expression following the .RETURN statement is the value returned
  1279. by the addressing mode function.  Note that more than one .RETURN may appear
  1280. within the function (perhaps within the confines of a conditional assembly
  1281. sequence).  If more than one .RETURN statement is encountered, all but the
  1282. last are ignored.  The expression returned in the .RETURN operand field may
  1283. contain addressing modes in addition to the actual expression value.  In
  1284. general, anything allowed as a macro parameter can be returned as an address
  1285. expression value.
  1286.  
  1287.         An address expression function is invoked by placing the function
  1288. name in some other expression followed by the parameters enclosed within
  1289. parentheses.  The parentheses are required even if the parameter list is
  1290. empty (just like the "C" programming language).  Examples follow:
  1291.  
  1292.         StripLONibble   .FUNC   ?#=1
  1293.         value           =       ?0 AND $F0
  1294.                         .RETURN value
  1295.                         .ENDF
  1296.         ;
  1297.         AppendTXT       .FUNC   ?#=1
  1298.         string          =       ?0 + ".TXT"
  1299.                         .RETURN string
  1300.                         .ENDF
  1301.         ;
  1302.                          .
  1303.                          .
  1304.                          .
  1305.                         LDA     #StripLONibble($FF)
  1306.                          .
  1307.                          .
  1308.                          .
  1309.                         .BYTE   AppendTxt("MyString")
  1310.  
  1311. The LDA instruction generates 
  1312.  
  1313.                         LDA #$F0,  
  1314.  
  1315. the .BYTE statement becomes
  1316.  
  1317.                         .BYTE   "MyString.TXT"
  1318.  
  1319. The latter example demonstrates that address expression functions can
  1320. return any valid type.  This includes strings, records, sets, and any
  1321. other entity allowed in an operand field.  Consider the following:
  1322.  
  1323.                 LBLX    .FUNC   ?#=2
  1324.                 L       =       ?0-?1,X
  1325.                         .RETURN L
  1326.                         .ENDF
  1327.  
  1328.                         LDA     LBLX($100,10)
  1329.  
  1330. This generates the code:
  1331.  
  1332.                         LDA     $100-10,X
  1333.  
  1334.  
  1335.         Address expression functions are required only at the full and
  1336. extended compliance levels.
  1337.  
  1338.  
  1339.  
  1340.  
  1341. The Label Type
  1342. --------------
  1343.  
  1344.         The ".LABEL" directive is used to declare a valueless symbol, that is, one which
  1345. is defined but is assigned no particular value.  The syntax for the .LABEL directive is:
  1346.  
  1347.                         .LABEL  symbol1 {, symbol2, ..., symboln}
  1348.  
  1349. Each symbol appearing in the operand field is inserted into the symbol table as a "label"
  1350. typed symbol.
  1351.  
  1352.         Label-typed symbols are useful mainly in macros and in the operand fields of
  1353. conditional assembly statements.  The only operations you can perform using label-typed
  1354. symbols are "=" and "<>".  Most of the reserved symbols in the assembler (such as A, X,
  1355. Y, DBR, D, M, S, etc.) are actually label-typed symbols.
  1356.  
  1357.         An example of where you might use a label-typed symbol follows:
  1358.  
  1359.                 CmpReg  .MACRO  ?#=2
  1360.                         .IF     ?0=A
  1361.                         cmp     ?1
  1362.                         .ELSE
  1363.                         .IF     ?0=X
  1364.                         cpx     ?1
  1365.                         .ELSE
  1366.                         .IF     ?0=Y
  1367.                         cpy     ?1
  1368.                         .ELSE
  1369.                         .PAUSE
  1370.                         .ENDIF
  1371.                         .ENDIF
  1372.                         .ENDIF
  1373.                         .ENDM
  1374.  
  1375.         The "=" equate can also be used to defined label-typed symbols by specifying a
  1376. label-typed symbol in the operand field, e.g.,
  1377.  
  1378.                 ACC     =       A
  1379.                 XReg    =       X
  1380.                         etc.
  1381.  
  1382. Note that the last equate above does not allow you to enter indexed by X addressing modes as
  1383.  
  1384.                         <expression>,XReg
  1385.  
  1386. it simply allows you to use a statement of the form:
  1387.  
  1388.                         .IF     XReg=X
  1389.  
  1390. and wind up assemblying the code after the ".IF".
  1391.  
  1392.         The ".LABEL" directive is required at the full and extended compliance levels; it
  1393. is not required at the subset compliance level.
  1394.  
  1395.  
  1396.  
  1397.  
  1398.  
  1399. Procedures:
  1400. -----------
  1401.  
  1402.         At the full and extended compliance levels, the .PROC and .ENDP
  1403. directives can be used to declare 65c816 procedures (subroutines).  Procedure
  1404. declarations take the form:
  1405.  
  1406.         procname        .PROC   {near|far}
  1407.  
  1408.                     <procedure body>
  1409.  
  1410.                         .ENDP
  1411.  
  1412. If an operand appears after the .PROC statement, it must be either "near" or
  1413. "far".  If no operand appears, "near" is assumed.
  1414.  
  1415.         The  procedure name that appears in the label field of the .PROC
  1416. statement is assigned the current value of the location counter at that
  1417. point in the program.  It is also given the type of near procedure or
  1418. far procedure, depending upon the .PROC operand field.
  1419.  
  1420.         All labels defined inside a procedure are local to that  procedure
  1421. unless the .GLOBAL directive is used to extend their scope beyond the
  1422. procedure.  Therefore, labels inside one procedure may be reused outside
  1423. that procedure.  If a label inside a procedure is already defined outside
  1424. that procedure an error is not generated, instead the new label supercedes
  1425. the old one INSIDE THE PROCEDURE (scoping rules are the same as for Pascal).
  1426. Procedures may be nested inside one other, the scoping rules used by Pascal
  1427. apply in such situations.
  1428.  
  1429.         Inside the procedure, RET can be used in place of RTS or RTL.  The
  1430. assembler will automatically choose the appropriate version depending upon
  1431. whether the procedure is a near or far procedure.  If RTS is used inside a
  1432. FAR procedure or RTL is used inside a NEAR procedure, the assembler will
  1433. generate a warning.
  1434.  
  1435.         The assembler automatically assembles JSR using the absolute or
  1436. long addressing mode depending upon the procedure definition.  If the
  1437. assembler supports the JSL mnemonic and a JSL is used to call a NEAR
  1438. procedure, the assembler must generate an warning.  If the address expression
  1439. following a JSR was coerced using the ":A" or ":L" suffixes, no warning will
  1440. be generated if the incorrect distance was specified.  I.e., the following
  1441. does NOT generate an error:
  1442.  
  1443.                         JSR     mysub:L
  1444.                          .
  1445.                          .
  1446.                          .
  1447.                 mysub   .PROC   NEAR
  1448.                          .
  1449.                          .
  1450.                          .
  1451.  
  1452. If you use a coercion operator, the assembler assumes that you know what
  1453. you are doing.
  1454.  
  1455.         Note that the use of the .PROC statement is optional.  You may con-
  1456. tinue to build and call subroutines without the .PROC directive.  However,
  1457. using .PROC allows the assembler to perform additional type checking on
  1458. certain operations.  An external data flow analysis program can also use the
  1459. procedure declarations to help locate logical bugs in your code.
  1460.  
  1461.         .PROC and .ENDP are required at all compliance levels of the
  1462. standard.
  1463.  
  1464.  
  1465.  
  1466.  
  1467.  
  1468. Module Communication Directives:
  1469. --------------------------------
  1470.  
  1471.         Three directives, .GLOBAL, .PUBLIC, and .EXTERNAL, are used to
  1472. communicate symbolic values across procedure, segment, and module boundaries
  1473. (a module is any one source file which is assembled as a whole unit).  The
  1474. .GLOBAL directive is used to make symbols visible outside of procedures,
  1475. macros, functions, and records.  The .PUBLIC directive is used to make
  1476. certain symbols visible outside the current module.  The .EXTERNAL directive
  1477. is used to make symbols defined outside the current module visible within
  1478. the module.
  1479.  
  1480.         The syntax for the .PUBLIC and .GLOBAL directives is identical, it
  1481. takes the form:
  1482.  
  1483.                         .PUBLIC         symbol1 {,symbol2, ..., symboln}
  1484. and,                    .GLOBAL         symbol1 {,symbol2, ..., symboln}
  1485.  
  1486. A label is not allowed in the label field of either mnemonic.  The symbols
  1487. specified in the operand field of these two instructions are made known
  1488. outside the procedure or module where they currently reside.  If a procedure
  1489. is nested inside another, the .GLOBAL statement makes its symbols known
  1490. only to the procedure encompassing the nested procedure.  In the following
  1491. example, LCL is known only inside procedure X1 and X2, not to the whole
  1492. program:
  1493.  
  1494.                 X1      .PROC
  1495.                           .
  1496.                           .
  1497.                 X2      .PROC
  1498.                         .GLOBAL LCL
  1499.                           .
  1500.                           .
  1501.                         .ENDP
  1502.                         .ENDP
  1503.  
  1504. If you wanted to make LCL visible at the level above X1, then another
  1505. .GLOBAL statement must appear inside the X1 procedure declaring LCL to
  1506. be global to that procedure.
  1507.  
  1508.         Another alternative is to use the .PUBLIC statement.  Any symbol
  1509. declared public with .PUBLIC is instantly visible throughout the program
  1510. (within the confines of the scoping rules).  However, keep in mind that
  1511. symbols declared as public are visible outside the current module as well
  1512. and may intefere with other modules.
  1513.  
  1514.         The .EXTERNAL directive is used to obtain access to symbols declared
  1515. outside the current module.  The syntax for the .EXTERNAL directive is:
  1516.  
  1517.                 .EXTERNAL  symbol1:type {,symbol2:type, ..., symboln:type}
  1518.  
  1519. Again, no label is allowed in the label field of the .EXTERNAL directive.
  1520. The type item is any of NEAR, FAR, CONST, DIRECT, ABS, or LONG.  
  1521.  
  1522.         Note: symbols declared with "=", .MACRO, .RECORD, .SET, and .TYPE
  1523. may not appear as operands to the .GLOBAL, .PUBLIC, or .EXTERNAL directives.
  1524.  
  1525.         These directives are not required at the subset compliance level,
  1526. only at the full and extended levels.
  1527.  
  1528.  
  1529.  
  1530.  
  1531. Segments:
  1532. ---------
  1533.  
  1534.         Segments are used to group a collection of logically and physically
  1535. related entities within a program.  A segment may contain the program code,
  1536. variables, stack area, direct page area, or other such data.  Typically
  1537. a segment is a load module.  That is, a segment is loaded as a whole into
  1538. memory.  If a program consists of two or more segments, they need not all
  1539. reside in memory at the same time.  The memory manager/loader may load
  1540. segments as needed into memory.
  1541.  
  1542.         Segment definitions are required at all compliance levels.  All
  1543. programs must consist of at least one segment (this is a source of minor
  1544. incompatibility with existing assemblers).  The most general form of the
  1545. segment definition is:
  1546.  
  1547.         label   .SEGMENT        TYPE=expr {,ALIGN=expr} {,ORG=expr} {,NOCODE}
  1548.  
  1549.               <segment body>
  1550.  
  1551.                 .ENDS
  1552.  
  1553.  
  1554. .SEGMENT lets you declare any general type of segment.  The symbol in the
  1555. label field need not be unique, but if it is redefined elsewhere within the
  1556. current scope, it must appear on a .SEGMENT definition whose type is exactly
  1557. the same as the current definition.
  1558.  
  1559.         Unlike .PROCs, .MACROs, etc.,  symbols defined inside a segment are
  1560. not local to the segment, but are instantly visible to the reset of the
  1561. module.  If you need to declare local variables within a segment, use the
  1562. .LOCAL and .RELEASE directives.
  1563.  
  1564.         The type of segment must be specified in the .SEGMENT operand field.
  1565. The actual segment types will be defined at a later date.  For now, assume 
  1566. the types used by the Apple //GS loader are specified after the TYPE= item.
  1567. The segment type describes the attributes of the segment, attributes such
  1568. as whether the segment is relocatable or absolute, fixed or movable, etc.
  1569.  
  1570.         The optional ALIGN operand is used to determine some number of bytes
  1571. to which this segment (portion) must be aligned.  If ALIGN=1 , the segment
  1572. will be aligned on any byte boundary.  If ALIGN=2 then the segment will be
  1573. aligned on a word boundary, etc.  Any value between 1 and $10000 can be used
  1574. (ALIGN=$10000 will align the segment on a bank boundary).
  1575.  
  1576.         The ORG=expr option can be used to fix the starting address of the
  1577. segment.  This option isn't normally used with code-generating segments.
  1578. It's mainly used to define I/O port addresses and other absolute variables.
  1579.  
  1580.         The NOCODE option is used to declare that a segment will not generate
  1581. any code (i.e., it's just used to declare variables).  If any 65c816 instruct-
  1582. ion appears in a NOCODE segment, an error will be generated.  All data
  1583. declaring pseudo-opcodes (e.g., .BYTE) must specify indeterminate values else
  1584. an error will be reported.
  1585.  
  1586.         If multiple segments with the same name appear in a module (or
  1587. across modules, for that matter), they will be combined into a single,
  1588. contiguous module by the assembler and/or linker.  Consider the following:
  1589.  
  1590.         MyCode          .SEGMENT        Type=$1AF
  1591.                            .
  1592.                            .
  1593.                            .
  1594.                         .ENDS
  1595.         ;
  1596.         MyData          .SEGMENT        Type=$100
  1597.                            .
  1598.                            .
  1599.                            .
  1600.                         .ENDS
  1601.         ;
  1602.         MyCode          .SEGMENT        Type=$1AF
  1603.                            .
  1604.                            .
  1605.                            .
  1606.                         .ENDS
  1607.  
  1608.  
  1609. Although MyCode appears in two completely disjoint areas, the assembler/linker
  1610. will combine these items into a single segment.  Segments appear in the
  1611. load module in the order they are declared in the source file.  In the
  1612. example above,  segment MyCode appears before segment MyData (even though
  1613. a portion of MyCode appears after MyData, MyCode was still declared before
  1614. MyData).
  1615.  
  1616.         Segments may be nested, but they don't follow any scoping rules.
  1617. Declaring one segment inside another is no different that declaring those
  1618. two segments completely separate.
  1619.  
  1620.         If you have two separate segments (different names but the same
  1621. type), you can combine them together using the .GROUP directive.  This
  1622. directive takes the form
  1623.  
  1624.         label   .GROUP  seg1, seg2 {,seg3, ..., segn}
  1625.  
  1626. Referring to "label" refers to the segment obtained by combining the
  1627. segments in the .GROUP operand field.
  1628.  
  1629.         To simply segment usage, there are six predeclared segments.  They
  1630. may be declared with the directives:
  1631.  
  1632.                 .CODE   .DATA   .DIRECT
  1633.                 .STACK  .VAR    .CONST
  1634.  
  1635. .CODE is used to declare static, code-generating segments which allow
  1636. 65c816 instructions.  .DATA is used to declare static data-generating
  1637. segments.  .CONST is identical to .DATA except data items inside the
  1638. .CONST directive are read-only.  Any attempt to write to items inside a
  1639. .CONST segment should generate an error by the assembler or data flow
  1640. analysis programs.  .DIRECT is used to declare segments containing direct
  1641. page variables.  This is a NOCODE segment, so only definitions are allowed,
  1642. initial values are illegal.  .STACK segments are also NOCODE segments.  They
  1643. are useful for declaring stack space down in bank zero.  The .VAR segment
  1644. is used like the .DATA segment, except .VAR segments are NOCODE segments.
  1645. They are used for declaring unintialized variables in main RAM.
  1646.  
  1647.         The syntax for these six directives is
  1648.  
  1649.         label   .xxxx   {ALIGN=expr | ORG=expr}
  1650.  
  1651.               <segment body>
  1652.  
  1653.                 .ENDS
  1654.  
  1655.  
  1656.  
  1657.  
  1658. The ASSUME Directive
  1659. --------------------
  1660.  
  1661.         With the addition of the bank registers and the mode bits in the
  1662. 65c816 processor, an assembler can no longer determine the proper addressing
  1663. mode to use in all circumstances without help from the programmer.  For
  1664. example, if the assembler encounters an instruction of the form "LDA Label"
  1665. and Label is a statement label inside some segment (i.e., not declared with
  1666. EDP, EQU, EQL, or other type-defining directive), it has no idea whether to
  1667. use the direct, absolute, or long addressing mode.  To do so would require
  1668. that the assembler know the current values of the direct page and data bank
  1669. registers at assembly time.  Frankly, it is not possible for the assembler
  1670. to always know the content of these registers, hence the programmer must
  1671. manually supply this information to the assembler.  This information, as well
  1672. as some other useful information, is supplied to the assembler via the
  1673. .ASSUME directive.
  1674.  
  1675.         The .ASSUME directive uses the syntax:
  1676.  
  1677.                         .ASSUME operand1 {,operand2, ..., operandn}
  1678.  
  1679. where operand(i) is one of the following:
  1680.  
  1681.         DBR:expression24
  1682.         DBR:NOTHING
  1683.         DP:expression16
  1684.         DP:NOTHING
  1685.         M:expression1
  1686.         M:NOTHING
  1687.         X:expression1
  1688.         X:NOTHING
  1689.         CPU:cpu_type
  1690.  
  1691. where expression24 is an expression yielding a 24-bit value, expression16 is
  1692. an expression yielding a 16-bit value, expression1 is an expression yielding
  1693. zero or one, NOTHING is a reserved word, and cpu_type is one of {6502, 65c02,
  1694. 65802, 65816} or one of the later versions of the 65c816 microprocessor.
  1695.  
  1696.         DP (direct page) is used to let the assembler know where the direct
  1697. page register is pointing.  If a segment name is given as the expression,
  1698. that segment must be one that resides in bank zero and is of type DIRECT.
  1699. If the assembler encounters a symbol declared in a segment that is assumed
  1700. to be a direct page segment via the DP:expression operand, the assembler will
  1701. reference that location using the direct page addressing mode (if posssible).
  1702. If the "DP:NOTHING" form is used, the assembler will only use the direct page
  1703. addressing mode if a symbol was declared with the EDP equate.  None of the
  1704. segments will be treated as direct page segments, even if they were declared
  1705. as type DIRECT.  If you want to simultaneously refer to several segments as
  1706. direct page segments, group them together using the .GROUP directive and
  1707. specify the group name as the expression value after the DP:, i.e.,
  1708.  
  1709.         DPGroup         .GROUP  DPSeg1, DPSeg2, DPSeg3
  1710.                         .ASSUME DP:DPGroup
  1711.  
  1712. By default, the assembler should assume DP:NOTHING.
  1713.  
  1714.  
  1715.         DBR is used to tell the assembler which segment/bank the DBR (data 
  1716. bank register) points at.  References to variables within that segment will
  1717. be assembled as absolute references (unless that segment name is also
  1718. specified after DP:expr, in which case the direct page addressing mode will
  1719. be used, if possible).  If DBR:NOTHING is specified, absolute addressing will
  1720. be used only for those symbols declared via EQU, all other references will
  1721. be assumed to be long references.  Note that the H.O. eight bits of the
  1722. 24-bit expression are used.  Therefore, to set the DBR assumption to an
  1723. absolute bank in memory, an expression of the form:
  1724.  
  1725.                         .ASSUME DBR:$200000     ;Assume DBR=$20
  1726.  
  1727. must be used.  By default, the assembler should assume DBR:NOTHING.
  1728.  
  1729.         Normally, a programmer should use "#" and "=" to specify eight or
  1730. sixteen bit immediate operand sizes.  To help ensure upwards compatibility
  1731. with existing source code, a mechanism has been added whereby the "#" is
  1732. used and the .ASSUME directive controls the size of immediate operands.  This
  1733. task is achieved using the M:expr and X:expr operands.  Normally the assembler
  1734. defaults to M:NOTHING and X:NOTHING.  In this mode,  "#" specifies 8-bit
  1735. immediate operands and "=" specifies 16-bit operands.  If the expression
  1736. following the M or X is zero or one,  then any immediate operand containing
  1737. an equal sign is flagged as an error and the "#" specifies an eight-bit
  1738. operand if the expression was 1, a sixteen-bit operand if the expression was
  1739. zero.  If the expression evaluates to any other value an error is generated.
  1740. Note that M only affects accumulator and memory operations while X affects
  1741. the index register operations.  It is perfectly permissible to have an
  1742. .ASSUME of the form:
  1743.  
  1744.                         .ASSUME         M:NOTHING,X:1
  1745.  
  1746. The "=" immediate specifier would be allowed for accumulator operations but
  1747. not for X/Y index register operations.
  1748.  
  1749.         To help ensure compatibility with the existing defacto standard,
  1750. LONGI, LONGA, SHORTI, and SHORTA should be provided as built-in macros
  1751. generating the appropriate .ASSUME statement.
  1752.  
  1753.         The "CPU:cpu_type" operand to the .ASSUME statement lets users
  1754. specify the exact 6500 family CPU they are using.  The effect of this
  1755. operand is to "disconnect" certain instructions.  If a certain CPU is
  1756. specified and a programmer uses an addressing mode or instruction which isn't
  1757. available on that CPU, the assembler will generate an error.  By default,
  1758. the assembler should assume the CPU of the machine on which the assembler
  1759. is intended to run (e.g., 65c816 for Apple //GS machines).  If the assembler
  1760. is running on a different processor other than a 6500 family chip, it should
  1761. default to 65c816.  The user should be able to choose this default value
  1762. from an assembler set-up program.
  1763.  
  1764.         The .ASSUME directive, and all operands available to it, must be
  1765. supported at all compliance levels.
  1766.  
  1767.  
  1768.  
  1769. Local Symbols
  1770. -------------
  1771.  
  1772.         In addition to local labels automatically specified inside procedures,
  1773. macros, and expression functions, you can also explicitly declare local sym-
  1774. bols within the source file.  User-defined local symbols come in two
  1775. varieties: numeric and symbolic.
  1776.  
  1777.         Up to 10 active numeric local labels can be specified at any given
  1778. time.  The numeric local labels are similar to those used by D. E. Knuth
  1779. in "The Art of Computer Programming, Vol 1", although the syntax is different.
  1780. Numeric local labels are declared by placing a caret (up-arrow) in front of
  1781. a single decimal digit in the label field.  Examples follow:
  1782.  
  1783.                 ^0      LDX     #05
  1784.                 ^9      DEX
  1785.                 ^4      LDA     LBL
  1786.  
  1787. Numeric local labels are referenced with the ">n" and "<n" items, where "n"
  1788. represents a single decimal digit.  If the greater than symbol prefaces a
  1789. digit, then the next occurrence of that numeric local label in the source
  1790. file is referenced.  If a less than ("<") symbol is used, then the previous
  1791. numeric local label is used.  Examples:
  1792.  
  1793.  
  1794.                         LDX     #5
  1795.                 ^0      CLR     Array,X
  1796.                         DEX
  1797.                         BPL     <0              ;References 2nd line above.
  1798.                 ;
  1799.                         LDA     Array+2
  1800.                         bne     >0              ;References ^0 below.
  1801.                         TXA
  1802.                 ^0      STA     Array+1
  1803.  
  1804. Note that multiple occurrences of the same numeric local label may appear
  1805. within the program.  The are differentiated by the "<" and ">" symbols.
  1806.  
  1807.         Since "<" and ">" may appear both as operators and as the beginning
  1808. of an operand, a minor ambiguity results.  If you see a portion of an ex-
  1809. pression like ">0",  does it mean  'is some value greater than zero' or does
  1810. it refer to the next occurrence of "^0"?  This is easily handled from context.
  1811. If the ">" or "<" appears where an operator is expected, then the appropriate
  1812. operation is performed.  If they appear where an operand is expected and they
  1813. are followed by a single decimal digit, then they are used as lead-ins for
  1814. numeric local labels.  Otherwise an error must be generated.
  1815.  
  1816.         Numeric local labels are great for those cases where you need to
  1817. perform a short branch or to set up a small loop and you don't want to use
  1818. meaningless mnemonics like "loop1",  "SkipInstr12", etc.  Other times, you
  1819. may want to use a meaningful name like "MainLoop" or "ElseQuit", without
  1820. having to worry about conflicts in other parts of the program.  Such cases
  1821. are easily handled by the symbolic local label facility specified by this
  1822. proposal.  Two assembler directives: .LOCAL and .RELEASE are used to define
  1823. the scope of user-specified local labels.  The syntax for these two directives
  1824. is identical, it is:
  1825.  
  1826.                         .LOCAL  label1  {,label2, ..., labeln}
  1827.                         .RELEASE label1 {,label2, ..., labeln}
  1828.  
  1829. A label defined with .LOCAL is confined to the scope of the .LOCAL/.RELEASE
  1830. pair.   .LOCAL/.RELEASE pairs may be nested allowing you to redefine a symbol
  1831. to any reasonable depth (say, a minimum of 8 levels).
  1832.  
  1833.         Numeric local labels are required at all compliance levels.  Symbolic
  1834. local labels are required at the full and extended compliance levels.
  1835.  
  1836.  
  1837.  
  1838. Conditional Assembly
  1839. --------------------
  1840.  
  1841.         Conditional assembly is handled by the  .IF, .ELSE, .IF1, .IF2,
  1842. .IFDEF,  .IFNDEF, and .ENDIF directives.  .IF is followed by a numeric
  1843. address expression that yields a zero (false) or non-zero (true) result.
  1844. The following code (up to the .ELSE or .ENDIF) is assembled if the result is
  1845. true.  Otherwise the code after the .ELSE (if it is present) is assembled in
  1846. its stead.   .IF1 and .IF2 assemble their respective code during passes
  1847. one and two.  .IFDEF and .IFNDEF accept a single symbol as their parameter
  1848. and test whether or not this symbol is currently defined.   The .ELSE
  1849. directive can be used to assemble additional code in the event the tested
  1850. condition is false.  Finally, the .ENDIF directive is used to terminate
  1851. a conditional assembly sequence.
  1852.  
  1853.         Conditional assembly blocks can be nested to at least eight levels,
  1854. preferably more.  Since all conditional assembly blocks are terminated with
  1855. .ENDIF, there is no need to worry about matching .ELSEs as you would, say,
  1856. in Pascal.  Every form of the IF statement is terminated with its own .ENDIF.
  1857.  
  1858.         The .IF1 and .IF2 directives are normally used to print messages and
  1859. perform other minor housekeeping chores.  In general, there's absolutely no
  1860. reason why anyone would want to generate code inside one of these conditional
  1861. assembly blocks.  Therefore, the assembler may optionally generate an error
  1862. message if the location counter is modified anywhere inside the .IF1/.IF2
  1863. conditional assembly block.
  1864.  
  1865.         .IF, .ELSE, and .ENDIF are required at all compliance levels.  .IF1,
  1866. .IF2, .IFDEF, and .IFNDEF are required only at the full and extended com-
  1867. pliance levels.
  1868.  
  1869.  
  1870.  
  1871. While Loops
  1872. -----------
  1873.  
  1874.         Sometimes, especially within macros, you will need some sort of
  1875. looping structure to process parameters or otherwise generate sequences of
  1876. code;  the .WHILE/.ENDW directives are used for this purpose.  The syntax
  1877. for the while section is:
  1878.  
  1879.                         .WHILE  expression
  1880.                     <body of loop>
  1881.                         .ENDW
  1882.  
  1883. The instructions in the loop body are repeated as long as the expression
  1884. yields a non-zero value.  For the loop to terminate, the variable(s)
  1885. controlling the loop must be defined using the "=" assembler directive
  1886. since this is the only directive that allows you to redefine an instance
  1887. of a variable.
  1888.  
  1889.         The .WHILE directive is especially useful for  processing a macro
  1890. (or record definition) with a variable number of parameters.  Consider the
  1891. following macro:
  1892.  
  1893.         ByteTable       .MACRO
  1894.         ParmCnt         =       ?#
  1895.                         .WHILE  ParmCnt
  1896.                         .BYTE   ?:(?#-ParmCnt)
  1897.         ParmCnt         =       ParmCnt-1
  1898.                         .ENDW
  1899.                         .ENDM
  1900.  
  1901.                         _ByteTable  0,5,4,2,7
  1902.  
  1903. This example emits the five bytes  0, 5, 4, 2, and 7 into the object code
  1904. stream.
  1905.  
  1906. INCLUDE Mechanism
  1907. -----------------
  1908.  
  1909.         A source file include mechanism is provided by the .INCLUDE directive.
  1910. Its syntax is
  1911.  
  1912.                         .INCLUDE        "filename"
  1913.  
  1914. The specified file will be inserted at the point of the .INCLUDE directive
  1915. in the current assembly, as though the code were actually inserted at that
  1916. point.
  1917.  
  1918.         The include mechanism must be capable of nested includes up to four
  1919. levels deep.  The .INCLUDE directive must be supported at all compliance
  1920. levels of the assembler, although assemblers operating at the subset
  1921. compliance level need not support nested include files.
  1922.  
  1923.  
  1924.  
  1925.  
  1926. Programs, Modules, and Units
  1927. ----------------------------
  1928.  
  1929.         The assembler handles three types of sources files: programs, modules,
  1930. and units.  Unless otherwise specified, all source files are assumed to be
  1931. programs.  A program is differentiated from a module or unit in that the
  1932. assembler/linker assumes that control is transferred to some point in a
  1933. 'program' when it is loaded into memory.  Modules and units are assumed to
  1934. be subserviant sections of code that contain data and/or code used by
  1935. programs.
  1936.  
  1937.         By default, a piece of code is assumed to be a program and control
  1938. is transferred to the first byte of that code when the program is loaded
  1939. into memory.  This helps improve compatibility with existing source files.
  1940. The .PROGRAM directive can be used to explicitly declare a piece of code as
  1941. a main program, as well as provide an entry address other than the first byte
  1942. of code emitted.  The syntax for the .PROGRAM directive is
  1943.  
  1944.                         .PROGRAM        label
  1945.  
  1946. where "label" is a program statement label somewhere within the current
  1947. assembly.  The address of this label is passed on to the linker/loader where
  1948. it will be used to provide a starting address for the code.   All of the
  1949. statements in the source file will be assembled into the program from the
  1950. .PROGRAM directive till the .END directive.  If a .PROGRAM directive appears
  1951. in the source file, it must appear before any other statement (other than a
  1952. comment or listing directive) and there may only be one .PROGRAM directive
  1953. encountered per assembly.  No modules or units may appear as part of a
  1954. program assembly (see below).
  1955.  
  1956.         The .MODULE directive is used to tell the assembler that it is
  1957. assemblying an object code module which is to be linked into a separate
  1958. program before execution.   The .PUBLIC statement is used as the means
  1959. to communicate linkage information to other modules, units, and programs.
  1960. Like the .PROGRAM directive,  the .MODULE directive must appear before most
  1961. statements in the source file and the module is terminated with the .END
  1962. directive.  However,  another module may appear in the source file immediately
  1963. after the .END directive.  Such modules are assembled as independent entries
  1964. in a library.  The syntax for the .MODULE directive is:
  1965.  
  1966.                         .MODULE         ModuleName
  1967.  
  1968. The module name operand is stored as part of the source file for use by the
  1969. linker, but is not otherwise refereced during the assembly process.  In fact,
  1970. this symbol may be redefined later in the source file.
  1971.  
  1972.         The .LINK directive can be used to link a module into another module,
  1973. unit, or program at assembly time.  The syntax for this directive is:
  1974.  
  1975.                         .LINK           "filename",ModuleName
  1976.  
  1977. where filename is the operating system name of the object code file or
  1978. library file containing the module, and ModuleName is the actual module
  1979. name specified with the .MODULE directive.  The specified object code is
  1980. inserted into the assembly at the point of the .LINK directive.  Access to
  1981. the symbols declared public within the module is accomplished using the
  1982. .EXTERNAL directive.
  1983.  
  1984.         Units are a much more structured form of modules.  With a unit,
  1985. you specify not only the symbols visible to the code using the unit, but
  1986. also how that data is used.  Units also allow you to pass type checking
  1987. information so the assembler can check for possible logical errors during
  1988. assembly.  Finally, as an added bonus, within units you can link in macros,
  1989. records, types, symbols defined by "=", and other entities that cannot be
  1990. handled by modules and the .PUBLIC/.EXTERNAL mechanism.
  1991.  
  1992.         A unit takes the form:
  1993.  
  1994.                         .UNIT   UnitName
  1995.  
  1996.                     <interface section>
  1997.  
  1998.                         .BEGIN
  1999.  
  2000.                     <implementation section>
  2001.  
  2002.                         .END
  2003.  
  2004. Like .MODULEs, several units may appear in the source file by simply following
  2005. the .END directive with the next unit definition.  In fact, .MODULEs and 
  2006. .UNITs can be intermixed in the same source file.  If more than one module or
  2007. unit appears in the source file, they will be assembled into different slots
  2008. in the object file generated (i.e., a library file will be generated).
  2009.  
  2010.         The interface section of a unit contains those items that will be
  2011. public to the unit.  Equates, records, macros, types, sets, and any other
  2012. non-code generating declaration can be used in the interface section (note:
  2013. an exact list of items will be specified later).  Such definitions will be
  2014. made available to the code that uses this unit as well as to the code in the
  2015. implementation section.  In addition to such declarations, the interface
  2016. section may also contain .PROC definitions and .ENTRY definitions.  The
  2017. .PROC definitions simply contain the .PROC statement (which must also appear
  2018. in the implementation section), the .ENTRY definition is used in lieu of the
  2019. .PUBLIC directive and takes the form:
  2020.  
  2021.                 label   .ENTRY  {NEAR or FAR}
  2022.  
  2023. An example of a simple unit might be:
  2024.  
  2025.                         .UNIT   SimpleUnit
  2026.                 MyMac   .macro
  2027.                         lda     #0
  2028.                         sta     ?0
  2029.                         .endm
  2030.                 ;
  2031.                 ClrSub  .proc   near
  2032.                 SetTrue .proc   far
  2033.                 SetIt   .entry  far
  2034.                 ;
  2035.                         .BEGIN          ;Start implemenation section.
  2036.                 ;
  2037.                 ClrSub  .proc   near
  2038.                         _MyMac  $11
  2039.                         ret
  2040.                         .endp
  2041.                 ;
  2042.                 SetTrue .proc   far
  2043.                         lda     #1
  2044.                 SetIt   sta     $23
  2045.                         ret
  2046.                         .endp
  2047.                         .end
  2048.  
  2049.  
  2050.         To use the code defined in a unit, the ".USE" directive is used in
  2051. a fashion not unlike the .LINK directive, namely,
  2052.  
  2053.                         .USE    "filename",UnitName
  2054.  
  2055. where filename is the operating system pathname and UnitName is the name
  2056. specified in the operand field of the unit directive.  Whenever the .USE
  2057. directive appears in a source file, the content of the implementation section
  2058. will be listed if the source listing option is turned on.
  2059.  
  2060.         Whenever the .USE or .LINK directives are employed, the corresponding 
  2061. object code is always inserted into the assembly.  Therefore the assembler
  2062. is performing double duty, it's acting as both the assembler and linker.
  2063. With units, the assembler always performs the link operation.  With modules,
  2064. you can defer the link operation to a separate linkage step, although there
  2065. are only a few instances where this would be beneficial (for example, while
  2066. creating libraries).
  2067.  
  2068.         All of the program linkage directives are optional at the subset
  2069. compliance level, but required at the full and extended levels.
  2070.  
  2071.  
  2072.  
  2073. Listing Controls
  2074. ----------------
  2075.  
  2076.         Several directives are used to control the appearence of the assem-
  2077. bled source listing.  The exact format of the listing will be specified with-
  2078. in this proposal (although at a later date).  The exact listing format must
  2079. be adhered to so that symbolic debuggers can take advantage of an assembled
  2080. source listing saved as a text file for use when stepping through a program.
  2081.  
  2082.                         .ON     operands
  2083.                         .OFF    operands
  2084.  
  2085.         These two directives are used to turn certain listing options or
  2086. or off.  Valid operands include  LIST, OBJ, MAC, and COND.  LIST controls
  2087. whether or not the source file is listed and supercedes all other options.
  2088. OBJ (if on) will force the assembler to display all bytes of object code
  2089. emitted by an instruction, even if it takes more than one line to display it
  2090. all;  if off, OBJ will only display the number of emitted object code bytes
  2091. that fit on the current source line.  MAC controls macro expansions during
  2092. the listing.  If off, only the macro name, not the expansion, will be dis-
  2093. played.  COND controls the printing of statements in a false conditional or
  2094. while loop section.
  2095.  
  2096.         The .TITLE and .SUBTITLE directives let you assign titles and sub-
  2097. titles to the source file.  The syntax for these directives is
  2098.  
  2099.                         .TITLE          "Title of source file"
  2100.                         .SUBTITLE       "Subtitle for this section"
  2101.  
  2102. The title is displayed at the top of each page and the subtitle is displayed
  2103. immediately below the title.  .TITLE always forces a page eject, .SUBTITLE
  2104. never does.
  2105.  
  2106.         The .PAGE directive forces an immediate page ejection on the listing.
  2107. It requires no operands.
  2108.  
  2109.         The .PRINTF directive has the syntax:
  2110.  
  2111.                         .PRINTF "Control string" {,operands}
  2112.  
  2113. It is used in a manner analogous to the PRINTF in the "C" programming
  2114. language.  If expressions follow the control string, "%" modifiers in the
  2115. control string specify their output format.  E.g.,
  2116.  
  2117.                         .PRINTF "Label = $%4h",Label
  2118.  
  2119. would print
  2120.  
  2121.                         Label = $1234
  2122.  
  2123. assuming the value associated with Label was $1234.
  2124.  
  2125.  
  2126.         The .PAUSE directive can be used to force an assembly time error.
  2127. It is useful mainly in macros, records, expression functions, etc. to force
  2128. an error if an illegal condition (like bad number of parameters) occurs.
  2129.  
  2130.         The listing control directives are required only at the full and
  2131. extended compliance levels.
  2132.  
  2133.  
  2134.  
  2135. Data Flow Analysis Directives
  2136. -----------------------------
  2137.  
  2138.         The following directives are quite useful to add-on debuggers and
  2139. data flow analysis programs.  They are required only at the full and extended
  2140. compliance levels:
  2141.  
  2142.                 label   .table
  2143.                       <data table>
  2144.                         .endt
  2145.  
  2146. For .table, the label is assigned the current value of the location counter
  2147. and label is treated like a statement label.  .TABLE and .ENDT are otherwise
  2148. ignored.
  2149.  
  2150.                 label   .REF    label1 {, label2, ..., labeln}
  2151.  
  2152. This statement is ignored by the assembler.  The statement label, if present,
  2153. is also ignored.
  2154.  
  2155.  
  2156.  
  2157. Other Optional Goodies
  2158. ----------------------
  2159.  
  2160.         The following are not required by this proposal, but should be
  2161. provided nonetheless:
  2162.  
  2163.                         .system         "DOS command"
  2164.  
  2165. .SYSTEM issues the specified command to the operating system.  This command
  2166. is useful for deleteing files during assembly, changing directories, etc.
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172. Operation of the Assembler
  2173. --------------------------
  2174.  
  2175.         Given the structure of the assembler, there's no way it can accomplish
  2176. its job in less than three passes without placing severe burdens on the
  2177. user (I could provide you with a mathematical proof of this, but I don't want
  2178. to bore you to death).  Therefore, the standard specifies that the assembler
  2179. must use three (or more) passes to do its job.  During the first pass the
  2180. assembler associates labels with segments (and groups of segments), determines
  2181. whether or not those symbols are near or far, and performs other housekeeping
  2182. chores fit for pass one.  Pass two of the assembler is equivalent to the
  2183. traditional pass one of an assembler, it computes the values for all of the
  2184. symbols in the program.  Pass three generates the actual object code.
  2185.  
  2186.  
  2187.  
  2188. In Addition to the Assembler...
  2189. -------------------------------
  2190.  
  2191.         The standard should also include specifications for a run-time
  2192. library to be provided with the assembler as well as a list of tools
  2193. (e.g., debugger, linker, librarian, etc.) which must be provided with the
  2194. product to meet the full compliance level.  I would like to propose the 
  2195. following items in the run-time library:
  2196.  
  2197.         TTY_IO: A set of routines to communicate with a text-based
  2198. user console.  INIT, GETC, and PUTC are the basic routines.  These three
  2199. routines are easily supported on any system supporting a user console.
  2200.  
  2201.         TERMINAL_IO: A set of routines to communicate with a cursor-based
  2202. terminal device.  Routines supported should include INIT, GETC, PUTC, GOTOXY,
  2203. HOME, CLREOLN, and CLREOP.
  2204.  
  2205.         CONSOLE_IO: A set of routines to communicate with a DMA-based video
  2206. display device.  See the specifications for ANIX's CHARIO driver for the
  2207. routines to be supplied with this library entry.
  2208.  
  2209.         AUX_IO: A driver for a set of one or more serial communication ports.
  2210. Routines should include INITA, SETUPA, GETA, PUTA, STATUSA.
  2211.  
  2212.         PRT_IO: A driver for a set of one or more printer ports.  Routines
  2213. should include INITP, SETUPP, PUTP, and STATUSP.
  2214.  
  2215.         NET_IO: A driver for a set of one or more network ports.  Routines
  2216. should include INITN, SETUPN, GETPacket, SendPacket, etc.
  2217.  
  2218.         CLK_IO: A driver for a real time clock or clock-calendar unit.
  2219.  
  2220.         FP: An IEEE floating point package for the 65c816 chip.
  2221.  
  2222.         MATH: A set of integer math routines (multiply, divide, extended
  2223. precision, etc.).
  2224.  
  2225.         CONV: A set of conversion routines (binary -> decimal, etc.).
  2226.  
  2227.         FILE_IO: A set of routines that interface to the host's operating
  2228. system providing a common interface to various operating systems.
  2229.  
  2230.         DVC_IO: A hardware independent device I/O package (allowing named
  2231. devices which can be connected through a BIOS (like the AUX_IO and PRT_IO
  2232. packages) to various hardware devices.
  2233.  
  2234.         STD_IO: A set of routines to perform various I/O operations such
  2235. as PRINT, PRINTF, SCANF, PUTI (integer), GETI, PUTH (hex), GETH, etc.
  2236.  
  2237.         MEM_MGR: A set of memory management routines to efficiently allocate
  2238. and deallocate memory.
  2239.  
  2240.         
  2241. This is, by no means, an exhaustive list, but a quick sample of the types of
  2242. routines that should be provided.
  2243.  
  2244.         Apple //GS users may complain that many of these routines already
  2245. exist within the confines of the Apple toolbox.  The intent, however, is to
  2246. provide a set of useful routines that can be utilized on ANY 65c816 system
  2247. so 65c816 code can be easily ported to systems other than the Apple //GS.
  2248.  
  2249.  
  2250.  
  2251.  
  2252.  
  2253.  
  2254.