Question

I'm writing an emulator for the 6502, and basically, there are some instructions where there's an offset saved in one of the registers (mostly X and Y) and I'm wondering, since branch instructions use signed 8 bit integers, do the registers keep their values as 8 bit signed? Meaning this:

switch(opcode) { 
    //Bunch of opcodes
    case 0xD5: 
    //Read the memory area with final address being address + x offset
    int rempResult = a - readMemory(address + x); 
    //Comparing some things, setting/disabling flags
    //Incrementing program counter and cycles/ticks
    break; 
    //More opcodes
}

Let's say in this situation that x = 0xEE. In regular binary, this would mean that x = 238. In the 6502 however, the branch instruction uses signed offset for jumping to memory addresses, so I'm wondering, is the 238 interpreted as -18 in this case, or is it just regular unsigned 8 bit value?

Was it helpful?

Solution

It varies.

They're not explicitly signed or unsigned for arithmetic, logical, shift, or load and store operations.

The conditional branches (and the unconditional one on the later 6502 descendants) all take the argument as signed; otherwise loops would be extremely awkward.

zero, x addressing is achieved by performing an 8-bit addition of x to the zero page address, ignoring carry, and reading from the zero page. So e.g.

LDX #-126    ; which is +130 if unsigned
LDA 23, x

Would read from address 23+130 = 153. But had it been 223+130 then the end read would have been from (223 + 130) MOD 256 = 97.

absolute, x/y is unsigned and carry works correctly (but costs an extra cycle)

(zero, x) is much like the direct version in that the offset is signed but the result is always within the zero page. Then the real address is read from there.

(zero), y is unsigned with carry working and costing.

OTHER TIPS

The "sign" is simply the value of the most significant (aka bit 7) in an 8-bit byte.

6502 has support for signed values in these ways:

  • The N bit in .P - but it really just tells you if the last instruction turned on or off bit 7 of a memory location or register. It was common to use BPL/BMI to do stuff based on bit 7 in a memory location for flag or "boolean" like use.
  • The V bit of .P which is flipped "when the result of adding two positive numbers overflows and ends up negative, and when the result of adding two negative numbers overflows and ends up positive"
  • And of course obeying the sign bit for relative branch instructions only, e.g. BEQ with a value with bit 7 set will move to a lower memory location, not a higher one.

Beyond that, whether that bit means anything is completely up to you and your program. What really makes numbers signed or unsigned is how you display the numbers.

The linked article above goes into what one's complement and two's complement is and how it makes the mathematics work without the 6502 having to care too much about the sign.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top