19

Assuming that this diagram is correct:

enter image description here

Instructions like INC, INX, and INY can easily perform increment using ALU sum with data on B input, 0 on A input and carry_in set.

But how do instructions like DEC, DEX and DEY work?

It can decrement by adding -1 which is $FF, and it can have $FF by inverting 0 BUT 0 can only be set on A input and inverting can only be done on B input.

So how does it perform a decrement?

0

1 Answer 1

26

But how instructions like DEC, DEX and DEY works ?

By adding $FF provided by the precharged internal data bus to the register content.


In Detail:

  • The internal databus is precharged with $FF during PHI2 (*1)
  • During the next phase it's loaded into the B register (signal DB/ADD)
  • At the same time the index register is transfered via SB (*/SB) to the A register (SB/ADD)
  • SUMS is pulled thus $FF is added to the register content, effectively decrementing it (*2).
  • The result is transfered back via SB (ADD/SB7 + ADD/SB(0..6)) to either index register (SB/*).

Background 1: NMOS switching (Abbreviated Version)

While using the precharge to supply a $FF constant is a real nifty feature, it's more of a hack based on a side effect to speed up NMOS operation.

The precharge exists due the way MOS-FET and NMOS Logic work. Effectively each FET (and line) is a (comparable) large capacitor. Loading and unloading takes time in relation to resistance in the circuit. In NMOS logic the transistor is placed between the output and ground. On the other side the output is connected to Vcc (+5V) via a resistor.

When the Transistor switches on, the output is grounded with a very low resistance, puting the output extrem fast toward Low. When it's switched off, the output is loaded via the resistor. Thus changing the signal output from Low to High takes considerable longer than going from High to Low.

By precharging lines with High value ahead of time and then pulling them down when a signal is to be transmitted, minimizes switch time to the lower of both, resulting in faster operation.


Background 2: Use of Precharge for Constant Generation on 6502

On the 6502 precharge is thus present on all 4 internal busses (DB, ADL, ADH, SB). Beside providing $FF for decrement on DB, it's well used on ADH and ADL to generate constant values:

  • Constant generated on DB
    • $FF by default
  • Constants generated on ADH:
    • $FF for vector pull - by default
    • $01 for stack page addressing - by pulling 0/ADH(1-7)
    • $00 for zero page addressing - by pulling 0/ADH(1-7) and 0/ADH0
  • Constants generated on ADL:
    • $FE/$FF for INT - by default value plus 0/ADL0 on first access
    • $FC/$FD for Reset - by 0/ADL1 plus 0/ADL0 on first access
    • $FA/$FB for NMI - by 0/ADL2 plus 0/ADL0 on first access

Another special use is with transfering ALU results to SB. The ALU does not shift-in Carry on a ROR, but always sets bit 7 to Zero. So when the ALU result is transfered after a ROR, bit 7 is only transfered if carry was cleared. Otherwise transfer for bit 7 is supressed, replacing it by a precharged One.

Precharge behaviour is a major reason why the 6502 is not static, as the precharged values will vanish after some time, making many operations invalid.


Background 3: Hanson Diagramm

It has been asked where the signal names originated. They are taken from the famous Hanson diagram - as cited by the OP (*3) - which is nowadays the de-facto standard for interpreting the 6502 (despite having a few little inconsistencies; *4). It was part of an equally famous 1995 article by Mr. Hanson about making D-Latches in VHDL. To my knowledge the diagram was first drawn up in 1982 during studies of the original 6502 blueprints.

The names are rather straight forward, like Y/SB meaning connect Y output to Special Bus (the register data bus), or SB/Y to enable loading Y from SB. Next to all modern sources use these names, or derivations thereof. Most notable maybe the Visual 6502 simulation (used in DPcontrol output; see the nodenames.js source for all names used; *5).


*1 - Note the Prechage MOSFET box in the top left quadrant, beside DB, right below the Data Output Register box

*2 - It's an unsigned 8 bit addition (n + 255) mod 256.

*3 - Please use, whenever possible the cleaned up version provided by Mr. Hanson at http://www.witwright.com/DonPub/6502-Block-Diagram.pdf. The often used copies of copies of scans are quite ugly and hard to read.

*4 - For example there is a signal generated if DB is negative or the flipflops shown as part of the logic don't fully add up, but these are details that only come up when trying to recreate the CPU.

*5 - Searching it is quite handy to find meaning and usage - as the Visual 6502 in general is a great tool to peek into the 6502.

17
  • 1
    Thanks, for the DEC instruction, memory read (input data latch) goes by DB to B and A is precharged with $FF by precharge MOSFET under stack pointer register ?
    – Johnmph
    Commented Jan 15, 2020 at 5:19
  • 1
    Did the 6502 save any circuitry by making the read-modify-write sequence for INC and DEC usable with the "accumulator" addressing mode? I find there are an annoying number of cases where the omission of those instructions converts what should be a 1 byte/2 cycle op into 3 bytes/4 cycles.
    – supercat
    Commented Jan 15, 2020 at 17:20
  • 1
    @supercat Simply no. It's one of several instructions that could have been added right away with not more than another row in ROM. I would attribute it (like some of the other) to kind of Betriebsblindheit - they were too much focused on seeing the A as the only work register while X/Y are only there for indexing. Each and every A instruction could have been made to work on X/Y as well by just adding appropriate columns to the decode ROM (as well as using A to index). All three registers are equal (except for the decimal adjuster at A). Having an ADY #8 to walk structures would have been nice.
    – Raffzahn
    Commented Jan 15, 2020 at 18:22
  • @Raffzahn: I thought the registers' placement on the internal buses was different, which is why the opcodes that should represent e.g. "STX abs,Y" behave oddly. Still, I have long been curious about how the amount of circuitry in the 6502 compares with what would have been necessary if the instruction set were partitioned into 24 instructions where the bottom two bits weren't 00, that all supported the same 8 addressing modes, 32 instructions (branches or NOP) that took one extension byte, and 32 instructions that took zero extention bytes. Note that having many NOP instructions would...
    – supercat
    Commented Jan 15, 2020 at 18:39
  • 1
    @lvd taken from the famous Hanson diagram - as cited by the OP - which is the de-facto standard for interpreting the 6502 (despite having a few little inconsistencies). It was part of an equally famous article by Mr. Hanson in 1995 about D-Latches in VHDL. To my knowledge it was drawn up in 1982 from the 6502 blueprints. The names are rather straight foreward, like Y/SB meaning connect Y output to Special Bus (the register data bus), or SB/Y for loading Y from SB.
    – Raffzahn
    Commented Jan 15, 2020 at 19:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .