Syncopated Systems™
Seriously Sound Science™
|
Home | Services | Case Studies | About | Library | Contact |
The 6502 MicroprocessorRecently—in 2024—while seeking information for another project, I noticed that the information available online about the 6502 was incomplete and/or poorly presented, even from some of the best sources, such as 6502.org. So, I made a web-friendly—all HTML—version of Synertek’s printing of the MOS Technology 6500 Family Programming Manual, which I expand upon herein. The microcomputer revolution started in 1977 with the introduction of the Atari Video Computer System (VCS)—later known as the Atari 2600—and Byte Magazine’s “1977 Trinity” of home computers: Apple II, Commodore PET 2001, and Tandy/Radio Shack TRS-80. Most of these machines—and many that followed—were made possible by the 6502 (“sixty-five oh two”) family of microprocessors created by MOS Technology in 1975 and manufactured by it and by others (“second sources”) including Rockwell International and Synertek. (That year MOS Technology was acquired by Commodore, securing a supply chain for its desktop calculators.) The 6502 was the CPU in both the Apple II and the Commodore PET (and later Commodore’s 1980 VIC-20 and 1982 CBM-II). Variants of the 6502 were used in machines including the Atari 2600 VCS, which used a 6507 as its CPU and popularized cartridge-based video games. (These were introduced the previous year, in 1976, by the Fairchild Channel F Video Entertainment System, or VES, which used a Fairchild F8 microprocessor as its CPU.) Released in 1979, Atari’s line of 8-bit home computers (starting with models 400 and 800) entered production using a revised 6502, the 6502B made by Synertek (Atari part number C014377-03), while later units and their following models used a custom 6502 variant that Atari named Sally (Atari part number C014806), which appears to be the basis for the 6502C. (Note that the “C” suffix indicates the third revision—and fourth version—of the mainstream 6502, not the 65C02, which was a CMOS version.) While in college I tested games for Mediagenic—the company merged from Activision, Infocom, and others—for PCs and the 1985 Nintendo Entertainment System, which used variants of the 6502 made by Ricoh. Later, while working for video game developer Iguana Entertainment—and moving with it to Austin, Texas—I created interface hardware to enable software-development, including versions for its 1990 successor, the Super Nintendo Entertainment System (SNES), which for its CPU used a modernized derivative of the 6502 based on the Western Design Center (WDC) 65C816 (“sixty-five-see-eight-sixteen”) released in 1983. (The 65C816 was also the CPU in the Apple IIgs released in 1986, which I saw in use at Mediagenic for early development of SNES games.) Roots in the Motorola 6800The 6502 and its many varieties were economical alternatives to the Motorola 6800, and created by many of the designers of the 6800; a short-lived twin of the 6502, the 6501 was pin-compatible with the 6800 (though not software-compatible) until its sales were ended by legal action from Motorola. Based in Valley Forge, Pennsylvania, MOS Technology was formed in 1969 by three former executives of General Instrument. After Motorola released its 6800 (“sixty-eight hundred”) microprocessor in 1974, several of its former designers wished not to be relocated by Motorola from Mesa, Arizona to Austin, Texas. So, they instead joined MOS Technology and in 1975 they created both the 6502 and its sibling the 6501 as simpler, lower-cost, and higher-performance alternatives to the 6800. Though neither the 6501 nor 6502 were compatible with 6800 software, the 6501 could be used as a pin-compatible replacement for the 6800. Both the 6501 and the 6502 were designed to be compatible with support chips for the 6800; for example, the 1976 Apple Computer 1 included both a 6502 CPU and a 6820 PIA (peripheral interface adapter). In September 1975, the 6501 and the 6502 cost only $20 and $25 (respectively), prompting Motorola in October 1975 to reduce the price of its 6800 from $175 to $69. In November 1975, Motorola sued MOS Technology, seeking injunction to stop MOS Technology from making and selling microprocessors, claiming patent infringement and misappropriation of trade secrets through seven of its former employees who joined MOS Technology. The pin-compatible 6501 did not survive. (I recall that, when I was a kid becoming interested in computers circa 1980, one of my favorite stores carried adapter modules that would allow a 6502 to be plugged into a circuit board designed for a 6800 microprocessors, allowing a 6502 to nearly mimic the functions of a 6501.) MOS Technology was acquired in November 1976 by Commodore International (parent of Commodore Business Machines, which later made the PET, VIC-20, Commodore 64, and others), with the condition that the 6502 designer Chuck Peddle would become Commodore’s chief engineer. (I was lucky enough to meet Chuck Peddle briefly in 2016.) ArchitectureThe 6502 design follows the Von Neumann (Princeton) architecture pattern (established in 1945), which essentially doesn’t differentiate between addresses used for instructions and those used for data, as is done by those that follow Harvard architecture. While operating, a microprocessor such as the 6502 follows a program, which is just an ordered list of instructions and operands. It copies data between externally-addressable locations and its registers. A 6502’s registers include an accumulator, X index, Y index, program counter (high byte and low byte), stack pointer (high byte and low byte), and processor status (a collection of bit flags). The external locations generally include random-access memories (usually including read-only memory, or ROM) and devices that provide interfaces for performing useful functions through sensing and controlling various signals. With this data, the microprocessor determines which outputs to provide when it receives certain inputs. These often affect which paths of the program are executed and which arithmetic operations are performed in the process. Processor Status RegisterThe 6502’s processor status register uses 7 bits as flags to detect and enable certain conditions. These flags are arranged in the order { N V E B D I Z C }, further described in the following table.
The individual flags or bits are often presented in a form as the following figure.
The meanings and functions of the bits are as follows. Carry Flag (C)The carry bit which is modified as a result of specific arithmetic operations or by a set or clear carry command has been discussed previously. In the case of shift and rotate instruction, the carry bit is used as a ninth bit as it is in the arithmetic operation. The carry flag can be set (to 1) or cleared (to 0) by the programmer. A SEC instruction will set and a CLC instruction will clear the carry flag. Operations which affect the carry are ADC, ASL, CLC, CMP, CPX, CPY, LSR, PLP, ROL, RTI, SBC, SEC. Zero Flag (Z)This flag is automatically set by the microprocessor during any data movement or calculation operation when the 8 bits of results of the operation are 0. Therefore, the bit is on (“1”) when the results are 0, and off (“0”) when the results are not equal to 0. The feature of the machine is similar to that of the PDP-11 in the sense that operations which are decrementing index registers or memory locations have a built-in test for 0 as a result of decrementing to the 0 condition. It is also possible to test for 0 condition immediately following load and other logical operations, as opposed to processors which have to do a test and branch instruction. The Z flag is not directly settable or resettable by an instruction but is affected by the following instructions: ADC, AND, ASL, BIT, CMP, CPY, CPX, DEC, DEX, DEY, EOR, INC, INX, INY, LDA, LDX, LDY, LSR, ORA, PLA, PLP, ROL, RTI, SBC, TAX, TAY, TXA, and TYA. Interrupt Disable (I)The interrupt disable is a flip-flop made use of by the programmer and by the microprocessor to control the operations of the interrupt request pin. A more detailed discussion of the effects of the interrupt disable are given in the discussion under interrupt control. However, the purpose of the interrupt disable is to disable the effects of the interrupt request pin. The interrupt disable, I, is set by the microprocessor during reset and interrupt commands. The I bit is reset by the CLI instruction or the PLP instruction, or at a return from interrupt in which the interrupt disable was reset prior to the interrupt. The interrupt flag may be set by the programmer using a SEI instruction and is cleared by the programmer by using a CLI instruction. Instructions which affect the interrupt disable are BRK, CLI, PLP, RTI, and SEI. Decimal Mode Flag (D)As discussed, the use of the decimal mode flag is to control whether or not the adder operates as a straight binary adder for add and subtract instructions or as a decimal adder for add and subtract instructions. The SED instruction sets the flag and the CLD instruction resets it. The only instructions which affect the decimal mode flag are CLD, PLP, RTI, and SED. Break Command (B)The break command flag is set only by the microprocessor and is used to determine during an interrupt service sequence whether or not the interrupt was caused by BRK command or by a real interrupt. A more detailed discussion of BRK is in the interrupt section. This bit should be considered to have meaning only during an analysis of a normal interrupt sequence. There are no instructions which can set or which reset this bit. Expansion Bit (E)The next bit in the flag register is an unused bit. It is most likely that this bit will appear to be on when one is analyzing the bit pattern in the processor status register; however, no guarantee as to its state is made as this bit will be used in expanded versions of the microprocessor. Overflow (V)As discussed in the section on arithmetic operations, if one is to look at the binary arithmetic operations as signed binary operations, there needs to be some indication of the fact the result of the arithmetic operation has a greater value than could be contained in the 7 bits of the result. This bit is the overflow bit and during ADC and SEC instructions represents a status of an overflow into the sign position. The user who is not using signed arithmetic can totally ignore this flag during his their programming; however, this flag has the same meaning as the carry to the user who is using signed binary numbers. It indicates that a sign correction routine must be used if this bit is'on after an add or subtract using signed numbers. In addition to its use to monitor the validity of the sign bit in ADC and SBC instructions, the overflow flag in the MCS650X products is dramatically changed from PDP-11 and the MC6800. In those systems the overflow flag was very carefully controlled so as to allow certain signed branches for analysis of signed numbers. These branches have been deleted from the MCS6500 series because of confusion and difficulty often associated with using them, and so therefore, the overflow flag is applicable only to the operation of ADC and SBC, and then only when using signed numbers. However, in order to maximize the effectiveness of this testable flag the BIT instruction which may be used to sample interface devices, allows the overflow flag to reflect the condition of bit 6 in the sampled field. During a BIT instruction the overflow flag is set equal to the content of the bit 6 on the data tested with BIT instruction. When used in this mode, the overflow has nothing to do with signed arithmetic but is just another sense bit for the microprocessor. Instructions which affect the V flag are ADC, BIT, CLV, PLP, RTI, and SBC. On certain versions of the microprocessor the V bit will also be available for stimulus from the outside world. Negative Flag (N)As already discussed, one of the uses of the microprocessor is to perform arithmetic operations on signed numbers. To allow the user to readily sample the status of the sign bit (bit 7), the N flag is set equal to bit 7 of the resulting value in all data movement and data arithmetic. This means, for instance, after a signed add one can determine the sign of the result by sampling the N flag directly rather than finding a way to isolate bit 7. Although signs were the primary purpose for which the N flag was intended, its usefulness far exceeds that of strictly a sign bit. Because of every operation including simple moves and add operations the N bit is equal to the status of bit 7 as a result of the operation; its primary use becomes that of an easily testable bit. AlmOSt all single-bit instructions, all interrupts and all I/O status flags use bit 7 as a sense bit. This allows the user to perform some type of memory access operation such as Load A followed by immediate conditional branch based on the status of bit 7 as reflected in the N flag. Like the Z bit, this flag is not settable or controllable by the programmer and represents the status of the last data movement operation. Instructions which affect the negative flag are ADC, AND, ASL, BIT, CMP, CPY, CPX, DEC, DEX, DEY, EOR, INC, INX, INY, LDA, LDX, LDY, LSR, ORA, PLA, PLP, ROL, SBC, TAX, TAY, TSX, TXA, and TYA. Flag SummaryTo summarize, the microprocessor treats a series of flags or status bits as a single register called the “P” or “Program Status” register. Some of these flags are controllable only by the programmer (such as the D flag); others are controllable by both the user program and microprocessor (such as the interrupt disable flag). Some of them are set and reset by almost every processor operation, such as the N and Z flags. Each of these flags has its own meaning to the programmer at a particular point in time. When combined with the concept of conditional branches, they represent a powerful test and jump capability not normally found in a machine of this magnitude. Other than perhaps the carry flag which is used as part of the arithmetic instructions, the flags by themselves have relatively little meaning unless one has the ability to test them. For this purpose there is a series of conditional branch instructions designed into the machine. Instruction SetTo perform its operations, the 6502 uses a set of 56 instructions. (The first version of the 6502 had only 55 instructions, with the ROR instruction added after June 1976.) Each instruction is given a mnemonic abbreviation. To help distinguish them from operands, labels, and other parts of the program code, the 6502 designers uniformly use three letters to abbreviate each instruction, as listed in the following table. Instruction GroupsThe 65XX microprocessor instruction set is divided into three basic groups:
There are eight Group One instructions, eight Group Two instructions, and all of the 39 remaining instructions are Group Three instructions. The three groups are obtained by organizing the OPCODE pattern to give maximum addressing flexibility (l6 addressing combinations) to Group One, to give eight combinations to Group Two instructions and the Group Three instructions are basically individually decoded. Group One InstructionsThese instructions are: Add With Carry (ADC), (AND), Compare (CMP), Exclusive Or (EOR), Load A (LDA), Or (ORA), Subtract With Carry (SBC), and Store A (STA). Each of these instructions has a potential for 16 addressing modes. However, in the MCS6501 through MCS6505, only eight of the available modes have been used. Addressing modes for Group One are: Immediate, Zero Page, Zero Page Indexed by X, Absolute, Absolute Indexed by X, Absolute Indexed by Y, Indexed Indirect, Indirect Indexed. The unused eight addressing modes are to be used in future versions of the MCS650X product family to allow addressing of additional on-chip registers, of on-chip I/O ports, and to allow two byte word processing. Group Two InstructionsGroup Two instructions are primarily Read, Modify, Write instructions. The primary function of Group Two instructions is to perform some memory operation using the appropriate index. Each Group One instruction may use all addressing modes (except Immediate mode is not used by STA), which ; in addition to these, Group Two instructions add an addressing mode for the accumulator and other special decodes in this basic group. There are two subcatagories within the Group Two instructions. The first subcategory includes the shift and rotate instructions Logical Shift Right (LSR), Arithmetic Shift Left (ASL), Rotate Left (ROL), and Rotate Right (ROR). The four shift instructions all have register A operations. The second subcategory includes the Increment (INC) and Decrement (DEC) instructions and the additional index register X instructions Load X (LDX), Store X (STX), Load X from A (assigned its own mnemonic, TAX), TXS, TSX, and the special function of Decrement X (DEX), which is one of the special cases of Store X (STX). (The location of NOP suggests it should be included in this subcategory.) These instructions would normally have eight addressing modes available to them because of the bit pattern. However, to allow for upward expansion, these instructions have only the following addressing modes defined: Zero Page, Zero Page Indexed by X, Absolute, Absolute Indexed by X, and a special Accumulator (or Register) mode. The incremented or decremented Load X and Store X instructions also have accumulator modes although Increment Accumulator and Decrement Accumulator have been reserved for other purposes (NOP and DEX). It should be noted for documentation purposes that the X instructions have a special mode of addressing in which register Y is used for all indexing operations; thus, instead of Zero Page Indexed by X, X instructions have Zero Page Indexed by Y, and instead of having Absolute Indexed by X, X instructions have Absolute Indexed by Y. Group Three InstructionsThere are two major classifications of Group Three instructions. Occupying about half of the OPCODE space for the Group Three instructions are Compare X (CPX) and the instructions that modify the Y index register: Load Y (LDY), Store Y (STY), Compare Y (CPY). Increment X (INX) and Increment Y (INY) are special subsets of the Compare X (CPX) and Compare Y (CPY) instructions. All of the branch instructions—BCC, BCS, BEQ, BMI, BNE, BPL, BVC, and BVS— are in Group Three and use only the Relative addressing mode. All of the flag operations—CLC, SEC, CLD, SED, CLI, SEI, and CLV— are in Group Three and use only use only the Implied addressing mode. All of the push and pull instructions—PHA, PHP, PLA, and PLP— and [other] stack operation instructions—BRK, JSR, RTI, and RTS— are Group Three instructions. (Note that I add RTI and RTS to the “stack” subgroup.) The JMP and BIT instructions are also included in this group. There is no common addressing mode available to members of this group. Load Y, Store Y, BIT, Compare X and Compare Y have Zero Page and Absolute. All of the Y and X instructions allow Zero Page Indexed operations and Immediate. Instruction List, Alphabetic by Mnemonic Definition of Instruction GroupsMCS6501-MCS6505 Microprocessor Instruction Set – Alphabetic Sequence
Addressing ModesEach instruction uses one or more addressing mode(s). The addressing modes used by the 6502 include those in the table below. Note that the number of bytes required for each instruction depends on the addressing mode and includes one byte for the opcode and one byte or two bytes for operands, depending on the addressing mode. The table below includes the full name of each operating mode. Words and terms often ommitted appear in brackets. The colors in the table are used to identify and highlight addressing modes of opcodes in tables that follow. Note that a “pointer” is a memory address that contains another memory address that identifies the location of a value. (An intermediate location is used to locate a value indirectly; this method of locating values is called indirection.)
OpcodesMicroprocessors use a unique number to represent each combination of instruction and addressing mode available for its use. Each of these numbers is called an operation code, which is frequently abbreviated as “opcodes”. (In short: instruction + addressing mode = opcode .) Like other microprocessors (especially of such early and economical design), the 6502 uses single 8-bit bytes to encode both the function of each operation to be performed and which addressing mode(s) to use with it. Microprocessors such as the 6502 store their opcodes as single 8-bit bytes, so they can have can have up to 256 (28) opcodes. For its 56 instructions and their variants, the 6502 uses only 151 of the 256 possible opcodes. (In contrast, the more-expensive Motorola 6800—a precessor to the 6502 that shared many of its designers—included 197 opcodes to represent its 72 instructions and the various addressing modes that it may use.) Please note that the opcodes described herein apply to the 6500 family including 6502 and 6502B, but not next-generation variants from the Western Design Center (WDC) such as the CMOS 65C02. Opcode MapsThe instructions and their variations have often been presented in tables often called “opcode maps”. These generally present terse information about each opcode (a mnemonic abbreviation and sometimes more) often in square tables of 16 columns by 16 rows, arranged in numerical order based on each opcode number’s lowest 4 bits (corresponding to the least-significant of its two hexadecimal digits) along one axis and the highest 4 bits (the most-significant digit, or MSD) along the other. (Groups of consecutive 4 bits are sometimes referred to as a digit, nibble, or nybble—the last two apparently differentiated by whether one sees such a digit as a collection of four “bits” or half of a “byte”, respectively.)
Notes: In the table above, dark gray areas indicate operation codes that are undefined for the 6502. In the table above and those that follow, opcodes that use addressing modes that deviate from the pattern are denoted with thick black borders. The Other ValuesOf the 256 possible values that could be presented to the 6502 as an opcode, its designers defined only 151 values as valid opcodes. I refer to the remaining 105 herein simply as “extra opcodes”, though some describe them using terms such as “illegal opcodes”, “invalid instructions”, “undefined”, “undocumented instructions”, “unimplemented operations”, “unintended opcodes”, or “unofficial”. (To differentiate the mneumonic abbreviations of extra opcodes, I enclose them in brackets.) For these extra opcodes, I rely on data (and reproduce text directly) from Extra Instructions Of The 65XX Series CPU by Adam Vardy, who cites Joel Shepherd (“Extra Instructions”, COMPUTE!, October 1983), Raymond Quirling (“6510 Opcode” The Transactor, March 1986), Jim Butterfield (“Strange Opcodes”, COMPUTE!, March 1993), and John West with Marko M„kel„ (“64doc” file, 1994/06/03). Extra Instructions, Alphabetic by Mnemonic Definition of Instruction GroupsSee also the alphabetic list of non-extra opcodes. The following summary of 22 extra instructions (plus apparent extensions of two non-extra instructions) uses the same notation used for other opcodes. Note that 18 of the 22 extra instructions use opcodes in the fourth group of opcodes (outside the three groups containing non-extra opcodes); the other instructions are marked with an asterisk (*).
* Not in Group 4 Hazards of the Extra OpcodesIf a 6502 seeking an opcode for its next instruction should instead encounter one of theese extra values, its behavior could be unpredictable and possibly undesirable, such as halting operation until it is turned off and on again. This problem is compounded by the many variants within the 6500 family and potential variations in their implementations and processes used by their many different manufacturers, which could also change over time. (Notably, 6500 family devices did not include the ROR instruction until after June 1976.) Still, some intrepid programmers could find utility in using them (hopefully only under very well-controlled conditions), and examining these extra opcodes could provide a glimpse of insight into the 6502’s inner workings and/or a roadmap for expanding functions of future devices. Mapping All of the Possible OpcodesThe extra opcodes fill in the opcode map, as in the table below.
Notes: Opcode RelationshipsWith the 6502 microprocessor (and likely others), opcode maps such as those above obscure the relationships between many opcodes. In the 6502, the 8 bits of an opcode (with the most-significant bit first, on the left) can be described as following the pattern AAABBBCC, where BBB represents the addressing mode, CC indicates the instruction group (except CC = 00 represents “Group 3” rather than a “Group 0”), and the remaining bits AAA specify the instruction to be performed. So, alternate presentations of the opcode maps seem worthwhile. Grouping Opcodes by Addressing ModeOpcodes with the same addressing modes can be grouped together by re-grouping the rows based on the value of bit 5, putting those with an even-numbered most-significant byte (MSB) at the top and those using odd numbers at the bottom. This reveals potential subsets in the upper two quarters, and some grouping among special cases in the fourth quarter.
Notes: Opcodes by Group and Addressing ModeThe 6502 opcodes seem even easier to understand when the bits in the opcode are re-ordered from AAABBBCC into rows by group and instruction as CCAAA and in columns by addressing mode BBB. (For simplicity, I keep the bits within those groups in their original order. I also don’t invert any bits; doing so is sometimes useful to aid understanding, but not in this case.) Applying this transformation to the above opcode map tables, the top half of every fourth column (starting from x0) form the left half of Group 3, and the bottom half of every fourth column form the left half of Group 3, as they appear at the top of the the table below. Similarly, following this pattern for opcodes from columns x1, x2, and x3 form Group 1, Group 2, and a new group containing only extra opcodes, which could be treated as a new Group 4. For example, the instruction for No Operation (NOP) is represented numerically as hexadecimal 0xEA or binary 1110 1010. Divided into groups using the pattern AAABBBCC, this is 111 010 10. Swapping the order of groups AAA and CC yields binary 10 111 (decimal 23) with the address mode remaining in group BBB as 010 (decimal 2), which in the following table correlate to the headings for rows and columns, respectively. The following table uses the same color codings (for addressing modes and instruction types) and the thick black borders (indicating instructions that deviate somewhat from the pattern) as in the previous opcode map tables.
Notes: Opcode TotalsThe table below summarizes opcode groups and some color codes used for backgrounds used for some opcodes in the table above. (Their addressing modes are coded based on colors in a previous table.)
What Opcode Relationships RevealSome opcodes reveal shadowing, which is an artifact of course decoding (the use of only enough logic to locate something at a desired location within a certain numerical space, but not enough to filter out its appearence at other locations). Some opcodes enable inferences about internal structures such as connections of data buses, etc. Instructions – Alphabetic by Mnemonic with Opcodes, Execution Cycles and Memory RequirementsSee also the alphabetic list of extra opcodes. The following notation applies to this summary:
Note: Following each table (except for NOP) is a copy of the Section in the MCS6500 Microcomputer Family Programming Manual (1975 First Edition) in which the instruction is defined and discussed.
Operation: A + M + C → A, C
This instruction adds the value of memory and carry from the previous operation to the value of the accumulator and stores the result in the accumulator. The symbolic representation for this instruction is A + M + C → A. It is a “Group One” instruction and has the following addressing modes: Immediate; Absolute; Zero Page; Absolute,X; Absolute,Y; Zero Page,X; Indexed Indirect; and Indirect Indexed. State Dependencies and Changes
ADC does not affect X, Y, S, PC, nor bits { B, D, I }. ExpositionThe ninth bit of the result is stored in the carry flag and the remaining 8 bits reside in the accumulator. The carry flag can be thought of as a flag bit which is remote from the accumulator itself but which is directly affected by accumulator operations as though it were a ninth bit in the accumulator. The primary reason for not viewing the carry bit as merely a ninth bit in the accumulator is that one has program control over its state by being able to set (to “1”) or clear (to “0”) the bit and, of course, it is not part of the 8-bit accumulator in data transfer operations. Examples employing the Add with Carry operation follow.
*(A) and (M) refer to the “contents” of the accumulator and “contents” of memory respectively.
While the accumulator contains “5,” the carry flag signals the user that the result exceeded 255 and, therefore, the result can be properly interpreted as 256 + 5 = 261.
Operation: A ∧ M → A
Logical AND to the accumulator The AND instructions transfer the accumulator and memory to the adder which performs a bit-by-bit AND operation and stores the result back in the accumulator. This is symbolically represented by A ∧ M → A. AND is a “Group One” instruction having addressing modes of Immediate; Absolute; Zero Page; Absolute,X; Absolute,Y; Zero Page,X; Indexed Indirect; and Indirect Indexed. State Dependencies and Changes
AND does not affect X, Y, S, PC, nor bits { V, B, D, I, C }. ApplicationsOne of the uses for the AND operation is that of clearing a bit in memory. In the example below, a byte is loaded into the accumulator and the AND instruction clears the accumulator bit 3 to 0. The accumulator is then stored back into memory, thereby clearing the bit.
Operation: C ← 76543210 ← 0
The shift left instruction shifts either the accumulator or the address memory location 1 bit to the left, with the bit 0 always being set to 0 and the bit 7 output always being contained in the carry flag. ASL either shifts the accumulator left 1 bit or is a read/modify/write instruction that affects only memory. The symbolic notation for ASL is
ASL is a read/modify/write instruction and has the following address ing modes: Accumulator; Zero Page; Zero Page,X; Absolute; Absolute,X State Dependencies and Changes
ASL does not affect X, Y, S, PC, nor bits { V, B, D, I }.
Operation: Branch on C = 0
This instruction tests the state of the carry bit and takes a conditional branch if the carry bit is clear (0). The addressing mode is Relative. State Dependencies and ChangesBCC affects no flags or registers other than the program counter and then only if the C flag is not on.
BCC does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: Branch on C = 1
This instruction takes the conditional branch if the carry flag (C) is set (1). The addressing mode is Relative. State Dependencies and ChangesBCS does not affect any of the flags or registers except for the program counter and only then if the carry flag is on.
BCS does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: Branch on Z = 1
BEQ is the complementary branch to Branch on Result Not Equal (BNE). BEQ could also be called “Branch on result zero”. It takes a conditional branch whenever the Z flag is on or the previous result is equal to 0. The addressing mode is Relative. State Dependencies and ChangesBEQ does not affect any of the flags or registers other than the program counter and only then when the Z flag is set.
BEQ does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: A ∧ M, M7 → N, M6 → V
Bit 6 and bit 7 are transferred to the status register. If the result of A ∧ M is zero then Z = 1; otherwise Z = 0 This instruction performs an AND between a memory location and the accumulator but does not store the result of the AND into the accumulator. The symbolic notation is A ∧ M. The addressing modes are Zero Page and Absolute. State Dependencies and Changes
BIT does not affect A, X, Y, S, PC, nor bits { B, D, I, Z }. ExpositionThe BIT instruction actually combines two instructions from the PDP-11 and MC6800, that of TST (Test Memory) and (BIT Test). This, like the compare test, allows the examination of an individual bit without disturbing the value in the accumulator and is illustra ted by the example below:
The value “MASK” loaded into the accumulator in this example is actually a descriptive title since, this byte is 8 bits, only one of which is a 1. Using this byte in the AND operation inherent in the BIT test will effectively mask out all bits in the memory location under test except that bit position corresponding to the 1 residing in the accumulator. In Example 4.8, the MASK byte is AND'ed to the data found in location ADHl, ADLl and if the bit under test is a l, the branch will be taken; if not a l, the second memory location will be tested with the same mask, etc. In addition to the nondestructive feature of the bit which allows us to isolate an individual bit by use of the branch equal or branch no equal test, two modifications to the PDP-11 version of that instruction have been made in the MCS650X microprocessor. These are to allow a test of bit 7 and bit 6 of the field examined with the BIT test. This feature is particularly useful in serving polled interrupts and particularly in dealing with the MCS6520 (Peripheral Interface Device). This device has an interrupt sense bit in bit 6 and bit 7 of the status words. It is a standard of the MC6800 bus that whenever possible, bit 7 reflects the interrupt status of an I/O device. This means that under normal circumstances, an analysis of the N flag after a load or BIT instruction should indicate the status of the bit 7 on the I/O device being sampled. To facilitate this test using the Bit instruction, bit 7 from the memory being tested is set into the N flag irrespective of the value in the accumulator. This is different from the bit instruction in the MC6800 which requires that bit 7 also be set on the accumulator to set N. The advantage to the user is that if he they decides to test bit 7 in the memory, it is done directly by sampling the N bit with a Bit followed by branch minus or branch plus instruction. This means that 1/0 sampling can be accomplished at any time during the operation of instructions irrespective of the value preloaded in the accumulator. Another feature of the BIT test is the setting of bit 6 into the V flag. As indicated previously, the V flag is normally reserved for overflow into the sign position during an add and subtract instruction. In other words, the V flag is not disturbed by normal instructions. When the BIT instruction is used, it is assumed that the user is trying to examine the memory that he is they are testing with the BIT instruction. In order to receive maximum value from a BIT instruction, bit 6 from the memory being tested is set into the V flag. In the case of a normal memory operation, this just means that the user should organize his their memory such that both of his their flags to be tested are in either bit 6 or bit 7, in which case an appropriate mask does not have to be loaded into the accumulator prior to implementing the BIT instruction. In the case of the MCS6520, the BIT instruction can be used for sampling interrupt, irrespective of the mask. This allows the programmer to totally interrogate both bit 6 and bit 7 of the MCS6520 without disturbing the accumulator. In the case of the concurrent interrupts, i.e., bit 6 and bit 7 both on, the fact that the V flag is automatically set by the BIT instruction allows the user to postpone testing for the “6th bit on” until after he has they have totally handled the interrupt “for bit 7 on” unless he they performs an arithmetic operation subsequent to the BIT operation.
Operation: Branch on N = 1
BMI is the complementary branch to Branch on Result Plus (BPL). BMI takes the conditional branch if the N bit is set. The mode of addressing for BMI is Relative. State Dependencies and ChangesBMI does not affect any of the flags or any other part of the machine other than the program counter and then only if the N bit is on.
BMI does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: Branch on Z = 1
BNE is the complementary branch to Branch on Result Equal (BEQ). BNE could also be called “Branch on result not zero”. It tests the Z flag and takes the conditional branch if the Z flag is not on, indicating that the previous result was not zero. The addressing mode is Relative. State Dependencies and Changes
BNE does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: Branch on N = 0
BPL is the complementary branch to Branch on Result Minus (BMI). BPL is a conditional branch which takes the branch when the N bit is clear (0). BPL is used to test if the previous result bit 7 was off (0) and Branch on Result Minus is used to determine if the previous result was minus or bit 7 was on (1). The addressing mode is Relative. State Dependencies and ChangesThe instruction affects no flags or other registers other than the P counter and only affects the P counter when the N bit is clear (0).
BPL does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: Forced Interrupt PC + 2 ↓ P ↓
The Break command causes the microprocessor to go through an interrupt sequence under program control. This means that the program counter of the second byte after the BRK is automatically stored on the stack along with the processor status at the beginning of the break instruction. The microprocessor then transfers control to the interrupt vector. Note: A BRK command cannot be masked by setting I. Symbolic notation for BRK is PC + 2↓, (FFFE)→PCL, (FFFF)→PCH. The BRK is a single byte instruction and its addressing mode is Implied. State Dependencies and ChangesOther than changing the program counter, the break instruction changes no values in either the registers or the flags.
BRK does not affect A, X, Y, nor bits { N, V, D, I, Z, C }. ExpositionAs is indicated, the most typical use for the break instruction is during program debugging. When the user decides that the particular program is not operating correctly, he they may decide to patch in the break instruction over some code that already exists and halt the program when it gets to that point. In order to minimize the hardware cost of the break which is applicable only for debugging, the microprocessor makes use of the interrupt vector point to allow the user to trap out that a break has occurred. In order to know whether the vector was fetched in response to an interrupt or in response to a BRK instruction, the B flag is stored on the stack, at stack pointer plus 1, containing a one in the break bit position, indicating the interrupt was caused by a BRK instruction. The B bit in the stack contains 0 if it was caused by a normal IRQ. Therefore, the coding to analyze for this is as follows in Example 9.7.
This coding can be inserted any place in the interrupt processing routine. During debugging, if the user can afford the execution time, it should be placed immediately after the save routine. If not, it can be put at the end of the polling routine which gives a priority to the polling devices as far as servicing the interrupts. However, it should be noted that in order not to lose the break, the returns from all interrupts during debugging should go through an equivalent routine. Once the user has determined that the break is on, a second analysis and correction must be made. It does not operate in a normal manner of holding the program counter pointing at the next location in memory during the BRK instruction. Because of this, the value on the stack for the program counter is at the break instruction plus two. If the break had been patched over an instruction, this is usually of no significant consequence to the user. However, if it is desired to process the next byte after the break instruction, the use of decrement memory instructions in the stack must be used. It is recommended that the user normally takes care of patching programs with break by processing a full instruction prior to returning and then use jump returns. An interesting characteristic about the break instruction is that its OPCODE is all zero’s (0), therefore, BRK coding can be used to patch fusable link PROMS through a break to an E-ROM routine which inserts patch coding. An example of using the break to patch with is shown below:
The interrupt vector routine points to:
This coding substitutes:
by use of the BRK and a break processing routine.
Operation: Branch on V = 0
This instruction tests the status of the V flag and takes the conditional branch if the flag is not set. The addressing mode is Relative. State Dependencies and ChangesBVC does not affect any of the flags and registers other than the program counter and only when the overflow flag is clear (0).
BVC does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: Branch on V = 1
This instruction tests the V flag and takes the conditional branch if V is on. The addressing mode is Relative. State Dependencies and ChangesBVS does not affect any flags or registers other than the program counter and only when the overflow flag is set.
BVS does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: 0 → C
This instruction initializes the carry flag to a 0. This operation should normally precede an ADC loop. It is also useful when used with a ROL instruction to clear a bit in memory. CLC is a single-byte instruction and its addressing mode is Implied. State Dependencies and Changes
CLC does not affect A, X, Y, S, PC, nor bits { N, V, B, D, I, Z }.
Operation: 0 → D
This instruction sets the decimal mode flag to a 0. This causes all subsequent ADC and SEC instructions to operate as simple binary operations. State Dependencies and ChangesCLD affects no registers in the microprocessor and no flags [other than D].
CLD does not affect A, X, Y, S, PC, nor bits { N, V, B, I, Z, C }.
Operation: 0 → I
This instruction initializes the interrupt disable to a 0. This allows the microprocessor to receive interrupts. CLI is a single-byte instruction and its addressing mode is Implied. State Dependencies and ChangesIt affects no registers in the microprocessor and no flags other than the interrupt disable which is cleared (0).
CLI does not affect A, X, Y, S, PC, nor bits { N, V, B, D, Z, C }.
Operation: 0 → V
This instruction clears the overflow flag to a 0. This command is used in conjunction with the set overflow pin which can change the state of the overflow flag with an external signal. State Dependencies and ChangesCLV affects no registers in the microprocessor and no flags other than the overflow flag which is cleared (0).
CLV does not affect A, X, Y, S, PC, nor bits { N, B, D, I, Z, C }.
Operation: A − M
This instruction subtracts the contents of memory from the contents of the accumulator. Its symbolic notation is A − M. State Dependencies and ChangesThe use of the CMP affects the following flags: Z flag is set on an equal comparison, reset otherwise; the N flag is set or reset by the result bit 7, the carry flag is set when the value in memory is less than or equal to the accumulator, reset when it is greater than the accumulator. The accumulator is not affected.
CMP does not affect A, X, Y, S, PC, nor bits { V, B, D, I }. ExpositionIt is a “Group One” instruction and therefore has as its addressing modes: Immediate; Zero Page; Zero Page,X; Absolute; Absolute,X; Absolute,Y; (Indirect,X); (Indirect),Y. The purpose of the compare instruction is to allow the user to compare a value in memory to the accumulator without changing the value of the accumulator. An example of where this becomes extremely important is when one is receiving command instructions from an external device. In this case, an input byte may have several values. Each value can cause the program to perform a different operation. The only rapid way to determine the value of the input data is to compare the memory with a series of constants. It is fairly simple to perform “compare to constant” operations. By use of the immediate addressing mode which will be developed later, the following example compares an input to three values and branches to different locations for each:
This example shows how to use the default option. A value was compared against 3 values and if none were equal a fourth, or default value, is assumed. This is a useful technique for code minimization. The compare instruction is designed to allow a signed comparison between 2 values assuming one makes appropriate use of the Z and N and C flags. In order to give maximum flexibility to the instruction, the instruction performs an effective subtract between the value in memory and the value in the accumulator. The reason it is an effective subtract is that subtraction allows the user to compare equal or less with one instruction. The results of a compare are:
So, to check if the accumulator is less than memory, the compare is followed by a BCC; to check if equal to is followed by a BEQ; and to check if greater it is followed by a BEQ followed by a BCS. Greater than or equal is checked by BCS.
Operation: X − M
This instruction subtracts the value of the addressed memory location from the content of index register X using the adder but does not store the result; therefore, its only use is to set the N, Z and C flags to allow for comparison between the index register X and the value in memory. The symbolic notation is X − M. The addressing modes for CPX are Immediate, Absolute and Zero Page. State Dependencies and ChangesThe CPX instruction does not affect any register in the machine; it also does not affect the overflow flag.
CPX does not affect A, X, Y, S, PC, nor bits { V, B, D, I }.
Operation: Y − M
This instruction performs a two’s complement subtraction between the index register Y and the specified memory location. The results of the subtraction are not stored anywhere. The instruction is strictly used to set the flags. The symbolic notation for CPY is Y − M. The addressing modes for CPY are Immediate, Absolute and Zero Page. State Dependencies and ChangesCPY affects no registers in the microprocessor and also does not affect the overflow flag.
CPY does not affect A, X, Y, S, PC, nor bits { V, B, D, I }.
Operation: M − 1 → M
This instruction subtracts 1, in two’s complement, from the contents of the addressed memory location. In many examples through the report, we have used the ability to increment and decrement registers in the microprocessors. The advantages of incrementing and decrementing in memory are that it is possible to keep external counters or to directly influence a bit value by means of these instructions. It is sometimes useful during I/O instructions. Symbolic notation for this instruction is M − 1 → M. The addressing modes for decrement are: Zero Page; Zero Page,X; Absolute; Absolute,X. State Dependencies and ChangesIf bit 7 is on as a result of the decrement, then the N flag is set (1); otherwise it is cleared (0). If the result of the decrement is 0, the Z flag is set (1); otherwise it is cleared (0). The decrement instruction does not affect any internal register in the microprocessor. It does not affect the carry or overflow flags.
DEC does not affect A, X, Y, S, PC, nor bits { V, B, D, I, C }.
Operation: X − 1 → X
This instruction subtracts one from the current value of the index register X and stores the result in the index register X. The symbolic notation is X − 1 → X. DEX is a single byte instruction, the addressing mode is Implied. State Dependencies and Changes
DEX does not affect A, Y, S, PC, nor bits { V, B, D, I, C }.
Operation: Y − 1 → X
This instruction subtracts one from the current value in the index register Y and stores the result into the index register Y. The result does not affect or consider carry so that the value in the index register Y is decremented to 0 and then through 0 to FF. NOTE: Decrement of the index registers is the most convenient method of using the index registers as a counter, in that the decrement involves setting the value N on as a result of having passed through 0 and sets Z on when the results of the decrement are 0. Symbolic notation is Y − 1 → Y. DEY is a single byte instruction and the addressing mode is Implied. State Dependencies and Changes
DEY does not affect A, X, S, PC, nor bits { V, B, D, I, C }.
Operation: A ⩝ M → A
The EOR instruction transfers the memory and the accumulator to the adder which performs a binary “EXCLUSIVE OR” on a bit-by-bit basis and stores the result in the accumulator. This is indicated symbolically by A ⩝ M → A. EOR is a “Group One” instruction having addressing modes of Immediate; Absolute; Zero Page; Absolute,X; Absolute,Y; Zero Page,X; Indexed Indirect; and Indirect Indexed. State Dependencies and Changes
EOR does not affect X, Y, S, PC, nor bits { V, B, D, I, C }. ApplicationsOne of the uses of the EOR instruction is in complementing bytes. This is accomplished below by exclusive ORA-ing the byte with all 1’s.
Operation: M + 1 → M
This instruction adds 1 to the contents of the addressed memory location. The symbolic notation is M + 1 → M. The addressing modes for increment are: Zero Page; Zero Page,X; Absolute; Absolute,X. State Dependencies and Changes
INC does not affect A, X, Y, S, PC, nor bits { V, B, D, I, C }.
Operation: X + 1 → X
Increment X adds 1 to the current value of the X register. This is an 8-bit increment which does not affect the carry operation, therefore, if the value of X before the increment was FF, the resulting value is 00. The symbolic notation is X + 1 → X. INX is a single byte instruction and the only addressing mode is Implied. State Dependencies and Changes
INX does not affect A, Y, S, PC, nor bits { V, B, D, I, C }.
Operation: Y + 1 → Y
Increment Y increments or adds one to the current value in the Y register, storing the result in the Y register. As in the case of INX the primary application is to step thru a set of values using the Y register. The symbolic notation is Y + 1 → Y. Increment Y is a single byte instruction and the only addressing mode is Implied. State Dependencies and Changes
INY does not affect A, X, S, PC, nor bits { V, B, D, I, C }.
Operation [JMP Absolute]: (PC + 1) → PCL, (PC + 2) → PCH [Operation (JMP Indirect): ((PC + 2)(PC + 1)) → PCL, ((PC + 2)(PC + 1) + 1) → PCH]
JMP AbsoluteIn this instruction, the data from the memory location located in the program sequence after the OPCODE is loaded into the low order byte of the program counter (PCL) and the data from the next memory location after that is loaded into the high order byte of the program counter (PCH). The symbolic notation for jump is (PC + 1)→PCL, (PC + 2)→PCH. The addressing modes are Absolute and Absolute Indirect. As stated earlier, the “( )” means “contents of” a memory location. PC indicates the contents of the program counter at the time the OPCODE is fetched. Therefore (PC + 2)→PCH reads, “the contents of the program counter two locations beyond the OPCODE fetch location are transferred to the new PC high order byte.” State Dependencies and Changes
JMP Absolute does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }. ExpositionThe JMP instruction allows use of the program counter to access the new program counter value as illustrated by the following example:
The program counter in the example starts out at location 100. The microprocessor loads a jump instruction. The program counter automatically increments to 101 where the microprocessor picks up and temporarily stores the 25. The program counter automatically increments to 102 where the microprocessor picks up the 36. The 3625 is substituted into the program counter and is used to address the next instruction. Therefore, the JMP instruction contains within its address the new program counter location. Although the jump allows the change of program sequence, it does so without performing any test. So it is a JMP instruction that is employed when it is desired to change the program counter no matter what conditions have occurred. Another JMP addressing mode is the Indirect Addressing Mode. Before this technique can be understood, the basis of indirect addressing found in Chapter 6 must be reviewed. JMP IndirectThis instruction establishes a new value for the program counter. It affects only the program counter in the microprocessor and affects no flags in the status register. JMP Indirect is a three byte instruction. In the JMP Indirect instruction, the second and third bytes of the instruction represent the indirect low and high bytes respectively of the memory location containing ADL. Once ADL is fetched, the program counter is incremented with the next memory location containing ADH.
State Dependencies and Changes
JMP Indirect does not affect A, X, Y, S, nor bits { N, V, B, D, I, Z, C }.
Operation: PC + 2 ↓, (PC + 1) → PCL, (PC + 2) → PCH
This instruction transfers control of the program counter to a subroutine location but leaves a return pointer on the stack to allow the user to return to perform the next instruction in the main program after the subroutine is complete. To accomplish this, JSR instruction stores the program counter address which points to the last byte of the jump instruction onto the stack using the stack pointer. The stack byte contains the program count high first, followed by program count low. The JSR then transfers the addresses following the jump instruction to the program counter low and the program counter high, thereby directing the program to begin at that new address. The symbolic notation for this is PC + 2↓, (PC + 1) → PCL, (PC + 2) → PCH. The addressing mode for the JSR is always Absolute. State Dependencies and Changes
JSR does not affect A, X, Y, nor bits { N, V, B, D, I, Z, C }. ExampleExample 8.3 gives the details of a JSR instruction.
In this example, it can be seen that during the first cycle the micro processor fetches the JSR instruction. During the second cycle, address low for new program counter low is fetched. At the end of cycle 2, the microprocessor has decoded the JSR instruction and holds the address low in the microprocessor until the stack operations are complete. NOTE: The stack is always stored in Page 1 (Hex address 0100-01FF). The operation of the stack in the MCS650X microprocessor is such that the stack pointer is always left pointing at the next memory location into which data can be stored. In Example 8.3, the stack pointer is assumed to be at 01FF in the beginning and PC at location 0100. During the third cycle, the microprocessor puts the stack pointer onto the address lines and on the fourth writes the contents of the current value of the program counter high, 01, into the memory location indicated by the stack pointer address. During the time that the write is being accomplished, the stack pointer is being automatically decremented by 1 to 01FE. During the fifth cycle the PCL is stored in the next memory location with the stack pointer being automatically decremented. It should be noted that the program counter low, which is now stored in the stack, is pointing at the last address in the JSR sequence. This is not what would be expected as a result of a JSR instruction. It would be expected that the stack points at the next instruction. This apparent anomaly in the machine is corrected during the Return from Subroutine in struction. Note: At the end of the JSR instruction, the values on the stack contain the program counter low and the program counter high which referenced the last address of the JSR instruction. Any subroutine calls which want to use the program counter as an intermediate pointer must consider this fact. It should be noted also that the Return from Subroutine instruction performs an automatic increment at the end of the RTS which means that any program counters which are substituted on the stack must be 1 byte or 1 pointer count less than the program count to which the programmer expects the RTS to return. The advantage of delaying the accessing of the address high until after the current program counter can be written in the stack is that only the address low has to be stored in the microprocessor. This has the effect of shortening the JSR instruction by 1 byte and also minimizing internal storage requirements. After both program counter low and high have been transferred to the stack, the program counter is used to access the next byte which is the address high for the JSR. During this operation, the sixth cycle, internally the microprocessor is storing the stack pointer which is now pointing at 01FD or the next location at which memory can be loaded. During the seventh cycle the address high from the data bus and the address low stored in the microprocessor are transferred to the new program counter and are used to access the next OPCODE, thus making JSR a 6-cyc1e instruction. At the completion of the subroutine the programmer wants to return to the instruction following the Jump-to-Subroutine instruction. This is accomplished by transferring the last 2 stack bytes to the program counter which allows the microprocessor to resume operations at the instruction fol lowing the JSR, and it is done by means of the RTS instruction.
Operation: M → A
When instruction LDA is executed by the microprocessor, data is transferred from memory to the accumulator and stored in the accumulator. Rather than continuing to give a word picture of the operation, introduced will be the symbolic representation M → A, where the arrow means “transfer to.” Therefore the LDA instruction symbolic representation is read, “memory transferred to the accumulator." For reference purpose, LDA is a “Group One” instruction and has all of the major addressing modes of the machine available to it as stated in Appendix A. These addressing modes include Immediate; Absolute; Zero Page; Absolute,X; Absolute,Y; Zero Page,X; Indexed Indirect; and Indirect Indexed. State Dependencies and ChangesLDA affects the contents of the accumulator, does not affect the carry or overflow flags;
LDA does not affect X, Y, S, PC, nor bits { V, B, D, I, C }. Exposition
Operation: M → X
Load the index register X from memory. The symbolic notation is M → X. The addressing modes for LDX are Immediate; Absolute; Zero Page; Absolute Indexed by Y; and Zero Page Indexed by Y. State Dependencies and ChangesLDX does not affect the C or V flags and affects only the X register.
LDX does not affect A, Y, S, PC, nor bits { V, B, D, I, C }.
Operation: M → Y
Load the index register Y from memory. The symbolic notation is M → Y. The addressing modes for load Y are Immediate; Absolute; Zero Page; Zero Indexed by X, Absolute Indexed by X. State Dependencies and ChangesLDY does not affect the C or V flags and only affects the Y register.
LDY does not affect A, X, S, PC, nor bits { V, B, D, I, C }.
Operation: 0 → 76543210 → C
This instruction shifts either the accumulator or a specified memory location 1 bit to the right, with the higher bit of the result always being set to 0, and the low bit which is shifted out of the field being stored in the carry flag. The symbolic notation for LSR is
LSR is a read/write/modify instruction and has the following address ing modes: Accumulator; Zero Page; Zero Page,X; Absolute; Absolute,X. State Dependencies and ChangesThe shift right instruction either affects the accumulator by shifting it right 1 or is a read/modify/write instruction which changes a specified memory location but does not affect any internal registers. The shift right does not affect the overflow flag.
LSR does not affect A, X, Y, S, PC, nor bits { V, B, D, I }.
Operation: No operation (2 cycles)
The NOP instruction performs no operation and allows the program to continue. It may be used in debugging to replace other instructions in their locations im memory or where additional delay is needed to adjust timing. Note that certain extra opcodes appear to perform no operation. State Dependencies and ChangesThe NOP instruction does not affect any flags or registers. NOP does not affect A, X, Y, S, PC, nor bits { N, Z, V, B, D, I, C }.
Operation: A ∨ M → A
The ORA instruction transfers the memory and the accumulator to the adder which performs a binary “OR” on a bit-by-bit basis and stores the result in the accumulator. This is indicated symbolically by A ∨ M → A.
ORA is a “Group One” instruction. It has the addressing modes Immediate; Absolute; Zero Page; Absolute,X; Absolute,Y; Zero Page,X; Indexed Indirect; and Indirect Indexed. To set a bit, the OR instruction is used as shown below:
Operation: A ↓
This instruction transfers the current value of the accumulator to the next location on the stack, automatically decrementing the stack to point to the next empty location. The symbolic notation for this operation is A↓. Noted should be that the notation ↓ means push to the stack, ↑ means pull from the stack. The Push A instruction only affects the stack pointer register which is decremented by 1 as a result of the operation. It affects no flags. PHA is a single-byte instruction and its addressing mode is Implied. The following example shows the operations which occur during Push A instruction.
As can be seen, the PHA takes 3 cycles and takes advantage of the fact that the stack pointer is pointing to the correct location to write the value of A. As a result of this operation, the stack pointer will be setting at 01FE. The notation (A) implies contents of A. Now that the data is on the stack, later on in the program the programmer will call for the data to be retrieved from the stack with a PLA instruction.
Operation: P ↓
This instruction transfers the contents of the processor status register unchanged to the stack, as governed by the stack pointer. Symbolic notation for this is P↓. The PHP instruction affects no registers or flags in the microprocessor. PHP is a single-byte instruction and the addressing mode is Implied.
Operation: A ↑
This instruction adds 1 to the current value of the stack pointer and uses it to address the stack and loads the contents of the stack into the A register. The symbolic notation for this is A↑. The PLA instruction does not affect the carry or overflow flags. The PLA instruction is a single-byte instruction and the addressing mode is Implied. State Dependencies and Changes
PLA does not affect X, Y, PC, nor bits { V, B, D, I, C }. ExampleIn the following example, the data stored on the stack in Example 8.8 is transferred to the accumulator.
When taking data off the stack, there is 1 extra cycle during which time the current contents of the stack register are accessed but not used and the stack pointer is incremented by 1 to allow access to the value that was previously stored on the stack. The stack pointer is left pointing at this location because it is now considered to be an empty location to be used by the stack during a subsequent operation.
Operation: P ↑
This instruction transfers the next value on the stack to the Processor Status register, thereby changing all of the flags and setting the mode switches to the values from the stack. Symbolic notation is ↑P. The PLP instruction affects no registers in the processor other than the status register. This instruction could affect all flags in the status register. PLP is a single-byte instruction and the addressing mode is Implied.
Operation:
The rotate left instruction shifts either the accumulator or addressed memory left 1 bit, with the input carry being stored in bit 0 and with the input bit 7 being stored in the carry flags. The symbolic notation for ROL is
The ROL instruction either shifts the accumulator left 1 bit and stores the carry in accumulator bit 0 or does not affect the internal registers at all. ROL is a read/modify/write instruction and it has the following address ing modes: Accumulator; Zero Page; Zero Page,X; Absolute; Absolute,X. State Dependencies and Changes
ROL does not affect X, Y, S, PC, nor bits { V, B, D, I }.
Operation:
The rotate right instruction shifts either the accumulator or addressed memory right 1 bit with bit 0 shifted into the carry and carry shifted into bit 7. The symbolic notation for ROR is
The ROR instruction either shifts the accumulator right 1 bit and stores the carry in accumulator bit 7 or does not affect the internal registers at all. ROR is a read/modify/write instruction and it has the following address ing modes: Accumulator; Zero Page; Absolute; Zero Page,X; Absolute,X. State Dependencies and Changes
ROR does not affect X, Y, S, PC, nor bits { V, B, D, I }.
Operation: P↑ PC↑
This instruction transfers from the stack into the microprocessor the processor status and the program counter location for the instruction which was interrupted. By virtue of the interrupt having stored this data before executing the instruction and thelfact that the RTI reinitializes the microprocessor to the same state as when it was interrupted, the combination of interrupt plus RTI allows truly reentrant coding. The symbolic notation for RTI is ↑P ↑PC. The RTI instruction reinitializes all flags to the position to the point they were at the time the interrupt was taken and sets the program counter back to its pre-interrupt state. It affects no other registers in the microprocessor. RTI is a single byte instruction and its addressing mode is Implied. In the following example, we can see the internal operation of the RTI which restores the microprocessor:
Note the effects of the extra cycle (3) necessary to read data from stack which causes the RTI to take six cycles. The RTI has restored the stack, program counter and status register to the point they were at before the interrupt was acknowledged. There is no automatic save of any of the other registers in the microprocessor. Because the interrupt occurred to allow data to be transferred using the microprocessor, the programmer must save the various internal registers at the time the interrupt is taken and restore them prior to returning from the interrupt. Saving of the registers is best done on the stack as this allows as many consecutive interrupts as the programming will allow for. Therefore, the routines which save all registers and restore them are as follows:
The SAVE coding assumes that the programmer wants to save and to restore registers A, X and Y. It should be noted that for many interrupts, the amount of coding that has to be performed in the interrupt is fairly small. In this type of operation, it is usually more desirable to shorten the interrupt processing time and not use all of the registers in the machine. Therefore, a more normal interrupt processing routine would consist of just saving registers A and X which means that the restore routine would be just restore registers X and A. This has the effect of shortening the interrupt routine by two bytes, and also shortens the restore routine by two bytes and will cut 5 cycles out of the interrupt routine and 6 cycles out of the restore routine. This technique combined with automatic features of the interrupt and the RTI allows multiple interrupts to occur with successive interrupts interrupting the current interrupt. This is one of the advantages of the use of the stack so that as many interrupts can interrupt other interrupts as can be held in the stack. The stack contains six bytes for every interrupt if all registers are saved, so 42 sequences of interrupts can be stored in one page. However, in more practical situations, consecutive interrupts hardly ever get more than about three deep. The advantage of allowing an interrupt to interrupt an interrupt is that the whole concept behind the interrupt is that asynchronous events can be responded to as rapidly as possible; therefore, it is desirable to allow the processing to service one interrupt to be interrupted to service the second, as long as the first interrupt has been properly serviced. To review how this is accomplished using the normal interrupt capability of the MCS650X, it is important that we review the bus concept which is inherent in the MCS6500 family and which is compatible with the MC6800. As has already been discussed, all I/O operations on this type of microprocessor are accomplished by reading and writing registers which actually represent connections to physical devices or to physical pins which connect to physical devices. Up until this point, this di3cussion has addressed itself to transferring of data into and out of the microprocessor. However, there is a concept that is inherent in the bus discipline that says that whenever an interrupt device capable of generating an interrupt desires to accomplish an interrupt, it performs two acts; first, it sets a bit, usually bit 7, in a register whose primary purpose is to communicate to the microprocessor the status of the device. The interrupting device causes one of perhaps many output lines to be brought low. These collector-or'd outputs are connected together to the Tia pin on the MCS650X microprocessor. The interrupt request to the MCS650X is the Tfia pin being at a TTL zero. In order to minimize the handshaking necessary to accomplish an interrupt, all interrupting devices obey a rule that says that once an interrupt has been requested by setting the bit and pulling interrupt low, the interrupt will be held by the device until the condition that caused the interrupt has been satisfied. This allows several devices to interrupt simultaneously and also allows the microprocessor to ignore an interrupt until it is ready to service it. This ignoring is done by the interrupt disable bit which can be set on by the programmer and is initialized on by the interrupt sequence or by the start sequence. Once the interrupt line is low and interrupt disable is off, the microprocessor takes an interrupt which sets on the interrupt disable. The interrupt disable then keeps the input low line from causing more than one interrupt until an interrupt has been serviced. There is no other handshaking between the microprocessor and the interrupting device other than the collector-or'd line. This means that the microprocessor must use the normal addressing registers to determine which of several collectoror'd devices caused the line to go low and to process the interrupt which has been requested. Once the processor has found the interrupting device by means of analyzing status bits which indicates an interrupt has been requested, the microprocessor then clears the status by reading or writing data as indicated by the status register. It should be noted that a significant difference between status registers and data registers in I/O devices is that status registers are never cleared by being read, only by being written into or by the microprocessor transferring data from a data register which corresponds to some status in the status register. Detailed examples of this interaction are discussed in Chapter 11. The clearing of the status register also releases the collector-or'd output thereby releasing the interrupt pin request. The basic interaction between the microprocessor and interrupting device is when interrupting device sets the status bit and brings its output IRQ line low. If its output IRQ line is connected to the microprocessor interrupt request line, the microprocessor waits until the interrupt disable is cleared, takes the interrupt vector, and sets the interrupt disable which inhibits further interrupts in the IRQ line. The microprocessor determines which interrupting device is causing an interrupt and transfers data from that device. Transferring of data clears the interrupt status and the IRQ pin. At this point, the programmer could decide that he was they were ready to accept another interrupt even though the data may have been read but not yet operated on. Allowing interrupts at this point, gives the most efficient operation of the microprocessor in most applications. There are also times when a programmer may be working on some coding the timing of which is so important that he they cannot afford to allow an interrupt to occur. During these times, he needs they need to be able to turn on the interrupt disable. To accomplish this, the microprocessor has a set and clear interrupt disable capability.
Operation: PC↑, PC + 1→PC
This instruction loads the program count low and program count high from the stack into the program counter and increments the program counter so that it points to the instruction following the JSR. The stack pointer is adjusted by incrementing it twice. The symbolic notation for the RTS is PC↑, INC PC. RTS is a single-byte instruction and its addressing mode is Implied. State Dependencies and ChangesThe RTS instruction does not affect any flags and affects only PCL and PCH.
RTS does not affect A, X, Y, nor bits { N, Z, V, B, D, I, C }. ExampleThe following Example 8.4 gives the details of the RTS instruction. It is the complete reverse of the JSR shown in Example 8.3.
As we can see, the RTS instruction effectively unwinds what was done to the stack in the JSR instruction. Because RTS is a single-byte instruction it wastes the second memory access in doing a look-ahead operation. During the second cycle the value located at the next program address after the RTS is read but not used in this operation. It should be noted that the stack is always left pointing at the next empty location, which means that to pull off the stack, the microprocessor has to wait 1 cycle while it adds 1 to the stack address. This is done to shorten the interrupt sequence which will be discussed below; therefore, cycle 3 is a dead cycle in which the microprocessor fetches but does not use the current value of the stack and, like the fetch of address low on Indexed and Zero Page Indexed operations, does nothing other than initialize the microprocessor to the proper state. It can be seen that the stack pointer decrements as data is pushed on to the stack and increments as data is pulled from the stack. In the fourth cycle of the RTS, the microprocessor puts out the 01FE address, reads the data stored there which is the program count low which was written in the second write cycle of the JSR. During the fifth cycle, the microprocessor puts out the incremented stack picking up the program count high which was written in the first write cycle of the JSR. As is indicated during the discussions of JSR, the program counter stored on the stack really points to the last address of the JSR instruction itself; therefore, during the sixth cycle the RTS causes the program count from the stack to be incremented. That is the only purpose of the sixth cycle. finally, in the seventh cycle, the incremented program counter is used to fetch the next instruction; therefore, RTS takes 6 cycles. Because every subroutine requires 1 JSR followed by 1 RTS, the time to jump to and return from a subroutine is 12 cycles. In the previous 2 examples, we have shown the operations of the JSR located in location 100 and the RTS located in location 300. The following pictorial diagram, Example 8.5, illustrates how the memory map for this operation might look:
With this capability of subroutining, the microprocessor allows the programmer to go from the main program to 1 subroutine, to the second sub routine, to a third subroutine, then finally working its way back to the main program. Example 8.6 is an expansion of Example 8.2 with the returns included.
This concept is known as nesting of subroutines, and the number of subroutines which can be called and returned from in such a manner is limited by only the length of the stack.
Operation: A − M − C → A (Note: C = Borrow)
This instruction subtracts the value of memory and borrow from the value of the accumulator, using two’s complement arithmetic, and stores the result in the accumulator. Borrow is defined as the carry flag complemented; therefore, a resultant carry flag indicates that a borrow has not occurred. The symbolic representation for this instruction is A − M − C → A. This instruction affects the accumulator.
It is a “Group One” instruction. It has addressing modes Immediate; Absolute; Zero Page; Absolute,X; Absolute,Y; Zero Page,X; Indexed Indirect; and Indirect Indexed. In a binary machine, the classical way to perform arithmetic is by using two’s complement notation. In using two’s complement notation, any subtraction operation becomes a sequence of bit complementations and additions. This reduces the complexity of the circuits required to perform a subtraction. When the SBC instruction is used in single precision subtraction, there will normally be no borrow; therefore, the programmer must set the carry flag, by using the SEC (Set carry to l) instruction, before using the SBC instruction. The microprocessor adds the carry flag to the complemented memory data, resulting in a true two’s complement form of the memory value with its sign inverted. Example 2.13: Subtract 2 numbers with borrow; positive resultAssume a single precision subtraction where A contains 5 and M contains 3. The carry flag must be set to a 1 using the SEC instruc tion, thereby representing the no-borrow condition. The adder changes the sign of M by taking the two’s complement of M. This involves complementing M and adding the carry bit.
The adder adds A and the two’s complement −M together. This operation occurs simultaneously with the complement operation.
The presence of the carry flag after this operation indicates that No Borrow was required, therefore the result is +2. Example 2.14: Subtract 2 numbers with borrow; negative resultAssume a single precision subtraction where A contains 5 and M contains 6. Set the carry flag to a 1 with SEC to indicate No Borrow.
The absence of the carry flag after this operation indicates that a borrow was required, therefore the result is a −1 in two’s complement form. The absolute (unsigned) result in straight binary could be obtained by taking the two’s complement of this number.
Operation: 1 → C
This instruction initializes the carry flag to a 1. This operation should normally precede a SBC loop. It is also useful when used with a ROL instruction to initialize a bit in memory to a 1. This instruction affects no registers in the microprocessor and no flags other than the carry flag which is set (1). SEC is a single-byte instruction and its addressing mode is Implied. State Dependencies and Changes
SEC does not affect A, X, Y, S, PC, nor bits { N, V, B, D, I, Z }.
Operation: 1 → D
This instruction sets the decimal mode flag D to a 1. This makes all subsequent ADC and SEC instructions operate as a decimal arithmetic operation. State Dependencies and Changes
SED does not affect A, X, Y, S, PC, nor bits { N, V, B, I, Z, C }.
Operation: 1 → I
This instruction initializes the interrupt disable to a 1. It is used to mask interrupt requests during system reset operations and during interrupt commands. SEI is a single-byte instruction and its addressing mode is Implied. State Dependencies and Changes
SEI does not affect A, X, Y, S, PC, nor bits { N, V, B, D, Z, C }.
Operation: A → M
This instruction transfers the contents of the accumulator to memory. The symbolic representation for this instruction is A → M. It is a “Group One” instruction and has the following addressing modes available to it: Absolute; Zero Page; Absolute,X; Absolute,Y; Zero Page,X; Indexed Indirect; and Indirect Indexed. State Dependencies and ChangesThis instruction affects none of the flags in the processor status register and does not affect the accumulator.
STA does not affect A, X, Y, S, PC, nor bits { N, B, C, I, D, V, C }.
Operation: X → M
Transfers value of X register to addressed memory location. The symbolic notation is X → M. State Dependencies and ChangesNo flags or registers in the microprocessor are affected by the store operation. The addressing modes for STX are Absolute, Zero Page, and Zero Page Indexed by Y.
STX does not affect A, X, Y, S, PC, nor bits { N, V, B, D, I, Z, C }.
Operation: Y → M Transfer the value of the Y register to the addressed memory location. The symbolic notation is Y → M.>/p> State Dependencies and ChangesSTY does not affect any flags or registers in the microprocessor. The addressing modes for STY are Absolute; Zero Page; and Zero Page Indexed by X.
STY does not affect A, X, Y, S, PC, nor bits { N, V, B, D, I, Z, C }.
Operation: A → X
This instruction takes the value from accumulator A and transfers or loads it into the index register X without disturbing the content of the accumulator A. The symbolic notation for this is A → X. TAX is a single byte instruction and its addressing mode is Implied. State Dependencies and ChangesTAX only affects the index register X, does not affect the carry or overflow flags.
TAX does not affect A, Y, PC, S, nor bits { V, B, D, I, C }.
Operation: A → Y
This instruction moves the value of the accumulator into index register Y without affecting the accumulator. The symbolic notation is A → Y. TAY is a single byte instruction and the addressing mode is Implied. State Dependencies and ChangesTAY instruction only affects the Y register and does not affect either the carry or overflow flags.
TAY does not affect A, X, PC, S, nor bits { V, B, D, I, C }.
Operation: S → X
This instruction transfers the value in the stack pointer to the index register X. Symbolic notation is S → X. TSX is a single-byte instruction and the addressing mode is Implied. State Dependencies and ChangesTSX changes the value of index X, making it equal to the content of the stack pointer. TSX does not affect the carry or overflow flags.
TSX does not affect A, Y, PC, S, nor bits { V, B, D, I, C }.
Operation: X → A
This instruction moves the value that is in the index register X to the accumulator A without disturbing the content of the index register X. The symbolic notation is X → A. The addressing mode is Implied, it is a single byte instruction. State Dependencies and ChangesTXA does not affect any register other than the accumulator and does not affect the carry or overflow flag.
TXA does not affect X, Y, S, PC, nor bits { V, B, D, I, C }.
Operation: X → S
This instruction transfers the value in the index register X to the stack pointer. Symbolic notation is X → S. TXS is a single-byte instruction and its addressing mode is Implied. State Dependencies and ChangesTXS changes only the stack pointer, making it equal to the content of the index register X. It does not affect any of the flags.
TXS does not affect A, X, Y, PC, nor bits { N, V, B, D, I, Z, C }. ApplicationsAnother application for TXS is the concept of passing parameters to the subroutine by storing them immediately after the jump to subroutine instruction. In Example 8.11, the from and to address, plus the count of number of values would be written right after the JSR instruction and its address. By locating the stack in Page Zero, the address of the last byte of the JSR can be incremented to point at the parameter bytes and then used as an indirect pointer to move the parameter to its memory location. The key to this approach is transferring the stack pointer to X which allows the program to operate directly on the address while it is in the stack. It should be noted that this approach automatically leaves the address on the stack, positioned so that the RTS picks up the next OPCODE address.
Before concluding this discussion on subroutines and parameter passing, one should again note the use of subroutines should be limited to those cases where the user expects to duplicate code of significant length several times in the program. In these cases, and only in these cases, is subroutine call warranted rather than the normal mode of knowing the addresses and specifying them in an instruction. In all cases where timing is of significant interest, subroutines should also be avoided. Subroutines add significantly to the setup and execution time of problem solution. However, subroutines definitely have their place in microcomputer code and there have been presented 3 alternatives for use in application programs. The user will find a combination of the above techniques most useful for solving their particular problem.
Operation: Y → A
This instruction moves the value that is in the index register Y to accumulator A without disturbing the content of the register Y. The symbolic notation is Y → A. Some of the applications of the transfer instructions between accumulator A and index registers X, Y are those when the user wishes to use the index register to access memory locations where there are multiple byte values between the addresses. In this application a count is loaded into the index register, the index register is transferred to the accumulator, a value such as 5, 7, 10, etc. is added immediate to the accumulator and results stored back into the index register using the TAX or TAY instruction. The consequence of this type of operation is that it allows the microprocessor to address non-consecutive locations in memory. Another application is where the internal transfer instructions allow the index registers to hold intermediate values for the accumulator which allows rapid transfer to and from the accumulator to help solve high speed data shuffling problems. The addressing mode is Implied and it is a single byte instruction. State Dependencies and ChangesTYA does not affect any other register other than the accumulator and does not affect the carry or overflow flag.
TYA does not affect X, Y, S, PC, nor bits { B, C, I, D, V }. Extra Instructions – Alphabetic by Mnemonic with Opcodes, Execution Cycles and Memory Requirements
Operation: A ∧ M → A, A7 → C
ANC ANDs the contents of the accumulator with an immediate value and then moves bit 7 of the accumulator into the Carry flag. This opcode works basically identically to AND Immediate except that the Carry flag is set to the same state that the Negative flag is set to. As an extra instruction and one that would be in Group 4, ANC has two opcodes. ANC at opcode 0B shadows the first-row Group 2 instruction ASL A and the first-row Group 1 instruction ORA Immediate. ANC at opcode 2B shadows the second-row Group 2 instruction ROL A and the second-row Group 1 instruction AND Immediate. Note that the Negative flag and Zero flag are set or cleared via the AND operation, and the Carry flag is copied from accumulator bit 7 apparently as a component of either ASL A or ROL A (which are shadowed by the two ANC opcodes) although no shifting nor rotation of the accumulator appears to occur. RLA appears to execute ROL before AND, and requires at least one more cycle than ROL (which requires more cycles than AND). ExampleANC #$FC ;OB FC Equivalent InstructionsAND #$FC ; AND A with value, stores A and sets/clears Negative and Zero ASL A ; set/clear Carry flag as desired, but seting/clearing Negative and Zero flags is not desired LSR A ; undo ASL AND #$FC ; sets/clears Negative and Zero flags as desired
Operation: A ∧ M → A, 0 → 76543210 → C
This opcode ANDs the contents of the A register with an immediate value and then LSRs the result. As an extra instruction and one that would be in Group 4, ALR shadows the third-row Group 2 instruction LSR A and the third-row Group 1 instruction EOR Immediate. ExampleALR #$FE ;4B FE Equivalent InstructionsAND #$FE LSR A
Operation: A ∧ M → A,
This opcode ANDs the contents of the A register with an immediate value and then RORs the result. As an extra instruction and one that would be in Group 4, ARR shadows the fourth-row Group 2 instruction ROR A and the fourth-row Group 1 instruction ADC Immediate. ExampleARR #$7F ;6B 7F Equivalent InstructionsAND #$7F ROR A
Operation: A ∧ X → M
AXS ANDs the contents of the accumulator and X index register (without changing the contents of either register) and stores the result in memory. AXS does not affect any flags in the processor status register. As an extra instruction and one that would be in Group 4, AXS shadows the fifth-row Group 2 instruction STX and the fifth-row Group 1 instruction STA. ExampleAXS $FE ;87 FE Equivalent InstructionsSTX $FE PHA AND $FE STA $FE PLA
M − 1 → M, A − M
This opcode DECs the contents of a memory location and then CMPs the result with the A register. As an extra instruction and one that would be in Group 4, DCM shadows the seventh-row Group 2 instruction DEC and the seventh-row Group 1 instruction CMP. DCM appears to execute DEC before CMP, and requires at least one more cycle than ASL (which requires more cycles than ORA). ExampleDCM $FF ;C7 FF Equivalent InstructionsDEC $FF CMP $FF
Operation: No operation (2 cycles)
When encountered, any of these 12 extra opcodes will cause the microprocessor to halt, ceasing functions until power is removed and re-applied. Note that other extra opcodes may have the same effect. For opcodes that do not affect the states of registers, see NOP, NOP (extra opcodes), SKB, and SKW.
M + 1 → M, A − M − C → A (Note: C = Borrow)
This opcode INCs the contents of a memory location and then SBCs the result from the A register. As an extra instruction and one that would be in Group 4, INS shadows the eighth-row Group 2 instruction INC and the eighth-row Group 1 instruction SBC. INS appears to execute INC before SBC, and requires at least one more cycle than ASL (which requires more cycles than ORA). ExampleINS $FF ;E7 FF Equivalent InstructionsINC $FF SBC $FF
Operation: M → X, M → A
This opcode loads both the accumulator and the X register with the contents of a memory location. As an extra instruction and one that would be in Group 4, LAX shadows the sixth-row Group 2 instruction LDX and the sixth-row Group 1 instruction LDA. Other instructions that shadow similarly will execute the Group 2 instruction before the Group 1 instruction, so this instruction might more-consistently be named “Load X Index, Then Load Accumulator” (LXA). However, the order of the operations is not significant in this case. LAX appears to execute LDX and LDA in the same number of cycles as a single LDA (which requires more cycles than LDX). ExampleLAX $8400,Y ;BF 00 84 Equivalent InstructionsLDA $8400,Y LDX $8400,Y
Operation: No operation (2 cycles)
These extra opcodes, like the prescribed NOP (opcode EA), perform no operation and allow the program to continue (unlike HLT). State Dependencies and ChangesThe NOP instruction does not affect any flags or registers. NOP does not affect A, X, Y, S, PC, nor bits { N, Z, V, B, D, I, C }.
Operation: A ∨ #$EE → A, A ∧ M → A, A → X
This opcode ORs the A register with #$EE, ANDs the result with an immediate value, and then stores the result in both A and X. As an extra instruction and one that would be in Group 4, OAL shadows the sixth-row Group 2 instruction TAX and the sixth-row Group 1 instruction LDA. OAL appears to execute TAX before LDA, and requires only as many cycles than as TAX (which requires fewer cycles than LDA). ExampleOAL #$AA ;AB AA Equivalent InstructionsORA #$EE AND #$AA
Operation:
RLA ROLs the contents of a memory location and then ANDs the result with the accumulator. As an extra instruction and one that would be in Group 4, RLA shadows the second-row Group 2 instruction ROL and the second-row Group 1 instruction AND. RLA appears to execute ROL before AND, and requires at least one more cycle than ROL (which requires more cycles than AND). ExampleRLA $FC,X ;37 FC Equivalent InstructionsROL $FC,X AND $FC,X
Operation:
RRA RORs the contents of a memory location and then ADCs the result with the accumulator. As an extra instruction and one that would be in Group 4, RRA shadows the fourth-row Group 2 instruction ROR and the fourth-row Group 1 instruction ADC. RRA appears to execute ROR before ADC, and requires at least one more cycle than ROR (which requires more cycles than ADC). ExampleRRA $030C ;6F 0C 03 Equivalent InstructionsROR $030C ADC $030C
Operation: A − M − C → A (Note: C = Borrow)
Opcode EB seems to work exactly like SBC using the Immediate addressing mode. Based on their positions in the table, this opcode appears to combine the functions of the eight-row Group 2 instruction NOP and the eight-row Group 1 instruction SBC (Immediate), with no increase in the number of cycles required. Because NOP performs no operation, the combination becomes effectively only SBC.
Operation: A ∧ X − M → X
SBX ANDs the contents of the A and X registers (leaving the contents of A intact), subtracts an immediate value, and then stores the result in X. ... A few points might be made about the action of subtracting an immediate value. It actually works just like the CMP instruction, except that CMP does not store the result of the subtraction it performs in any register. This subtract operation is not affected by the state of the Carry flag, though it does affect the Carry flag. It does not affect the Overflow flag. As an extra instruction and one that would be in Group 4, SBX shadows the seventh-row Group 2 instruction DEX and the seventh-row Group 1 instruction CMP Immediate. SBX appears to execute TAX before LDA, and requires only as many cycles than as TAX (which requires fewer cycles than LDA). ExampleSBX #$5A ;CB 5A Equivalent InstructionsSTA $02 TXA AND $02 SEC SBC #$5A TAX LDA $02
Operation: Skip next 1 byte
SKB stands for skip next byte. State Dependencies and ChangesThe SKB instruction does not affect any flags or registers. SKB does not affect A, X, Y, S, PC, nor bits { N, Z, V, B, D, I, C }.
Operation: Skip next 2 bytes
SKW skips next word (two bytes). To be dizzyingly precise, SKW actually performs a read operation. It’s just that the value read is not stored in any register. Further, opcode 0C uses the absolute addressing mode, in which the two bytes that follow the opcode form the absolute address. All the other SKW opcodes use the absolute indexed X addressing mode. If a page boundary is crossed, the execution time of one of these SKW opcodes is upped to 5 clock cycles. State Dependencies and ChangesThe SKW instruction does not affect any flags or registers. SKW does not affect A, X, Y, S, PC, nor bits { N, Z, V, B, D, I, C }.
Operation: C ← 76543210 ← 0, A ∨ M → A
This opcode ASLs the contents of a memory location and then ORs the result with the accumulator. As an extra instruction and one that would be in Group 4, SLO shadows the first-row Group 2 instruction ASL and the first-row Group 1 instruction ORA. SLO appears to execute ASL before ORA, and requires at least one more cycle than ASL (which requires more cycles than ORA). ExampleSLO $C010 ;0F 10 C0 Equivalent InstructionsASL $C010 ORA $C010
Operation: 1 + AH(M) ∧ X ∧ A → M
This opcode stores the result of A AND X AND the high byte of the target address of the operand + 1 in memory. SOA appears to use part of the same mechanism used to access the stack pointer. As the stack pointer (S) accesses locations on page one, it places a value of one (1) onto the high byte of the address bus... ExampleSOA $7133,Y ;9F 33 71 Equivalent InstructionsSTX $02 PHA AND $02 AND #$72 STA $7133,Y PLA LDX $02 SOA appears to work like SOX, but also ANDs the accumulator.
Operation: 1 + AH(M) ∧ X → M
This opcode ANDs the contents of the X register with 1 + the high byte of Oper,Y and stores the result in memory. SOX appears to use part of the same mechanism used to access the stack pointer. As the stack pointer (S) accesses locations on page one, it places a value of one (1) onto the high byte of the address bus... SOX appears to work like SOA, but without ANDing the accumulator. ExampleSOX $6430,Y ;9E 30 64 Equivalent InstructionsPHA TXA AND #$65 STA $6430,Y PLA
Operation: 1 + AH(M) ∧ X → M
This opcode ANDs the contents of the Y register with 1 + the address high byte and stores the result in memory. ? SOY appears to use part of the same mechanism used to access the stack pointer. As the stack pointer (S) accesses locations on page one, it places a value of one (1) onto the high byte of the address bus... SOY appears to work like SOA, but without ANDing the accumulator. ExampleSOY $7700,X ;9C 00 77 Equivalent InstructionsPHA TYA AND #$78 STA $7700,X PLA
Operation: 0 → 76543210 → C, M ⩝ A → A
SRE LSRs the contents of a memory location and then EORs the result with the accumulator. As an extra instruction and one that would be in Group 4, SRE shadows the third-row Group 2 instruction LSR and the third-row Group 1 instruction EOR. SRE appears to execute LSR before EOR, and requires at least one more cycle than LSR (which requires more cycles than EOR). ExampleSRE $C100,X ;5F 00 C1 Equivalent InstructionsLSR $C100,X EOR $C100,X
Operation: M ∧ S → S, S → X, S → A
This opcode ANDs the contents of a memory location with the contents of the stack pointer register and stores the result in the accumulator, the X register, and the stack pointer. Affected flags: N Z. SXA appears to perform its AND function on S without affecting the accumulator, then executes TSX and LDA in the same number of cycles as a single LDA (which requires more cycles than TSX). Based on this function, I renamed “LAS” to SXA.
Operation: A ∧ X → S, 1 + AH(M) ∧ S → M
This opcode ANDs the contents of the A and X registers (without changing the contents of either register) and transfers the result to the stack pointer. It then ANDs that result with the contents of the high byte of the target address of the operand + 1 and stores that final result in memory. TOS appears to use part of the same mechanism used to access the stack pointer. As the stack pointer (S) accesses locations on page one, it places a value of one (1) onto the high byte of the address bus... ExampleTOS $7700,Y ;9B 00 77 Equivalent InstructionsSTX $02 PHA AND $02 TAX TXS AND #$78 STA $7700,Y PLA LDX $02
Operation: X → A, A ∧ M → A
XAA transfers the contents of the X register to the A register and then ANDs the accumulator with an immediate value. As an extra instruction and one that would be in Group 4, XAA shadows the fifth-row Group 2 instruction TXA and the only non-extra opcode in Group 1 (in the fifth row, with the extra opcode SKB). ExampleXAA #$44 ;8B 44 Equivalent InstructionsTXA AND #$44 See AlsoMy web-friendly—all HTML—version of Synertek’s printing of the MOS Technology 6500 Family Programming Manual |
Syncopated attempts to present a model Web site that meets or exceeds all applicable technical and legal requirements, including those of the A.D.A., COPPA, GDPR, ICANN, and W3C. | Syntax validated |
Style sheet validated |
Highest accessibility |
“Syncopated Systems” and “Syncopated Software” are registered trademarks, the interlaced tuning forks device and the “seriously sound science” and “recreate reality” slogans are trademarks, and all contents (except as otherwise noted) are copyright ©2004-2024 Syncopated Systems. ALL RIGHTS RESERVED. Any reproduction without written permission or other infringement is prohibited by United States and international laws. |