Indirect Y indexed addressing mode in MOS 6502

2.8k views Asked by At

I was looking at the addressing modes for the MOS 6502 instruction set from the here.

The description of indirect, Y-indexed is a bit inconsistent with other sources.

It says

OPC ($LL),Y operand is effective address incremented by Y with carry; effective address is word at zeropage address

But other sources don't mention about the addition with carry bit. Like here.

What is the right way of calculating the effective address?

1

There are 1 answers

14
Margaret Bloom On BEST ANSWER

When in doubt it's better to look at the official documentation.
There is a fascinating original datasheet from MOS here also [1] that reads

INDIRECT INDEXED ADDRESSING - In indirect indexed addressing (referred to as ( Indirect) , Y), the second byte of the instruction points to a memory location in page zero.
The contents of this memory location is added to the contents of the Y index register, the result being the low order eight bits of the effective address.
The carry from this addition is added to the contents of the next page zero memory location, the result being the high order eight bits of the effective address.

So there the second addition is performed with carrying.
You can see this as a 16-bit addition between the 16-bit word pointed by Immediate (in little-endian) and the contents of the Y register zero extended to 16 bits.

For example, if the memory and Y are

All values in hex

Address    00  01  02  03  04 ...
Value      80  02  f3  00  03 ...

Y = 90

then (0), Y is

  low 8 bits:  80 + 90     = 10   (with carry = 1)
  high 8 bits: 02 + 00 + 1 = 03 

giving an effective address of 0310. Similarly (3), Y is

  low 8 bits:  00 + 90     = 90   (with carry = 0)
  high 8 bits: 03 + 00 + 0 = 03 

that results in an effective address of value 0390.

You can see that when considered as 16-bit quantities the word at 0 is 0280 and Y is 0090, their addition is 0310 as expected.

The long description just encodes these facts: a) the 16-bit word pointed by Indirect is stored in little-endian b) Y is zero-extended c) the addition is a 16-bit one.

In C, it should look like this

uint16_t effective_addr(uint8_t indirect)
{
   //Take the INDIRECT immediate and make a pointer to a 16-bit LE word out of it
   //In C int-to-ptr is implementation define, we assume an identity map here
   uint16_t* page_zero_ptr = (uint16_t*)indirect;

   //The Y register is 8-bit, we consider it a 16-bit one instead
   //Assume y is of unsigned type 
   uint16_t  y_zero_ext = y;

   //Do a 16-bit addition, this is equivalent to two 8-bit additions with carry
   return *page_zero_ptr + y;
}