Copyright (C) 2004-2013 by Anton Treuenfels
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
This document briefly describes the portions of the HXA65 variant of HXA which are specific to the 6502-family microprocessors it supports.
Microprocessors Supported by HXA65
Additional Programming Information
Additional Hardware Information
HXA for Windows
HXA for MS-DOS
HXA65 accepts a single filename as a command-line argument:
There are no other command-line arguments, options or switches.
In addition to the __HXA__ built-in label defined by all HXA variants, HXA65 defines a variant identifier label:
This label may be used anywhere but is intended mainly for <hxa:IF--DEF|"IFDEF"> conditional blocks.
The register names A\, S\, X and Y are reserved and cannot be assigned values.
While determing instruction mnemonic address modes HXA65 notes their presence or absence in the expression field, but not their values. If they are referenced outside the context of an instruction mnemonic they have a value of TRUE.
In official useage this mode is indicated by a single literal character 'A' in the expression field. A blank expression field officially indicates implied address mode.
However no instruction which allows implied addressing also allows accumulator addressing, and vice-versa. Therefore use of the single character 'A' in the expression field is optional, and it may be left blank if desired.
Many 6502-family instructions have both absolute and zero page forms. In object code the zero page form is usually shorter and faster than the absolute form, but in source code both forms look alike.
HXA65 normally assembles the zero page form only if during pass one the operand address is calculated to be in the range $0000 to $00FF. If the expression that represents the operand address cannot be resolved during pass one or is greater than $00FF, HXA65 assembles the absolute form.
For timing or size purposes it can occasionally be desirable to override HXA65's automatic selection of zero page mode. Forced address mode can be used to force absolute mode on an otherwise zero page address (and vice-versa, though this is rarer).
On some systems and some processors it is possible to change the default location of zero page (or "direct page"). HXA65 can adapt to this using the ASSUME psuedo opcode (below).
HXA65 accepts several aliases recommended by Western Design Center for standard instruction mnemonics:
HXA65 accepts additional address modes for several standard instruction mnemonics. These generate exactly the same object code as the standard mnemonics. They are intended mainly to make some tasks easier or to make the sometimes-odd W65C816S standard syntax more closely resemble that of the other supported microprocessors. Note that these extensions are not portable.
|BRK $12||zero page||extended||Y||Y||Y||Y||Y|
The BRK instruction occupies one byte of object code and accepts no arguments, but executing it actually advances the program counter by two bytes before it is stored on the stack and control transferred to the software interrupt service (IRQ) routine. When the IRQ routine returns, execution resumes at the second byte past the BRK instruction.
It is possible for the IRQ routine to retrieve the stored program counter from the stack, use it to examine the skipped ("signature") byte, and make a control branch based on that examination.
The HXA65 extensions are designed to make it easier to specify the value of the signature byte. The zero page mode is designed to make the instruction resemble the standard W65C816S COP instruction syntax.
|COP $12||zero page||standard||-||-||-||-||Y|
The Western Design Center standard requires the COP instruction to be followed by a zero page address operand (ie., a "signature" byte).
However whether a co-processor uses the value at the zero page address (as implied by the syntax) or the value of the zero page address (ie., as an immediate value) is ambiguous.
HXA65 allows both forms.
Also note COP signatures $80-$FF are reserved, while signatures $00-$7F are available for user definition.
|JML ($1234)||absolute indirect||standard||-||-||-||-||Y|
|JML $123456||long absolute||extended||-||-||-||-||Y|
The W65C816S JML "jump long" instruction officially has only one address mode, absolute indirect.
The JMP "jump" instruction officially is assigned the long absolute address mode. However this causes a problem for HXA65 when dealing with long forward jumps. Any forward reference means the destination address cannot be resolved during pass one. Therefore HXA65 will generate the official default address mode, which is absolute rather than long.
In fact it is officially impossible to use the JMP mnemonic to create a long forward jump without also either using forced address mode or pre-defining the destination address via an equate .
Alternatively HXA allows the JML instruction be used for the same purpose. If the operand of the JML instruction is not indirect (ie., surrounded by balanced parentheses), HXA65 will generate a "JMP long absolute" opcode.
This may be the safer option if there is any possibility at all of confusing a program bank address with a data bank address. HXA65 always generates a 16-bit address rather than a 24-bit address if it thinks the address is in the data bank, but a 16-bit JMP generates its 24-bit effective address using the program bank.
|JSR ($1234,X)||absolute X-indexed indirect||standard||-||-||-||-||Y|
|JSR $123456||long absolute||extended||-||-||-||-||Y|
Officially only the JSL "jump to subroutine long" instruction permits (and requires) the "long absolute" address mode. HXA65 will automatically generate a "JSL long absolute" opcode if it recognizes during the first pass that the operand of a JSR instruction represents a long (greater than 16-bit) address.
The Western Design Center standard requires the PEA instruction to be followed by an absolute address operand.
However the PEA instruction pushes the value of the address onto the stack, rather than the value at the address. That is, the operand value is actually used as an immediate value, rather than the address value implied by the standard syntax.
HXA65 therefore also allows immediate addressing with the PEA mnemonic to better reflect what actually happens.
|PEI ($12)||direct indirect||standard||-||-||-||-||Y|
The Western Design Center standard requires the PEI instruction to be followed by a direct indirect address operand ("direct" is the same as "zero page" on the other processors).
However there is no actual indirection involved. The PEI instruction simply pushes the value stored at the direct address onto the stack. That is, the operand is not treated as an address which holds the effective address of the actual value (a "pointer" to the effective address), but as the effective address itself.
HXA65 therefore also allows direct addressing with the PEI mnemonic to better reflect what actually happens.
|WDM $12||zero page||extended||-||-||-||-||Y|
Although the WDM instruction is reserved and currently acts as a NOP, any possible future instruction extensions will require WDM to be followed by a "signature" byte (WDM thus acting as an "escape" instruction).
HXA allows this presumed signature byte to be specified as an immediate or zero page address operand. The zero page mode is designed to make the instruction resemble the standard W65C816S COP instruction syntax.
The ASSUME pseudo opcode must be followed by a string argument. The recognized arguments vary with the microprocessor in use. If no argument is recognized, an error is reported.
Note the case of the argument is ignored.
Forced address mode permits the programmer to override the address mode which would otherwise be selected by HXA65. In general, zero page instructions can be forced to absolute, and vice versa, on all supported microprocessors. In the case of the W65C816S, long instructions can also be forced.
When address forcing is applied HXA does not perform any range-checking on the expression following the instruction. A result larger than will fit in the allowed space is silently truncated instead of causing an error. Forcing the same address mode as HXA65 would itself select thus has the effect of preventing any potential operand size error.
Address forcing preserves register indexing if present. For example, forcing zero page X-indexed to absolute X-indexed is legal if the instruction allows both forms.
Note that in cases where multiple address modes are possible, HXA65 defaults to choosing absolute mode (two byte operands) whenever it cannot resolve the associated expression on the first pass (ie., the expression contains a forward reference). Address forcing can be used in these cases to provide a "hint" as to the correct size to choose.
Address forcing applies for only a single instruction source code line. It must be applied to every instruction for which forcing is desired.
Note all four force modes are available only in the case of the W65C816S. There are actually only three force modes, as ADDR:DIRECT and ADDR:ZEROPAGE are synonyms and have the same effect.
At startup the W65C816S microprocessor is in 8-bit emulator mode. When programmatically switched to 16-bit native mode, the sizes of the accumulator and index registers can be controlled by manipulating two bits in the status register. One bit ("M") controls the accumulator size and the other ("X") controls the X- and Y-index register sizes.
In general this doesn't matter to HXA65, as the object code produced doesn't change - except in the case of immediate address mode. HXA65 must store an immediate value as either 8- or 16-bits, but doesn't itself know which is appropriate at any given time. Therefore HXA65 uses the ASSUME pseudo opcode to allow the progammer to tell it which size to use.
|Argument String||Immediate Mode Meaning|
|accum:8||Accumulator is 8 Bits|
|accum:16||Accumulator is 16 Bits|
|index:8||X- and Y-Registers are 8 Bits|
|index:16||X- and Y-Registers are 16 Bits|
The default sizes are eight bits for both accumulator and index registers (equivalent to ACCUM:8 and INDEX:8, and the same as the default state of the microprocessor). It is up to the programmer to keep HXA65 in sync with the state of the status register bits.
The size value following ACCUM: or INDEX: may be any numeric expression that evaluates to eight or sixteen. Any other value causes an error and the current size remains unchanged.
There are some instructions which allow immediate addressing but do not involve the accumulator or index registers (eg., the REP and SEP instructions which affect status register bits). These always remain the same size regardless of any register size manipulations, whether by ASSUME pseudo opcodes during assembly or by status register changes during execution.
The default location of zero page on all supported processors is page zero, $0000->$00FF. However some processors and some systems with memory management chips allow changing the location of zero page.
The ZEROPAGE:expr assumption allows the programmer to inform HXA65 that the location of zero page has changed.
Expr may be any numeric expression which results in an value in the range $00->$FF. It is treated as the page number of "zero page" (so if "expr" = "$xx", "zero page" is located at $xx00->$xxFF).
If an instruction allows multiple possible modes, zero page addressing will be chosen if the high byte of the expression matches this page number.
The default location of the direct page on the W65C816S is page zero in bank zero, $00:0000->$00:00FF. However this may be set to any bank zero location in the range $00:0000->$00:FF00.
The DIRECTPAGE:expr assumption allows the programmer to inform HXA65 that the location of the direct page has changed.
Expr may be any numeric expression which results in a value in the range $0000->$FF00. It is treated as the base address of the direct page (so if "expr" = "$xxxx", the direct page is located at $00:xxxx->$00:xxxx+$FF). Direct addresses are specified as an offset from this base address.
If an instruction allows multiple possible modes, direct page addressing will be chosen if the direct page base <= expression < direct page base + 256.
The default location of the data bank on the W65C816S is bank zero. $00:0000->$00:FFFF. However this may be changed to any bank in the range $00->$FF.
The DATABANK:expr assumption allows the programmer to inform HXA65 that the location of the data bank has changed.
Expr may be any numeric expression which results in an value in the range $00->$FF. It is treated as the data bank number (so if "expr" = "$xx", the data bank is located at $xx:0000->$xx:FFFF).
Every data address that is specified as a 16-bit absolute address is automatically extended to 24 bits using the data bank byte. If an instruction allows multiple possible modes, absolute addressing will be chosen if the bank byte of the expression matches the data bank number.
|Stack Placement||Page 1 / 8 Bits||Page 1 / 8 Bits||Page 1 / 8 Bits (E=1); Bank 1 / 16 Bits (E=0)|
|Zero Page,X and Zero Page,Y Addressing||Always Page 0||Always Page 0||Always Page 0 (E=1); Cross Page (E=0)|
|Accumulator Size||8 Bits||8 Bits||8 Bits (M=1); 16 Bits (M=0)|
|X- and Y-Index Register Size||8 Bits||8 Bits||8 Bits (X=1); 16 Bits (X=0)|
|Status (P) Register N+V+D Flags in Decimal Mode||invalid||valid||valid|
|Status (P) Register D-Flag After Reset/Interrupt||unknown/not modified||clear/clear||clear/clear|
|Decimal Mode||no additional cycle||add one cycle||no additional cycle|
|Absolute,X Addressing w/ ASL+LSR+ROR+ROL and No Page Crossing||7 cycles||6 cycles||7 cycles|
|Jump Indirect Addressing with $xxFF Operand||5 cycles/invalid page crossing||6 cycles||5 cycles|
|Branch Across Page Boundary||4 cycles||4 cycles||4 cycles (E=1); 3 cycles (E=0)|
|Unused Op Codes||unknown/some hang processor||all NOPs||only WDM (reserved; performs NOP)|
|BRK Vector Location||$FFFE/F||$FFFE/F||$00FFFE/F (E=1); $00FFE6/7 (E=0)|
|B-Flag on Stack After Software Break||set||set||set (E=1); replaced by X-Flag status (E=0)|
|Program Bank Register (PBR) Pushed and Pulled by Interrupts+RTI||n/a||n/a||No (E=1); Yes (E=0)|
|Program Bank Register (PBR) Value After Reset or Interrupt||n/a||n/a||=$00|
|Absolute,X/Absolute,Y/(Indirect),Y Addressing Across Page Boundary||extra read of invalid address||extra read of last instruction||extra read of invalid address|
|Memory Lock Signal =0 During Read+Modify+Write||n/a||during Modify+Write||during Read+Modify+Write|
|Read/Write Signal =0 During Read+Modify+Write||during Modify+Write||during Write||during Modify+Write (E=1); during Write (E=0)|
|RDY Pulled During Write Cycle||ignored||processor stops||processor stops|
This table is based on Western Design Center references.