Search code examples
cpu-registers6502signedness

Does the 6502 use signed or unsigned 8 bit registers (JAVA)?


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?


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.