10

How does the 6502's machine code process $ vs #$, as in it's assembly language? Does every piece of machine code have an extra byte or something telling to use addresses or values or was it something more clever? (finding info on 6502 assembly is easy, on machine code processing in general not so much, so I don't know if there's a standard way or if this is a stupid question or not!)

16

While @dirkt's is a good answer, I think it might be missing the high-level overview you're after.

On the most basic level, instructions using immediate vs absolute addressing are encoded into different opcodes. For example, LDA # (immediate mode) is encoded as A9 (after which the CPU knows, by mechanisms detailed in @dirkt's answer, to read one byte and interpret it as a value), whereas LDA (absolute mode) is encoded as AD (and the CPU knows to read two bytes and interpret it as an address).

  • 2
    I agree that this answer probably is what the OP was looking for although @dirkt's answer explains how this is possible without resorting to extra opcode bytes. Look at an opcode table to see how the various opcodes are defined: oxyron.de/html/opcodes02.html – Robin Elvin Jan 26 '17 at 12:15
11

How does the 6502's machine code process $ vs #$, as in it's assembly language? Does every piece of machine code have an extra byte or something telling to use addresses or values or was it something more clever?

Just to expand a bit on Muzer's answer...

All 6502 opcodes use exactly one byte, no exceptions. In this one byte, is encoded both what the operation is (load, store, add, rotate etc) and what the address mode is. The address mode is what tells the processor where to get the operand. For example in LDA #10is immediate - the operand follows the opcode. With LDA $10 the address mode can be either absolute (the operand is in the location specified by the two bytes following the opcode) or zero page which is the same as absolute except that, because you know the highest byte of the address is 0, it can be specified by the one byte following the opcode.

The address mode is specified by some of the bits in the opcode. For LDA we have the following bit patterns:

LDA zp, x indirect 0xA1 10100001
LDA zero page      0xA5 10100101
LDA immediate      0xA9 10101001
LDA absolute       0xAD 10101101
LDA zp ind, y      0xB1 10110001
LDA zp, x          0xB5 10110101
LDA abs, y         0xB9 10111001
LDA abs, x         0xBD 10111101

If you focus on bits 2, 3 and 4, you can see that these three bits are the only difference for each of the above instructions and they specify the address mode for LDA. The other bits specify "LDA" i.e. 101xxx01 means LDA.

Eight of the instructions follow that pattern, for example 000xxx01 is for ORA, 001xxx01 is for AND, 100xxx01 is for STA except that 10001001 does not mean STA immediate for obvious reasons.

The principle sort of holds for some of the other instructions too. e.g. LDX, LDY but usually not all the address modes make sense for these or there is a deliberate choice not to have them. e.g. CPX does not have a full set of address modes. The gaps are used for other things e.g. INX is in the place where you would expect CPX #xx.

10

The 6502 has been decapped and traced, and a simulator is available, so you can find out the workings of anything in as much detail as you want.

The block diagram (available even before the decap) helps a lot in understanding what is going on.

Generally, instructions were executed in several phases (T0-T5), and the instruction register and the current phases were decoded first with a ROM, and then with a PLA into signals which drive the various parts of the CPU, including the next phase. The state machine wiki page has some of the more intricate details.

So for immediate vs. absolute addressing, the state machine sequences would slightly differ: Immediate would fetch the byte after the opcode (actually this was pipelined, and happened always at the same time as opcode decoding, which is why each opcode takes at least 2 cycles), and then this value would be routed to the ALU. Absolute addressing would fetch two bytes after the opcode, route them to the address bus latches, use them to fetch the byte at this address, and route that to the ALU.

The simulator allows you to enter your own programs, so just enter both variantes and see what happens.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.