In 6502 Assembly, we can use INX
and INY
to increase the value stored in X and Y. They can be decreased with DEX
and DEY
. However, it seems that there are no such instructions for A, like INA
or DEA
. There is however an instruction to increment and decrement the content of an address (INC
and DEC
). But why are there no instructions like that for A? Does this have a reason? Or am I missing something? I know that you could just use ADC
or SBC
but I'm still wondering.
-
1It really is strange when you think about it, as the accumulator is the one place you'd most expect to be supported by any given arithmetic instruction. Something like, say, an absolute memory address offset by the X register, seems far less likely to be incrementable in a single instruction. And yet the 6502 can increment/decrement literally anything but the accumulator, including that. (Well, you can using ADC/SBC, but there's no way I know of to do it in a single instruction unless it's a point in the code where the carry flag will always be in the same state.)– SparketteDec 30, 2020 at 1:55
-
Does anyone know if the 6502 was developed under a tight deadline? That could be the reason why something got left out even though it was added in later updates.– UncleBodAug 2 at 17:53
3 Answers
The designers figured that you'd use X and Y for looping, indexing etc, and use A for adding and subtracting, shifts etc. So they saw a need for INX
and INY
, but didn't see a enough of a need for an instruction to increment or decrement the accumulator.
That's also the reason why X and Y cannot participate in many ALU operations, like adds, shifts, and whatever.
Unlike adc
and sbc
, the instructions to increment and decrement also do not heed the decimal mode. This might have been seen as a shortcoming early on, as the design was coming together.
(Later, with the 65C02, the instruction you are talking about was added, and variously called INA
, INC A
or INC
.)
-
1"but didn't see a need for an instruction to increment or decrement the accumulator." - apparently the addition of INA/DEA reduced typical code size by about 5% - adding STZ and similar changes made the overall reduction 10 to 15%. I suspect they would have been aware of the advantages even during the original design. Dec 11, 2019 at 16:08
-
3
-
5@MauryMarkowitz There are a lot of instructions that could be added to the 6502 to decrease code size and/or increase performance but weren't. The designers were trying to make a cheap microprocessor, not a fully featured one and they drew their line with
INA
on the wrong side of it.– JeremyPDec 12, 2019 at 10:22 -
1Oh for sure, they didn't have the statistics that were available to WDC two years later. Dec 12, 2019 at 16:56
-
2@JeremyP: I can be quite certain that an NMOS 6502 that includes the indicated instructions wouldn't cost any more than the NMOS 6502s that were actually produced, because the only thing necessary to make any existing NMOS 6502 chips or other parts based on that core store the bitwise AND of A and X to e.g. address $1234 is to feed it the instruction bytes 8F 34 12, and the only thing necessary to make such a chip decrement $56 and compare the result with A is to feed it the instruction bytes C7 56.– supercatDec 13, 2019 at 16:54
If one writes opcodes in binary, using the format III-AAA-gg (with "III" generally being "Instruction", "AAA" being "Address mode", and "gg" as "general instruction group"), most instructions of the form III-AAA-01 or III-AA0-10 process addresses the same way using the address mode specified by AAA. The latter group of instructions are read-modify-write except that 10I-AAA-xx are LD_/ST_, with the registers selected by xx (in particular, 10I-AAA-10 are LDX/STX). The exception is that address mode 010, which would normally be immediate (e.g. ORA #imm is 000-010-01), becomes "accumulator" addressing for read-modify write instructions of the 0II-010-10 form. The increment and decrement instructions have the form 11I-AA0-10, which doesn't match that pattern.
The opcode map is a bit goofy in the areas which would match the general III-AAA-10 and 10I-AAA-xx patterns, but aren't used for read-modify-write or LD_/ST_ instructions. I would guess that instructions like "TXA" and "TAX", which are placed where "STX #imm" and "LDX #imm" would go, are placed at those spots to exploit the fact that instructions of the form 100-AAA-1x place X on the internal bus, and 101-AAA-1x loads X from the internal bus. I'm not sure when chronologically it was decided that various instructions would be supported, but supporting accumulator mode with INC and DEC would have required some extra circuitry, and would also require relocating DEX (which uses the opcode that would have fit the patterns of 110-AAA-10 for "decrement something" and 1x0-AAA-1x for "put something into X").
Incidentally, one thing that made chip designs of the 1970s and 1980s very different from those of today was that chips had only three layers that could carry current and signals, and any place the bottom two layers crossed would form a transistor. As a consequence, one needed to be very mindful of which signals would be sent to what part of a chip, or else a chip would spend more area on routing wires than on transistors. Today's fabrication processes generally support at least five layers, and many support far more than that, which allows much more routing flexibility.
-
Actually everything in 6502 controlled with its PLA or "microcode ROM" (though technically it is not pure ROM). The question could be whether
INC A/DEC A
was at all possible to implement within the existing PLA and why didn't they do it.– lvdDec 11, 2019 at 20:09 -
3@lvd: It would be interesting to have a 6502 simulator that would allow editing the PLA. I suspect that many of the 6502's annoyances could be eased if parts of the instruction set were reworked, while keeping the same chip layout otherwise, but I suspect some features were added after other parts of the instruction set had already been decided upon.– supercatDec 11, 2019 at 20:20
-
1@lvd: If I were trying to design a chip given the 6502's list of features, I think I'd be inclined to make all instructions whose two LSBs aren't 00 compute and access an effective address based on bits 2-4 of the opcode, and then perform some action based on bits 0-1 and 5-7. There's enough space in the opcode map to do that, and I would think that having the opcodes for LDX be the same as LDA except that the bottom two bits would be 10 rather than 01, would be simpler than having LDX, STX, and BIT use different address encodings.– supercatDec 11, 2019 at 20:57
Although the instructions LSR, ROR, ASL, and ROL were described as having five addressing modes that include "accumulator mode", each of them should really be thought of as two instructions, e.g. "LSR memory" and "LSR accumulator". If the 6502 hadn't included circuitry specifically to support the accumulator modes of those instructions, but simply advanced the state machine to "cleanup and fetch next instruction" after the second cycle for any bit pattern that would code an immediate-mode operand, the opcodes that would code the immediate-operand forms of those instructions would act as either one-cycle or two-cycle NOPs, depending upon whether incrementing of the program counter was suppressed during the second cycle, because the actual shifting work performed by the instructions occurs on the cycle after the memory-operand fetch, and immediate-mode opcodes don't perform a memory-operand fetch.
Making those instructions usable with both memory operands and the accumulator required a fair amount of extra circuitry--probably more than some other features that didn't make the cut, but they were included because some common operations would be awkward if only one were supported. Without accumulator mode, the scenario of loading a bit from one I/O port, shifting it, and then outputting it, would have gone from:
LDA input
LSR
STA output
to
LDA input
STA temp
LSR temp
LDA temp
STA output
increasing the time from 7 bytes/10 cycles to 12 bytes/19 cycles. Without memory mode, the scenario where one wants to shift a bit through a sequence of addresses would have increased from:
LSR buff+3
ROR buff+2
ROR buff+1
ROR buff
to
LDA buff+3
LSR
STA buff+3
LDA buff+2
ROR
STA buff+2
LDA buff+1
ROR
STA buff+1
LDA buff
ROR
STA buff
increasing the cost from 8 bytes/20 cycles ot 20 bytes/32 cycles. If the carry flag state is known, a lack of INC A/DEC A would add one byte and zero cycles; if it's not known, it would add two bytes and two cycles. If the 6502 had used all opcodes of the form xxxxxx11 as "some kind of add/subtract", using one opcode bit to enable/disable carry input, and one to control BCD mode, then I don't think the cost/benefit analysis of adding support for INC A/DEC A would have been particularly close to justifying it. As it is, the frequent need for a CLC or SEC when using ADC or SBC means that INC A/DEC A would have offered some savings, but more general ADD/SUB instructions would have been better yet.