Volver a la página principal.DOCUMENTACIÓN TÉCNICA: Ensamblador para 65816 (2ª parte)
Table of Contents: i Preface
1.00 Introduction
2.00 New 65816 Instructions
3.00 65816 Native Mode Programming Model:
3.01 · Native Mode Processor Status Register
4.00 Native Mode Registers:
4.01 · Accumulator
4.02 · X,Y Index Registers
4.03 · Direct Page Register (D)
4.04 · Stack Pointer (S)
4.05 · Program Bank Register (PBR)
4.06 · Data Bank Register (DBR)
4.07 · Status Register:
4.07.1 · Emulation Bit E: Hidden Bit
4.07.2 · Sixteen BIT User Registers
4.07.3 · Index Register Select
4.07.4 · Accumulator/Memory Select
4.08 · Setting Status Register Bits
5.00 65816 Emulation Mode Programming Model:
5.01 · Emulation Mode Registers
6.00 Relocating the Stack and Direct Page
7.00 Addressing Modes:
7.01 · New 65816 Specific Addressing Modes
7.02 · Addressing Mode Descriptions
Appendix A: 65816 Instruction Set
Appendix B: Composite Instruction List
Appendix C: IC Pinouts
Ir a la primera parte del artículo
===========
8.00 Interrupts
=========== There are some quirks to 65816 interrupts that you should consider. If you are going to be writing native 65816 code you should give some consideration to how your interrupt routine is going to be handled. If you have written custom a IRQ routine that assumes Native mode, then your considerations are minor. However, if you are writing Native mode 65816 code with 16 bit accumulator and/or 16 bit index registers, and you are using a stock kernal IRQ that assumes emulation mode, then you must do some coding to handle the discrepancies. In 6502 emulation mode, and IRQ pushes the program counter high, then pc low, and finally the status register on to the stack. When in Native mode an IRQ starts by stacking the following:
Program Counter Bank (PBR)
Program Counter High
Program Counter Low
Status Register
Next; the status register decimal mode bit (d) is cleared (setting binary mode), and the IRQ flag is set (non NMI only). Finally, the program bank (PBR) is set to zero and the 65816 jumps through the IRQ hardware vector.
The implications are that if the 65816 is running in emulation mode in a ram bank other than Bank zero, then the program bank is going to be lost (not good). There are two solutions to the problem. One is never to run in emulation mode outside of Ram Bank zero. Second; you could save off the current program bank value somewhere in Ram before running in emulation mode beyond Bank Zero.
One thing that is unclear at this point, is if the CMD Super CPU can even handle a Native Mode IRQ. Native Mode features a new hardware vector table:
8.01 Hardware Vectors:
Notice that there is a separate BRK vector for Native mode, and no need to poll bit 5 for the brk flag. However when running in emulation mode, remember that bit 5 is still the BRK flag, and your IRQ will still need to check for the source of the IRQ.
While in Native mode, a BRK instruction is two bytes. The Zero BRK opcode followed by an optional "signature" byte. This way, you can detect what BRK caused the vector to be taken for multiple BRK's while debugging.
COP is for a coprocessor interrupt. (see the instruction COP)
Notice in Native mode where the IRQ vector destinations are...hmm
When an IRQ is triggered, the current instruction is completed before the interrupt is processed. This "interrupt latency" may be up to 7 clock cycles. If you are running a time critical IRQ you may want to examine the WAI:wait for interrupt instruction whereby you can stop the processor until and interrupt occurs.
The ABORT vector listed above is taken when the 65816's Abort pin is pulled low. This pin is only available on the 65816.
==========================
Appendix A: 65816 Instruction Set
==========================
n - negative.
v - overflow.
m - 8/16 memory/accumulator.
x - 8/16 bit index registers.
d - decimal mode.
i - irq enable disable.
z - zero result.
c - carry.
e - emulation.
ADC Add with carry.
When using 16 bit accumulator mode, as expected, a carry will be properly rolled over from bit 7 to bit 8 when generated by the operation. (ie: $FF+4 = $0103 with 1 in high byte an 3 in low byte of the accumulator.) Thus carry need only be cleared when the low order bytes are added. Manual checking for carry above bit 15 will still have to be done just as when in 8 bit accumulator mode.
When in 16 bit mode, the low-order bits are located in the effective address, and the high order bits are located in the effective address plus one.
Flags Altered nv----zc
n Set if most-significant bit of result is set.
v Set if signed overflow.
z Set if result is zero.
c Set if overflow.

AND And Accumulator with Memory
Logically ANDs the data located at the effective address
specified by the operand and the accumulator.
If in 16 bit accumulator mode (m=0) Data ANDed from memory is
16 bits wide, the low byte is the effective address and the high
byte is the effective address+1.
Flags Altered n-----z-
n Set if most significant bit of result is set.
z Set if result of and is zero.

ASL Arithmetic Shift Left
Shifts all bits left with most significant bit moving into the
carry flag. If in 16 bit accumulator mode (m=0), data shifted
is 16 bits.
Flags Altered n-----zc
n Set if most significant bit of result is set.
z Set if result is zero.
c High bit (7 or 15) is moved into carry.
Branching Instructions:The following branch instructions work identically to a 6502 - therefore, no indepth discussion will be presented.
Branching commands do not affect any status register flags. The single byte operand range is +128 to -127.
BCC Branch Carry Clear / alias BLT Branch Less Than.
BCS Branch Carry Set / alias BGE Branch Greater Than or Equal.
BEQ Branch Equal
BNE Branch Not Equal
BMI Branch Result Minus
BPL Branch Result Positive
BVC Branch Overflow Clear
BVS Branch Overflow Set
New Branch Instructions:BRA Branch Always
Branch always takes the operand branch without regard for the current state of the status register. The single byte operand range is +128 to -127. This instruction and the following BRL instruction ease the task of writing relocatable code.

BRL Branch Always Long
Same as BRA, but the operand is 2 bytes giving the instruction a 64k range. This instruction is similar to the JMP command, with the advantage being that JMP is and absolute address and BRL is a relative address.
No flags are affected.

BIT Test Memory Bits against Accumulator
The 65816 provides 3 new addressing modes for the old standard BIT instruction. The only true difference is that when the processor is in 16 bit mode, the top two bits xfered to the status register will come from bits 14 and 15. When in 8 bit mode bits 6 and 7 are xfered to the status register.
Flags affected nv----z- (Other than immediate addressing).
------z- (Immediate addressing only).
n Takes value of most significant bit of memory data.
v Takes value from bit 6 or 14 of memory data.
z Set if logical AND of mem and acc is zero.

BRK Software Break
While in native 65816 mode, BRK is unaffected by the I interrupt disable flag. Additionally, you may now pass a one byte signature byte to indicate which BRK instruction caused the BRK to be preformed.
The new BRK handler includes a Hardware Vector- thus, it is no longer required to check for the BRK bit flag via the IRQ.
When a BRK is performed in 65816 Native mode:
· the program counter bank register is pushed onto stack.
· the program counter is incremented by two and pushed on the stack.
· the status register is pushed onto the stack
· the interrupt disable flag is set.
· the decimal mode flag is cleared.
· the program bank register is cleared to zero.
· the program counter is loaded from the break vector at $FFE6-$FFE7.
While in 6502 emulation mode, (e=1) a BRK is preformed true to it's 6502 forerunner (b flag set, status pushed onto stack, SEI and IRQ performed.).
Status Register Setting and Clearing:The following status set and reset instructions operate the same in 65816 native mode and 6502 emulation mode.
CLC Clear carry flag.
CLD Clear decimal flag.
CLI Clear interrupt flag.
CLV Clear overflow flag.
SEC Set carry flag.
SED Set decimal flag.
SEI Set interrupt flag.

CMP Compare Accumulator with Memory
For the most part, this instruction works the same in 6502 emulation mode and 65816 mode.
While in 16 bit accumulator mode the low byte of the compare will come from the effective address and the high byte from the effective address plus one.
Flags Altered n-----zc
n Set if most significant bit of result is set.
z Set if result is zero.
c Set if no borrow was required. Acc => memory.
C=0 if borrow required Acc < memory.

COP Coprocessor Empowerment
COP cause a software interrupt through a separate COP hardware vector. The vector is to be located at $FFF$-$FFF5. In 6502 emulation mode:
· The program counter is incremented by 2 and pushed on stack.
· The status register is pushed onto the stack.
· The interrupt status bit is set.
· The program counter is loaded with the hardware vector.
· The decimal flag is cleared.
In Native mode:
· The PC bank register is pushed onto stack.
· The PC is incremented by two and pushed onto stack.
· The status register is pushed onto stack.
· The interrupt status flag is set.
· The program bank register is cleared to zero.
· The PC is loaded with the hardware vector.
· The decimal flag is cleared after COP executed.
Flags Altered ----di--
d decimal mode flag is reset to zero.
i Interrupt disable is set.

CPX Compare X Index register with Memory
CPX functions the same as a 6502. The only notable exception is to remember that when in 16 bit index register mode (x=0) that date/memory will be 16 bits wide. The low order byte will come from the the effect address and the high order byte from the effective address plus one.
Flags Altered n-----zc
n Set if most significant bit of result is set.
z Set if result is zero.
c Set if no borrow was required ( X >= memory).
Cleared if borrow required (X < memory).

CPY Compare Y Index register with Memory
CPY functions the same as a 6502. The only notable exception is to remember that when in 16 bit index register mode (x=0) that date/memory will be 16 bits wide. The low order byte will come from the the effect address and the high order byte from the effective address plus one.
Flags Altered n-----zc
n Set if most significant bit of result is set.
z Set if result is zero.
c Set if no borrow was required ( Y >= memory).
Cleared if borrow required (Y < memory).

DEC Decrement Memory
DEC also works nearly the same as a 6502 mode. When in 16 bit accumulator/memory mode (m=0) data altered will be 16 bits wide with automatic underflow from high byte to low byte. The low order byte will come from the the effect address and the high order byte from the effective address plus one.
Flags Altered n-----z-
n Set if most significant bit of result is set.
z Set if result is zero.

DEX, DEY Decrement Index Registers
Both instructions operate just as a 6502. When in 16 bit index register mode, the register will be treated as 16 bits wide.
Flags Altered n-----z-
n Set if most significant bit of result is set.
z Set if result is zero.

EOR Exclusive-OR Accumulator with Memory
Another instruction that operates just as a 6502, only new addressing modes. When in 16 bit memory/accumulator mode data is 16 bits wide - as usual the low byte will come from the effective address and the high byte from the effective address plus one.
Flags Altered n-----z-
n Set if most significant bit of result is set.
z Set if result is zero.

INC Increment Data
Also operates just as the 6502 INC instruction. When in 16 bit memory/accumulator mode (m=0) data acted upon is 16 bits wide.
One new addressing mode is Accumulator addressing that will increment the Accumulator.
Flags Altered n-----z-
n Set if most significant bit of result is set.
z Set if result is zero.

INX, INY Increment Index Registers
Both instructions operate just as a 6502. When in 16 bit index register mode, the register will be treated as 16 bits wide.
Flags Altered n-----z-
n Set if most significant bit of result is set.
z Set if result is zero.

JMP Jump to New Location
JMP transfers control to the operand address. If a long jump is executed the program counter bank register is loaded with the third byte of the target address.
The 65816 Designers also specify that an assembler could possibly use JML in place of a JMP Long instruction, and also JML [adr] for Absolute indirect long.

JSR, JSL Jump to Subroutine (gosub)
JSR works just as a 6502 with the new addressing modes available. If an absolute address is coded by the assembler that is less than $FFFF then a standard JSR is used, else if it is greater than $FFFF then absolute long addressing is used. A standard JSR gosubs to the the routine in the current program bank.
JSR can also use Indexed Indirect addressing. (see section on addressing modes for an example.)
JML is a four byte instruction that will JSR to a subroutine located in any bank. When executed the current program counter bank is pushed onto the stack before the program counter high/low bytes.

LDA Load the Accumulator with Memory
LDA is nearly identical to the standard 6502 LDA instruction. New features are the implementation of the new addressing modes. While the status register is set for 16 bit memory/accumulator mode (m=0), data loaded is 16 bits wide with the load byte coming from the effective address and the high byte of the accumulator coming from the effective address plus one.
Flags affected n-----z-
n Takes value of most significant bit of memory data.
z Set if data loaded is zero.

LDX Load X Register from Memory
LDX is identical to a stock 6502.
The only new feature to remember is that when in 16 bit index register mode (x=0) that data will be 16 bits wide. The X register low byte will come from the effective address and the high byte from the effective address plus one.
Flags affected n-----z-
n Takes value of most significant bit of memory data.
z Set if data loaded is zero.

LDY Load Y Register from Memory
LDY is identical to a stock 6502.
The only new diversion is to remember that when in 16 bit index register mode (x=0) that data will be 16 bits wide. The Y register low byte will come from the effective address and the high byte from the effective address plus one.
Flags affected n-----z-
n Takes value of most significant bit of memory data.
z Set if data loaded is zero.

LSR Logical Shift Right.
Yet another instruction unchanged from the standard 6502 instruction set.
16 bit mode (m=0) data shifted will be 16 bits wide.
Flags Altered n-----zc
n Cleared.
z Set if result is zero.
c Bit zero becomes new carry.
Block Move InstructionsMVP Move Positive destination > source
MVN Move Negative destination < source
This instruction is new 65816 only. MVN and MVP move data from memory location to memory location without user intervention.
Two instructions are necessary so that as the data is being moved in a negative direction it will not overwrite itself.
The source address for the move is taken from the X register. The destination address for the move is taken for the Y register. The 16 bit length of the move is taken from the Accumulator regardless of the m flag setting. This value should be one less than the actual length of the move (ie a=$0000 and one byte will be moved).
The two operand bytes specify the source bank of 64k and the destination bank of 64k. The assembler order of the operand bytes is source, destination - however, the actual binary output code will be the MVN or MVP opcode followed byte the destination bank byte and the source bank byte.
MVN Move Negative is used when the source address is greater than the destination address, or conversely when the destination range is lower than the source range.
The MVN instruction uses the X and Y registers to denote the bottom (beginning) address of the two memory segments to be moved. With MVN the data is moved from the source in X to the destination in Y, then the X and Y registers are are incremented and the accumulator decremented until the accumulator underflows to $FFFF.
MVP Move Positive is used with the source address is less than the destination, or conversely when the destination range is higher in memory than the source range.
The MVP instruction uses the X and Y registers to denote the top address of the two blocks of memory. The data is moved from the source in X to the address in Y and then the XY and accumulator registers are decremented until the accumulator underflows to $FFFF.
If the index registers are set for 8 bit mode (x=1) or the processor is set for 6502 emulation mode, then the data moved will be in page zero only because the high bytes will default to zero.
To reduce code length it is very easy to setup the move instructions in a subroutine, then use dynamically modified code to exchange the MVN and MVP opcodes on-the-fly.
Status register flags are NOT affect by the move instructions.

NOP No Operation.
Same as 6502. No flags are affected with NOP.

ORA OR Accumulator with Memory.
Same function as 6502 ORA with new addressing modes.
When in 16 bit memory/accumulator mode (m=0) data acted upon is 16 bits wide. The low byte is the effective address and the high byte is the effective address plus one.
Flags Affected: n-----z-
n Set if most significant bit of result is set.
z Set if result is zero.

PEA Push Effective Absolute Address
PEA pushes the sixteen-bit operand onto the stack. The stack pointer is decremented by two. No flags are affected. Unlike other instructions that use similar assembler notations, PEA pushes the value of the operands onto the stack, NOT the data located at an effective address. A more appropriate name should have been to push Immediate data onto the stack - it is unclear why this discrepancy exists.
For example:
Pushes a #$12 and then a #$34 onto the stack.

PEI Push Effective Indirect Address
This 65816 instruction pushes the address of the effective address onto the stack. This instruction always pushes 16 bits of data onto the stack without regard for the settings of the x and m status bits.
The address of the effective address plus one is pushed on the stack first and then the address of the effective address is pushed on second.
For example: suppose $5678 is stored at location $21/$22 in standard low byte/high byte format, then a
would get the $5678 from $21/$22 and push it onto the stack.

PER Push effective PC Relative Indirect Address
This instruction takes the program counter and adds the 16 bit operand and pushes the resulting 16 bits onto the stack. The destination address must be located within the current bank of 64k memory. The value of the program counter used in the calculation is the address of the NEXT instruction following the PER and two operand bytes.
The result high byte is pushed first, followed by the low byte of the result.
Because this instruction uses a relative offset for the operand, it can aid in writing relocatable code. One could envision pushing an unknown run-time address onto the stack with PER and then pulling the address off to determine the programs run time origin.
Another use of this instruction could be to push a return address onto the stack for 6502 pha:pha:rts style coding

Push, Pull APXY Instructions
PHA,PHP,PLA,PLP are unchanged from their 6502 forerunners. The only notable difference is that 16 bits will be pushed on when in accumulator/memory (m=0) mode and a PHA or PLA is executed (PHP/PLP only operate on 8 bits).
New push and pull stack instructions include PHY,PLY,PHX,PLX. These four new instructions push and pull the index registers on and off the stack. When the status register is set to 16 bit index register mode (x=0), the pull and push index registers will operate on 16 bits when the status register x is set to 0.

Push, Pull Bank Registers
PHB Pushes the 8 bit contents of the data bank register on the stack.
PHD Pushes the 16 bit contents of the direct page register on stack.
The high byte is pushed first, followed by the low byte.
PHK Pushes the 8 bit contents of the program bank register on stack.
PLB Pulls a byte off the stack into the data bank register. This is the only instruction that can directly change the data bank register.
PLD Pulls a sixteen bit value off stack into the direct page register. The low byte is pulled first, followed by the high byte.
Pulled Flags Affected by pull instructions:
n Set if most significant bit of value pulled is set.
z Set if value pulled is zero.

REP Reset Status Bits.
REP is a new 65816 instruction. When used, it will reset (clear) the bits specified by the 1 byte immediate value.
For Example to clear bit 5 of the status register:
REP #%00100000 ;clear bit 5.
or to clear multiple bits:
REP #%10110000 ;clear 7,5 and 4.
Any combination is acceptable.
To set a bit, see SEP.
Flags affected: nvmxdizc
All flags that have an operand bit set are cleared.
Other flags are not affected.

ROL Rotate Memory or Accumulator Left
ROL works same as the 6502 ROL instruction.
When in 16 bit accumulator/memory mode (m=0) Data rotated is 16 bits wide with the former bit 15 becoming the new carry. - the low-order bits are located in the effective address, and the high order bits are located in the effective address plus one.
Flags affected: n-----zc
n Set if most significant bit of result is set.
z Set if result is zero.
c The high bit (7 or 15) becomes the new carry.

ROR Rotate Memory or Accumulator Right.
Works as 6502 ROR expected.
When in 16 bit memory/accumulator mode (m=0) data rotated will be 16 bits wide, plus the carry - the low-order bits are located in the effective address, and the high order bits are located in the effective address plus one.
Flags affected: n-----zc
n Set if most significant bit of result is set.
z Set if result is zero.
c Low bit becomes the new carry.

RTI Return from Interrupt
While in 6502 emulation mode (e=1) RTI is handled the same as a stock 6502.
While in native 65816 mode (e=0) RTI also pulls the program bank register byte off of the stack. Since this extra byte is present, it is essential that the RTI be executed in the same mode (e=?) that the processor was in when the interrupt was executed.
Flags Affected: The status register is pulled from the stack, therefore all flags are affected.

RTL Return from Subroutine Long
RTL works similar to an RTS but it also pulls the program bank register off of the stack. This instruction should be used in conjunction with the JSR long instruction or by a setup routine that also pushes the program bank onto the stack. RTL pulls 24 bits off of the stack. First the two bytes of the program counter low/high are pulled and incremented, then the program bank register is pulled.
No Flags are affected by RTL.

RTS Return from Subroutine
Same as the 6502 instruction. No flags are affected.
One interesting use of RTS is to push a return address on the stack and then execute it via RTS. In order to use this type of coding the address pushed onto the stack must be one less than the actual routine address because when pulled back off, the processor automatically inc's the program counter before continuing. While in Native mode with 16 bit accumulator/memory set, this can easily be accomplished by:
DEC A ; dec 16 be accum. or DEA.
PHA ; push 16 bit return adr on stack.
RTS ; return to execute the instruction.

SBC Subtract from Accumulator
SBC also works just a a 6502. Again the only difference is a few new addressing modes, and the fact that data maybe worked in a 16 bit accumulator or 16 bit memory location.
SBC and ADC when used in 16 bit memory/accumulator mode greatly enhance the overall utility of the 65816. A programmer can easily see how much faster addition and subtraction routines could be performed while operating on 16 bits instead of 8.
Flags Altered nv----zc
n Set if most-significant bit of result is set.
v Set if signed overflow.
z Set if result is zero.
c Set if unsigned borrow not required.

SEP Set Status Bits
SEP is a new 65816 instruction. When used, it will set the bits specified by the 1 byte immediate value.
This is the only means of setting the M and X status register bits.
For Example to set bit 5 of the status register:
SEP #%00100000 ;set bit 5.
or to clear multiple bits:
SEP #%10110000 ;set bits 7,5 and 4.
Any combination is acceptable.
To reset a bit, see REP.
Flags affected: nvmxdizc
All flags that have an operand bit set are set.
Other flags are not affected.


STP Stop the Processor
STP shuts the processor down until a hardware reset. It is used in some systems to put the processor to sleep and reduce power consumption. There is a RESet B pin on some 65816 processors that allow for the usage of this instruction.

STX Store X Register to Memory
Another the same as 6502 mode.
Only exception is that when set for 16 bit index registers (x=0) data stored will be 16 bits wide. Low 8 bits of Y will be stored to the effective address and the high byte to the effective address plus one.
No flags are affected by STX.

STY Store Y Register to Memory
Same as 6502 mode.
Only exception is that when set for 16 bit index registers (x=0) data stored will be 16 bits wide. Low 8 bits of Y will be stored to the effective address and the high byte to the effective address plus one.
No flags are affected by STY.

STZ Store Zero byte to Memory
A new instruction of the 65816. STZ stores a zero byte to the destination address. When in 8 bit accumulator/memory mode (m=1) one byte is stored at the effective address. While in 16 bit memory/accumulator mode (m=0) a zero is stored to the effective address and to the effective address plus one. No flags are affected.
This instruction could be defined as a replacement for stock 6502 code as:
The perky thing about STZ is that the accumulator is unchanged and the status register is also unchanged.

Register Transfer Instructions:
TAX,TXA,TAY,TYA,TSX,TXS transfer instructions transfer bytes between the processor registers.
TAX: Transfer accumulator to X index register. TAY: Transfer accumulator to Y index register. TYA: Transfer Y index register to the accumulator. TXA: Transfer X index register to the accumulator. TSX: Transfer Stack pointer to the X index register. TXS: Transfer X index register to the Stack pointer.
Two new register transfer instructions are TXY to transfer directly from the X register into the Y register and TYX to transfer from Y register to X register.
Because the accumulator and index registers can be set for either 8 or 16 bits independently, the width of the transfer is determined by the destination register. The following table shows the possible combinations:
8 bit acc to 8 bit index regs. (m=1,x=1) 8 bits transferred.
8 bit acc,to 16 bit index regs (m=1, x=0), 16 bits are transferred.
The hidden high order accumulator byte becomes the
X or Y high byte.
16 bit index regs to 8 bit acc (m=1, x=0), 8 bits are transferred.
The hidden high order accumulator byte is not
affected and the previous values remain.
8 bit index regs to 16 bit acc (m=0, x=1), Two bytes
transferred with the high byte being zero.
16 bit acc to 8 bit index regs (m=0, x=1), Only the low byte of the
accumulator is transferred to the index register.
16 bit acc to 16 bit index regs (m=0, x=0) 16 bits transferred.
16 bit stack pointer to 8 bit X register. Only the low byte
8 bit X reg to 16 bit stack pointer, sets stack high byte to zero.
Flags Affected: n-----z-
n Set if most significant bit of transfer value is set.
z Set if transferred value is zero.
Direct Page Instructions:Two new 65816 instructions are used to exchange data between the accumulator and the Direct Page Register.
TCD Transfer Accumulator to Direct Page Register.
TDC Transfer Direct Page Register to Accumulator.
TCD transfers a 16 bit value from the accumulator into the direct (zero page) pointer. A full 16 bits is transferred regardless of the 16/8 bit setting (m) of the accumulator.
The C in TCD is used to specify that the accumulator is referenced as C when it is 16 bits wide (low byte being A and high byte being B).
TDC transfers from the Direct Page register into the full 16 bit accumulator without regard for the setting of status bit m.
Some assemblers also allow TAD or TDA for the mnemonics.
Flags Affected: n-----z-
n Set if most significant bit of transfer value is set.
z Set if transferred value is zero.

TCS Transfer Accumulator to Stack Pointer
TCS transfers a full 16 bits to the stack pointer without regard for the setting of status bit m.
As with TCD and TDC the C in TCS refers to the accumulator as a full 16 bits.
The mnemonic TAS, transfer a to stack pointer, is used by some assemblers.
While in 6502 emulation mode only the eight-bit A accumulator value is transferred because the stack is always located at page 1 on a 6502 TCS and TXS are the only two instructions that alter the stack pointer register.
No flags are affected by TCS.

TSC Transfer Stack Pointer to Accumulator
TSC transfers a full 16 bits of the stack pointer to the 16 bit accumulator without regard for the setting of status bit m.
As with TCD and TDC the C in TSC refers to the accumulator as a full 16 bits.
The mnemonic TSA, transfer a to stack pointer, is used by some assemblers.
While in 6502 emulation mode a one will be transferred to the hidden B (upper 8 bits) accumulator because the stack is always located at page one in 6502 mode.
Flags Affected: n-----z-
n Set if most significant bit of transfer value is set.
z Set if transferred value is zero.
TRB Test and Reset Memory BitsTRB performs a logical AND of the accumulator's compliment and the effective address - data is then rewritten back to the specified address. This clears each memory bit that has a corresponding bit set in the accumulator, leaving all other memory bits unchanged.
To put it another way - TRB flips or inverts the accumulator value and then AND's that value with memory operand and stores the result back to the effective address.
While is 16 bit accumulator mode (m=0) data is operated on in the expected 16 bit fashion. The low byte of the operation is at the effective address and the high byte at the effective address plus one.
Flags Affected: ------z-
z Set if memory value AND'ed with accumulator value is zero.
TSB Test and Set Memory BitsTSB logically OR's the accumulator and the data at the effective address. This effectively sets a bit at the memory location for each bit set in the accumulator.
While is 16 bit accumulator mode (m=0) data is operated on in the expected 16 bit fashion. The low byte of the operation is at the effective address and the high byte at the effective address plus one.
The status register zero flag is set after the accumulator is AND'd with the memory value. (same as the BIT instruction).
Flags Affected: ------z-
z Set if memory value AND'ed with accumulator value is zero.
WAI Wait for InterruptWAI suspends operations until and external hardware interrupt is generated. Power consumption by the processor is also reduced. If the disable interrupt flag (i=1) is set and an IRQ is pending before the execution of the WAI, then the WAIT is terminated and execution continues with the next instruction.
No flags are affected by WAI.
WDM Reserved for Future ExpansionWDM is the first byte of a multi-byte instruction set to be used in future versions of the processor.
At current WDM is treated like a NOP no operation.
This instruction should NOT be used in current versions of the processor.
WDM: William D. Mensch, JR. (65816 designer).
XBA Exchange B and A AccumulatorsXBA exchanges the low eight bits of the accumulator (A) with the high order 8 bits of the accumulator (B). This operation has no regard for the setting of the status bit M.
This instruction will also work in 6502 emulation mode.
XBA can be used to save a temp copy of the low accumulator in the upper accumulator. It is also good when in 16 bit mode to invert a low and high byte value.
XBA is the only instruction that can access the upper 8 bits of the accumulator in emulation mode.
Some assemblers will also accept SWA (swap) for a mnemonic.
Flags Affected: n------z-
n Set if the most significant bit of the new value in the low order 8 bits (A) of the accumulator is set. (former bit 15)
z Set if new value of the lower order 8 bit accumulator (A) is zero.
XCE Exchange Carry and Emulation BitsXCE exchanges (swaps) the value in the E emulation bit and the C carry flag. This is the only means to access the E emulation bit.
To set emulation mode:
sec ;set carry.
xce ;exchange carry and emulation bits.
To set native mode:
clc ;clear carry
xce ;exchange carry and e bit.
Flags Affected --mx/b---c
e from previous carry flag.
c from previous emulation flag.
m native mode flag only. switching to native 65816 mode sets to one.
x x is a native mode flag only.
b brk is an emulation 6502 flag only. it is set to 1 to become the x flag in native mode
============================
Appendix B:Composite Instruction List
============================





* Add 1 if m=0 (16 bit memory/accumulator).
** Opcode is 1 byte, but program counter value pushed onto stack is incremented by 2 allowing for optional signature byte.
+ Add 1 byte if x=0 (16-bit index registers).
1 Add 1 cycle if m=0 (16-bit memory/accumulator).
2 Add 1 cycle if low bye of Direct Page (zero page) register is other than zero (DL<>0).
3 Add 1 cycle if adding index crosses a page boundary.
4 Add 1 cycle if CPU is 65C02 and d=1 (decimal mode. 65C02 only).
5 Add 2 cycles if m=0 (16-bit memory/accumulator).
6 Subtract 1 cycle if CPU is 65C02 and no page boundary crossed.
7 Add 1 cycle if branch is taken.
8 Add 1 more cycle if branch taken crosses page boundary on 6502, 65C02, or 65816/65082's emulation mode (e=1).
9 Add 1 cycle for 65802/65816 native mode (e=0).
10 Add 1 cycle if x=0 (16-bit index registers).
11 Add 1 cycle if CPU is 65C02.
12 6502: if low byte of operand is $FF (ie. operand is $xxFF): yields incorrect result.
13 7 cycles per byte moved.
14 Uses 3 cycles to shut the processor down; additional cycles are required by reset to restart CPU.
15 Uses 3 cycles to shut the processor down; additional cycles are required by interrupt to restart it.
16 Byte and cycle counts subject to change in future processors which expand WDM into 2-byte opcode portions of instructions of varying lengths.
These are the 255 opcodes of the 65816. (TODO: fix the mistakes in the list; explain the format of the list.)
MACHINE ASSEMBLY EFFECT FLAGS
00 00 brk brk interrupt --------
00 nn brk $nn brk interrupt --------
01 nn ora ($nn,x) a | operand => a n-----z-
02 00 cop cop interrupt --------
02 nn cop $nn cop interrupt --------
03 nn ora $nn,s a | operand => a n-----z-
04 nn tsb $nn operand | a => operand ------&-
05 nn ora $nn a | operand => a n-----z-
06 nn asl $nn operand << 1 => operand n-----zc
07 nn ora [$nn] a | operand => a n-----z-
08 php push processor flags --------
09 nn ora #$nn a | operand => a n-----z-
09 nn mm ora #$mmnn a | operand => a n-----z-
0a asl a a << 1 => a n-----zc
0b phd push direct page location --------
0c nn mm tsb $mmnn.w operand | a => operand ------&-
0d nn mm ora $mmnn.w a | operand => a n-----z-
0e nn mm asl $mmnn.w operand << 1 => operand n-----zc
0f nn mm kk ora $kkmmnn.l a | operand => a n-----z-
10 nn bpl label branch if negative == 0 --------
11 nn ora ($nn),y a | operand => a n-----z-
12 nn ora ($nn) a | operand => a n-----z-
13 nn ora ($nn,s),y a | operand => a n-----z-
14 nn trb $nn operand & ~a => operand ------&-
15 nn ora $nn,x a | operand => a n-----z-
16 nn asl $nn,x operand << 1 => operand n-----zc
17 nn ora [$nn],y a | operand => a n-----z-
18 clc 0 => carry -------c
19 nn mm ora $mmnn.w,y a | operand => a n-----z-
1a inc a a + 1 => a n-----z-
1b tcs c => stack pointer --------
1c nn mm trb $mmnn.w operand & ~a => operand ------&-
1d nn mm ora $mmnn.w,x a | operand => a n-----z-
1e nn mm asl $mmnn.w,x operand << 1 => operand n-----zc
1f nn mm kk ora $kkmmnn.l,x a | operand => a n-----z-
20 nn mm jsr $mmnn call 'jsr' subroutine --------
21 nn and ($nn,x) a & operand => a n-----z-
22 nn mm kk jsl $kkmmnn call 'jsl' subroutine --------
23 nn and $nn,s a & operand => a n-----z-
24 nn bit $nn test two highest bits nv----&-
25 nn and $nn a & operand => a n-----z-
26 nn rol $nn rotate left operand, carry n-----zc
27 nn and [$nn] a & operand => a n-----z-
28 nn plp pull processor flags nvmxdizc
29 nn and #$nn a & operand => a n-----z-
29 nn mm and #$mmnn a & operand => a n-----z-
2a rol a rotate left a, carry n-----zc
2b pld pull direct page location n-----z-
2c nn mm bit $mmnn.w test two highest bits nv----&-
2d nn mm and $mmnn.w a & operand => a n-----z-
2e nn mm rol $mmnn.w rotate left operand, carry n-----zc
2f nn mm kk and $kkmmnn.l a & operand => a n-----z-
30 nn bmi label branch if negative == 1 --------
31 nn and ($nn),y a & operand => a n-----z-
32 nn and ($nn) a & operand => a n-----z-
33 nn and ($nn,s),y a & operand => a n-----z-
34 nn bit $nn,x test two highest bits nv----&-
35 nn and $nn,x a & operand => a n-----z-
36 nn rol $nn,x rotate left operand, carry n-----zc
37 nn and [$nn],y a & operand => a n-----z-
38 sec 1 => carry -------c
39 nn mm and $mmnn.w,y a & operand => a n-----z-
3a dec a a - 1 => a n-----z-
3b tsc stack pointer => c n-----z-
3c nn mm bit $mmnn.w,x test two highest bits nv----&-
3d nn mm and $mmnn.w,x a & operand => a n-----z-
3e nn mm rol $mmnn.w,x rotate left operand, carry n-----zc
3f nn mm kk and $kkmmnn.l,x a & operand => a n-----z-
40 rti return from interrupt nvmxdizc
41 nn eor ($nn,x) a ^ operand => a n-----z-
43 nn eor $nn,s a ^ operand => a n-----z-
44 nn mm mvp $mm,$nn move block previous --------
45 nn eor $nn a ^ operand => a n-----z-
46 nn lsr $nn operand >> 1 => operand n-----zc
47 nn eor [$nn] a ^ operand => a n-----z-
48 pha push a --------
49 nn eor #$nn a ^ operand => a --------
4a lsr a a >> 1 => a n-----zc
4b phk push program bank --------
4c nn mm jmp $mmnn jump within program bank --------
4d nn mm eor $mmnn.w a ^ operand => a n-----z-
4e nn mm lsr $mmnn.w operand >> 1 => operand n-----zc
4f nn mm kk eor $kkmmnn.l a ^ operand => a n-----z-
50 nn bvc label branch if overflow == 0 --------
51 nn eor ($nn),y a ^ operand => a n-----z-
52 nn eor ($nn) a ^ operand => a n-----z-
53 nn eor ($nn,s),y a ^ operand => a n-----z-
54 nn mm mvn $mm,nn move block next --------
55 nn eor $nn,x a ^ operand => a n-----z-
56 nn lsr $nn,x operand >> 1 => operand n-----zc
57 nn eor [$nn],y a ^ operand => a n-----z-
58 cli 0 => IRQ disabled -----i--
59 nn mm eor $mmnn.w,y a ^ operand => a n-----z-
5a phy push y --------
5b tcd c => direct page location --------
5c nn mm kk jml $kkmmnn jump to long address --------
5d nn mm eor $mmnn.w,x a ^ operand => a n-----z-
5e nn mm lsr $mmnn.w,x operand >> 1 => operand n-----zc
5f nn mm kk eor $kkmmnn.l,x a ^ operand => a n-----z-
60 rts return from 'jsr' subroutine --------
61 nn adc ($nn,x) a + operand + carry => a nv----zc
62 nn mm per label push pc-relative address --------
63 nn adc $nn,s a + operand + carry => a nv----zc
64 nn stz $nn 0 => operand --------
65 nn adc $nn a + operand + carry => a nv----zc
66 nn ror $nn rotate right operand, carry n-----zc
67 nn adc [$nn] a + operand + carry => a nv----zc
68 pla pull a n-----z-
69 nn adc #$nn a + operand + carry => a nv----zc
69 nn mm adc #$mmnn a + operand + carry => a nv----zc
6a ror a rotate right a, carry n-----zc
6b rtl return from 'jsl' subroutine --------
6c nn mm jmp ($mmnn) jump within program bank --------
6d nn mm adc $mmnn.w a + operand + carry => a nv----zc
6e nn mm ror $mmnn.w rotate right operand, carry n-----zc
6f nn mm kk adc $kkmmnn.l a + operand + carry => a nv----zc
70 nn bvs label branch if overflow == 1 --------
71 nn adc ($nn),y a + operand + carry => a nv----zc
72 nn adc ($nn) a + operand + carry => a nv----zc
73 nn adc ($nn,s),y a + operand + carry => a nv----zc
74 nn stz $nn,x 0 => operand --------
75 nn adc $nn,x a + operand + carry => a nv----zc
76 nn ror $nn,x rotate right operand, carry n-----zc
77 nn adc [$nn],y a + operand + carry => a nv----zc
78 sei 1 => IRQ disabled -----i--
79 nn mm adc $mmnn.w,y a + operand + carry => a nv----zc
7a ply pull y n-----z-
7b tdc direct page location => c n-----z-
7c nn mm jmp ($mmnn,x) jump within program bank --------
7d nn mm adc $mmnn.w,x a + operand + carry => a nv----zc
7e nn mm ror $mmnn.w,x rotate right operand, carry n-----zc
7f nn mm kk adc $kkmmnn.l,x a + operand + carry => a nv----zc
80 nn bra label branch --------
81 nn sta ($nn,x) a => operand --------
82 nn mm brl label long branch --------
83 nn sta $nn,s a => operand --------
84 nn sty $nn y => operand --------
85 nn sta $nn a => operand --------
86 nn stx $nn x => operand --------
87 nn sta [$nn] a => operand --------
88 dey y - 1 => y n-----z-
89 nn bit #$nn test two highest bits nv----&-
89 nn mm bit #$mmnn test two highest bits nv----&-
8a txa x => a n-----z-
8b phb push data bank --------
8c nn mm sty $mmnn.w y => operand --------
8d nn mm sta $mmnn.w a => operand --------
8e nn mm stx $mmnn.w x => operand --------
8f nn mm kk sta $kkmmnn.l a => operand --------
90 nn bcc label branch if carry == 0 --------
91 nn sta ($nn),y a => operand --------
92 nn sta ($nn) a => operand --------
93 nn sta ($nn,s),y a => operand --------
94 nn sty $nn,x y => operand --------
95 nn sta $nn,x a => operand --------
96 nn stx $nn,y x => operand --------
97 nn sta [$nn],y a => operand --------
98 tya y => a --------
99 nn mm sta $mmnn.w,y a => operand --------
9a txs x => stack pointer --------
9b txy x => y n-----z-
9c nn mm stz $mmnn.w 0 => operand --------
9d nn mm sta $mmnn.w,x a => operand --------
9e nn mm stz $mmnn.w,x 0 => operand --------
9f nn mm kk sta $kkmmnn.l,x a => operand --------
a0 nn ldy #$nn operand => y n-----z-
a0 nn mm ldy #$mmnn operand => y n-----z-
a1 nn lda ($nn,x) operand => a n-----z-
a2 nn ldx #$nn operand => x n-----z-
a2 nn mm ldx #$mmnn operand => x n-----z-
a3 nn lda $nn,s operand => a n-----z-
a4 nn ldy $nn operand => y n-----z-
a5 nn lda $nn operand => a n-----z-
a6 nn ldx $nn operand => x n-----z-
a7 nn lda [$nn] operand => a n-----z-
a8 tay a => y n-----z-
a9 nn lda #$nn operand => a n-----z-
a9 nn mm lda #$mmnn operand => a n-----z-
aa tax a => x n-----z-
ab plb pull data bank --------
ac nn mm ldy $mmnn.w operand => y n-----z-
ad nn mm lda $mmnn.w operand => a n-----z-
ae nn mm ldx $mmnn.w operand => x n-----z-
af nn mm kk lda $kkmmnn.l operand => a n-----z-
b0 nn bcs label branch if carry == 1 --------
b1 nn lda ($nn),y operand => a n-----z-
b2 nn lda ($nn) operand => a n-----z-
b3 nn lda ($nn,s),y operand => a n-----z-
b4 nn ldy $nn,x operand => y n-----z-
b5 nn lda $nn,x operand => a n-----z-
b6 nn ldx $nn,y operand => x n-----z-
b7 nn lda [$nn],y operand => a n-----z-
b8 clv 0 => overflow -v------
b9 nn mm lda $mmnn.w,y operand => a n-----z-
ba tsx stack pointer => x n-----z-
bb tyx y => x n-----z-
bc nn mm ldy $mmnn.w,x operand => y n-----z-
bd nn mm lda $mmnn.w,x operand => a n-----z-
be nn mm ldx $mmnn.w,y operand => x n-----z-
bf nn mm kk lda $kkmmnn.l,x operand => a n-----z-
c0 nn cpy #$nn y - operand n-----zc
c0 nn mm cpy #$mmnn y - operand n-----zc
c1 nn cmp ($nn,x) a - operand n-----zc
c2 nn rep #$nn reset processor flags nvmxdizc
c3 nn cmp $nn,s a - operand n-----zc
c4 nn cmy $nn y - operand n-----zc
c5 nn cmp $nn a - operand n-----zc
c6 nn dec $nn operand - 1 => operand n-----z-
c7 nn cmp [$nn] a - operand n-----zc
c8 iny y + 1 => y n-----z-
c9 nn cmp #$nn a - operand n-----zc
c9 nn mm cmp #$mmnn a - operand n-----zc
ca dex x - 1 => x n-----z-
cb wai wait for interrupt --------
cc nn mm cpy $mmnn.w y - operand n-----zc
cd nn mm cmp $mmnn.w a - operand n-----zc
ce nn mm dec $mmnn.w operand - 1 => operand n-----z-
cf nn mm kk cmp $kkmmnn.l a - operand n-----zc
d0 nn bne label branch if zero flag == 0 --------
d1 nn cmp ($nn),y a - operand n-----zc
d2 nn cmp ($nn) a - operand n-----zc
d3 nn cmp ($nn,s),y a - operand n-----zc
d4 nn pei ($nn) push address of operand --------
d5 nn cmp $nn,x a - operand n-----zc
d6 nn dec $nn,x operand - 1 => operand n-----z-
d7 nn cmp [$nn],y a - operand n-----zc
d8 cld 0 => decimal flag ----d---
d9 nn mm cmp $mmnn.w,y a - operand n-----zc
da phx push x --------
db stp stop the processor --------
dc nn mm jml [$mmnn] jump to long address --------
dd nn mm cmp $mmnn.w a - operand n-----zc
de nn mm dec $mmnn.w operand - 1 => operand n-----z-
df nn mm kk cmp $kkmmnn.l,x a - operand n-----zc
e0 nn cpx #$nn x - operand n-----zc
e0 nn mm cpx #$mmnn x - operand n-----zc
e1 nn sbc ($nn,x) a + ~operand + carry => a nv----zc
e2 nn sep #$nn set processor flags nvmxdizc
e3 nn sbc $nn,s a + ~operand + carry => a nv----zc
e4 nn cpx $nn x - operand n-----zc
e5 nn sbc $nn a + ~operand + carry => a nv----zc
e6 nn inc $nn operand + 1 => operand n-----z-
e7 nn sbc [$nn] a + ~operand + carry => a nv----zc
e8 nn inx x + 1 => x n-----z-
e9 nn sbc #$nn a + ~operand + carry => a nv----zc
e9 nn mm sbc #$mmnn a + ~operand + carry => a nv----zc
ea nop no operation --------
eb xba swap b with a --------
ec nn mm cpx $mmnn.w x - operand n-----zc
ed nn mm sbc $mmnn.w a + ~operand + carry => a nv----zc
ee nn mm inc $mmnn.w operand + 1 => operand n-----z-
ef nn mm kk sbc $kkmmnn.l a + ~operand + carry => a nv----zc
f0 nn beq label branch if zero flag == 1 --------
f1 nn sbc ($nn),y a + ~operand + carry => a nv----zc
f2 nn sbc ($nn) a + ~operand + carry => a nv----zc
f3 nn sbc ($nn,s),y a + ~operand + carry => a nv----zc
f4 nn mm pea $mmnnn push address of operand --------
f5 nn sbc $nn,x a + ~operand + carry => a nv----zc
f6 nn inc $nn,x operand + 1 => operand n-----z-
f7 nn sbc [$nn],y a + ~operand + carry => a nv----zc
f8 sed 1 => decimal flag ----d---
f9 nn mm sbc $mmnn.w,y a + ~operand + carry => a nv----zc
fa plx pull x n-----z-
fb xce swap carry, emulation flags -------c
fc nn mm jsr ($mmnn,x) call 'jsr' subroutine --------
fd nn mm sbc $mmnn.w,x a + ~operand + carry => a nv----zc
fe nn mm inc $mmnn.w,x operand + 1 => operand --------
ff nn mm kk sbc $kkmmnn.l,x a + ~operand + carry => a nv----zc
=================
Appendix C: IC Pinouts
=================
Notes:
ML: Memory Lock line (pin 5) is asserted low during the execution of the read-modify-write (asl,dec,inc,lsr,rol,ror,trb, and tsb instructions to inform other ics that the bus may not be claimed yet.
VP: Vector Pull is asserted whenever any of the hardware vector address's are being accessed during an IRQ.
Abort: An input. When asserted caused the current instruction to be aborted.
VPA/VDA. Valid Program Address and Valid Data Address. These two signals extend on the 6502 SYNC line - to better handle DMA schemes.
VPA VDA
0 0 -Internal Operation
0 1 -Valid program address
1 0 -Valid data address
1 1 -Opcode fetch
M/X: Memory and Index lines. These signals are multiplexed on pin
38. M is available during phase zero and X during Phase one.
These two signals reflect the contents of the status register m and x flags, allowing other devices to decode opcode fetches.
E: Emulation pin. This signal reflects the state of the processors emulation bit (E).
===================================================================
44 PIN PLCC Pinout.
Ir a la primera parte del artículo
Volver a la página principal.