Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
MOS Technology 6502
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Technical description== [[Image:MOS 6502 die.jpg|right|thumb|6502 processor die. The regular section at the top is the instruction decoding ROM, the seemingly random section in the center is the control logic, and at the bottom are the registers (right) and the ALU (left). The data bus connections are along the lower right, and the address bus along the bottom and lower left.{{sfn|Cushman|1975|p=40}}]] [[Image:MOS6502.svg|right|thumb|215px|6502 pin configuration (40-pin [[Dual in-line package|DIP]])]] <div class="floatright" style="border: 1px solid #a2a9b1;background-color: #f8f9fa;padding:0.2em;font-size:88%"> {{center|'''MOS 6502 registers'''}} {| style="font-size:88%;border-spacing: 1px;" |- style="text-align:center;" | style="width:10px"| <sup>1</sup><sub>5</sub> | style="width:10px"| <sup>1</sup><sub>4</sub> | style="width:10px"| <sup>1</sup><sub>3</sub> | style="width:10px"| <sup>1</sup><sub>2</sub> | style="width:10px"| <sup>1</sup><sub>1</sub> | style="width:10px"| <sup>1</sup><sub>0</sub> | style="width:10px"| <sub>9</sub> | style="width:10px"| <sub>8</sub> | style="width:10px"| <sub>7</sub> | style="width:10px"| <sub>6</sub> | style="width:10px"| <sub>5</sub> | style="width:10px"| <sub>4</sub> | style="width:10px"| <sub>3</sub> | style="width:10px"| <sub>2</sub> | style="width:10px"| <sub>1</sub> | style="width:10px"| <sub>0</sub> | style="width:auto;" | ''(bit position)'' |- |colspan="17" | '''Main registers''' |- style="background:silver;color:black" | style="text-align:center; background:white" colspan="8"| | style="text-align:center;" colspan="8"| A | style="width:auto; background:white; color:black;"| [[Accumulator (computing)|'''A'''ccumulator]] |- |colspan="17" | '''[[Index registers]]''' |- style="background:silver;color:black" | style="text-align:center; background:white" colspan="8"| | style="text-align:center;" colspan="8"| X | style="background:white; color:black;"| '''X''' index |- style="background:silver;color:black" | style="text-align:center; background:white" colspan="8"| | style="text-align:center;" colspan="8"| Y | style="background:white; color:black;"| '''Y''' index |- style="background:silver;color:black" | style="text-align:center; background:#DDDDDD"| 0 | style="text-align:center; background:#DDDDDD"| 0 | style="text-align:center; background:#DDDDDD"| 0 | style="text-align:center; background:#DDDDDD"| 0 | style="text-align:center; background:#DDDDDD"| 0 | style="text-align:center; background:#DDDDDD"| 0 | style="text-align:center; background:#DDDDDD"| 0 | style="text-align:center; background:#DDDDDD"| 1 | style="text-align:center;" colspan="8"| S | style="background:white; color:black;"| [[Stack pointer|'''S'''tack pointer]] |- |colspan="17" | '''[[Program counter]]''' |- style="background:silver;color:black" | style="text-align:center;" colspan="16"| PC | style="background:white; color:black;"| [[Program counter|'''P'''rogram '''C'''ounter]] |- |colspan="17" | '''[[Status register]]''' |- style="background:silver;color:black" | style="text-align:center; background:white" colspan="8" | | style="text-align:center;"| [[Sign flag|N]] | style="text-align:center;"| [[Overflow flag|V]] | style="text-align:center;"| - | style="text-align:center;"| [[#BRK Flag|B]] | style="text-align:center;"| [[Binary-coded decimal|D]] | style="text-align:center;"| [[Interrupt flag|I]] | style="text-align:center;"| [[Zero flag|Z]] | style="text-align:center;"| [[Carry flag|C]] | style="background:white; color:black" |[[Status register|'''P'''rocessor flags]] |} </div> The 6502 is a [[little-endian]] [[8-bit computing|8-bit]] processor with a [[16-bit computing|16-bit]] [[address bus]]. The original versions were fabricated using an {{nowrap|8 Β΅m}}<ref name="Corder 1999">{{cite web |last=Corder |first=Mike |title=Big Things in Small Packages |work=Pioneers' Progress with picoJava Technology |publisher=Sun Microelectronics |date=Spring 1999 |url=http://www.sun.com/microelectronics/picoJava/pioneers/vol3/licensee-jCan.html |url-status=dead |archive-url=https://web.archive.org/web/20060312110759/http://www.sun.com/microelectronics/picoJava/pioneers/vol3/licensee-jCan.html |archive-date=2006-03-12 |quote=The first 6502 was fabricated with 8 micron technology, ran at one megahertz and had a maximum memory of 64k.| access-date=April 23, 2012}}</ref> process technology chip with a [[Die (integrated circuit)|die size]] of {{Convert|153|Γ|168|mil|abbr=on|order=flip}}, for a total area of {{val|16.6|u=mm2}}.{{sfn|Cushman|1975|p=40}} The internal logic runs at the same speed as the external clock rate. It featured a simple pipeline; on each cycle, the processor fetches one byte from memory and processes another. This means that any single instruction can take as few as two cycles to complete, depending on the number of operands that instruction uses. For comparison, the [[Zilog Z80]] required two cycles to fetch memory, and the minimum instruction time was four cycles. Thus, despite the lower clock speeds compared to competing designs, typically in the neighborhood of 1 to {{val|2|ul=MHz}}, the 6502's performance was competitive with CPUs using significantly faster clocks. This is partly due to a simple state machine implemented by [[Combinational logic|combinational (clockless) logic]] to a greater extent than in many other designs; the two-phase clock (supplying two synchronizations per cycle) could thereby control the machine cycle directly. This design also led to one useful design note of the 6502, and the 6800 before it. Because the chip only accessed memory during a certain part of the clock cycle, and this duration was indicated by the Ο2-low clock-out pin, other chips in a system could access memory during those times when the 6502 was off the bus. This was sometimes known as "hidden access". This technique was widely used by computer systems; they would use memory capable of access at 2 MHz, and then run the CPU at 1 MHz. This guaranteed that the CPU and video hardware could interleave their accesses, with a total performance matching that of the memory device. Because this access was every other cycle, there was no need to signal the CPU to avoid using the bus, making this sort of access easy to implement without any bus logic. <ref>{{cite web |url=https://retrocomputing.stackexchange.com/questions/12718/how-to-implement-bus-sharing-dma-on-a-6502-system |title=How to implement bus sharing / DMA on a 6502 system |access-date=2020-09-30 |archive-date=2020-08-15 |archive-url=https://web.archive.org/web/20200815134410/https://retrocomputing.stackexchange.com/questions/12718/how-to-implement-bus-sharing-dma-on-a-6502-system |url-status=live}}</ref> When faster memories became available in the 1980s, newer machines could use this same technique while running at higher clock rates, the [[BBC Micro]] used newer RAM that allowed its CPU to run at 2 MHz while still using the same bus sharing techniques. Like most simple CPUs of the era, the dynamic [[NMOS logic|NMOS]] 6502 chip is not sequenced by [[microcode]] but decoded directly using a dedicated [[Programmable logic array|PLA]]. The decoder occupied about 15% of the chip area. This compares to later microcode-based designs like the [[Motorola 68000]], where the microcode ROM and decoder engine represented about a third of the gates in the system. ===Registers=== Like its precursor, the 6800, the 6502 has very few [[processor register|registers]]. They include<ref>{{Cite book |title=MOS MICROCOMPUTERS PROGRAMMING MANUAL |date=January 1976 |publisher=MOS TECHNOLOGY, INC. |chapter=PROGRAMMING MODEL MCS650X}}</ref> * <code>A</code> = 8-bit [[accumulator (computing)|accumulator]] register * <code>P</code> = 7-bit<ref>{{cite book |last=Anderson |first=J.S. |date=2012-08-21 |title=Microprocessor Technology |url=https://books.google.com/books?id=VKjkUsCV4moC&pg=PA153 |publisher=[[Routledge]] |page=153 |isbn=9781136078057}}</ref> processor [[status register]] ** <code>n</code> = [[Negative flag|Negative]] ** <code>v</code> = [[Overflow flag|Overflow]] ** <code>b</code> = Break (only in stack values, not in hardware<ref>{{Cite web |title=Status flags |url=https://www.nesdev.org/wiki/Status_flags |access-date=2024-06-11 |website=NESdev Wiki |language=en}}</ref>) ** <code>d</code> = [[Binary-coded decimal|Decimal]] ** <code>i</code> = [[Interrupt]] disable ** <code>z</code> = [[Zero flag|Zero]] ** <code>c</code> = [[Carry flag|Carry]] * <code>PC</code> = 16-bit [[program counter]] * <code>S</code> = 8-bit [[stack (abstract data type)|stack pointer]] * <code>X</code> = 8-bit [[index register]] * <code>Y</code> = 8-bit index register This compares to a contemporaneous competitor, the [[Intel 8080]], which likewise has one 8-bit accumulator and a 16-bit program counter, but has six more general-purpose 8-bit registers (which can be combined into three 16-bit pointers) and a larger 16-bit stack pointer.<ref>{{cite web |title=8080A/8080A-1/8080A-2 8-Bit N Channel Microprocessor |url=http://www.elektronikjk.com/technika_komputerowa/CPU/Intel_8080A.pdf |publisher=Intel |access-date=November 16, 2021 |archive-date=November 15, 2021 |archive-url=https://web.archive.org/web/20211115165927/http://www.elektronikjk.com/technika_komputerowa/CPU/Intel_8080A.pdf |url-status=live }}</ref> In order to make up somewhat for the lack of registers, the 6502 includes a ''[[zero page]]'' addressing mode that uses one address byte in the instruction instead of the two needed to address the full {{val|64|u=KB}} of memory. This provides fast access to the first {{val|256|u=bytes}} of RAM by using shorter instructions. For instance, an instruction to add a value from memory to the value in the accumulator would normally be three bytes, one for the instruction and two for the 16-bit address. Using the zero page reduces this to an 8-bit address, reducing the total instruction length to two bytes, and thus improving instruction performance. The stack address space is [[Wiktionary:Hardwired|hardwired]] to memory page <code>$01</code>, i.e. the address range <code>$0100</code>β<code>$01FF</code> (<code>256</code>β<code>511</code>). Software access to the stack is done via four implied addressing mode instructions, whose functions are to push or pop (pull) the accumulator or the processor status register. The same stack is also used for subroutine calls via the JSR (jump to subroutine) and RTS (return from subroutine) instructions and for [[interrupt]] handling. ===Addressing=== The chip uses the index and stack registers effectively with several [[addressing mode]]s, including a fast "direct page" or "zero page" mode, similar to that found on the [[PDP-8]], that accesses memory locations from addresses 0 to 255 with a single 8-bit address (saving the cycle normally required to fetch the high-order byte of the address){{mdash}}code for the 6502 uses the zero page much as code for other processors would use registers. On some 6502-based microcomputers with an operating system, the [[operating system]] uses most of zero page, leaving only a handful of locations for the user. Addressing modes also include ''implied'' (1-byte instructions); ''absolute'' (3 bytes); ''indexed absolute'' (3 bytes); ''indexed zero-page'' (2 bytes); ''relative'' (2 bytes); ''accumulator'' (1); ''indirect,x'' and ''indirect,y'' (2); and ''immediate'' (2). Absolute mode is a general-purpose mode. Branch instructions use a signed 8-bit offset relative to the instruction after the branch; the numerical range β128..127 therefore translates to 128 bytes backward and 127 bytes forward from the instruction following the branch (which is 126 bytes backward and 129 bytes forward from the start of the branch instruction). Accumulator mode operates on the accumulator register and does not need any [[operand]] data. Immediate mode uses an 8-bit [[literal (computer programming)|literal]] operand. ===Indirect addressing=== The indirect modes are useful for [[Array (data type)|array]] processing and other looping. With the 5/6 cycle "(indirect),y" mode, the 8-bit Y register is added to a 16-bit base address read from zero page, which is located by a single byte following the opcode. The Y register is therefore an ''index'' register in the sense that it is used to hold an actual ''index'' (as opposed to the X register in the 6800, where a base address was directly stored and to which an immediate offset could be added). Incrementing the index register to walk the array byte-wise takes only two additional cycles. With the less frequently used "(indirect,x)" mode the effective address for the operation is found at the zero page address formed by adding the second byte of the instruction to the contents of the X register. Using the indexed modes, the zero page effectively acts as a set of up to 128 additional (though very slow) address registers. The 6502 is capable of performing addition and subtraction in binary or [[binary-coded decimal]]. Placing the CPU into BCD mode with the <code>SED</code> (set D flag) instruction results in decimal arithmetic, in which <code>$99 + $01</code> would result in <var>$00</var> and the carry (C) flag being set. In binary mode (<code>CLD</code>, clear D flag), the same operation would result in <var>$9A</var> and the carry flag being cleared. Other than [[Atari BASIC]], BCD mode was seldom used in home-computer applications. See the [[wikibooks:Computer Programming/Hello world#Accumulator + index register machine: MOS Technology 6502, CBM KERNEL, MOS assembler syntax|Hello world!]] article for a simple but characteristic example of 6502 [[assembly language]]. ===Instructions and opcodes=== 6502 instruction [[opcode|operation code]]s (''opcodes'') are 8 bits long and have the general form AAABBBCC, where AAA and CC define the opcode, and BBB defines the addressing mode.<ref name=ii>{{cite web |url=http://nparker.llx.com/a2/opcodes.html |title=The 6502/65C02/65C816 Instruction Set Decoded |first=Neil |last=Parker |website=Neil Parker's Apple II page |access-date=2019-07-16 |archive-date=2019-07-16 |archive-url=https://web.archive.org/web/20190716023057/http://nparker.llx.com/a2/opcodes.html |url-status=live}}</ref> For example, the <code>ORA</code> instruction performs a bitwise OR on the bits in the accumulator with another value. The instruction opcode is of the form 000bbb01, where bbb may be 010 for an immediate mode value (constant), 001 for zero-page fixed address, 011 for an absolute address, and so on.<ref name=ii/> This pattern is not universal, as there are exceptions, but it allows opcode values to be easily converted to assembly mnemonics for the majority of instructions, handling the edge cases with special-purpose code.<ref name=ii/> Of the 256 possible opcodes available using an 8-bit pattern, the original 6502 uses 151 of them, organized into 56 instructions with (possibly) multiple [[addressing mode]]s. Depending on the instruction and addressing mode, the opcode may require zero, one or two additional bytes for operands. Hence 6502 machine instructions vary in length from one to three bytes.<ref>[http://www.masswerk.at/6502/6502_instruction_set.html 6502 Instruction Set] {{Webarchive|url=https://web.archive.org/web/20180508053805/http://www.masswerk.at/6502/6502_instruction_set.html |date=2018-05-08}}.</ref><ref>[http://www.6502.org/tutorials/6502opcodes.html NMOS 6502 Opcodes]. {{Webarchive|url=https://web.archive.org/web/20160114001557/http://www.6502.org/tutorials/6502opcodes.html |date=2016-01-14}}.</ref> The operand is stored in the 6502's customary [[endianness|little-endian format]]. Each CPU machine instruction takes up a certain number of clock cycles, usually equal to the number of memory accesses. For example, the absolute indexing mode of the ORA instruction takes 4 clock cycles; 3 cycles to read the instruction and 1 cycle to read the value of the absolute address. If no memory is accessed, the number of clock cycles is two. The minimum clock cycles for any instruction is two. When using indexed addressing, if the result crosses a page boundary an extra clock cycle is added. Also, when a zero page address is used in indexing mode (e.g. zp,X) an extra clock cycle is added. The [[WDC 65C816|65C816]], the 16-bit [[CMOS]] descendant of the 6502, also supports 24-bit addressing, which results in instructions being assembled with three-byte operands, also arranged in little-endian format. The remaining 105 opcodes are undefined. In the original design, instructions where the low-order 4 bits (''nibble'') were 3, 7, B or F were not used, providing room for future expansion. Likewise, the $x2 column had only a single entry, <code>LDX #''constant''</code>. The remaining 25 empty slots were distributed. Some of the empty slots were used in the 65C02 to provide both new instructions and variations on existing ones with new addressing modes. The $xF instructions were initially left free to allow 3rd-party vendors to add their own instructions, but later versions of the 65C02 standardized a set of [[bit manipulation]] instructions developed by [[Rockwell Semiconductor]]. ===Assembly language=== A 6502 [[assembly language]] statement consists of a three-character instruction [[mnemonic]], followed by any [[operand]]s. Instructions that do not take a separate operand but target a single register based on the addressing mode combine the target register in the instruction mnemonic, so the assembler uses <code>INX</code> as opposed to <code>INC X</code> to increment the X register. ===Instruction table=== {| class="wikitable collapsible collapsed" !colspan=13| Opcode matrix for the 6502 instruction set |- |colspan=13| Addressing modes: {{font color||#e0e0e0|'''''A'''''}} β accumulator, {{font color||#99ff99|'''''#'''''}} β immediate, {{font color||#ffe0e0|'''''zpg'''''}} β zero page, {{font color||#e0ffff|'''''abs'''''}} β absolute, {{font color||#ffc299|'''''ind'''''}} β indirect, '''''X''''' β indexed by X register, '''''Y''''' β indexed by Y register, {{font color||#ffffe0|'''''rel'''''}} β relative |- !rowspan=2| High nibble ||colspan=12| Low nibble |- ! 0|| 1|| 2|| 4|| 5|| 6|| 8|| 9|| A|| C|| D|| E |- ! 0 | bgcolor=#e0e0e0|BRK | bgcolor=#ffc299|ORA (''ind'',X) | | | bgcolor=#ffe0e0|ORA ''zpg'' | bgcolor=#ffe0e0|ASL ''zpg'' | bgcolor=#e0e0e0|PHP | bgcolor=#99ff99|ORA # | bgcolor=#e0e0e0|ASL A | | bgcolor=#e0ffff|ORA ''abs'' | bgcolor=#e0ffff|ASL ''abs'' |- ! 1 | bgcolor=#ffffe0|BPL ''rel'' | bgcolor=#ffc299|ORA (''ind''),Y | | | bgcolor=#ffe0e0|ORA ''zpg'',X | bgcolor=#ffe0e0|ASL ''zpg'',X | bgcolor=#e0e0e0|CLC | bgcolor=#e0ffff|ORA ''abs'',Y | | | bgcolor=#e0ffff|ORA ''abs'',X | bgcolor=#e0ffff|ASL ''abs'',X |- ! 2 | bgcolor=#e0ffff|JSR ''abs'' | bgcolor=#ffc299|AND (''ind'',X) | | bgcolor=#ffe0e0|BIT ''zpg'' | bgcolor=#ffe0e0|AND ''zpg'' | bgcolor=#ffe0e0|ROL ''zpg'' | bgcolor=#e0e0e0|PLP | bgcolor=#99ff99|AND # | bgcolor=#e0e0e0|ROL A | bgcolor=#e0ffff|BIT ''abs'' | bgcolor=#e0ffff|AND ''abs'' | bgcolor=#e0ffff|ROL ''abs'' |- ! 3 | bgcolor=#ffffe0|BMI ''rel'' | bgcolor=#ffc299|AND (''ind''),Y | | | bgcolor=#ffe0e0|AND ''zpg'',X | bgcolor=#ffe0e0|ROL ''zpg'',X | bgcolor=#e0e0e0|SEC | bgcolor=#e0ffff|AND ''abs'',Y | | | bgcolor=#e0ffff|AND ''abs'',X | bgcolor=#e0ffff|ROL ''abs'',X |- ! 4 | bgcolor=#e0e0e0|RTI | bgcolor=#ffc299|EOR (''ind'',X) | | | bgcolor=#ffe0e0|EOR ''zpg'' | bgcolor=#ffe0e0|LSR ''zpg'' | bgcolor=#e0e0e0|PHA | bgcolor=#99ff99|EOR # | bgcolor=#e0e0e0|LSR A | bgcolor=#e0ffff|JMP ''abs'' | bgcolor=#e0ffff|EOR ''abs'' | bgcolor=#e0ffff|LSR ''abs'' |- ! 5 | bgcolor=#ffffe0|BVC ''rel'' | bgcolor=#ffc299|EOR (''ind''),Y | | | bgcolor=#ffe0e0|EOR ''zpg'',X | bgcolor=#ffe0e0|LSR ''zpg'',X | bgcolor=#e0e0e0|CLI | bgcolor=#e0ffff|EOR ''abs'',Y | | | bgcolor=#e0ffff|EOR ''abs'',X | bgcolor=#e0ffff|LSR ''abs'',X |- ! 6 | bgcolor=#e0e0e0|RTS | bgcolor=#ffc299|ADC (''ind'',X) | | | bgcolor=#ffe0e0|ADC ''zpg'' | bgcolor=#ffe0e0|ROR ''zpg'' | bgcolor=#e0e0e0|PLA | bgcolor=#99ff99|ADC # | bgcolor=#e0e0e0|ROR A | bgcolor=#ffc299|JMP (''ind'') | bgcolor=#e0ffff|ADC ''abs'' | bgcolor=#e0ffff|ROR ''abs'' |- ! 7 | bgcolor=#ffffe0|BVS ''rel'' | bgcolor=#ffc299|ADC (''ind''),Y | | | bgcolor=#ffe0e0|ADC ''zpg'',X | bgcolor=#ffe0e0|ROR ''zpg'',X | bgcolor=#e0e0e0|SEI | bgcolor=#e0ffff|ADC ''abs'',Y | | | bgcolor=#e0ffff|ADC ''abs'',X | bgcolor=#e0ffff|ROR ''abs'',X |- ! 8 | | bgcolor=#ffc299|STA (''ind'',X) | | bgcolor=#ffe0e0|STY ''zpg'' | bgcolor=#ffe0e0|STA ''zpg'' | bgcolor=#ffe0e0|STX ''zpg'' | bgcolor=#e0e0e0|DEY | | bgcolor=#e0e0e0|TXA | bgcolor=#e0ffff|STY ''abs'' | bgcolor=#e0ffff|STA ''abs'' | bgcolor=#e0ffff|STX ''abs'' |- ! 9 | bgcolor=#ffffe0|BCC ''rel'' | bgcolor=#ffc299|STA (''ind''),Y | | bgcolor=#ffe0e0|STY ''zpg'',X | bgcolor=#ffe0e0|STA ''zpg'',X | bgcolor=#ffe0e0|STX ''zpg'',Y | bgcolor=#e0e0e0|TYA | bgcolor=#e0ffff|STA ''abs'',Y | bgcolor=#e0e0e0|TXS | | bgcolor=#e0ffff|STA ''abs'',X | |- ! A | bgcolor=#99ff99|LDY # | bgcolor=#ffc299|LDA (''ind'',X) | bgcolor=#99ff99|LDX # | bgcolor=#ffe0e0|LDY ''zpg'' | bgcolor=#ffe0e0|LDA ''zpg'' | bgcolor=#ffe0e0|LDX ''zpg'' | bgcolor=#e0e0e0|TAY | bgcolor=#99ff99|LDA # | bgcolor=#e0e0e0|TAX | bgcolor=#e0ffff|LDY ''abs'' | bgcolor=#e0ffff|LDA ''abs'' | bgcolor=#e0ffff|LDX ''abs'' |- ! B | bgcolor=#ffffe0|BCS ''rel'' | bgcolor=#ffc299|LDA (''ind''),Y | | bgcolor=#ffe0e0|LDY ''zpg'',X | bgcolor=#ffe0e0|LDA ''zpg'',X | bgcolor=#ffe0e0|LDX ''zpg'',Y | bgcolor=#e0e0e0|CLV | bgcolor=#e0ffff|LDA ''abs'',Y | bgcolor=#e0e0e0|TSX | bgcolor=#e0ffff|LDY ''abs'',X | bgcolor=#e0ffff|LDA ''abs'',X | bgcolor=#e0ffff|LDX ''abs'',Y |- ! C | bgcolor=#99ff99|CPY # | bgcolor=#ffc299|CMP (''ind'',X) | | bgcolor=#ffe0e0|CPY ''zpg'' | bgcolor=#ffe0e0|CMP ''zpg'' | bgcolor=#ffe0e0|DEC ''zpg'' | bgcolor=#e0e0e0|INY | bgcolor=#99ff99|CMP # | bgcolor=#e0e0e0|DEX | bgcolor=#e0ffff|CPY ''abs'' | bgcolor=#e0ffff|CMP ''abs'' | bgcolor=#e0ffff|DEC ''abs'' |- ! D | bgcolor=#ffffe0|BNE ''rel'' | bgcolor=#ffc299|CMP (''ind''),Y | | | bgcolor=#ffe0e0|CMP ''zpg'',X | bgcolor=#ffe0e0|DEC ''zpg'',X | bgcolor=#e0e0e0| CLD | bgcolor=#e0ffff|CMP ''abs'',Y | | | bgcolor=#e0ffff|CMP ''abs'',X | bgcolor=#e0ffff|DEC ''abs'',X |- ! E | bgcolor=#99ff99|CPX # | bgcolor=#ffc299|SBC (''ind'',X) | | bgcolor=#ffe0e0|CPX ''zpg'' | bgcolor=#ffe0e0|SBC ''zpg'' | bgcolor=#ffe0e0|INC ''zpg'' | bgcolor=#e0e0e0|INX | bgcolor=#99ff99|SBC # | bgcolor=#e0e0e0|NOP | bgcolor=#e0ffff|CPX ''abs'' | bgcolor=#e0ffff|SBC ''abs'' | bgcolor=#e0ffff|INC ''abs'' |- ! F | bgcolor=#ffffe0|BEQ ''rel'' | bgcolor=#ffc299|SBC (''ind''),Y | | | bgcolor=#ffe0e0|SBC ''zpg'',X | bgcolor=#ffe0e0|INC ''zpg'',X | bgcolor=#e0e0e0|SED | bgcolor=#e0ffff|SBC ''abs'',Y | | | bgcolor=#e0ffff|SBC ''abs'',X | bgcolor=#e0ffff|INC ''abs'',X |- |colspan=13|Blank opcodes (e.g., '''F2''') and all opcodes whose low nibbles are '''3''', '''7''', '''B''' and '''F''' are undefined in the 6502 instruction set. |} ===Example code=== The following 6502 [[assembly language]] [[source code]] is for a subroutine named <code>TOLOWER</code>, which copies a [[null-terminated string|null-terminated]] [[string (computer science)|character string]] from one location to another, converting upper-case letter characters to lower-case letters. The string being copied is the "source", and the string into which the converted source is stored is the "destination". <!-- NOTE: This is not intended to be optimized code, but to illustrate the variety of instructions available on the CPU. --> <!-- NOTE: Now it is optimized. :) Best to post examples that reflect good programming style & efficiency, rather than examples that are obfuscated in an effort to use the maximum number of different instructions. Also, please avoid using non-standard assembler syntax in 6502 programming examples, e.g., a pseudo-op such as DW, which is not supported by all assemblers. The MOS Technology standard exists for a reason. --> {| | style="vertical-align:top;"| <pre> 0080 0080 00 04 0082 00 05 0600 0600 A0 00 0602 B1 80 0604 F0 11 0606 C9 41 0608 90 06 060A C9 5B 060C B0 02 060E 09 20 0610 91 82 0612 C8 0613 D0 ED 0615 38 0616 60 0617 91 82 0619 18 061A 60 061B </pre> | <syntaxhighlight lang="ca65" highlight="19"> ; TOLOWER: ; ; Convert a null-terminated character string to all lower case. ; Maximum string length is 255 characters, plus the null term- ; inator. ; ; Parameters: ; ; SRC β Source string address ; DST β Destination string address ; ORG $0080 ; SRC .WORD $0400 ;source string pointer DST .WORD $0500 ;destination string pointer ; ORG $0600 ;execution start address ; TOLOWER LDY #$00 ;starting index ; LOOP LDA (SRC),Y ;get from source string BEQ DONE ;end of string ; CMP #'A' ;if lower than UC alphabet... BCC SKIP ;copy unchanged ; CMP #'Z'+1 ;if greater than UC alphabet... BCS SKIP ;copy unchanged ; ORA #%00100000 ;convert to lower case ; SKIP STA (DST),Y ;store to destination string INY ;bump index BNE LOOP ;next character ; ; NOTE: If Y wraps the destination string will be left in an undefined ; state. We set carry to indicate this to the calling function. ; SEC ;report string too long error &... RTS ;return to caller ; DONE STA (DST),Y ;terminate destination string CLC ;report conversion completed &... RTS ;return to caller ; .END </syntaxhighlight> |}
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)