Interrupts in 65xx processors

Last updated

The 65xx family of microprocessors, consisting of the MOS Technology 6502 and its derivatives, the WDC 65C02, WDC 65C802 and WDC 65C816, and CSG 65CE02, all handle interrupts in a similar fashion. There are three hardware interrupt signals common to all 65xx processors and one software interrupt, the BRK instruction. The WDC 65C816 adds a fourth hardware interruptABORT, useful for implementing virtual memory architecturesand the COP software interrupt instruction (also present in the 65C802), intended for use in a system with a coprocessor of some type (e.g., a floating point processor). [1] [2]

Contents

Interrupt types

65xx interrupt vector locations [2] [3]
InterruptVector (hexadecimal)
LSB MSB
ABORT [nb 1] FFF8FFF9
COP [nb 2] FFF4FFF5
IRQ/BRKFFFEFFFF
NMIFFFAFFFB
RESETFFFCFFFD

The hardware interrupt signals are all active low, and are as follows: [1]

RESET
a reset signal, level-triggered
NMI
a non-maskable interrupt, edge-triggered
IRQ
a maskable interrupt, level-triggered
ABORT
a special-purpose, non-maskable interrupt (65C816 only, see below), level-triggered

The detection of a RESET signal causes the processor to enter a system initialization period of six clock cycles, after which it sets the interrupt request disable flag in the status register and loads the program counter with the values stored at the processor initialization vector ($00FFFC$00FFFD) before commencing execution. [1] If operating in native mode, the 65C816/65C802 are switched back to emulation mode and stay there until returned to native mode under software control.

65C816/65C802 native mode interrupt vector locations [2]
InterruptVector (hexadecimal)
LSB MSB
ABORT [nb 1] 00FFE800FFE9
BRK00FFE600FFE7
COP [nb 2] 00FFE400FFE5
IRQ00FFEE00FFEF
NMI00FFEA00FFEB
RESETNone [nb 3]

The detection of an NMI or IRQ signal, as well as the execution of a BRK instruction, will cause the same overall sequence of events, which are, in order: [1] [3]

  1. The processor completes the current instruction and updates registers or memory as required before responding to the interrupt.
  2. 65C816/65C802 when operating in native mode: The program bank register (PB, the A16-A23 part of the address bus) is pushed onto the hardware stack.
  3. The most significant byte (MSB) of the program counter (PC) is pushed onto the stack.
  4. The least significant byte (LSB) of the program counter is pushed onto the stack.
  5. The status register (SR) is pushed onto the stack.
  6. The interrupt disable flag is set in the status register.
  7. 65C816/65C802: PB is loaded with $00.
  8. PC is loaded from the relevant vector (see tables).

The behavior of the 65C816 when ABORT is asserted differs in some respects from the above description and is separately discussed below.

Note that the processor does not push the accumulator and index registers on to the stackcode in the interrupt handler must perform that task, as well as restore the registers at the termination of interrupt processing, as necessary. Also note that the vector for IRQ is the same as that for BRK in all eight bit 65xx processors, as well as in the 65C802/65C816 when operating in emulation mode. When operating in native mode, the 65C802/65C816 provide separate vectors for IRQ and BRK. [4]

When set, the interrupt request disable flag (the I bit in the status register) will disable detection of the IRQ signal, but will have no effect on any other interrupts (however, see below section on the WAI instruction implemented in WDC CMOS processors). Additionally, with the 65(c)02 or the 65C816/65C802 operating in emulation mode, the copy of the status register that is pushed on to the stack will have the B flag set if a BRK (software interrupt) was the cause of the interrupt, or cleared if an IRQ was the cause. [nb 4] Hence the interrupt service routine must retrieve a copy of the saved status register from where it was pushed onto the stack and check the status of the B flag in order to distinguish between an IRQ and a BRK. [1] [2] [4] This requirement is eliminated when operating the 65C802/65C816 in native mode, due to the separate vectors for the two interrupt types. [2]

ABORT interrupt

The 65C816's ABORTB interrupt input is intended to provide the means to redirect program execution when a hardware exception is detected, such as a page fault or a memory access violation. Hence the processor's response when the ABORTB input is asserted (negated) is different from when IRQB and/or NMIB are asserted. Also, achieving correct operation in response to ABORTB requires that the interrupt occur at the proper time during the machine cycle, whereas no such requirement exists for IRQB or NMIB.

When ABORTB is asserted during a valid memory cycle, that is, when the processor has asserted the VDA and/or VPA status outputs, the following sequence of events will occur: [2]

  1. The processor completes the current instruction but does not change the registers or memory in any waythe computational results of the completed instruction are discarded. An abort interrupt does not literally abort an instruction. [2]
  2. The program bank (PB, see above) is pushed to the stack.
  3. The most significant byte (MSB) of the aborted instruction's address is pushed onto the stack.
  4. The least significant byte (LSB) of the aborted instruction's address is pushed onto the stack.
  5. The status register is pushed onto the stack.
  6. The interrupt disable flag is set in the status register.
  7. PB is loaded with $00.
  8. The program counter is loaded from the ABORT vector (see tables).

As the address pushed to the stack is that of the aborted instruction rather than the contents of the program counter, executing an RTI (ReTurn from Interrupt) following an ABORT interrupt will cause the processor to return to the aborted instruction, rather than the next instruction, as would be the case with the other interrupts.

In order for the processor to correctly respond to an abort, system logic must assert (negate) the ABORTB input as soon as a valid address has been placed on the bus and it has been determined that the address constitutes a page fault, memory access violation or other anomaly (e.g., attempted execution of a privileged instruction). Hence the logic must not assert ABORTB until the processor has asserted the VDA or VPA signals. Also, ABORTB must remain asserted until the fall of the phase-two clock and then be immediately released. If these timing constraints are not observed, the abort interrupt handler itself may be aborted, causing registers and/or memory to be changed in a possibly-undefined manner. [2]

Interrupt anomalies

In the NMOS 6502 and derivatives (e.g., 6510), the simultaneous assertion of a hardware interrupt line and execution of BRK was not accounted for in the designthe BRK instruction will be ignored in such a case. Also, the status of the decimal mode flag in the processor status register is unchanged following an interrupt of any kind. This behavior can potentially result in a difficult to locate bug in the interrupt handler if decimal mode happens to be enabled at the time of an interrupt. These anomalies were corrected in all CMOS versions of the processor. [2]

Interrupt handler considerations

A well-designed and succinct interrupt handler or interrupt service routine (ISR) will not only expeditiously service any event that causes an interrupt, it will do so without interfering in any way with the interrupted foreground taskthe ISR must be "transparent" to the interrupted task (although exceptions may apply in specialized cases). This means that the ISR must preserve the microprocessor (MPU) state and not disturb anything in memory that it is not supposed to disturb. Additionally, the ISR should be fully reentrant, meaning that if two interrupts arrive in close succession, the ISR will be able to resume processing the first interrupt after the second one has been serviced. Reentrancy is typically achieved by using only the MPU hardware stack for storage (though there are other possible methods).

Preserving the MPU state means that the ISR must assure that whatever values were in the MPU registers at the time of the interrupt are there when the ISR terminates. A part of the preservation process is automatically handled by the MPU when it acknowledges the interrupt, as it will push the program counter (and program bank in the 65C816/65C802) and status register to the stack prior to executing the ISR. At the completion of the ISR, when the RTI instruction is executed, the MPU will reverse the process. No member of the 65xx family pushes any other registers to the stack. [2]

In most ISRs, the accumulator and/or index registers must be preserved to assure transparency and later restored as the final steps prior to executing RTI. In the case of the 65C816/65C802, consideration must be given to whether it is being operated in emulation or native mode at the time of the interrupt. If the latter, it may also be necessary to preserve the data bank (DB) and direct (zero) page (DP) registers to guarantee transparency. Also, a 65C816 native mode operating system may well use a different stack location than the application software, which means the ISR would have to preserve and subsequently restore the stack pointer (SP). Further complicating matters with the 65C816/65C802 is that the sizes of the accumulator and index registers may be either 8 or 16 bits when operating in native mode, requiring that their sizes be preserved for later restoration. [2]

The methods by which the MPU state is preserved and restored within an ISR will vary with the different versions of the 65xx family. For NMOS processors (e.g., 6502, 6510, 8502, etc.), there can be only one method by which the accumulator and index registers are preserved, as only the accumulator can be pushed to and pulled from the stack. [5] Therefore, the following ISR entry code is typical:

PHA; save accumulatorTXAPHA; save X-registerTYAPHA; save Y-registerCLD; ensure binary mode by clearing decimal flag

The CLD instruction is necessary because, as previously noted, NMOS versions of the 6502 do not clear the D (decimal mode) flag in the status register when an interrupt occurs.

Once the accumulator and index registers have been preserved, the ISR can use them as needed. When the ISR has concluded its work, it would restore the registers and then resume the interrupted foreground task. Again, the following NMOS code is typical:

PLATAY; restore Y-registerPLATAX; restore X-registerPLA; restore accumulatorRTI; resume interrupted task

A consequence of the RTI instruction is the MPU will return to decimal mode if that was its state at the time of the interrupt. [5]

The 65C02, and the 65C816/65C802 when operating in emulation mode, require less code, as they are able to push and pull the index registers without using the accumulator as an intermediary. [2] They also automatically clear decimal mode before executing the ISR. [2] The following is typical:

PHA; save accumulatorPHX; save X-registerPHY; save Y-register

Upon finishing up, the ISR would reverse the process:

PLY; restore Y-registerPLX; restore X-registerPLA; restore accumulatorRTI; resume interrupted task

As previously stated, there is a little more complexity with the 65C816/65C802 when operating in native mode due to the variable register sizes and the necessity of accounting for the DB and DP registers. In the case of the index registers, they may be pushed without regard to their sizes, as changing sizes automatically sets the most significant byte (MSB) in these registers to zero and no data will be lost when the pushed value is restored, provided the index registers are the same size they were when pushed. [2]

The accumulator, however, is really two registers: designated .A and .B. [2] Pushing the accumulator when it is set to 8 bits will not preserve .B, [2] which could result in a loss of transparency should the ISR change .B in any way. Therefore, the accumulator must always be set to 16 bits before being pushed or pulled if the ISR will be using .B. It is also more efficient to set the index registers to 16 bits before pushing them. Otherwise, the ISR has to then push an extra copy of the status register so it can restore the register sizes prior to pulling them from the stack.

For most ISRs, the following entry code will achieve the goal of transparency:

PHB; save current data bankPHD; save direct page pointerREP#%00110000; select 16 bit registersPHA; save accumulatorPHX; save X-registerPHY; save Y-register

In the above code fragment, the symbol % is MOS Technology and WDC standard assembly language syntax for a bitwise operand.

If the ISR has its own assigned stack location, preservation of the stack pointer (SP) must occur in memory after the above pushes have occurredit should be apparent why this is so. The following code, added to the above sequence, would handle this requirement:

TSC; copy stack pointer to accumulatorSTAstkptr; save somewhere in safe RAMLDAisrptr; get ISR's stack pointer &...TCS; set new stack location

At the completion of the ISR, the above processes would be reversed as follows:

REP#%00110000; select 16 bit registersTSC; save ISR's SP...STAisrptr; for subsequent useLDAisstkptr; get foreground task's SP &...TCS; set itPLY; restore Y-registerPLX; restore X-registerPLA; restore accumulatorPLD; restore direct page pointerPLB; restore current data bankRTI; resume interrupted task

Note that upon executing RTI, the 65C816/65C802 will automatically restore the register sizes to what they were when the interrupt occurred, since pulling the previouslysaved status register sets or clears both register size bits to what they were at the time of the interrupt. [2]

While it is possible to switch the 65C816/65C802 from native mode to emulation mode within an ISR, such is fraught with peril. [2] In addition to forcing the accumulator and index registers to 8 bits (causing a loss of the most significant byte in the index registers), entering emulation mode will truncate the stack pointer to 8 bits and relocate the stack itself to page 1 RAM. [2] The result is the stack that existed at the time of the interrupt will be inaccessible unless it was also in page 1 RAM and no larger than 256 bytes. In general, mode switching while servicing an interrupt is not a recommended procedure, but may be necessary in specific operating environments.

Using BRK and COP

As previously noted, BRK and COP are software interrupts and, as such, may be used in a variety of ways to implement system functions.

A historical use of BRK has been to assist in patching PROMs when bugs were discovered in a system's firmware. A typical technique often used during firmware development was to arrange for the BRK vector to point to an unprogrammed "patch area" in the PROM. In the event a bug was discovered, patching would be accomplished by "blowing" all of the fuses at the address where the faulty instruction was located, thus changing the instruction's opcode to $00. Upon executing the resulting BRK, the MPU would be redirected to the patch area, into which suitable patch code would be written. Often, the patch area code started by "sniffing the stack" to determine the address at which the bug was encountered, potentially allowing for the presence of more than one patch in the PROM. The use of BRK for PROM patching diminished once EPROMs and EEPROMs became commonly available.

Another use of BRK in software development is as a debugging aid in conjunction with a machine language monitor. By overwriting an opcode with BRK ($00) and directing the BRK hardware vector to the entry point of the monitor, one can cause a program to halt at any desired point, allowing the monitor to take control. At that time, one may examine memory, view the processor's register values, patch code, etc. Debugging, as advocated by Kuckes and Thompson, can be facilitated by liberally sprinkling one's code with NOP instructions (opcode $EA) that can be replaced by BRK instructions without altering the actual behaviour of the program being debugged. [5] [6] [7]

A characteristic of the BRK and COP instructions is that the processor treats either of them as a two byte instruction: the opcode itself and the following byte, which is referred to as the "signature." [2] Upon execution of BRK or COP, the processor will add two to the program counter prior to pushing it to the stack. Hence when RTI (ReTurn from Interrupt) is executed, the interrupted program will continue at the address immediately following the signature. If BRK is used as a debugging device, the program counter may have to be adjusted to point to the signature in order for execution to resume where expected. Alternatively, a NOP may be inserted as a signature "placeholder," in which case no program counter adjustment will be required.

The fact that BRK and COP double-increment the program counter before pushing it to the stack facilitates the technique of treating them as supervisor call instructions, as found on some mainframe computers. The usual procedure is to treat the signature as an operating system service index. The operating system BRK or COP handler would retrieve the value of the program counter pushed to the stack, decrement it and read from the resulting memory location to get the signature. [8] [9] After converting the signature to a zero-based index, a simple lookup table can be consulted to load the program counter with the address of the proper service routine. Upon completion of the service routine, the RTI instruction would be used to return control to the program that made the operating system call. Note that the signature for BRK may be any value, whereas the signature for COP should be limited to the range $00-$7F. [2]

The use of BRK and/or COP to request an operating system service means user applications do not have to know the entry address of each operating system function, only the correct signature byte to invoke the desired operation. Hence relocation of the operating system in memory will not break compatibility with existing user applications. Also, as executing BRK or COP always vectors the processor to the same address, simple code may be used to preserve the registers on the stack prior to turning control over to the requested service. However, this programming model will result in somewhat slower execution as compared to calling a service as a subroutine, primarily a result of the stack activity that occurs with any interrupt. Also, interrupt requests will have been disabled by executing BRK or COP, requiring that the operating system re-enable them.

WAI and STP instructions

WAI (WAit for Interrupt, opcode $CB) is an instruction available on the WDC version of the 65C02 and the 65C816/65C802 microprocessors (MPU) that halts the MPU and places it into a semi-catatonic state until a hardware interrupt of any kind occurs. [2] The primary use for WAI is in low-power embedded systems where the MPU has nothing to do until an expected event occurs and minimal power consumption is desired as the system is waiting, and/or a quick response is required. A typical example of code that would make use of WAI is as follows:

SEI; disable IRQsWAI; wait for hardware interrupt; ... execution resumes here

In the above code fragment, the MPU will halt upon execution of WAI and go into a very low power consumption state. Despite interrupt requests (IRQ) having been disabled prior to the WAI instruction, the MPU will respond to any hardware interrupt while waiting. Upon receipt of an interrupt, the MPU will "awaken" in one clock cycle and resume execution at the instruction immediately following WAI. Hence interrupt latency will be very short (70 nanoseconds at 14 megahertz), resulting in the most rapid response possible to an external event.

Similar in some ways to WAI is the STP (SToP, opcode $DB) instruction, which completely shuts down the MPU while waiting for a single interrupt input. [2] When STP is executed, the MPU halts its internal clock (but does retain all data in its registers) and enters a low power state. The MPU is brought out of this state by pulling its reset input pin (RESB, which is classified as an interrupt input) low. Execution will then resume at the address stored at locations $00FFFC-$00FFFD, the hardware reset vector. As with WAI, STP is intended for use in low power embedded applications where long periods of time may elapse between events that require MPU attention and no other processing is required. STP would not be used in normal programming, as it would result in total cessation of processing.

Footnotes

  1. 1 2 The ABORT input is available only with the W65C816S. [2]
  2. 1 2 The COP instruction is available in both operating modes. [2]
  3. The 65C816/65C802 has no native mode interrupt vector for the RESET signal, as a reset always reverts the processor to emulation mode. [2]
  4. The value of the B flag in the status register itself is always 1, regardless of the interrupt type.  B is meaningful only in the copy of the status register that is pushed onto the stack in response to an interrupt, and does not actually exist in the flags register. [2]

Related Research Articles

Hitachi 6309 Hitachi variant of the Motorola 6809 8-bit microprocessor.

The 6309 is Hitachi's CMOS version of the Motorola 6809 microprocessor, released in late 1982. It was initially marketed as a low-power version of the 6809, without reference to its many internal improvements.

Interrupt Signal to a computer processor emitted by hardware or software

In digital computers, an interrupt is a request for the processor to interrupt currently executing code, so that the event can be processed in a timely manner. If the request is accepted, the processor will suspend its current activities, save its state, and execute a function called an interrupt handler to deal with the event. This interruption is often temporary, allowing the software to resume normal activities after the interrupt handler finishes, although the interrupt could instead indicate a fatal error.

MOS Technology 6502 8-bit microprocessor

The MOS Technology 6502 is an 8-bit microprocessor that was designed by a small team led by Chuck Peddle for MOS Technology. The design team had formerly worked at Motorola on the Motorola 6800 project; the 6502 is essentially a simplified, less expensive and faster version of that design.

Motorola 6809 8-bit microprocessor

The Motorola 6809 ("sixty-eight-oh-nine") is an 8-bit microprocessor with some 16-bit features. It was designed by Motorola's Terry Ritter and Joel Boney and introduced in 1978. Although source compatible with the earlier Motorola 6800, the 6809 offered significant improvements over it and 8-bit contemporaries like the MOS Technology 6502, including a hardware multiplication instruction, 16-bit arithmetic, system and user stack registers allowing re-entrant code, improved interrupts, position-independent code and an orthogonal instruction set architecture with a comprehensive set of addressing modes.

Zilog Z80 8-bit microprocessor

The Z80 is an 8-bit microprocessor introduced by Zilog as the startup company's first product. The Z80 was conceived by Federico Faggin in late 1974 and developed by him and his 11 employees starting in early 1975. The first working samples were delivered in March 1976, and it was officially introduced on the market in July 1976. With the revenue from the Z80, the company built its own chip factories and grew to over a thousand employees over the following two years.

x86 assembly language is the name for the family of assembly languages which provide some level of backward compatibility with CPUs back to the Intel 8008 microprocessor, which was launched in April 1972. It is used to produce object code for the x86 class of processors.

Addressing modes are an aspect of the instruction set architecture in most central processing unit (CPU) designs. The various addressing modes that are defined in a given instruction set architecture define how the machine language instructions in that architecture identify the operand(s) of each instruction. An addressing mode specifies how to calculate the effective memory address of an operand by using information held in registers and/or constants contained within a machine instruction or elsewhere.

ANTIC

Alphanumeric Television Interface Controller (ANTIC) is an LSI ASIC dedicated to generating 2D computer graphics to be shown on a television screen or computer display. Under the direction of Jay Miner, the chip was designed in 1977-1978 by Joe Decuir, Francois Michel, and Steve Smith for the Atari 8-bit family of home computers first released in 1979 and was patented by Atari, Inc. in 1981. ANTIC is also used in the Atari 5200 video game system released in 1982, which shares most of the same hardware as the 8-bit computers.

Intel 8259

The Intel 8259 is a Programmable Interrupt Controller (PIC) designed for the Intel 8085 and Intel 8086 microprocessors. The initial part was 8259, a later A suffix version was upward compatible and usable with the 8086 or 8088 processor. The 8259 combines multiple interrupt input sources into a single interrupt output to the host microprocessor, extending the interrupt levels available in a system beyond the one or two levels found on the processor chip. The 8259A was the interrupt controller for the ISA bus in the original IBM PC and IBM PC AT.

WDC 65C02 CMOS microprocessor in the 6502 family

The Western Design Center (WDC) 65C02 microprocessor is an enhanced CMOS version of the popular nMOS-based 8-bit MOS Technology 6502. The 65C02 fixed several problems in the original 6502 and added some new instructions, but its main feature was greatly lowered power usage, on the order of 10 to 20 times less than the original 6502 running at the same speed. The reduced power consumption made the 65C02 useful in portable computer roles and microcontroller systems in industrial settings. It has been used in some home computers, as well as in embedded applications, including medical-grade implanted devices.

WDC 65C134

The Western Design Center (WDC) W65C134S is an 8-bit CMOS microcontroller based on a W65C02S processor core, which is a superset of the MOS Technology 6502 processor.

WDC 65C51

The CMOS W65C51 Asynchronous Communications Interface Adapter (ACIA) provides an easily implemented, program controlled interface between microprocessor based systems and serial communication data sets and modems. It is produced by Western Design Center (WDC) and is a drop-in replacement for the MOS Technology 6551.

WDC 65C265

The Western Design Center (WDC) W65C265S is a 16-bit CMOS microcontroller based on a W65C816S processor core, which is a superset of the MOS Technology 6502 processor.

The Ricoh 5A22 is an 8/16-bit microprocessor produced by Ricoh for the Super Nintendo Entertainment System (SNES) video game console. It is based on the 8/16-bit WDC 65C816, which was developed between 1982 and 1984 for the Apple IIGS personal computer. It has 92 instructions, an 8-bit data bus, a 16-bit accumulator, and a 24-bit address bus. The CPU runs between 1.79 MHz and 3.58 MHz, and uses an extended MOS Technology 6502 instruction set.

The CSG 65CE02 is an 8/16-bit microprocessor developed by Commodore Semiconductor Group in 1988. It is a member of the MOS Technology 6502 family, developed from the CMOS WDC 65C02 released by the Western Design Center in 1983.

The Mitsubishi 740, also known as MELPS 740, is a series of 8-bit CMOS microcontrollers and microprocessors with an enhanced MOS Technology 6502 compatible core based on the expanded WDC 65C02. The ICs were manufactured by Mitsubishi Electric during the 1980s and 1990s.

The 9S08 is a 8-bit microcontroller (µC) family originally produced by Motorola, later by Freescale Semiconductor, and currently by NXP, descended from the Motorola 6800 microprocessor. It is a CISC microcontroller. A slightly extended variant of the 68HC08, it shares upward compatibility with the aging 68HC05 microcontrollers, and is found in almost any type of embedded systems. The larger members offer up to 128 KiB of flash, and 8 KiB of RAM via a simple MMU which allows bank-switching 16 KiB of the address space and an address/data register pair which allows data fetches from any address. The paging scheme used allows for a theoretical maximum of 4MB of flash.

The PDP-11 architecture is a CISC instruction set architecture (ISA) developed by Digital Equipment Corporation (DEC). It is implemented by central processing units (CPUs) and microprocessors used in PDP-11 minicomputers. It was in wide use during the 1970s, but was eventually overshadowed by the more powerful VAX-11 architecture in the 1980s.

ST6 and ST7

The ST6 and ST7 are 8-bit microcontroller product lines from STMicroelectronics. They are commonly used in small embedded applications like washing machines.

WDC 65C816 8/16-bit microprocessor

The W65C816S is an 8/16-bit microprocessor (MPU) developed and sold by the Western Design Center (WDC). Introduced in 1983, the W65C816S is an enhanced version of the WDC 65C02 8-bit MPU, itself a CMOS enhancement of the MOS Technology 6502 NMOS MPU. The 65C816 was the CPU for the Apple IIGS and, in modified form, the Super Nintendo Entertainment System.

References

  1. 1 2 3 4 5 Anderson, J. S. (1994). Microprocessor Technology . Butterworth-Heinemann. pp. 143–144. ISBN   9780750618397.
  2. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 David Eyes and Ron Lichty (1992-04-28). "Programming the 65816" (PDF). The Western Design Center, Inc. Archived from the original (PDF) on 2012-07-23. Retrieved 2012-11-29.
  3. 1 2 "Basic Architecture". 6502. 2002-01-02.
  4. 1 2 Leo J. Scanlon (1980). 6502 Software Design . H. W. Sams. pp.  172–173. ISBN   9780672216565.
  5. 1 2 3 Lance A. Leventhal (1986). 6502 Assembly Language Programming. Osborne/McGraw-Hill. ISBN   9780078812163.
  6. Ronald J. Tocci and Lester P. Laskowski (1979). Microprocessors and Microcomputers: Hardware and Software . Prentice-Hall. p.  379. ISBN   9780135813225.
  7. Kuckes, Arthur F.; Thompson, B. G. (1987). Apple II in the Laboratory. UP Archive. p.  93. ISBN   9780521321983. LCCN   86-21531.
  8. Harrod, Dennette A. (October 1980). "6502 Gets Microprogrammable Instructions". BYTE . Vol. 5, no. 10. McGraw Hill. pp. 282–285. Archived from the original on 2006-05-25. Retrieved 2009-05-31.
  9. Richard R. Smardzewski (1984). Microprocessor Programming and Applications for Scientists and Engineers . Elsevier. p.  125. ISBN   9780444424075.

Further reading