65xx Processor Data by: Mark Ormston (aka Zolaerla or MeMSO) of NeueTECH Software memso@memso.net Version: 0.2b Last Modified: 2007-02-17 Please leave this notice in any version of this text file! This document was made for readability in any general ASCII system, with 100 or more characters per line and 2 spaces per tab. I shall endeavor to convert all tabs to spaces before releasing a version of this document, but if I forget, this at least tells you how to correct it. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! NOTICE! Though I attempt to be as accurate as possible, I am limited to what other sources state. Often times these sources disagree with one another and I end up having to pick and choose what sounds "right", even if it may not necessarily be so. I can give no guarantee of any sort that this information is 100% accurate. I just would like to think it is! If there is any information that would make this more complete, please email me above and let me know! Please put "For MeMSO" (capitalize it properly please) in the subject so I know it's not spam (I get up to 100 of those a day!). !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! This document describes in full detail exactly how the 65xx processors work. This information was gathered so I could program the CPU cores into my emulator. Anybody that knows much of anything about emulators knows that they need to be very exact to properly emulate the systems they are designed for, and it is this exactness I sought when creating this document. Many sources were used, and I have listed as many as I could in an appendix. A .xls file should come with this file. It contains charts of the opcodes/mnemonics in Opcode and Mnemonic sort order, for reference purposes. I have used this chart extensively myself. This document currently covers the following processors: o 6501, 6502, 6507, 6509, 6510 (as far as I can tell, they're programmatically identical) o 2A03 o 65c02 o R65c02 (Rockwell Extended 65c02) o 65sc02 o 65c02S o 65ce02 (4510 and 4502) [As complete as possible, some gaps may still exist] o HuC6280 [As complete as possible, some gaps still exist, esp with the T flag] o 65c816, 65c802 o M740 Family What this document *IS*: o Quite Unabridged o A gathering of information from many, many different sources to consolodate information in just a couple files o Useful for details on the inner workings of these CPUs o A place to find psuedo-code for EVERY opcode (often times not optimized for clarity's sake) o Will give all information necessary to both program and to emulate these processors o System independent. The code and descriptions of the CPUs ignore any hardware they are designed for as much as is humanly possible. About the only exception here is the HuC6280 which seems to be designed only to work for the TG16 What this document *IS NOT*: o A teaching guide for using/programming these processors o A guide for creating computers/systems using these processors (unless you just want the CPU details) o System dependent Hexidecimal values on the 65xx processors is done with a $. $10 is 10 hex (16 decimal), for example. Because these processors use this convention, I am using it throughout the documentation. I personally would prefer to use 0xABCD like C/C++ does, but any other 65xx documentation will also use the $ABCD notation. Throughout this document, I may add an indented section with "* Opinion" to show when I am stating my opinion on something. These may be ignored completely but may point out something that you may not otherwise think about. [x] - I use this to denote sources. For example, if I mention something from "Programming Guide for the 6502, 65c02 and 65c816", I will simply call it [1]. See Sources at the end of the file for a list of sources. ??? - I put this anywhere where I am making a guess but do not know for certain. These are very frustrating for everyone, to be sure. KERBLUH - This is what I use to tell me that more information is needed. *************************************************************************************************** TABLE OF CONTENTS 1 Description of the 65xx line of processors 1.1 6502 Family 1.2 65c02 Family 1.3 R65c02 Family 1.3.1 HuC6280 1.3.2 65ce02 1.4 65c816 Family 1.5 M740 Family 1.6 M7700 Family 2 List of processor registers 2.1 A: Accumulator 2.2 X: X Index 2.3 Y: Y Index 2.4 PC: Program Counter 2.5 S: Stack Pointer 2.6 P: Program flags 2.7 B: Upper Accumulator (65c816 Family Only) 2.8 C: 16bit Accumulator (65c816 Family Only) 2.9 D: Direct Page (65c816 Family Only) 2.10 DBR: Data Bank Register (65c816 Family Only) 2.11 PBR: Program Bank Register (65c816 Family Only) 2.12 e: Emulation Bit (65c816 Family Only) 2.13 cs: Clock Select (HuC6280 Only) 2.14 MPRx: Memory Page Registers (HuC6280 Only) 2.15 B: Base Page Register (65ce02 Only) 2.16 Z: Zero Index (65ce02 Only) 2.17 LRAO: Lower Region Address Offset URAO: Upper Region Address Offset MMRF: Masked Map Region Flags 4510 (65ce02) Only 2.18 fid: Full Interrupt Disable flag (Hidden Flag) (4510 (65ce02) Only) 3 Addressing Modes 3.1 Imp: Implied 3.2 Acc: Accumulator 3.3 Imm: Immediate 3.4 Abs: Absolute 3.5 AbsX: Absolute with X Indexing 3.6 AbsY: Absolute with Y Indexing 3.7 JmpInd: Jump Indirect Absolute 3.8 DP: Zero/Direct/Base Page 3.9 DPX: Zero/Direct/Base Page with X Indexing 3.10 DPY: Zero/Direct/Base Page with Y Indexing 3.11 DPIndX: Zero/Direct/Base Page Indirect with X Pre-Indexing 3.12 DPIndY: Zero/Direct/Base Page Indirect with Y Post-Indexing 3.13 Rel: Relative 3.14 JmpIndX: Jump Indirect with X Pre-Indexing (65c02+ Only) 3.15 DPInd: Zero/Direct Page Indirect (65c02+ & M740 Family Only, not 65ce02) 3.16 DPAndRel: Zero/Base Page and Relative (R65c02 Family and M740 Family Only) 3.17 RelL: Relative Long (65sc02, 65ce02 and 65c816 Family Only) 3.18 SRel: Stack Relative (65c816 Family Only) 3.19 SRelIndY: Stack Relative Indirect with Y Post-Indexing (65c816 Family and 65ce02 Only) 3.20 Block: Block Move (65c816 Family Only) 3.21 AbsL: Absolute Long (65c816 Family Only) 3.22 AbsXL: Absolute Long with X Indexing (65c816 Family Only) 3.23 JmpIndL: Jump Indirect Long (65c816 Family Only) 3.24 DPIndL: Direct Page Indirect Long (65c816 Family Only) 3.25 DPIndYL: Direct Page Indirect Long with Y Post-Indexing (65c816 Family Only) 3.26 DPIndZ: Base Page Indirect with Z Post-Indexing (65ce02 Only) 3.27 Txx: Transfer (HuC6280 Only) 3.28 ImmDP: Immediate and Zero Page (HuC6280 and M740 Family Only) 3.29 ImmDPX: Immediate and Zero Page with X Indexing (HuC6280 Only) 3.30 ImmAbs: Immediate and Absolute (HuC6280 Only) 3.31 ImmAbsX: Immediate and Absolute with X Indexing (HuC6280 Only) 3.32 AAndRel: Accumulator Bit Relative (M740 Family Only) 3.33 JMPSP: Special Page (M740 Family Only) 4 Opcodes/Mnemonics 4.1 Mnemonic Listing Format 4.1.1 Definitions for Code Snippets 4.1.2 Opcode References 4.2 Alphabetic Mnemonic Listing and Full Descriptions 5 Interrupts 5.1 IRQ: Interrupt 5.2 RESET: Reset 5.3 NMI: Non-Maskable Interrupt 5.4 ABORT: Abort 5.5 BRK: Break 5.6 COP: Co-Processor 6 Pins [INCOMPLETE] 7 Quirks and Nuances [INCOMPLETE] ___________________________________________________________________________________________________ A1 Miscellaneous Notes and Issues A2 List of computers/game systems that used these processors (probably forever incomplete, but I can try) A3 TO DO List A4 Updates List ___________________________________________________________________________________________________ Sources Information Sources ___________________________________________________________________________________________________ In the Spreadsheet: Sheet1 Opcodes, sorted by Opcode Sheet2 Opcodes, sorted by Mnemonic Sheet3 Opcodes, sorted by Addressing Mode Sheet4 Reference values *************************************************************************************************** 1 Description of the 65xx line of processors Specifications for this line of processors: Native Depth: 8bit, 65c816 Family: 8bit or 16bit, M7700 Family: 16bit The 65c816 family supported both the old 8bit processing depth and a new 16bit processing depth. The M7700 family removed support for the 8bit method of processing. Endianness: Little (LSB first, 0x1234 is stored as 34 12) Addressing: 16bit (64KB), HuC6280: 21bit (2MB), 4510: 20bit (2MB), 65c816 and M7700 Family: 24bit (16MB) 64KB is directly addressable from the processor 6502 family: Some processors only have enough pins for 4KB to 8KB. Accessing memory above this simply wrapped around HuC6280: Up to 2MB is directly addressable 4510: Up to 1MB is direct addressable 65c816 and M7700 family: Up to 16MB is directly addressable. Note that this does not include the 65c802, which only supported 16bit addressing and only up to 64KB. Hardware Via: Memory Mapped Interrupts: RESET, some have: NMI, Maskable Interrupt, HALT, Software, Special All 65xx processors support RESET, NMI, a maskable interrupt INT and a software interrupt via the BRK instruction. The 6502C (custom for the Atari) added a HALT pin M740: ??? 65c816: Added hardware interrupts for ABORT (cancel an opcode), ???. Added a new software interrupt via the COP instruction. M7700: ??? # of gen regs: 3, 4510: 4 A, X and Y The 4510 introduced an extra general register: Z # of spcl regs:0 (see Segmentation) Stack: Post decremented, Single 256 byte region of memory OR 16bit address capable The stack pointer is decremented AFTER pushing and incremented BEFORE popping. The current stack pointer is pointing to the next address to be pushed to. The 65ce02, 65c816 family and M7700 family all supported 16bit addressing for the stack, allowing it to be up to 64KB (65536 bytes) in size theoretically. Segmentation: None or Special or Segment Registers The 6502 and 65c02 family had no segmentation. The HuC6280 has 8 mapper registers for memory access: MPR0 - MPR7. These replace the upper 3bits of the normal 16bit addressing. The 4510 has 2 mapper registers and a mapper flag register for memory access: LRAO, URAO and MMRF, as well as a page register for their Base Page: B. URAO and LRAO replace the upper 3bits of the normal 16bit addressing The 65c816 Family and the M7700 Family have a page register for their Direct Page: D They also had a bank register for data and a bank register for program code: DBR and PBR Bitwise: Poor to Fair AND, OR and XOR, single bit shifting, single bit rotating, bit testing; some had single bit arithmetic right shifting, bit setting/clearing, branch on bit Single bit rotation and shifting: ROR, ROL, ASL and LSR. The 65ce02 adds arithmetic right shifting: ASR Two value bit testing: BIT HuC6280 has it's own bit tester: TST R65c02 Family and M740 Family has set/reset bit instructions: CLBx/RMBx, SEBx/SMBx R65c02 Family and M740 Family have branch on a specific bit set/reset instructions: BBCx/BBRx, BBSx 65ce02 added two's complement: NEG Relocatable: Minimal to Decent The 6502 Family, R65c02 Family (except 65sc02 and 65ce02) and M740 Family only have relative jump support and indexable memory access, but no relative JSR support. The M740 Family did have a JSR ($ab), but this is of minimal use for jumping to subroutines. The HuC6280 had a BSR to a relative address, but since it only used a signed byte (-128 to 127 bytes) for addressing, it is essentially useless for relocatable code. The 65sc02 and 65ce02 both had a BSR to a relative address, which by itself permits decent relocatable code support. The 65ce02 also added 16bit relative jumps which further add relocatable code support. The 65c816 Family and M7700 Family have a roundabout way of supporting relative subroutines. You can push a relative address onto the stack. To properly call a local subroutine would require two PERs, one for the return address, followed by a RTS to pop the second PER and jump to that location. That routine then could use an RTS to return control back where you started: PER 4 ; Push our return address PER OffsetToJSR ; Put the address of the subroutine on the stack RTS ; Pop the subroutine's location into PC If it was a relative jump out of the current program bank, then you could use: PHK PER 8 ; Push our return address LDX BankOfJSR ; | PHX ; +-> Put the address of the subroutine on the stack PER OffsetToJSR ; | RTL ; Pop the subroutine's location into PBR:PC The subroutine could then use a RTL to return you back to where you started. The 65ce02, 65c816 Family and M7700 Family also all had stack relative addressing, making values pushed onto the stack for function parameters and local variables easy to support. Conditions: Poor Branching if: equal, not equal, above or equal, below, greater or equal, less, positive, negative (BEQ, BNE, BCC, BCS, BVC, BVS, BPL, BMI) Compare and branch if not equal (CBNE) R65c02 family and M740 family had branch if a bit is set or clear (BBCx/BBRx, BBSx) Loop Opcodes: None Mult/Div: None to Minimal M740 added 8bit divide and multiply: DIV, MUL Block Opcodes: None to Poor HuC6280 introduced hard-coded memory copying instructions (forwards and backwards): TAI, TDD, TIA, TII, TIN 65c816 Family and M7700 Family had memory copying (forward and backwards): MVN and MVP Floating Point:None BCD Math: None to Internal for Add & Subtract A flag can be set to determine whether BCD operations are used or not. 2A03: These processors had no BCD support Priviledges: None Pipelining: None Multitasking: No hardware support Mult Proc Supp:None SIMD Support: None The 65xx processors are fairly simple 8bit or 16bit processors. They are little endian, meaning they store multi-byte data with the least significant byte (LSB) first and moving up to the most significant byte (MSB) at the end of the memory location. Hardware is accessed through memory locations. This means that hardware devices use a shared region of memory for read/write operations. These processors are NOT register-oriented (there is only one general purpose register and two indexing registers). They are designed to work on systems where memory is comparably quick to using on-CPU registers, and to compensate for the lack of unique registers there are many addressing modes for accessing memory. Of particular interest is what is called Zero or Direct Page addressing, which makes accessing a 256 byte region of memory available quickly and with fewer bytes than other memory accessing addressing modes. The processors are also not arithmetic-oriented. The only math functions that exist are addition (ADC) and subtraction (SBC) as well as increment and decrement, though there are a few bitwise operations available such as single bit shifting, and/or/xor, etc. To use any other math operations, such as multiplication, special routines need to be written. * Opinion: This is the single biggest reason why I would look to any other processor for creating my own devices, unless they were very simple. The Western Design Center documentation at least provides functions for multiply and divide (with remainder) to simulate the multiply and divide opcodes in other CPUs. 65xx processors are incredibly fast for memory and data accessing for the time they came out. Moving an 8bit value to the accumulator on the 6502, "LDA $ABCD" for example, takes only 4 cycles. The same thing on the 8086, "mov al, [0ABCDh]", takes 13 cycles, and on the 68000, "move.b D1, $ABCD.w", takes 12 cycles! As you can see, for the same amount of CPU power, the 6502 can do about three moves for every move on the 68000 or 8086. If the 6502 was doing a Zero Page memory read, it'd reduce the time to 3 cycles. * Opinion: This part is really cool. 65xx systems are fairly quick if memory reading and writing is the most important task of the processor, especially back when they were first created. Most of the 65xx processors support IRQ (Interrupt ReQuest) which can be masked via a flag, and an NMI (Non-Maskable Interrupt) which will always occur as necessary. See the 6502 Family of Processors below for the list of CPUs that do not support IRQ and NMI. Software interrupts are possible with the break instruction (BRK). All processors in the 65c02, R65c02 and 65c816 families support both. Note that 65x pull instructions set the negative and zero flags, unlike 68xx and x86 processors; that store instructions do not set any flags, unlike 68xx processors; that transfer and exchange instructions do set flags, unlike Motorola and Intel processors; that load instructions do set flags, unlike the x86; and increment and decrement instructions do not affect the carry flag. There are six basic families of the 65xx processors: 6502, 65c02, R65c02 (Rockwell 65c02), 65c816, M740 and M7700. I have no idea if anybody else groups them like this, but it makes logical sense to me because these families all share almost identical register and opcode lists. The reason I separate R65c02 into it's own family is that the list of processors in that group have their own extra instructions that are not upward compatible with the 16bit 65c816; in essence, they are a separate branch from the 65c816. A family tree of processors will look like: 6502 ---- M740 / | \ 65c02 6510 2A03 / \ 65c816 R65c02 / / | \ M37700 65c02S 65sc02 HuC6280 | | M37750 65ce02 * Opinion: In my opinion, the most versatile of these processors is the 65c816, with true 8/16bit support. The 65CE02 is the most advanced 8bit processor in the list, though some would argue the HuC6280 is moreso. However, I find the design and structure of the HuC6280 to be rather sloppy and not well thought out, and it also is not really designed from a computer's standpoint but more for a dedicated machine, as it was used for. The M7700 series, especially the M37750 (extended instruction set), is the most powerful processor in this list, though it is a bit obscure compared to many of the others and the cycles-per-instruction on it are terrible compared to the 65c816 (eg, BCC takes 4/6 clocks instead of 2/3). Though not in this document, there are many other processors that were created based on the original 65xx line of processors. These include the M7900 family of processors (designed to be M7700 series source compatible but they have completely different opcodes), and the SPC700 (used by the SNES for it's sound processor). As far as I can tell, the original 65xx (the 6501?) was based on the Motorola 6800 CPU. ___________________________________________________________________________________________________ 1.1 6502 Family of Processors This is the first family of 65xx processors developed (I think so anyways...) by MOS Semiconductors around 1975. They are 8bit processors with 16bit addressing (up to 64KB), have 56 "documented" instructions, 13 addressing modes, and are made using the NMOS (N-channel Metal-Oxide Semiconductor) process. They can access anywhere from 4KB to 64KB of RAM, depending on the type of the CPU. --------------------------------------------------------------------------------------------------- Quirks and Nuances ................................................................................................... Illegal Opcodes Several of the undocumented opcodes actually do something, even if they were somewhat unpredictable. This gives 24 new "illegal" instructions, though one always locks up the CPU (HLT) and three others are essentially NOPs (No OPeration; these are NOP other than EA, SKB for skip byte, and SKW for skip word). Of the 20 others, 12 are stable (predictable) and may actually be used. * Opinion: This is one of the most amazing things I've heard of on a processor. It's almost like finding an easter egg or secret room in a game. The fact that it was completely unintentional is somewhat amusing, but explains why some of them are so unstable. ................................................................................................... JMP ($abcd) Bug When using indirect addressing with the jump instruction, and the operand ends with $FF, the low byte is grabbed from the correct address, but the high byte of the address to jump to is at $00 of the same page. For example: if you do a JMP ($10FF), the address jumped to would be $10FF for the low byte, and $1000 for the high byte (instead of $1100 as would be expected). ................................................................................................... Decimal Mode (BCD) and ADC/SBC When using decimal mode (BCD or Binary Coded Decimal), the negative, overflow and zero flags are not set properly. ................................................................................................... Flags on reset On a reset (even on a hardware reset), the decimal flag's status is not cleared so it is unknown and needs to be cleared by the reset handler. --------------------------------------------------------------------------------------------------- Processor Versions The basic differences between most of the 6502 family are visible in this chart (according to [3]): 6 6 6 6 6 6 6 6 6 6 5 5 5 5 5 5 5 5 5 5 0 0 0 0 0 0 1 1 1 1 2 3 4 5 6 7 2 3 4 5 # of Pins 40 28 28 28 28 28 40 28 28 28 Max KB of Memory 64 4 8 4 4 8 64 4 8 4 On-Chip Clock X X X X X X - - - - TTL-Level input X - - - - - - - - - RC time base input X - - - - - - - - - Crystal time input X - - - - - - - - - 2phase output clock X - - - X - X X X X IRQ interrupt X X X X X - X X X X NMI interrupt X X - - - - X X - - RDY signal X - - X - X X - - X SYNC signal X - - - - - X - - - Data Bus Enable - - - - - - X - - - Several other versions of the 6502 family of processors existed: 2A03 NES's NTSC processor. Same as a 6502 but without decimal mode support. The d flag is simply ignored 2A07 NES's PAL processor. Same as the 2A03 but with a different speed ??? 6501 First version of the 6502 which was pin-compatible with the Motorola 6800. The 6502 was created later with the pins rearranged because of a lawsuit by Motorola over the compatible pin arrangement on the 6501 6502A Original version of the 6502 ??? 6502B Possibly identical to the 6502A except for speed 6502C Has a HALT pin built in, to allow external devices to halt the CPU 6507 As you can see in the chart above, this is essentially the same as a 6502 but with only 8KB of addressable memory and no NMI or IRQ pins available (no hardware interrupts!) 6508 ??? 6509 As far as I can tell, this is the same as the 6502 6510 The successor to the 6502. It had an additional 8bit general purpose I/O port, as well as allowing the addressing bus to be made tristate (KERBLUH - what does this mean for emulation purposes?) 7501 ??? 8500 ??? 8501 ??? 8502 Another name for the 6510 DECO16 A 6502-like processor that seems to have only been used for a couple arcade machines ___________________________________________________________________________________________________ 1.2 65c02 Family of Processors These were created as an update and correction to the original 6502 family of processors created around 1981. These CPUs used CMOS (Complementary Metal-Oxide Semiconductor) technology instead of NMOS, which makes them use less power and give off less heat. The most significant changes in the 65c02 are the fixes from the 6502: all previous "bugs" have been amended. JMP to an indirect location when the low byte of the address is $FF, the flags when working in decimal mode, the decimal flag not being reset after a reset, and even the list of unimplemented instructions have all been corrected. In the case of the unimplemented instructions, these act like NOP instructions, though they can take 1 to 3 bytes and 1 to 8 cycles to execute, depending on the value. However, the JMP ($abcd) instruction correction costs an extra cycle (only when the low byte is $FF), as do the correctly set flags in decimal mode. 10 new instructions are added: BRA, DEA, INA, PHX, PHY, PLX, PLY, STZ, TRB and TSB 2 new addressing modes are added: Absolute Indexed Indirect (JMP ($abcd,X)) and Zero Page Indirect (ADC ($ab)). A couple of the most important new addressing modes added to existing instructions are DEA (DEC A) and INA (INC A), since on the 6502s, there was no way to DEC or INC on the Accumulator without using the SBC or ADC instructions. Also the very handy BRA (BRanch Always) was added, allowing relative jumps that use one less byte than JMP $abcd. --------------------------------------------------------------------------------------------------- Processor Versions Aside from the straight 65c02 that was used on some of the Apple II computers, I don't know of any other processors that fit into this family. The similar R65c02 processors I have grouped into a separate family because they are not upward compatible with the 65c816, having created a "niche" of their own, while the 65c02 is upward compatible with the 65c816. Maybe because of this, the 65c02 should belong in the 6502 family. I believe it's different enough to warrant it's own category however. ___________________________________________________________________________________________________ 1.3 R65c02 Family of Processors While this is really a different "version" of the 65c02, it has so many differences and since it is not upwardly compatible with the 65c816 like the 6502 and 65c02 are, I have classified it under it's own family. I do not know the "official" name of this line of processors, so I am naming it after the R65c02 (Rockwell model 65c02) which seems to be the first (or maybe the most common) that uses the extra instructions in the set. 4 new instructions are added: BBRx, BBSx, RMBx, and SMBx. These are NOT present on the 65c816. 1 new addressing mode is added: Zero Page and Relative (BBS0 $ab, nearlabel). The basic differences between some of the R65c02s are visible in this chart (according to [4]): R65c02 R65c102 R65c112 Pin Compatible with NMOS 6502 X - - 64KB addressable bytes of memory X X X IRQ interrupt X X X On-chip clock oscillator - X - External clock only X - X TTL level single phase clock input X X - RC time base clock input X X - Crystal time base clock input X X - Single phase clock input - - X Two phase output clock X X - SYNC and RDY signals X X X Bus Enable (BE) signal - X X Memory Lock (ML) output signal - X X Direct Memory Access (DMA) capacity - X X NMI interrupt signal X X X --------------------------------------------------------------------------------------------------- Processor Versions A few versions of the R65c02 exist: R65c02 The Rockwell 65c02 as described above R65c102 This is the full version of the R65c02 and includes DMA support R65c112 This is the slave processor version of the R65c02 65c02S An update on the R65c02 design, but by Western Design Center. It also adds support for the WAI and STP instructions that are available on the 65c816. It is mostly designed for low power System-on-Chip (SoC) designs 65sc02 As far as I can tell, this is an R65c02 with a 16bit relative BSR added (Opcode 63) from GTE 65ce02 A custom made 65c02 for the (never released) C64DX (or C65) Commodore computer. See section 1.3.2 C4502R1 The name of the 65ce02 before the memory mapping was added to it. On this CPU, EA is still NOP and 5C is AUG (Augment) instead of MAP. I could find no more information on this CPU anywhere, and since both the 4502 and the 4510 were never really released, I doubt I ever will. CSG4510 Another name for the 65ce02, which seems to include the CPU, the memory mapping module, timers, and serial connections. It is also called the 4510R3 in places HuC6280 Hudson Soft's "improved" 65c02 CPU used for the Turbo Grafix 16. See section 1.3.1 =================================================================================================== 1.3.1 HuC6280 This processor has 21bit addressing instead of 16bit addressing which is controlled through the (unusual) memory mapper registers which are accessed through the top 3 bits of every address. While it is a faster CPU, many memory accessing opcodes take more cycles (I'd assume because of this complicated MPR handling). 21 new instructions are added: BSR, CLA, CLX, CLY, CSH, CSL, SAX, SAY, SET, SXY, ST0, ST1, ST2, TAI, TAM, TDD, TIA, TII, TIN, TMA, TST. 5 new addressing modes are added: Transfer (TII $1234,$5678,$9ABC), Immediate and Zero Page (TST #$12,$34), Immediate and Zero Page with X Indexing (TST #$12,$34,X), Immediate and Absolute (TST #$12,$3456), and Immediate and Absolute with X Indexing (TST #$12,$3456,X). In my opcodes/timing charts, I have no clue if the HuC6280 is affected by 65c02 extra cycles or not, except where listed. Various documentation varies greatly on even simple things such as processor timing. Since [19] seems to have the most realistic cycles listed, I am going to base my information on it's information. I can't believe that DPInd takes more cycles than DPIndX or DPIndY! For modifiers to cycles taken, I'm basing my data on [16]'s implementation, no clue which is more accurate and since I started with [16] it means I don't need to redo everything I've done already at least in that regard. All invalid instructions on the HuC6280 are simply 1 byte NOPs and take 2 cycles according to [17]. * Opinion: Most of the new opcodes added to this processor are almost a waste of time. Sure, the SAX, SAY, etc. are useful. And the Memory Mapping registers are cool, though kinda difficult to understand. However, the TAI,TDD,TIA,TII and TIN opcodes were all created with HARD CODED parameters, both breaking the standard addressing mode format of the 6502s, and also making them no where near as useful as they could have been had they used registers or indirect addressing. Others, like CLA,CLX,CLY are almost useless. They take 2 cycles, just like an LDA #$00, LDX #$00, etc. would take, though I guess they do save a byte; but why waste a whole opcode for that? And then we get to the really stupid BSR nearlabel (how many subroutines do we keep within 127 bytes of our code???) If it was a signed 16bit value, then it'd be VERY useful! =================================================================================================== 1.3.2 65ce02 There are two versions of this processor, though neither was ever really released: 4502 and 4510. The 4502 is only hinted at in [13]. As far as I can tell, the only differences are that EOM is still just NOP on that CPU and that instead of MAP, it has an AUG (Augment) opcode that nobody knows anything about (probably because the CPU never existed!). The 4510 had internal support for 20bit memory addressing, though all of it's instructions only used 8bit (for Base Page) and 16bit pointers. This was possible with a set of memory mapping registers and a MAP instruction which set the values of the memory mapping registers. From this point forward, we are assuming the 65ce02 is a 4510 and not a 4502 since as far as I know, there never was any documentation on the 4502. The processor has 20bit addressing available through memory mapping similar to the HuC6280, where opcodes still access only 8/16bit addresses but addresses support mapping into 20bit memory addresses. 26 new instructions are added: ASR, ASW, BSR, CLE, CPZ, DEW, DEZ, EOM, INW, INZ, LDZ, MAP, NEG, PHW, PHZ, PLZ, ROW, RTN, SEE, STZ, TAB, TAZ, TBA, TSY, TYS, TZA. 3 new addressing modes are added: Relative Long (BCC farlabel), Stack Relative Indirect with Y Post-Indexing (LDA ($ab,S),Y; also available on the 65c816) and Direct Page Indirect becomes Base Page Indirect with Z Post-Indexing (ADC ($ab),Z). 3 new registers are added: B (Base Page, similar to D on the 65c816 except it points to the Page the Zero Page is on [high byte only]), e (Extended Stack Disable bit, to permit using an "Extended" 16bit Stack) and Z (Z or Zero Index). All Zero Page addressing modes are called Base Page on the 65ce02. It changed Zero Page Indirect to Base Page Indirect Z Indexed, and adding the Stack Indexed with Y addressing mode that is available on the 65c816. All branches have 16bit relative versions as well as the 8bit relative versions. Many of the new instructions also are for use on a 16bit value in memory; all of the ones ending in W (for word). The cycles required for many operations have been reduced, in particular register only, absolute indexed, zero page indexed and zero page indirect instructions. The extra cycles for taking jumps, crossing page boundaries, etc. no longer exist. The instructions that use only 1 cycle do not allow the processor to check for interrupts. This is useful if you are moving the 16bit stack to a new location because no interrupt will occur until after you've executed both TXS and TYS. If an interrupt could occur between these instructions, then the stack may be pointing to an invalid position in memory that the interrupt would then push it's data into, a bad situation in any case! ** These registers are statuses on the processor, but I have assigned names to them to describe them more easily: LRAO, the Lower Region Address Offset, URAO, the Upper Region Address Offset, MMRF, the Masked Map Region Flags, and fid, the Full Interrupt Disable flag (Hidden Flag). ___________________________________________________________________________________________________ 1.4 65c816 Family of Processors The 65c816 (or just 65816) was created as an enhanced 65c02 processor, and first released in early 1985. Just like the 65c02, the 65c816 is a CMOS processor, but it does not have the same pin out configuration. This processor was a huge leap from the 6502 and 65c02 because it supported both the old 8bit w/ 16bit addressing (emulation mode) that the older processors supported, as well as adding 16bit w/ 24bit addressing (native mode) support. 26 new instructions (though STP and WAI were on the 65c02S) are added: BRL, COP, MVN, MVP, PEA, PEI, PER, PHB, PHD, PHK, PLB, PLD, REP, RTL, SEP, STP, TCD, TCS, TDC, TSC, TXY, TYX, WAI, WDM, XBA and XCE. 9 new addressing modes are added: Relative Long (BRL farlabel), Stack Relative (SBC $12,S), Stack Relative Indirect with Y Post-Indexing (EOR ($12,S),Y), Block Move (MVP $01,$23), Absolute Long (CMP $123456), Absolute Long with X Indexing (LDA $123456,X), Jump Indirect Long (JMP [$1234]), Direct Page Indirect Long (ADC [$12]), and Direct Page Indirect Long with Y Post-Indexing (ORA [$ab],Y) It does NOT have the BBRx, BBSx, RMBx and SMBx instructions that are available on the R65c02 Family. The new addressing modes are for 24bit addressing support, to support some of the new instructions such as MVN/MVP, as well as two stack relative addressing modes for accessing local variables in a subroutine. And lastly but definitely not least, Zero Page was changed to what is called Direct Page: a pointer register called D (Direct Page Pointer) was added that points to anywhere in the first 64KB that Zero Page access actually reaches. * Opinion: This processor is worlds apart from the 65c02 in reality. Sure, in emulation mode, it functions very similar albeit with several new instructions. But man, some of the new additions are huge, even without 16bit support, such as direct page support, the ability to relocate code, and the MVN/MVP (block move) instructions. Too bad they didn't add a MUL, DIV, or even a BSR! --------------------------------------------------------------------------------------------------- Quirks and Nuances ................................................................................................... From [1]: Direct Page and 8bit/Emulation Mode: Pay particular attention to the peculiarities of the direct page in the emulation mode: as with the 6502 and 65C02, instructions which use direct page addressing modes will "wrap" to stay within the zero page, but only when the direct page register is equal to zero. Opcodes which are not found on the 6502 or 65C02 will not wrap at all, even when the direct page is equal to zero in the emulation mode. Also, if ever the low byte of D is non-zero, a cycle is added to every direct page addressing mode so it's highly recommended that this is never done. Stack and 8bit/Emulation Mode: Although the high byte of the stack register is consistently forced to one, new 65c816 opcodes executed in the emulation mode will not wrap the stack if the low byte over- or underflowed in the middle of an instruction. For example, if the stack pointer is equal to $101, and a JSL is executed, the final byte of the three bytes pushed on the stack will be at $FF, not $1FF; but the stack pointer at the end of the instruction will point to $1FE. However, if JSR (a 6502 instruction) is executed in the emulation mode with the stack pointer equal to $100, the second of the two bytes pushed will be stored at $1FF. Addressing wrap around: Whenever a 65c816 base is specified by a 24-bit (long) address, or the base is specified by sixteen bits and assumes the data bank as its bank, then, if an index plus the low-order sixteen bits of its base exceeds $FFFF, it will temporarily (just for the current instruction) increment the bank. The 65c816 assumes that the array being accessed extends into the next bank. ................................................................................................... Something I could not find in [1] was what happened on the very rare case that a 16bit read occurred at $FFFF in a particular bank. The answer came from [10]. In the cases where bank cross over is supported, a word read at $FFFF actually DOES extend into the next bank. If we are reading A in 16bit mode from $01FFFF, then the high byte of A will be read from $020000. I am assuming this only happens to new instructions or in Native Mode ???, but I'm not positive. --------------------------------------------------------------------------------------------------- Processor Versions A couple versions of the 65c816 exist: 65c816 The 16bit upgraded 65c02 described above 65c802 This processor is identical to the 65c816, EXCEPT it can only access bank 0, and all bank access values are ignored. It was created using the same pin out as the 65c02 so it could be used to replace 65c02s on older systems. Because of this, it also does not support the ABORT interrupt ___________________________________________________________________________________________________ 1.5 M740 Family of Processors These processors are based on the 6502 (NMOS) CPUs, though they themselves are CMOS-based. They have many of the quirks of that line of processor ([21] states that you should never call JMP ($abcd) if the low byte of the address is $FF, which tells me that even that bug is still present). P (Processor flags) is called PS in [20] (Processor Status flags). 14 new instructions are added: BBCx (same as BBRx on R65c02), BBSx (same as BBSx on R65c02), CLBx (same as RMBx on R65c02), CLT, COM, DIV, LDM, MUL, RRF, SEBx (same as SMBx on R65c02), SET, STP (same as STP on 65c816), TST, WIT (same as WAI on 65c816). 3 new addressing modes are added: Special page (JMP \$12), Zero Page and Relative (BBS1 $ab, nearlabel; same as on R65c02), and Accumulator Bit Relative (BBC3 A, nearlabel). Bit 5 of PS is replaced with a memory transfer flag, similar to the HuC6280 but it can be turned on and it will stay on until it is turned off. Interrupts are handled differently. KERBLUH- Need more info --------------------------------------------------------------------------------------------------- Quirks/Nuances: KERBLUH- These are directly taken from [20]. I need to change them to match the language style of the rest of this document. ................................................................................................... Setting for interrupt request bit and interrupt enable bit: To set an interrupt request bit and an interrupt enable bit for interrupts, execute as the following sequence: 1. Clear an interrupt request bit to 0 (no interrupt request issued). 2. Set an interrupt enable bit to 1 (interrupts enabled). Reason: If the above setting are performed simultaneously with one instruction, an unnecessary interrupt processing routine is executed. Because an interrupt enable bit is set to 1 (interrupts enabled) before an interrupt request bit is cleared to 0. ................................................................................................... Switching of detection edge: For the products able to switch the external interrupt detection edge (KERBLUH- which are?), switch it as the following sequence: 1. Clear an interrupt enable bit to 0 (interrupt disabled) 2. Switch the detection edge 3. Clear an interrupt request bit to 0 (no interrupt request issued) 4. Set the interrupt enabled bit to 1 (interrupt enabled) Reason: The interrupt circuit recognizes the switching of the detection edge as the change of external input signals. This may cause to execute an unnecessary interrupt processing routine. ................................................................................................... Distinction of interrupt request bit: When executing the BBC or BBS instruction to an interrupt request (request distinguish) bit of an interrupt request register (interrupt request distinguish register) immediately after this bit is set to 0 by using a data transfer instruction], execute one or more instructions before executing the BBC or BBS instruction: 1. Clear an interrupt request (request distinguish) bit to 0 (no interrupt request issued) 2. NOP instruction (one or more instructions) 3. Execute the BBC or BBS instruction Data transfer instruction : LDM, LDA, STA, STX, STY Reason If the BBC or BBS instruction is executed immediately after an interrupt request (request distinguish) bit of an interrupt request register (interrupt request distinguish register) is cleared to 0, the value of the interrupt request (request distinguish) bit before being cleared to 0 is read. ................................................................................................... Initialization of Processor Status Register: Flags which affect program execution must be initialized after a reset. In particular, it is essential to initialize the T and D flags because they have an important effect on calculations. Reason After a reset, the contents of processor status register (PS) are undefined except for the I flag which is 1. ................................................................................................... How to reference Processor Status Register: To reference the contents of the processor status register (PS), execute the PHP instruction once then read the contents of (S + 1). If necessary, execute the PLP instruction to return the PS to its original status. A NOP instruction should be executed after every PLP instruction. KERBLUH- Why do we need a NOP? Are flags not actually set until the next clock cycle? ................................................................................................... Interrupt priority level: At the following status, 1.the interrupt request bit has set to 1 2. the interrupt enable bit has set to 1 3. the interrupt disable flag (I) has set to 1 If the BRK instruction is executed, the interrupt disable state is cancelled and it becomes in the interrupt enable state. So that the requested interrupts (the interrupts that corresponding to their request bits have set to 1) are accepted. ................................................................................................... Execution of Decimal calculations: The ADC and SBC are the only instructions which will yield proper decimal results in decimal mode. To calculate in decimal notation, set the decimal mode flag (D) to 1 with the SED instruction. After executing the ADC or SBC instruction, execute another instruction before executing the SEC, CLC, or CLD instruction. Example: SED ADC #$12 NOP CLD KERBLUH- Why do we need a NOP? Are flags not actually set until the next clock cycle? ................................................................................................... Status flags in decimal mode: When decimal mode is selected (D = 1), the values of three of the flags in the status register (the flags N, V, and Z) are invalid after a ADC or SBC instruction is executed. The carry flag (C) is set to 1 if a carry is generated as a result of the calculation, or is cleared to 0 if a borrow is generated. To determine whether a calculation has generated a carry, the C flag must be initialized to 0 before each calculation. To check for a borrow, the C flag must be initialized to 1 before each calculation. KERBLUH- Why does C need to be cleared before each ADC or set before each SBC? Doesn't this negate the purpose of the C flag for BCD calculations? ................................................................................................... Quirks carried over from the 6502: JMP ($xxFF) still grabs the high byte from ($xx00) If the decimal flag is set in ADC or SBC, the N, V and Z flags are set incorrectly ................................................................................................... Illegal Opcodes: KERBLUH- I have no clue what happens on this processor when an illegal opcode is encountered. For now, I will assume that they are NOPs that use 1 byte and 2 cycles, just like opcode EA. On M740 Family CPUs that do not have STP, the 42 opcode acts just like a NOP --------------------------------------------------------------------------------------------------- Processor Versions They are made by Mitsubishi and have a number of alternate names. The best documented of those that I could find was the M37531 line, which [21] states "is useful for control of home electric appliances and office automation equipment." Here is a comparison chart for the M37531 line from [21]: Product ROM (bytes) RAM Package Remarks (user ROM) (bytes) M37531M4-XXXSP 8192 (8062) 256 32P4B Mask ROM Version M37531M4T-XXXSP 8192 (8062) 256 32P4B Mask ROM Version (extended operating temperature version) M37531E4SP 8192 (8062) 256 32P4B One Time PROM version (blank) M37531M4-XXXFP 8192 (8062) 256 36P2R-A Mask ROM Version M37531M4T-XXXFP 8192 (8062) 256 36P2R-A Mask ROM Version (extended operating temperature version) M37531E4FP 8192 (8062) 256 36P2R-A One Time PROM version (blank) M37531M4-XXXGP 8192 (8062) 256 36P6B-A Mask ROM Version M37531M4T-XXXGP 8192 (8062) 256 36P6B-A Mask ROM Version (extended operating temperature version) M37531M4V-XXXGP 8192 (8062) 256 36P6B-A Mask ROM Version (extended operating temperature 125°C version) M37531E4GP 8192 (8062) 256 36P6B-A One Time PROM version (blank) M37531E4T-XXXGP 8192 (8062) 256 36P6B-A One Time PROM version (shipped after programming, extended operating temperature version) M37531E4V-XXXGP 8192 (8062) 256 36P6B-A One Time PROM version (shipped after programming, extended operating temperature 125°C version) M37531M8-XXXSP 16834 (16254) 384 32P4B Mask ROM version M37531E8SP 16834 (16254) 384 32P4B One Time PROM version (blank) M37531M8-XXXFP 16834 (16254) 384 36P2R-A Mask ROM version M37531E8FP 16834 (16254) 384 36P2R-A One Time PROM version (blank) M37531M8-XXXGP 16834 (16254) 384 32P6B-A Mask ROM version M37531RSS ------------- 384 42S1M Emulator MCU A few versions of the M740 family exist: M37408 Does not have the MUL or DIV instructions M37409 Does not have the MUL or DIV instructions M37410 Does not have the MUL or DIV instructions M37412 Does not have the MUL or DIV instructions M37413 Does not have the MUL or DIV instructions M37414 Does not have the MUL or DIV instructions M37415 Does not have the MUL or DIV instructions M37416 Does not have the MUL or DIV instructions M37417 Does not have the MUL or DIV instructions M37418 Does not have the MUL or DIV instructions M37420 Does not have the MUL or DIV instructions M37421 Does not have the MUL or DIV instructions M37424 Does not have the STP instruction M37524 Does not have the STP instruction M37531 Full featured M740 with all instructions M507XX Does not have the MUL or DIV instructions M509XX Does not have the MUL or DIV instructions ___________________________________________________________________________________________________ 1.6 M7700 Family of Processors These processors are based on the 65c816 CPUs and are made by Mitsubishi. However, a few key differences are: emulation mode is NOT available (native mode only), it has advanced internal timers, it has priviledge level based interrupts similar to the Motorola 68000 line of processors, KERBLUH- anything else?. Several of the existing 65c816 opcodes are replaced or changed: Opcodes 1A and 3A (INA and DEA respectively on the 65c816) have switched places to match the M740 family of processors (INA is 3A and DEA is 1A). Opcode 42 (WDM on 65c816) is used for a number of instructions that operate on B, a secondary accumulator; the opcode following 42 must be an opcode that normally works on A, but it will operate on B instead. Opcode 89 (BIT #$ab on 65c816) is used as a prefix for extended opcodes, mostly the new multiply (MPY and MPYS) and divide (DIV and DIVS) opcodes. Opcode EB (XBA on 65c816) was removed to put in PSH, which pushes several registers onto the stack simultaneously. Opcode FB (XCE on 65c816) was removed to put in PUL, which does the reverse of PSH; pulling several registers from the stack simultaneously. ??? new instructions are added (after the 65c816): (KERBLUH- list) The latest line of these processors, the M37750 series, adds five more instructions: ASR, DIVS, EXTS, EXTZ and MPYS. ??? new addressing modes are added (after the 65c816): (KERBLUH- list). --------------------------------------------------------------------------------------------------- Processor Versions [22] lists that there are four distinct series of CPUs in this family: 37700 Series The original M7700 series ??? 37750 Series As far as I can tell, these are the most advanced of the M7700s, though why they have a lower number than other series is beyond me. The extra instructions they support are mostly for signed operations 37770 Series ??? 37790 Series ??? *************************************************************************************************** 2 Registers *SPECIAL NOTES FOR THE 65c816 and M7700 Families Only* 8bit mode on the 65c816 is known as Emulation Mode and 16bit mode is known as Native Mode, though the 65c816 is natively in emulation mode (for downward compatibility), so the wording is a bit confusing. The M7700 family is ALWAYS in Native Mode (16bit). When 16bit to 8bit functions occur, such as when A is 16bit and X/Y are 8bit, X and Y always take 0 for the high byte. For example, if A is 16bit and X is 8bit, then TXA will put the zero-extend 8bit value of X into A. If TAX is used, then the top byte of A is removed and the lower byte placed into X. KERBLUH - Is this true for the M7700 family? On the 65c816, When switching from emulation to native mode the processor replaces the b BREAK flag and bit 5 with the 65c816 x and m flags respectively, and sets them to one. This leaves the index registers and accumulator/memory in 8 bit mode (which is the same as emulation mode). The remaining bits in the status register are unchanged. The stack pointer remains at page one. When switching from native mode into emulation mode; the m and x status register bit disappear, putting the accumulator and index registers at 8 bit. Whenever x is changed to 8bit, the X and Y low bytes are retained, but the high bytes are lost. When m is changed to 8bit or switching to emulation mode, the Accumulator low and high bytes are both retained (of course the high byte is hidden but accessible with the XBA instruction). The stack pointer is returned to eights bits with the high byte forced to one when changing to emulation mode. *END SPECIAL NOTE* These are sorted by processor, then most common use. So A comes first, then X, then Y, then PC, etc. ___________________________________________________________________________________________________ 2.1 A: Accumulator 8bit (16bit on the M7700 Family or in native mode on the 65c816). The accumulator, the main register. Most of the work of the processor operates through this register, especially math and binary operations. 65c816: In emulation mode, this is specifically the lower 8bits of A When switching from native to emulation mode, the upper byte of A is NOT lost, and is still accessible through the B register. ___________________________________________________________________________________________________ 2.2 X: X Index 8bit (16bit on the M7700 Family or on 65c816 if in native mode and x bit is clear). A general purpose indexing register. Often used for preindexed indirect addressing (an offset into a list of pointers). 65c816: When switched between 16bit and 8bit, the upper byte is set to 0. M7700: The upper byte is NOT set to 0 when switching from 16bit to 8bit. ___________________________________________________________________________________________________ 2.3 Y: Y Index 8bit (16bit on the M7700 Family or on 65c816 if in native mode and x bit is clear). A general purpose indexing register. Often used for postindexed indirect addressing (an offset to a pointer). 65c816: When switched between 16bit and 8bit, the upper byte is set to 0. M7700: The upper byte is NOT set to 0 when switching from 16bit to 8bit. ___________________________________________________________________________________________________ 2.4 PC: Program Counter 16bit. This register points to the location the program is currently executing at. For Example: If PC is $2000, then the next instruction to be executed will be that at $2000 in memory. 65c816: If PC increments past $FFFF, it simple wraps around to $0000 WITHOUT affecting PBR. ___________________________________________________________________________________________________ 2.5 S: Stack Pointer 8bit (16bit on the M7700 Family, on 65c816 in native mode, or on 65ce02 when the Extended Stack Disable bit is cleared). Where the stack currently is located, offset in $0100 in memory if it is 8bit. Whenever a value is pushed onto the stack (see the PH* opcodes, such as PHA), that value is written to memory where S is pointing, then S is decreased by the size of the data (by 1 for 8bit, 2 for 16bit). When a value is popped off of the stack, S is incremented before each byte of data is popped off of the stack. S is reset to $FF either by the reset code or by the CPU on reset on later CPUs, giving 256 bytes of stack space for 8bit modes. 65c816: This can point to anywhere in bank 0 in native mode, but acts the same as on 6502 in emulation mode (ie, always relative to $0100). This also means that more than 256 bytes may be used for the stack. 65CE02: If the e bit (Exted Disable) is cleared, then this is a 16bit value that can point to anywhere in the addressable 16bits of memory. This also means that more than 256 bytes may be used for the stack. 65ce02 documentation calls this SP instead of just S. As far as I can tell from the 65ce02 documentation, the only difference between 8bit and 16bit stack access is that pushing and pulling values from the stack wrap around in the same page in 8bit mode, and they can access all RAM in 16bit mode. The document states, "The programmer can quickly change the default stack page by loading the Y register with the desired page and transferring its contents to the stack pointer high byte, using the TYS opcode." This is stated just after it mentions the stack page defaults to 1, so I'm assuming it means that you can have the stack anywhere, even in 8bit mode. I believe the stack pointer *IS* affected by the memory mapping because the following is stated when describing the MAP opcode, "After executing the MAP opcode, all interrupts are inhibited. This is done to allow the operating system as complete a mapping sequence without fear of getting an interrupt. An interrupt occurring before the proper stack- pointer is set will cause return address data to be written to an undesired area." ___________________________________________________________________________________________________ 2.6 P: Program flags 8bit. This is a register that holds flags for the system. Bits .......... 7 6 5 4 3 2 1 0 n v - b d i z c 6502, 65c02, R65c02 and 65c816 in 8bit/emulation mode n v m x d i z c 65c816 in native mode or M7700 Family n v t b d i z c HuC6280 and M740 Family n v e b d i z c 65ce02 (Note that this e flag should not be confused with the e flag on the 65c816!) BIT: 0 - 01 - Carry This bit is mostly used for carrying a bit from one operation to the next. This is especially useful for multi-byte operations. 65c816: Swappable with the hidden Emulation Bit e via the XCE instruction, which governs whether we're in emulation (set) or native (clear) mode 1 - 02 - Zero This flag is set when a value is zero, and is cleared if not zero 2 - 04 - Interrupt Disable This flag can be set to disable normal interrupts (but not the NMI), or cleared to permit them 3 - 08 - Decimal mode This flag can be set to switch ADC and SBC to BCD mode, or cleared to use standard binary math 2A03: This flag is always ignored 4 - 10 - Break - Always 1, except after an interrupt This bit exists only to tell the difference between a standard interrupt, and a software interrupt/break (see the BRK instruction). 65c816: If in native mode, then this selects whether Index registers are 8bit (set) or 16bit (clear) This bit is known as x (Index size flag) in native mode M7700: This is ALWAYS the x bit as described above for the 65c816 5 - 20 - Always 1 65c816: Selects whether the Accumulator is 8bit (set) or 16bit (clear) in native mode. It is always set (and 8bit) in emulation mode. This bit is known as m (Memory/Accumulator size flag) M7700: This is ALWAYS the m bit as described above for the 65c816 HuC6280:Sets the processor into a special "accumulator-ish" mode This bit is set with the SET instruction and only stays set for a single instruction If the next instruction following this one is an immediate mode operation, then instead of A, the value at X in the zero page is used instead. The immediate value is used as normal. ??? this is just a guess This bit is known as t (Memory Transfer flag) M740: Like the HuC6280, this bit is set to change certain opcodes that normally function with A into memory based functions which access the zero page address pointed to by X. The instructions that are affected are: ADC, SBC, AND, ORA, EOR, CMP and LDA. This bit is known as t (Memory Transfer flag) For example, if X is $12, then: SET ADC #$FF CLT adds $FF to the value at $0012 ((X) in the zero page) in memory * Opinion: This is really cool. Being able to directly manipulate memory like this without having to do LDA, operation(s), STA is a great time saver (and A is not lost either!). Too bad that SET and CLT take 2 cycles each. 65ce02: This bit is used for controlling whether S is an 8bit or 16bit value. If it is set, then S is 8bit and can only access a single page of memory, governed by Sh. If it is clear, then S is 16bit, allowing the stack to be anywhere in memory. To set the stack register, you would use TXS to set the low byte and TYS to set the high byte. This is is known as e (Extended Stack Disable flag) 6 - 40 - Overflow This bit is set on overflow. It indicates invalid carry into the high bit of arithmetic results (generally used with signed operations) 7 - 80 - Negative This bit is set then the operation left the highest bit set, and cleared if not ___________________________________________________________________________________________________ 2.7 B: Upper Accumulator 65c816 Family Only 8bit. This is specifically for the upper 8bits of the 16bit accumulator when in emulation mode. NOTE: A special register, the Bank Register, existed on the 65CE02. Please see section 2.3 for the details on this register. ___________________________________________________________________________________________________ 2.8 C: 16bit Accumulator 65c816 Family Only 16bit. C is only used to represent the full 16bit Accumulator regardless of mode. ___________________________________________________________________________________________________ 2.9 D: Direct Page 65c816 Family Only 16bit. This allows setting an offset to all Zero Page instructions to anywhere in bank 0 (the first 64KB). It is HIGHLY recommended that the low byte of D is 0, since all direct page memory access adds 1 cycle if the low byte is not 0, I'd assume because an add operation is required instead of a simple bitwise OR. For example: If D is $8000, then all zero page access occurs in $8000 to $80FF. ___________________________________________________________________________________________________ 2.10 DBR: Data Bank Register 65c816 Family Only 8bit. This register is used to determine which data bank to access for 24bit memory access. For example: If DBR is $80 and we attempt to access $1234 in memory, the final address would actually be $801234. ___________________________________________________________________________________________________ 2.11 PBR: Program Bank Register 65c816 Family Only 8bit. Used to determine which data bank in 24bit the program is executing from. For Example: If PBR is $20, then code is executing in the range of $200000 to $20FFFF, based on PC. ___________________________________________________________________________________________________ 2.12 e: Emulation Bit 65c816 Family Only 1bit. This hidden bit is used to determine if the 65c816 is in emulation or native mode. If it is set (the default), then we are in emulation mode. If it is clear, then we are in native mode. This value can only be accessed with the XCE (eXchange Carry and Emulation bits) instruction. ___________________________________________________________________________________________________ 2.13 cs: Clock Select HuC6280 Only 1bit. This is a hidden bit/value on the HuC6280. When it is High (1), the CPU runs at full speed (7.16Mhz on the TG16). When it is Low (0), the CPU runs at half/quarter??? speed (3.58Mhz on the TG16). There are two instructions, CSL and CSH, to set Low and High speed ___________________________________________________________________________________________________ 2.14 MPRx: Memory Page Registers (0 - 7) HuC6280 Only 8x8bit. To access the 21bit addressing range available to the HuC6280, all memory access is broken up into 8KB (13bit) chunks. The upper 3 bits of any memory access is translated to an MPR value. These registers store an 8bit value that needs to be multiplied by 8192 (value << 13) to calculate the final address, giving a total range of 21bits ($000000 to $1FFFFF). For Example: If we try to access $3000, the top 3 bits are (001) or 1, so we read the value from MPR1. If MPR1 is $20, then to get the final address, we do: address = (0x20 << 13) + address & 0x1FFF; This results in 0x028000 + 0x1000 or 0x029000 MPR1 is always used for Zero Page and Stack Access (logical addresses $2000 to $21FF). ___________________________________________________________________________________________________ 2.15 B: Base Page Register 65ce02 Only 8bit. This is the "base page" register. It is used to select which page (256 byte range) of memory the zero page is located in. This is similar to D on the 65c816. Because of this register, the 65ce02 calls all zero page addressing "Base Page" addressing. For example: If B is $80, then all zero page access occurs in $8000 to $80FF. It is similar to the D register on the 65c816. KERBLUH- Is the base page affected by memory mapping? For now, I am guessing that it is... ___________________________________________________________________________________________________ 2.16 Z: Z Index 65ce02 Only 8bit. This new index register does two jobs. First, it is used to replace Zero Page Indexed (not any of the other Zero Page instructions though) with Zero Page Indirect Z Indexed (this is shown as xxx ($ab), Z and I'd assume it acts like Zero Page Indirect Y Indexed). Secondly, it is the value used in the STZ instructions (which is Store Zero on other 65c02s). ___________________________________________________________________________________________________ 2.17 LRAO: Lower Region Address Offset URAO: Upper Region Address Offset MMRF: Masked Map Region Flags 4510 (65ce02) Only ** NOTE: I have no clue what anything is actually named on the CPU. All naming here is I made up to help explain this system. These registers are not generally considered registers at all, but are more a state inside the CPU to control how addressing works. Fundamentally, the concept is very similar to the MPR registers used on the HuC6280. Here's how the registers work: Addresses are split into 8 different blocks of 8192 bytes ($2000 bytes): $0000 - $1FFFF, $2000 - $3FFF, etc. The bottom half of the 16bit addresses ($0000 - $7FFF) are the "Lower Region" of memory, whereas the top half ($8000 - $FFFF) are the "Upper Region" of memory. The registers work by using offsets in memory. An offset of $000000 means the memory location is exactly where expected. An offset of $010000 means that you add $010000 to every address that is affected. The offsets are 20 bit values, but the lower 8 bits are always 0 giving the offsets a granularity of 256 bytes (one page). It is stored like this: LRAO: This is the offset for mapped addresses in the lower region (the bottom four blocks, $0000 - $7FFF). It is between $000000 and $0FFF00, giving access to $000000 to $107EFF. Since only $000000 to $0FFFFF is accessible (1MB), this gives access to every address in RAM. URAO: This is the offset for mapped addresses in the upper region (the upper four blocks, $8000 - $FFFF) It is between $000000 and $0FFF00, giving access to $008000 to $10FEFF. Since only $008000 to $0FFFFF is accessible (1MB), this gives access to every address in RAM except the bottom $8000. Of course, maybe it wraps around at the 20bit mark, in which case you can access ALL of RAM (Does it wrap around???) MMRF: This stores which addresses are mapped or not. For each address range, a 0 (not set) means it is mapped, a 1 (set) means it is not mapped. Bits 0 - 3 are offset with LRAO. Bits 4 - 7 are offset with URAO. BITS 0 - 01 - Block $0000 to $1FFF (mapped with LRAO) 1 - 02 - Block $2000 to $3FFF (mapped with LRAO) 2 - 04 - Block $4000 to $5FFF (mapped with LRAO) 3 - 08 - Block $6000 to $7FFF (mapped with LRAO) 4 - 10 - Block $8000 to $9FFF (mapped with URAO) 5 - 20 - Block $A000 to $BFFF (mapped with URAO) 6 - 40 - Block $C000 to $DFFF (mapped with URAO) 7 - 80 - Block $E000 to $FFFF (mapped with URAO) There is no way to read from these values. However, to set them, we can use the MAP opcode. MAP reads in the following data from the A, X, Y and Z registers: Reg BITS Desc A 0 to 7 Bits 8 to 15 of LRAO X 0 to 3 Bits 16 to 19 of LRAO 4 to 7 Bits 0 to 3 of MMRF Y 0 to 7 Bits 8 to 15 for URAO Z 0 to 3 Bits 16 to 19 for URAO 4 to 7 Bits 4 to 7 of MMRF To calculate the values: LRAO = ((X & 0x0F) << 16) + (A << 8); URAO = ((Z & 0x0F) << 16) + (Y << 8); MMRF = (Z & 0xF0) + ((X & 0xF0) >> 4); So, if we wanted to make memory region $4000 - $7FFF access $040000 in RAM, and $8000 - $9FFF access $050000, then we'd want: LRAO to be $03C000 ($4000 + $03C000 = $040000) URAO to be $048000 ($8000 + $048000 = $050000) MMRF to be $E3 (bit 4 clear to map $8000 - $9FFF, bit 2 and 3 clear to map $4000 to $7FFF) To set this in code, we'd want: A = $C0, X = $33, Y = $80 and Z = $E4 when we call the map function. This would look something like: LDA #$C0 ; Set bits 8 - 15 of LRAO to $C0 LDX #$33 ; Set bits 16 - 19 of LRAO to $3, giving LRAO a final value of $03C000 ; Set bits 0 - 3 of MMRF to $3 LDY #$80 ; Set bits 8 - 15 of URAO to $80 LDZ #$E4 ; Set bits 16 - 19 of URAO to $4, giving URAO a final value of $048000 ; Set bits 4 - 7 of MMRF to $E, giving MMRF a final value of $E3 MAP ; Do the map! EOM ; End map mode since we aren't moving the stack ___________________________________________________________________________________________________ 2.18 fid: Full Interrupt Disable flag (Hidden Flag) 4510 (65ce02) Only This flag is similar to the I flag, except that it disables ALL interrupts of any kind (even BRK???), including the NMI. It is set using the MAP opcode and cleared using the EOM opcode. *************************************************************************************************** 3 Addressing Modes There are thirteen addressing modes available on the 6502, the 65c02 adds two more and the 65c816 adds nine more on top of that. The R65c02 family has it's own special addressing mode (Zero Page and Relative). The HuC6280 has many odd addressing modes that I don't think should be considered unique addressing modes per se, more like combinations thereof, such as TII's $abcd,$abcd,#$abcd (Abs, Abs, 16bit Imm). In case you're wondering what the prefix is on these modes (such as Imp:), it's what I use to name these in short hand because a lot of these have very long names (I don't plan on writing DIRECT PAGE INDIRECT INDEXED WITH X over and over again when DPIndX works just the same). ___________________________________________________________________________________________________ 3.1 Imp: Implied xxx The operand is indicated in the mnemonic eg, DEX ; Decrement the X register ___________________________________________________________________________________________________ 3.2 Acc: Accumulator xxx A The operand is the accumulator itself eg, ASL A ; Shifts the bits of A one to the left ___________________________________________________________________________________________________ 3.3 Imm: Immediate xxx #$ab xxx #$abcd (16bit) The operand is the byte following the opcode eg, LDA #$EF ; Load A with the value $EF ___________________________________________________________________________________________________ 3.4 Abs: Absolute xxx $abcd The word following the opcode is the address of the operand. 65c816: Supports Bank Cross Over eg, LDA $ABEF ; Load A with the value at address $ABEF ___________________________________________________________________________________________________ 3.5 AbsX: Absolute with X Indexing aka Absolute X xxx $abcd, X The word following the opcode is added to register X (as an unsigned word) to give the address of the operand. If it overflows, it wraps around. 65c816: In native mode, it will move to the next bank instead of wrapping around eg, LDA $ABEF, X ; Load A with the value at address ($ABEF + X) ; If X = $20, then we would grab the value at address ($ABEF + $0020) = $AC0F ___________________________________________________________________________________________________ 3.6 AbsY: Absolute with Y Indexing aka Absolute Y xxx $abcd, Y Same as AbsY, but with Y instead of X. If it overflows, it wraps around. 65c816: In native mode, it will move to the next bank instead of wrapping around eg, LDA $ABEF, Y ; Load A with the value at address ($ABEF + Y) ; If Y = $20, then we would grab the value at address ($ABEF + $0020) = $AC0F ___________________________________________________________________________________________________ 3.7 JmpInd: Jump Indirect Absolute aka Indirect aka Indirect Absolute JMP ($abcd) Only used by JMP The word following the opcode is the address of a word which is the address of the operand. On all CPUs but the 6502 family, if the low byte of the address is $FF, a clock is added to the time to execute the instruction. 6502: There is a bug in the 6502 that causes this addressing mode to work improperly in some cases. If the jump operation is accessing the last byte of a page (ie, $xxFF), then the high byte will be accessed at $00 of that page, instead of $00 of the next page. eg, JMP ($21FF) will grab the low byte from $21FF and the high byte from $2100 instead of $2200 as would be expected. 65c816: This instruction always reads the address from specifically in bank 0. eg, JMP ($ABEF) ; Jumps to the 16bit value of the address pointed to by the address $ABEF ; If the value in memory at $ABEF is $12, and $ABF0 is $34, then we jump to $3412 ___________________________________________________________________________________________________ 3.8 DP: Zero/Direct/Base Page xxx $ab The byte following the opcode is the address on page 0 of the operand eg, LDA $EF ; Load A with the value at address $00EF ___________________________________________________________________________________________________ 3.9 DPX: Zero/Direct/Base Page with X Indexing aka Zero/Direct/Base Page X xxx $ab, X The byte following the opcode is added to register X to give the address on page 0 of the operand. If it overflows, it wraps around in the zero/direct page. 65c816: In native mode, on overflow it will move to the next page, but will wrap around inside the same bank eg, LDA $EF, X ; Load A with the value at address ($00EF + X) ; If X = $20, then we would grab the value at $EF + $20 = $000F (it wraps around) ___________________________________________________________________________________________________ 3.10 DPY: Zero/Direct/Base Page with Y Indexing aka Zero/Direct/Base Page Y xxx $ab, Y Same as DPX, but with Y instead of X. If it overflows, it wraps around in the zero/direct page. 65c816: In native mode, on overflow it will move to the next page, but will wrap around inside the same bank eg, LDA $EF, Y ; Load A with the value at address ($00EF + Y) ; If Y = $20, then we would grab the value at $EF + $20 = $000F (it wraps around) ___________________________________________________________________________________________________ 3.11 DPIndX: Zero/Direct/Base Page Indirect with X Pre-Indexing aka Indirect X aka Indexed Indirect aka Zero/Direct/Base Page Indirect Indexed with X xxx ($ab, X) The byte following the opcode is added to register X to give the address on page 0 which contains the address of the operand. 65c816: Supports Bank Cross Over. In native mode, it will move to the next page instead of wrapping around eg, LDA ($EF, X) ; Load A with the value at the 16bit address at address ($EF + X) ; If X = $20, then we would grab the value at address ($EF + $20) = $000F (it ; wraps around) * Opinion: All of the Indirect addressing modes are really cool. Such a thing doesn't exist on our modern x86 processors! To use pointers like that on an x86, one would have to load the address to a register first, then access memory with that. ___________________________________________________________________________________________________ 3.12 DPIndY: Zero/Direct/Base Page Indirect with Y Post-Indexing aka Indirect Y aka Zero/Direct/Base Page Indirect Indexed with Y xxx ($ab), Y The byte following the opcode is an address on page 0. This word at this address is added to register Y (as an unsigned word) to give the address of the operand. 65c816: If the address + Y is greater than a 16bit value, it crosses over to the next bank. eg, LDA ($EF), Y ; Load A with the value at Y + the 16bit address at address $00EF ; If Y = $20, then we would grab the address at $00EF then add $20 to it, then ; place that value in A ___________________________________________________________________________________________________ 3.13 Rel: Relative aka Program Counter Relative xxx nearlabel Only used by branch statements. The byte following the opcode is added (as a signed word) to the Program Counter to give the address of the operand. Since this only uses a "signed byte", RELATIVE only gives us a range of -128 to 127 for branching. Note that PC is modified AFTER it has passed the current instruction. So, if at $1234 in memory, there is a BEQ $04 (2 bytes), PC would be $1236 before adding the relative value, and $123A after. 65c816: This addressing mode only affects PC; PBR is never changed by it. eg, BRA $EF ; Jumps back 17 bytes BRA SOMELABEL ; Jumps to some label in 65xx assembly ___________________________________________________________________________________________________ 3.14 JmpIndX: Jump Indirect with X Pre-Indexing aka Absolute Indexed Indirect xxx ($abcd, X) 65c02+ Only Only used by JMP/JSR This addressing mode works like INDIRECT X, but takes a 16bit address and adds X to it. This is useful for "case" or "switch" statements. 65c816: This instruction always operates specifically in the PBR program bank and wraps around eg, JMP ($1234, X) ; Jump to the address at ($1234 + X) ___________________________________________________________________________________________________ 3.15 DPInd: Zero/Direct Page Indirect xxx ($ab) 65c02+ & M740 Family Only, not 65ce02 Uses the value at the address at the specific zero/direct page address. This works just like DPIndX (eg, LDA ($12, X)), except that X is not added to the address. 65c816: Supports Bank Cross Over eg, LDA ($12) ; Loads A with the value at the address at $0012 ___________________________________________________________________________________________________ 3.16 DPAndRel: Zero/Base Page and Relative aka Zero/Base Page Test Relative aka Bit Relative xxx $ab, nearlabel R65c02 Family and M740 Family Only This instruction type is only used in the BBRx/BBCx and BBSx branch instructions that exist on the R65c02 and M740 families of processors. eg, BBR0 $12, $EF ; If bit 0 is clear on the value at $0012, branch back 17 bytes. ___________________________________________________________________________________________________ 3.17 RelL: Relative Long; Program Counter Relative Long xxx farlabel 65c816 Family, 65sc02 and 65ce02 Only This is the same as Rel, except that it uses a signed 16bit value, instead of a signed 8bit value, allowing branch statements to use a range of -32768 to 32767. Note that, just like Rel, PC is modified AFTER it has passed the branch instruction. Note that some non-Branch statements (such as PER) can use this addressing mode as well. 65c816: This addressing mode only affects PC; PBR is never changed by it. eg, BRA $FEEF ; Jumps back 273 bytes BRL SOMELABEL ; Jumps to some label in 65c816 assembly ___________________________________________________________________________________________________ 3.18 SRel: Stack Relative xxx $ab, S 65c816 Family Only Accesses the value at S + the value specified. Since S points at the next valid stack position, a 0, S value will not return a meaningful result. eg, LDA $03, S ; Load A with the value at (S + $03) in bank 0 ___________________________________________________________________________________________________ 3.19 SRelIndY: Stack Relative Indirect with Y Post-Indexing aka Stack Relative Indirect Y aka Stack Relative Indirect Indexed with Y xxx ($ab, S), Y 65c816 Family and 65ce02 Only Access the value at the address of (Y + (the address at (S + the value)) specified. The final pointer is grabbed from the data bank pointed to by DBR instead of the zero bank. This also support next bank wrap-around, so if the address in the stack is $FFFF and Y is 2, then $0001 in the next bank after DBR is accessed. eg, LDA ($05, S), Y ; Load A with the value at the address of (Y + the address at (S + 5)) in the ; DBR bank ___________________________________________________________________________________________________ 3.20 Block: Block Move xxx #$ab, #$cd 65c816 Family Only Block moves use the following values: A - The number of bytes to move X - The source address Y - The destination address value1 - The source bank value2 - The destination bank This is stored as: OPCODE DEST SOURCE eg, MVP 0,1 ; Copies A bytes from bank 0, address of X to bank 1, address of Y ___________________________________________________________________________________________________ 3.21 AbsL: Absolute Long xxx $abcdef 65c816 Family Only Same as Abs, but with a 24bit value instead of 16bit. Supports bank cross over. eg, LDA $123456 ; Load A with the value at $123456 ___________________________________________________________________________________________________ 3.22 AbsXL: Absolute Long with X Indexing aka Absolute Long Indexed X xxx $abcdef, X 65c816 Family Only Same as AbsX, but with a 24bit value instead of 16bit. Supports bank cross over. eg, LDA $123456,X ; Load A with the value at ($123456 + X) ___________________________________________________________________________________________________ 3.23 JmpIndL: Absolute Indirect Long xxx [$abcd] 65c816 Family Only Only used by JMP Same as JmpInd, but it reads a 24bit address from the memory value instead of 16bit. This instruction always operates specifically in bank 0. eg, JMP [$1234] ; Jump to the 24bit address at $001234 ___________________________________________________________________________________________________ 3.24 DPIndL: Direct Page Indirect Long xxx [$ab] 65c816 Family Only Same as DPInd, but it reads a 24bit address from the memory value instead of 16bit. Supports bank cross over. eg, LDA [$12] ; Load A with the value at the 24bit address at ($0012 + D) ___________________________________________________________________________________________________ 3.25 DPIndYL: Direct Page Indirect Long with Y Post-Indexing aka Direct Page Indirect Long Indexed Y xxx [$ab], Y 65c816 Family Only Same as DPIndY, but it reads a 24bit address from the memory value instead of 16bit. Supports bank cross over. eg, LDA [$77],Y ; Load A with Y + the value at the 24bit address at ($0077 + D) ___________________________________________________________________________________________________ 3.26 DPIndZ: Base Page Indirect with Z Post-Indexing aka Base Page Indirect Indexed with Z xxx ($ab), Z 65ce02 Only On the 65ce02, this addressing mode replaces DPInd. It is identical to DPIndY except it uses the new Z index register instead of Y. Since Z defaults to 0, it acts the same as DPInd until Z is modified. eg, LDA ($33), Z ; Load A with the value at the address at ($0033 + Z) ___________________________________________________________________________________________________ 3.27 Txx: Transfer Txx $1234, $5678, #$9ABC HuC6280 Only The Txx instructions take a total of six bytes of data: An absolute address for the source, an absolute address for the destination and a 16bit count value. The count is used for the number of bytes to transfer from the source to the destination. If count is 0, 65536 bytes are transferred. The specific opcode determines how the absolute addresses change during the transfer: TII - Increments the source and the destination pointer each transfer. This is useful for general transfers, as long as the destination buffer is not less than the source buffer or the two do not overlap. If the two buffers overlap but the destination is less than the source buffer but the buffers overflow, then TII is also the best choice. TDD - Decrements the source and the destination pointer each transfer. This is useful when the destination buffer is greater than the source buffer and overlap is expected. To use TDD properly, be certain that the last bytes of both buffers are being pointed to. TAI - Alternates the source between source, and source + 1, increments the destination after every transfer This is useful when reading a buffer of words from a single 16bit hardware memory address (Does this occur on the TG16???) TIA - Increments the source, alternates the destination between destination and destination + 1, for every transfer This is useful when writing a buffer of words to a single 16bit hardware memory address TIN - Increments the source, does nothing to the destination for every transfer This is useful when writing a buffer or bytes to a single 8bit hardware memory address The data is stored in the same order the instruction shows. For example, if the instruction is "TAI $1234, $5678, #$9ABC", it is stored as: F3 34 12 78 56 BC 9A eg, TII $3000,$4000,#$1000 ; Transfer #$1000 (4096) bytes from $3000 to $4000 ___________________________________________________________________________________________________ 3.28 ImmDP: Immediate and Zero Page xxx #$ab, $cd HuC6280 and M740 Family Only This addressing mode is only used for the TST instruction on the HuC6280, and the LDM instruction on the M740 family. It takes an immediate value and a zero page pointer. The data is stored in the same order the instruction shows. For example, if the instruction is "TST #$12,$34", it is stored as: 83 12 34 eg, TST #$12,$34 ; Test the value at $34 with #$12 ___________________________________________________________________________________________________ 3.29 ImmDPX: Immediate and Zero Page w/ X TST #$ab, $cd, X HuC6280 Only This addressing mode is only used for the TST instruction. It takes an immediate value and a zero page pointer with X indexing. The data is stored in the same order the instruction shows. For example, if the instruction is "TST #$12,$34,X", it is stored as: A3 12 34 eg, TST #$12,$34,X ; Test the value at ($34 + X) with #$12 ___________________________________________________________________________________________________ 3.30 ImmAbs: Immediate and Absolute TST #$ab, $cdef HuC6280 Only This addressing mode is only used for the TST instruction. It takes an immediate value and an absolute pointer. The data is stored in the same order the instruction shows. For example, if the instruction is "TST #$12,$3456", it is stored as: 93 12 56 34 eg, TST #$12,$7134 ; Test the value at $7134 with #$12 ___________________________________________________________________________________________________ 3.31 ImmAbsX: Immediate and Absolute w/ X TST #$ab, $cdef, X HuC6280 Only This addressing mode is only used for the TST instruction. It takes an immediate value and an absolute pointer with X indexing. The data is stored in the same order the instruction shows. For example, if the instruction is "TST #$12,$3456,X", it is stored as: B3 12 56 34 eg, TST #$12,$7134,X ; Test the value at ($7134 + X) with #$12 ___________________________________________________________________________________________________ 3.32 AAndRel: Accumulator Bit Relative xxx A, nearlabel M740 Family Only Similar to DPAndRel, this instruction type is only used in the BBCx and BBSx branch instructions that exist on the M740 families of processors. eg, BBC0 A, $EF ; If bit 0 is clear on the Accumulator, branch back 17 bytes. ___________________________________________________________________________________________________ 3.33 JMPSP: Special Page JSR \$ab M740 Family Only This addressing mode looks just like zero page, except for a \ before the address. This address is in the last page ($FF) of memory instead of the zero page. eg, JSR \$1E ; Jump to a sub routine at $FF1E. *************************************************************************************************** 4 Opcodes/Mnemonics ___________________________________________________________________________________________________ 4.1 Mnemonic Listing Format Each mnemonic has a table listing all of the opcodes, timing, supported processors and access modes after it. The basic chart for opcodes is according to the six most unique processors: 6502, 65c02, R65c02, HuC6280, 65ce02 and 65c816. When other specific CPUs have different opcode meanings, those will be listed as a new column for those specific opcodes. Also for each opcode is a translation of the name. The names will look funny because I uppercase the letters that the name of the mnemonic relates to (at least, as far as I can tell). Because of this I will often emphasize which register is affected by spelling them out completely, such as accumulator instead of just A. This is to avoid confusion since elsewhere, case determines which register it is (x for the 16/8bit toggle flag on the 65c816, but X for the X index register). The illegal opcodes are listed with as many variations as I could find for those opcodes and they are cross-referenced to one another. For example, if you look up SLO*, you will see that it says "See ASO*". Under ASO* it says "aka SLO*". Which mnemonic gets the full description is my preference (pretty much the one I saw first unless one mnemonic is more meaningful than another [like HLT* for HaLT as opposed to CIM* for Crash IMmediate]), since everybody calls them different things. ANY mnemonic with a * in the name means it's an undocumented or illegal opcode. Also, some opcodes have different mnemonics across CPUs, but mean the same thing, such as BBCx (Branch if Bit Clear) vs BBRx (Branch if Bit Reset). The BBCx instructions are on the M740 family of CPUs, but the BBRx instructions are on the R65c02 family. Since they are identical except for name and opcode, the BBCx definition simply refers you to BBRx where the full details are available. --------------------------------------------------------------------------------------------------- 4.1.1 Definitions for Code Snippets Each opcode has a C-style psuedo code snip, and a textual description of the opcodes. VERY IMPORTANT: If an operand or register value is used, it is assumed that it has the same bit depth as the value would on the real CPU being emulated. This means that a 4bit value that is 0x0F, when incremented will become 0x00 NOT 0x10 which is impossible for a 4bit value! Unless a code section says "Code: [Full Version]", we are assuming that: Before starting the code: The effective address(es) are already calculated PC incremented as necessary If there is an operand read in, it will be in the operand variable If two operands are read in, the first will be operand1 and the second will be operand2 After the code: If any data is written out (eg, operand), it will be output/stored/etc. Value/Variable Definitions: A Accumulator (in 8bit or 16bit) Al 65c816- Specifically the lower byte of the accumulator B 65c816- Specifically the upper byte of the accumulator B 65ce02- Base page register b Break flag C 65c816- Full 16bit accumulator c Carry flag D 65c816- Direct Page pointer d Decimal flag DBR 65c816- Data Bank Register e 65c816- Emulation flag e 65ce02- Extended Stack Disable flag i Interrupt Disable flag fid 65ce02- Full Interrupt Disable flag LRAO 65ce02- Lower Region Address Offset m 65c816- Memory/Accumulator select flag MMRF 65ce02- Masked Map Region Flags MPRx HuC6280- Memory Mapper Register x (0 - 7 are valid) n Negative flag P Program flags, as a single 8bit value PC Program Counter S Stack Pointer t HuC6280 & M740- Memory Transfer flag URAO 65ce02- Upper Region Address Offset v Overflow flag X X Index register x 65c816- Index select flag Y Y Index register z Zero flag Z 65ce02- Z Index register All flag values, if set in the code, become 1 if the value was true or non-zero, 0 if it was false or zero. When used as a value, they only contain 1 (if set) or 0 (if clear). Specials: (U8/16) Sets a value to the appropriate 8bit or 16bit limit for the variable limit = (CPU == 65c816 && !e && !m) ? 16bit : 8bit; for Accumulator and Memory values limit = (CPU == 65c816 && !e && !x) ? 16bit : 8bit; for X and Y address The address passed in to the opcode BEFORE X or Y modifiers, if applicable CPU The CPU type. This will be one of the CPU types above For example, if we're on a 65ce02, CPU will hold 65ce02. We can test for it with (CPU == 65ce02) This is to show differences in how different CPUs handle opcodes highbit Holds the value of the highest bit of the register's current size nexthbit Holds the value of the second highest bit of the register's current size maxval Holds the maximum value of the register's current size operand Holds the current operand. If operand is modified, the opcode updates it in memory (or the register it applies to, if applicable) operand1 The first operand when multiple operands exist in an opcode operand2 The second operand when multiple operands exist in an opcode result The result before it is stored anywhere temp1 Temporary value 1 temp2 Temporary value 2 temp3 Temporary value 3 temp4 Temporary value 4 value May hold the value from the operand when we may want to modify the operand without storing it back where it came from. This is also used to hold an immediate value --------------------------------------------------------------------------------------------------- 4.1.2 Opcode References Code Description ............................................................................................. Shared 01 Add 1 cycle if adding index crosses a page boundary HuC6280, 65ce02, M740- No additional cycles (Some documentation says add 1 cycle for HuC6280) 02 Add 1 cycle if branch is taken (which always occurs on BRA) Also, add 1 cycle if branch taken crosses page boundary on pre-65c816, or in 65c816 emulation mode (e=1) HuC6280- Add 2 cycle if branch is taken instead of 1 (some documentation says add only 1 cycle) Add no cycles if a page boundary is crossed (some documentation says to add 1 cycle) 65ce02- No additional cycles for taking the branch or crossing a page boundary M740- Add 2 cycles if branch is taken instead of 1 Add no cycles if a page boundary is crossed 03 6502 & M740- if low byte of operand is $FF (ie. operand is $xxFF), this yields an incorrect result 65c02 & R65c02- Add 1 cycle HuC6280, 65ce02, 65c816- No additional cycles 04 Uses 3 cycles to shut the processor down; additional cycles are required by reset to restart CPU 05 Uses 3 cycles to shut the processor down; additional cycles are required by interrupt to restart it ............................................................................................. 65c02 and R65c02 Specific 10 65c02 & R65c02- Add 1 cycle if CPU is 65c02 and d=1 (decimal mode only) HuC6280 & 65ce02- Also add 1 cycle if d=1 65c816- Not affected 11 65c02 & R65c02- Subtract 1 cycle if no page boundary crossed HuC6280, 65ce02, 65c816- Not affected 65c816- Not affected ............................................................................................. 65c816 Specific 20 65c816- Byte and cycle counts subject to change in future processors which expand WDM into 2-byte opcode portions of instructions of varying lengths 21 65c816- 7 cycles per byte moved 22 65c816- Add 1 cycle if low byte of Direct Page (zero page) register is other than zero (Dl!=0) 23 65c816- Add 1 cycle for native mode (e=0) 24 65c816- Add 1 byte if m=0 (16 bit memory/accumulator) 25 65c816- Add 1 cycle if m=0 (16-bit memory/accumulator) 26 65c816- Add 2 cycles if m=0 (16-bit memory/accumulator) 27 65c816- Add 1 byte if x=0 (16 bit index registers) 28 65c816- Add 1 cycle if x=0 (16-bit index registers) ............................................................................................. HuC6280 Specific 30 HuC6280- 17 cycles plus 6 cycles per byte transferred 31 HuC6280- Add 1 cycle 32 HuC6280- Add 2 cycles ............................................................................................. 65ce02 Specific 40 65ce02- Remove 1 cycle 41 65ce02- Remove 2 cycles 42 65ce02- Exact information is not available for these opcodes on the 65ce02, the values listed are guesses based on the existing 65ce02 data and the 65c02 data ............................................................................................. M740 Specific 50 M740- Supports the memory transfer flag. If T is set, (X) is used instead of A, adding 1 cycle. 51 M740- Supports the memory transfer flag. If T is set, (X) is used instead of A, adding 2 cycles. 52 M740- Supports the memory transfer flag. If T is set, (X) is used instead of A, adding 3 cycles. 53 M740- Add 1 cycle ............................................................................................. Illegal Opcodes * Undocumented instruction. These are commonly used by demo groups on specific computers for special effects, but should be avoided. Ill1 These opcodes were observed on the Atari800, their names and behavior are taken from [5] They are called "illegal" or "undocumented" opcodes because they were not specifically designed in the processor Other versions of the 6502 may operate differently Ill2 These opcodes are basically NOP commands for the 65c02 and R65c02 families The SKB and SKW opcodes are due to the number of bytes they skip The addressing mode is only listed to show that the values are 8bit or 16bit, and should be ignored completely. The number of bytes and cycles required are taken from [8] ___________________________________________________________________________________________________ 4.2 Alphabetic Mnemonic Listing --------------------------------------------------------------------------------------------------- AAC* And Accumulator, setting Carry flag to negative flag [ILLEGAL OPCODE] 6502 Only See ANC* --------------------------------------------------------------------------------------------------- AAX* Accumulator And X index store [ILLEGAL OPCODE] 6502 Only See SAX* --------------------------------------------------------------------------------------------------- ADC ADd with Carry Description: .......................................................................... Adds the specified value to A, and adds 1 if carry is set. 6502- The Z, N and V flags are not set properly in decimal mode (this is according to [5]): Z is if A + c + value (non-BCD format) is zero N is if the High bit is set BEFORE correcting the result's top nybble (ie, if it's > 9) V is tested for BEFORE correcting the results top nybble (ie, if it's > 9) HuC6280- The V flag is not modified in BCD mode Flags: ................................................................................ nv-bdizc **----** n - Was the high bit of the result set? v - Was there signed overflow? v is set only if one of the following is true: If both A and value are negative and the result is positive If both A and value are positive and the result is negative z - Was the result 0? c - Was there overflow? Code: ................................................................................. // Non-BCD version if (!d || CPU == 2A03) { result = A + operand + c; n = result & highbit; v = (~(A ^ operand) & (A ^ result)) & highbit; c = result > maxval; A = (U8/16) result; z = !A; // 16bit BCD Version } else if (CPU == 65c816 && !e && !m) { // First nibble result = (A & 0x0F) + (operand & 0x0F) + c; if (result > 0x09) result += 0x06; // Second nibble result += (A & 0xF0) + (operand & 0xF0); if (result > 0x9F) result += 0x60; // Third nibble result += (A & 0x0F00) + (operand & 0x0F00); if (result > 0x9FF) result += 0x0600; // Fourth nibble result += (A & 0xF000) + (operand & 0xF000); if (result > 0x9FFF) result += 0x6000; c = result > 0xFFFF; v = (~(A ^ operand) & (A ^ result)) & highbit; A = (U16) result; z = !A; n = A & highbit; // 8bit BCD Version } else { result = (A & 0x0F) + (operand & 0x0F) + c; // Invalid values may not add up properly... but they're invalid already, so why bother? if (result > 0x09) result += 0x06; result += (A & 0xF0) + (operand & 0xF0); // Bugged 6502 code, taken from [5] if (CPU == 6502) { z = !(A + operand + c); n = result & highbit; v = (~(A ^ operand) & (A ^ result)) & highbit; } // Test for overflow if (result > 0x9F) result += 0x60; c = result > 0xFF; // Fixed v if (CPU != 6502 && CPU != HuC6280) v = (~(A ^ operand) & (A ^ result)) & highbit; A = (U8) result; // "Fixed" version if (CPU != 6502) { z = !A; n = A & highbit; } } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 61 ADC ($ab,X) X X X X X 2 6 25,22,10,31,40,52 63 ADC $ab,S - - - - X 2 4 25 65 ADC $ab X X X X X 2 3 25,22,10,31,52 67 ADC [$ab] - - - - X 2 6 25,22 69 ADC #$ab X X X X X 2 2 25,10,24,52 6D ADC $abcd X X X X X 3 4 25,10,31,52 6F ADC $abcdef - - - - X 4 5 25 71 ADC ($ab),Y X X X X X 2 5 25,22,01,10,32,52,53 72 ADC ($ab) - X X - X 2 5 25,22,10,32 72 ADC ($ab),Z - - - X - 2 5 73 ADC ($ab,S),Y - - - - X 2 7 25 75 ADC $ab,X X X X X X 2 4 25,22,10,40,52 77 ADC [$ab],Y - - - - X 2 6 25,22 79 ADC $abcd,Y X X X X X 3 4 25,01,10,31,52,53 7D ADC $abcd,X X X X X X 3 4 25,01,10,31,52,53 7F ADC $abcdef,X - - - - X 4 5 25 --------------------------------------------------------------------------------------------------- ALR* And then Logical shift Right aka ASR* And then logical Shift Right [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... ANDs A and the immediate, then LSRs A (All documents agree on this) Flags: ................................................................................ nv-bdizc *-----** n - Was the high bit of the result set? z - Was the result 0? c - Was bit 0 set before the LSR? Code: ................................................................................. A &= operand; c = A & 1; A >>= 1; z = !A; n = A & highbit; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 4B ALR* #$ab X - - - 2 2 Ill1 --------------------------------------------------------------------------------------------------- ANC* And with accumulator then move Negative flag to Carry flag aka AAC* And Accumulator, setting Carry flag to negative flag [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... ANDs A and immediate, then moves N into C (All documents agree on this one) Flags: ................................................................................ nv-bdizc *------* n - Was the high bit of A set? c - Was the high bit of A set? Code: ................................................................................. A &= operand; c = n = A & highbit; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 0B ANC* #$ab X - - - 2 2 Ill1 2B ANC* #$ab X - - - 2 2 Ill1 --------------------------------------------------------------------------------------------------- AND AND accumulator and value Description: .......................................................................... ANDs the Accumulator with the specified value Flags: ................................................................................ nv-bdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. A &= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 21 AND ($ab,X) X X X X X 2 6 25,22,31,40,52 23 AND $ab,S - - - - X 2 4 25 25 AND $ab X X X X X 2 3 25,22,31,52 27 AND [$ab] - - - - X 2 6 25,22 29 AND #$ab X X X X X 2 2 25,24,52 2D AND $abcd X X X X X 3 4 25,31,52 2F AND $abcdef - - - - X 4 5 25 31 AND ($ab),Y X X X X X 2 5 25,22,01,32,52,53 32 AND ($ab) - X X - X 2 5 25,22,32 32 AND ($ab),Z - - - X - 2 5 33 AND ($ab,S),Y - - - - X 2 7 25 35 AND $ab,X X X X X X 2 4 25,22,40,52 37 AND [$ab],Y - - - - X 2 6 25,22 39 AND $abcd,Y X X X X X 3 4 25,01,31,52,53 3D AND $abcd,X X X X X X 3 4 25,01,31,52,53 3F AND $abcdef,X - - - - X 4 5 25 --------------------------------------------------------------------------------------------------- ANE* ANd accumulator, x index, and immediate [no clue where the E goes] aka AXA* And with X index and load into Accumulator aka XAA* X index to Accumulator then And value [ILLEGAL OPCODE] 6502 Only [UNSTABLE] [DISCREPENCY IN DEFINITION] Description: .......................................................................... [5] says: ANDs A, X and (value OR'd by 0xEF) [7] says: Exact operation unknown. [6] says: TXA AND #$ab Further details in [6] about differences between different machines. Flags: ................................................................................ nv-bdizc *-----*- n - Bit 7 of (A AND X AND immediate) set? z - (A AND X AND immediate) = 0? Code: ................................................................................. result = (A & X & operand); n = result & highbit; z = !result; A &= X & (operand | 0xEF); // According to [5] Opcodes: Op Format 6502 65c02 R65c02 65c816 Size Cyc References 8B ANE* #$ab X - - - 2 2 Ill1 --------------------------------------------------------------------------------------------------- ANX* ANd accumulator then transfer to X index aka ATX* And accumulator, Transfer to X index aka LXA* Load X index and Accumulator with accumulator and value aka OAL* Or accumulator, And with value then Load x index [ILLEGAL OPCODE] 6502 Only [UNSTABLE] [DISCREPENCY IN DEFINITION] Description: .......................................................................... [5]: ANDs A and the immediate, then transfers A to X [7]: Same as [5] [6]: 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. Further details in [6] about differences between different machines. Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit set in the result? z - Was the result 0? Code: ................................................................................. X = A &= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References AB ANX* #$ab X - - - 2 2 Ill1 --------------------------------------------------------------------------------------------------- ARR* And accumulator then Rotate Right [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... ANDs A and the immediate, then RORs A [5]: If the Decimal flag is set, some "fake clean up" is done on the result [7]: Same as the others, but it does not mention decimal mode [6]: Same as [5], but not as specific (All documents agree on this except the decimal mode flags) Flags: ................................................................................ nv-bdizc **----** n - Was the highbit set on the result? v - If the Decimal Flag is set, this is set if bit 6 is different than the original data's bit 6 Otherwise, it is set if bit 6 of the result is different than bit 5 of the result z - Was the result 0? c - If the decimal flag is set, this is set if (operand & 0xF0) + (operand & 0x10) is greater than 0x50 Otherwise, was bit 6 set on the value after the bit shift? Code: ................................................................................. result = A & operand; result >>= 1; if (c) result |= highbit; n = c; z = !result; // BCD code from [5] if (d && CPU != 2A03) { v = ((result ^ operand) & 0x40); if ((operand & 0x0F) + (operand & 0x01) > 5) result = (result & 0xF0) | ((result + 0x06) & 0x0F); if ((operand & 0xF0) + (operand & 0x10) > 0x50) { result = (result & 0x0F) | ((result + 0x60) & 0xF0); c = 1; } else { c = 0; } // Strange flag settings, according to [5] } else { c = result & 0x40; v = ((result >> 6) ^ (result >> 5)) & 1; } A = result; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 6B ARR* #$ab X - - - 2 2 Ill1 --------------------------------------------------------------------------------------------------- ASL Arithmetic Shift Left Description: .......................................................................... Shifts bits left one, moving the original high bit into the carry flag, and putting a 0 at the low bit Flags: ................................................................................ nv-bdizc *-----** n - Was the highbit of the result set? z - Was the result 0? c - Was highbit of the value set before this instruction? Code: ................................................................................. c = operand & highbit; operand <<= 1; n = operand & highbit; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 06 ASL $ab X X X X 2 5 22,26,31,40 0A ASL A X X X X 1 2 40 or ASL 0E ASL $abcd X X X X 3 6 26,31,40 16 ASL $ab,X X X X X 2 6 22,26,41 1E ASL $abcd,X X X X X 3 7 26,11,41 --------------------------------------------------------------------------------------------------- ASO* Arithmetic Shift left then Or aka SLO* Shift Left then Or [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... ASL the value in memory, then ORA with A (All documents agree on this one) Flags: ................................................................................ nv-bdizc *-----** n - Was the highbit of the result set? z - Was the result 0? c - Was highbit of the value set before this instruction? Code: ................................................................................. c = operand & highbit; operand <<= 1; A |= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 03 ASO* ($ab,X) X - - - 2 8 Ill1 07 ASO* $ab X - - - 2 5 Ill1 0F ASO* $abcd X - - - 3 6 Ill1 13 ASO* ($ab),Y X - - - 2 8 Ill1 17 ASO* $ab,X X - - - 2 6 Ill1 1B ASO* $abcd,Y X - - - 3 7 Ill1 1F ASO* $abcd,X X - - - 3 7 Ill1 --------------------------------------------------------------------------------------------------- ASR Arithmetic Shift Right 65ce02 Only Description: .......................................................................... Does a bit shift right, preserving the high bit of the value Flags: ................................................................................ nvebdizc *-----** n - Was the highbit of the result set? z - Was the result 0? c - Was the bit shifted out set? Code: ................................................................................. c = operand & 0x01; n = operand & highbit; operand = (operand >> 1) | (operand & 0x80); z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65ce02 65c816 Size Cyc References 43 ASR A - - - - X - 1 2 44 ASR $ab - - - - X - 2 4 54 ASR $ab,X - - - - X - 2 4 --------------------------------------------------------------------------------------------------- ASR* And then logical Shift Right [ILLEGAL OPCODE] 6502 Only See ALR* --------------------------------------------------------------------------------------------------- AST* And STack pointer and value then load into accumulator and x index [ILLEGAL OPCODE] 6502 Only See LAS* --------------------------------------------------------------------------------------------------- ASW Arithmetic Shift left Word 65ce02 Only Description: .......................................................................... Bit shifts a word one bit left Flags: ................................................................................ nvebdizc *-----** n - Was the high bit of the result set? z - Was the result 0? c - Was the high bit set before the operation? Code: ................................................................................. c = operand & 0x8000; operand <<= 1; n = operand & 0x8000; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References CB ASW $abcd - - - X - 3 7 --------------------------------------------------------------------------------------------------- ASX* And x index with accumulator then Subtract from X index [ILLEGAL OPCODE] 6502 Only See SBX* --------------------------------------------------------------------------------------------------- ATX* And accumulator, Transfer to X index [ILLEGAL OPCODE] 6502 Only See ANX* --------------------------------------------------------------------------------------------------- AUG Augment 4502 Only (not all 65ce02s) Description: .......................................................................... It is unknown what this opcode does. It is only hinted at in [13]. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. Opcodes: .............................................................................. 6502 65c02 R65c02 65ce02 65ce02 65c816 Size Cyc References Op Format 4502 4510 5C AUG - - - X - - ? ? --------------------------------------------------------------------------------------------------- AXA* And X and A [ILLEGAL OPCODE] 6502 Only See SHA* --------------------------------------------------------------------------------------------------- AXA* And with X index and load into Accumulator [ILLEGAL OPCODE] 6502 Only See ANE* --------------------------------------------------------------------------------------------------- AXS* Accumulator and X index Store [ILLEGAL OPCODE] 6502 Only See SAX* --------------------------------------------------------------------------------------------------- AXS* And X index with accumulator then Subtract [ILLEGAL OPCODE] 6502 Only See SBX* --------------------------------------------------------------------------------------------------- BBCx Branch on Bit Clear M740 Family Only See BBRx --------------------------------------------------------------------------------------------------- BBRx Branch on Bit Reset aka BBCx Branch on Bit Clear (used on the M740 Family) R65c02 Family and M740 Family Only Description: .......................................................................... Branch on bit reset/clear. If the specified bit is clear, the branch is taken. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (!(operand & (1 << bittouse))) PC += offset; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 0F BBR0 $ab,nearlabel - - X - - 3 5 02,31,42 13 BBC0 A,nearlabel - - - X - 2 4 02 17 BBC0 $ab,nearlabel - - - X - 3 5 02 1F BBR1 $ab,nearlabel - - X - - 3 5 02,31,42 2F BBR2 $ab,nearlabel - - X - - 3 5 02,31,42 33 BBC1 A,nearlabel - - - X - 2 4 02 37 BBC1 $ab,nearlabel - - - X - 3 5 02 3F BBR3 $ab,nearlabel - - X - - 3 5 02,31,42 4F BBR4 $ab,nearlabel - - X - - 3 5 02,31,42 53 BBC2 A,nearlabel - - - X - 2 4 02 57 BBC2 $ab,nearlabel - - - X - 3 5 02 5F BBR5 $ab,nearlabel - - X - - 3 5 02,31,42 6F BBR6 $ab,nearlabel - - X - - 3 5 02,31,42 73 BBC3 A,nearlabel - - - X - 2 4 02 77 BBC3 $ab,nearlabel - - - X - 3 5 02 7F BBR7 $ab,nearlabel - - X - - 3 5 02,31,42 93 BBC4 A,nearlabel - - - X - 2 4 02 97 BBC4 $ab,nearlabel - - - X - 3 5 02 B3 BBC5 A,nearlabel - - - X - 2 4 02 B7 BBC5 $ab,nearlabel - - - X - 3 5 02 D3 BBC6 A,nearlabel - - - X - 2 4 02 D7 BBC6 $ab,nearlabel - - - X - 3 5 02 F3 BBC7 A,nearlabel - - - X - 2 4 02 F7 BBC7 $ab,nearlabel - - - X - 3 5 02 --------------------------------------------------------------------------------------------------- BBSx Branch on Bit Set R65c02 Family and M740 Family Only Description: .......................................................................... Branch on bit set. If the specified bit is set, the branch is taken Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (operand & (1 << bittouse)) PC += offset; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 03 BBS0 A,nearlabel - - - X - 2 4 02 07 BBS0 $ab,nearlabel - - - X - 3 5 02 23 BBS1 A,nearlabel - - - X - 2 4 02 27 BBS1 $ab,nearlabel - - - X - 3 5 02 43 BBS2 A,nearlabel - - - X - 2 4 02 47 BBS2 $ab,nearlabel - - - X - 3 5 02 63 BBS3 A,nearlabel - - - X - 2 4 02 67 BBS3 $ab,nearlabel - - - X - 3 5 02 83 BBS4 A,nearlabel - - - X - 2 4 02 87 BBS4 $ab,nearlabel - - - X - 3 5 02 8F BBS0 $ab,nearlabel - - X - - 3 5 02,31,42 9F BBS1 $ab,nearlabel - - X - - 3 5 02,31,42 A3 BBS5 A,nearlabel - - - X - 2 4 02 A7 BBS5 $ab,nearlabel - - - X - 3 5 02 AF BBS2 $ab,nearlabel - - X - - 3 5 02,31,42 BF BBS3 $ab,nearlabel - - X - - 3 5 02,31,42 C3 BBS6 A,nearlabel - - - X - 2 4 02 C7 BBS6 $ab,nearlabel - - - X - 3 5 02 CF BBS4 $ab,nearlabel - - X - - 3 5 02,31,42 DF BBS5 $ab,nearlabel - - X - - 3 5 02,31,42 E3 BBS7 A,nearlabel - - - X - 2 4 02 E7 BBS7 $ab,nearlabel - - - X - 3 5 02 EF BBS6 $ab,nearlabel - - X - - 3 5 02,31,42 FF BBS7 $ab,nearlabel - - X - - 3 5 02,31,42 --------------------------------------------------------------------------------------------------- BCC Branch on Carry Clear aka BLT Branch on Less Than Description: .......................................................................... Branches to the near label if carry is clear The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode 90 if (!c) PC += operand; // Opcode 93 if (!c) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 90 BCC nearlabel X X X X X 2 2 02 93 BCC farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BCS Branch on Carry Set aka BGE Branch on Greater than or Equal Description: .......................................................................... Branches to the near label if carry is set The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode B0 if (c) PC += operand; // Opcode B3 if (c) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References B0 BCS nearlabel X X X X X 2 2 02 B3 BCS farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BEQ Branch on EQual Description: .......................................................................... Branches to the near label if zero is set The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode F0 if (z) PC += operand; // Opcode F3 if (z) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References F0 BEQ nearlabel X X X X X 2 2 02 F3 BEQ farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BGE Branch on Greater than or Equal See BCS --------------------------------------------------------------------------------------------------- BIT test BITs Description: .......................................................................... Does an internal-only AND of A and the value, for setting flags Flags: ................................................................................ if Opcode == 89 nv-bdizc ------*- z - Set if value AND A is 0 else nv-bdizc **----*- n - Is the high bit of A set? v - Is the second highest bit of A set? z - Set if value AND A is 0 Code: ................................................................................. Opcode 89 version: z = !(A & operand); Others: result = A & operand; z = !result; n = result & highbit; v = result & nexthbit; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 24 BIT $ab X X X X 2 3 25,22,31,42 2C BIT $abcd X X X X 3 4 25,31,42 34 BIT $ab,X - X X X 2 4 25,22,40,42 3C BIT $abcd,X - X X X 3 4 25,01,31,42 89 BIT #$ab - X X X 2 2 25,24,42 --------------------------------------------------------------------------------------------------- BLT Branch on Less Than see BCC --------------------------------------------------------------------------------------------------- BMI Branch on MInus Description: .......................................................................... Branch to the near label if n is set The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode 30 if (n) PC += operand; // Opcode 33 if (n) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 30 BMI nearlabel X X X X X 2 2 02 33 BMI farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BNE Branch on Not Equal Description: .......................................................................... Branch to the near label if z is clear The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode D0 if (!z) PC += operand; // Opcode D3 if (!z) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References D0 BNE nearlabel X X X X X 2 2 02 D3 BNE farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BPL Branch on PLus Description: .......................................................................... Branch to the near label if n is clear The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode 10 if (!n) PC += operand; // Opcode 13 if (!n) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 10 BPL nearlabel X X X X X 2 2 02 13 BPL farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BRA BRanch Always 65c02+ and M740 Only Description: .......................................................................... Branches to the near label The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. M740: [20] states that BRA takes 4 cycles but adds 2 cycles for the branch, whereas all condition based branches only take 2 cycles and add 2 cycles for branching. I believe this is a mistake and that BRA actually only takes 2 cycles + 2 for the branch (in effect 4 still). Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode 80 PC += operand; // Opcode 83 (65ce02) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 80 BRA nearlabel - X X X X 2 2 02 83 BRA farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BRK BReaK Description: .......................................................................... Force a software interrupt. Ignores the Interrupt flag. Although BRK is only a one byte instruction, PC is incremented by 2, leaving a 1 byte signature byte to indicate which break caused the interrupt. 6502/65c02/65c816 in 8bit/emulation mode: The break flag is set, then PC is pushed onto the stack, P is then pushed onto the stack (a 3 byte total), the Interrupt flag is set, the decimal flag is cleared (except on the 6502) and PC is loaded with the interrupt vector which is located at $FFFE. 65c816 in native mode: PBR is pushed onto the stack, then PC, then P (a 4 byte total), the Interrupt flag is set, the decimal flag is cleared, PBR is set to 0, and PC is loaded with the interrupt vector which is located at $00FFE6. [5]: Mentions a BRK bug, but we have no clue what this is since they don't emulate it Flags: ................................................................................ nv-bdizc ---**1-- b - This is set in 6502, 65c02 and 65c816 in 8bit/emulation mode. d - This flag is NOT modified on the 6502. It is 0 on the 65c02 and 65c816 i - This is set to 1, to disable hardware interrupts Code: ................................................................................. if (CPU == 65c816 && !e) { StackPushByte(PBR); StackPushWord(PC); StackPushByte(P); i = 1; d = 0; PBR = 0; PC = GetWord($00FFE6); } else { StackPushWord(PC); StackPushByte(P); i = 1; if (CPU != 6502) d = 0; PC = GetWord($FFFE); } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 00 BRK #$ab X X X X 2 7 23,31 --------------------------------------------------------------------------------------------------- BRL BRanch Long 65c816 Family Only Description: .......................................................................... Branches to the far label The value of the label is a signed word, with a range from -32768 to 32767 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. PC += operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 82 BRL farlabel - - - X 3 4 --------------------------------------------------------------------------------------------------- BSR Branch to Sub-Routine 65sc02, 65ce02 and HuC6280 Only * Opinion: The HuC6280 version by Hudson Soft is rather lame! BSR only gives you a range of a single S8 which kinda defeats the purpose of a sub routine (which is reusable over and over in your code). Of course it can be used really close in your code to the sub routine, but how often does this really happen? Description: .......................................................................... Pushes the absolute address of the next instruction - 1 onto the stack, then jumps to the routine. The HuC6280 version only uses a nearlabel (8bit signed), whereas the 65sc02/65ce02 version uses a farlabel (16bit signed). Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // HuC6280 Opcode 44: StackPushWord(PC - 1); PC += operand; // 65sc02/65ce02 Opcode 63: StackPushWord(PC - 1); PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65sc02 HuC6280 65ce02 65c816 Size Cyc References 44 BSR nearlabel - - - - X - - 2 8 63 BSR farlabel - - - X - X - 3 6 40 --------------------------------------------------------------------------------------------------- BVC Branch on oVerflow Clear Description: .......................................................................... Branch to the near label if v is clear The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode 50 if (!v) PC += operand; // Opcode 53 if (!v) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 50 BVC nearlabel X X X X X 2 2 02 53 BVC farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- BVS Branch on oVerflow Set Description: .......................................................................... Branch to the near label if v is set The value of the label is a signed byte, with a value between -128 and 127 If overflow occurs on PC, then it wraps around inside the current bank The value of PC affected is based off of the byte immediated after the instruction 65ce02: A signed word version is also provided. This gives a range of -32768 to 32767. However, unlike the one byte version, this is based on PC - 1. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode 70 if (v) PC += operand; // Opcode 73 if (v) PC += operand - 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 70 BVS nearlabel X X X X X 2 2 02 73 BVS farlabel - - - X - 3 3 --------------------------------------------------------------------------------------------------- CIM* Crash Immediately [ILLEGAL OPCODE] 6502 Only See HLT* --------------------------------------------------------------------------------------------------- CLA CLear Accumulator HuC6280 Only Description: .......................................................................... Sets A to 0 Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. A = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 62 CLA - - - X - 1 2 --------------------------------------------------------------------------------------------------- CLBx CLear Bit M740 Family Only See RMBx --------------------------------------------------------------------------------------------------- CLC CLear Carry flag Description: .......................................................................... Clears the carry flag Flags: ................................................................................ nv-bdizc -------0 Code: ................................................................................. c = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 18 CLC X X X X 1 2 40 --------------------------------------------------------------------------------------------------- CLD CLear Decimal flag Description: .......................................................................... Clears the decimal flag Flags: ................................................................................ nv-bdizc ----0--- Code: ................................................................................. d = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References D8 CLD X X X X 1 2 40 --------------------------------------------------------------------------------------------------- CLE CLear Extended stack disable flag 65ce02 Only Description: .......................................................................... Clear e Flags: ................................................................................ nvebdizc --0----- Code: ................................................................................. e = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 02 CLE - - - X - 1 2 42 --------------------------------------------------------------------------------------------------- CLI CLear Interrupt flag Description: .......................................................................... Clears the interrupt disable flag Flags: ................................................................................ nv-bdizc -----0-- Code: ................................................................................. i = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 58 CLI X X X X 1 2 --------------------------------------------------------------------------------------------------- CLT CLear memory Transfer flag M740 Family Only Description: .......................................................................... Clears the memory transfer flag Flags: ................................................................................ nvtbdizc --0----- Code: ................................................................................. t = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 12 CLT - - - X - 1 2 --------------------------------------------------------------------------------------------------- CLV CLear oVerflow Description: .......................................................................... Clears the overflow flag Flags: ................................................................................ nv-bdizc -0------ Code: ................................................................................. v = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References B8 CLV X X X X 1 2 40 --------------------------------------------------------------------------------------------------- CLX CLear X index HuC6280 Only Description: .......................................................................... Sets X to 0 Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. X = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 82 CLX - - - X - 1 2 --------------------------------------------------------------------------------------------------- CLY CLear Y index HuC6280 Only Description: .......................................................................... Sets Y to 0 Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. Y = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References C2 CLY - - - X - 1 2 --------------------------------------------------------------------------------------------------- CMP CoMPare values Description: .......................................................................... Compares a value with A, setting flags for branch functions. This is done by subtracting the value from A. The result is discarded, only flags are changed. Flags: ................................................................................ nv-bdizc *-----** n - Was the high bit of the result set? z - Was the result 0? c - Was there NOT borrow (ie, was the result greater or equal to 0 or A >= operand)? The z and c flags are set according to this chart: z c --------------------- A < operand 0 0 A = operand 1 1 A > operand 0 1 Code: ................................................................................. result = A - operand; n = result & highbit; z = !result; c = A >= operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References C1 CMP ($ab,X) X X X X X 2 6 25,22,31,40,50 C3 CMP $ab,S - - - - X 2 4 25 C5 CMP $ab X X X X X 2 3 25,22,31,50 C7 CMP [$ab] - - - - X 2 6 25,22 C9 CMP #$ab X X X X X 2 2 25,24,50 CD CMP $abcd X X X X X 3 4 25,31,50 CF CMP $abcdef - - - - X 4 5 25 D1 CMP ($ab),Y X X X X X 2 5 25,22,01,32,50,53 D2 CMP ($ab) - X X - X 2 5 25,22,32 D2 CMP ($ab),Z - - - X - 2 5 D3 CMP ($ab,S),Y - - - - X 2 7 25 D5 CMP $ab,X X X X X X 2 4 25,22,40,50 D7 CMP [$ab],Y - - - - X 2 6 25,22 D9 CMP $abcd,Y X X X X X 3 4 25,01,31,50,53 DD CMP $abcd,X X X X X X 3 4 25,01,31,50,53 DF CMP $abcdef,X - - - - X 4 5 25 --------------------------------------------------------------------------------------------------- COM COMplement M740 Family Only Description: .......................................................................... Sets the value to it's one's complement. This is the same as doing EOF #$FF, but it affects memory instead of just the Accumulator. Flags: ................................................................................ nvtbdizc *-----*- n - Was the high bit of the result set? z - Was the result zero? Code: ................................................................................. operand = ~operand; n = (operand & 0x80); z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 44 COM $ab - - - X - 2 5 --------------------------------------------------------------------------------------------------- COP CO-Processor enable 65c816 Family Only Description: .......................................................................... This instruction is very similar to the BRK instruction The COP instruction is only 1 byte in length, but has a second "signature" byte afterwards. 65c816 in 8bit/Emulation mode: PC is pushed onto the stack, then P is pushed onto the stack (3 bytes), the Interrupt disable flag is set, decimal is cleared, and PC is loaded with the vector at $FFF4 65c816 in Native mode: PBR is pushed onto the stack, then PC, then P (4 bytes), the interrupt disable flag is set, the decimal flag is cleared, PBR becomes 0, and PC is loaded with the at $00FFE4 Flags: ................................................................................ nv-bdizc nvmxdizc ----01-- d - Set to 0 i - Set to 1, to disable hardware interrupts Code: ................................................................................. if (!e) { StackPushByte(PBR); StackPushWord(PC); StackPushByte(P); i = 1; d = 0; PBR = 0; PC = GetWord($00FFE4); } else { StackPushWord(PC); StackPushByte(P); i = 1; d = 0; PC = GetWord($FFF4); } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 02 COP #$ab - - - X 2 7 23 --------------------------------------------------------------------------------------------------- CPX ComPare with X index Description: .......................................................................... Compares a value with X, setting flags for branch functions. This is done by subtracting the value from X. The result is discarded, only flags are changed. Flags: ................................................................................ nv-bdizc *-----** n - Was the high bit of the result set? z - Was the result 0? c - Was there NOT borrow (ie, was the result greater or equal to 0 or X >= operand)? The z and c flags are set according to this chart: z c --------------------- X < operand 0 0 X = operand 1 1 X > operand 0 1 Code: ................................................................................. result = X - operand; n = result & highbit; z = !result; c = A >= operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References E0 CPX #$ab X X X X 2 2 28,27 E4 CPX $ab X X X X 2 3 22,28,31 EC CPX $abcd X X X X 3 4 28,31 --------------------------------------------------------------------------------------------------- CPY ComPare with Y index Description: .......................................................................... Compares a value with Y, setting flags for branch functions. This is done by subtracting the value from Y. The result is discarded, only flags are changed. Flags: ................................................................................ nv-bdizc *-----** n - Was the high bit of the result set? z - Was the result 0? c - Was there NOT borrow (ie, was the result greater or equal to 0 or Y >= operand)? The z and c flags are set according to this chart: z c --------------------- Y < operand 0 0 Y = operand 1 1 Y > operand 0 1 Code: ................................................................................. result = Y - operand; n = result & highbit; z = !result; c = Y >= operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References C0 CPY #$ab X X X X 2 2 28,27 C4 CPY $ab X X X X 2 3 22,28,31 CC CPY $abcd X X X X 3 4 28,31 --------------------------------------------------------------------------------------------------- CPZ ComPare with Z index 65ce02 Only Description: .......................................................................... Compares a value with Z, setting flags for branch functions. This is done by subtracting the value from Z. The result is discarded, only flags are changed. Flags: ................................................................................ nv-bdizc *-----** n - Was the high bit of the result set? z - Was the result 0? c - Was there NOT borrow (ie, was the result greater or equal to 0 or Z >= operand)? The z and c flags are set according to this chart: z c --------------------- Z < operand 0 0 Z = operand 1 1 Z > operand 0 1 Code: ................................................................................. result = Z - operand; n = result & highbit; z = !result; c = Z >= operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References C2 CPZ #$ab - - - X - 2 2 D4 CPZ $ab - - - X - 2 3 DC CPZ $abcd - - - X - 3 4 --------------------------------------------------------------------------------------------------- CSH Clock Select High HuC6280 Only Description: .......................................................................... Sets cs to high (1), setting the CPU back to full speed (or doing nothing if it already was) Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. cs = 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References D4 CSH - - - X - 1 3 --------------------------------------------------------------------------------------------------- CSL Clock Select Low HuC6280 Only * Opinion: This instruction is kinda stupid. Why would anybody ever want to down clock their CPU? Did the TG16 overheat? It's not like there was an older TG16 to be compatible with, and the cycles of the HuC6280 don't match anything else anyways... Description: .......................................................................... Sets cs to low (0), effectively quartering the speed of the CPU Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. cs = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 54 CSL - - - X - 1 3 --------------------------------------------------------------------------------------------------- DCP* Decrement then ComPare [ILLEGAL OPCODE] 6502 Only See DCM* --------------------------------------------------------------------------------------------------- DCM* Decrement then CoMpare aka DCP* Decrement then ComPare [ILLEGAL OPCODE] 6502 Only [DISCREPENCY IN DEFINITION] Description: .......................................................................... [5] and [6]: Decrements the value in memory, then CMPs the result with A [7]: Decrements a value in memory, setting only the carry flag Flags: ................................................................................ nv-bdizc *-----** n - Was the high bit of the result set? z - Was the result 0? c - Was there NOT borrow (ie, was the result greater or equal to 0 or A >= operand)? The z and c flags are set according to this chart: z c --------------------- A < operand 0 0 A = operand 1 1 A > operand 0 1 Code: ................................................................................. operand--; result = A - operand; n = result & highbit; z = !result; c = A >= operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References C3 DCM* ($ab,X) X - - - 2 8 Ill1 C7 DCM* $ab X - - - 2 5 Ill1 CF DCM* $abcd X - - - 3 6 Ill1 D3 DCM* ($ab),Y X - - - 2 8 Ill1 D7 DCM* $ab,X X - - - 2 6 Ill1 DB DCM* $abcd,Y X - - - 3 7 Ill1 DF DCM* $abcd,X X - - - 3 7 Ill1 --------------------------------------------------------------------------------------------------- DEA DEcrement Accumulator aka DEC A 65c02+ Only Description: .......................................................................... Decreases A by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. A--; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 3A DEA - X X X 1 2 40,42 or DEC A --------------------------------------------------------------------------------------------------- DEC DECrement value Description: .......................................................................... Decreases the value by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. operand--; n = operand & highbit; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References C6 DEC $ab X X X X 2 5 22,26,31,40,42 CE DEC $abcd X X X X 3 6 26,31,40,42 D6 DEC $ab,X X X X X 2 6 22,26,41,42 DE DEC $abcd,X X X X X 3 7 26,11,41,42 --------------------------------------------------------------------------------------------------- DEW DEcrement Word 65ce02 Only Description: .......................................................................... Decrements a word in memory Flags: ................................................................................ nvebdizc *-----*- n - Was the high bit of the result set? Or does this just test bit 7??? z - Was the result 0? Code: ................................................................................. operand--; n = operand & 0x8000; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References C3 DEW $ab - - - X - 2 5 42 --------------------------------------------------------------------------------------------------- DEX DEcrement X index Description: .......................................................................... Decreases X by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. X--; n = X & highbit; z = !X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References CA DEX X X X X 1 2 40,42 --------------------------------------------------------------------------------------------------- DEY DEcrement Y index Description: .......................................................................... Decreases Y by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. Y--; n = Y & highbit; z = !Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 88 DEY X X X X 1 2 40,42 --------------------------------------------------------------------------------------------------- DEZ DEcrement Z index 65ce02 Only Description: .......................................................................... Decrements Z Flags: ................................................................................ nvebdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. Z--; n = Z & highbit; z = !Z; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 3B DEZ - - - X - 1 1 42 --------------------------------------------------------------------------------------------------- DIV DIVide M740 Family Only Description: .......................................................................... Divides the 16bit value at the specified memory address by A. The quotient is stored in A and the one's complement of the remainder is pushed onto the stack. Overflow and division by zero are not detected. To test for overflow, simply check if the high byte of the value is greater or equal to A BEFORE doing the divide. KERBLUH- What happens when A is zero? For now, I'm assuming the one's complement of the low byte is pushed onto the stack since there'd be a full remainder, and A remains 0. Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. if (A) { result = operand / A; temp = ~(operand % A); A = result; } else { temp = ~(operand & 0xFF); } StackPushByte(temp); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References E2 DIV $ab,X - - - X - 2 16 --------------------------------------------------------------------------------------------------- DOP* Double no OPeration [ILLEGAL OPCODE] All but 65c816 and 65ce02 See SKB* --------------------------------------------------------------------------------------------------- EOM End Of Map 4510 Only (65ce02) Description: .......................................................................... This opcode replaces NOP on the other 6502 CPUs, and fulfills that duty as well as turning off the Full Interrupt Disable flag, after a MAP function has been called. Flags: ................................................................................ nvebdizc -------- Code: ................................................................................. fid = 0; Opcodes: .............................................................................. 6502 65c02 R65c02 65ce02 65ce02 65c816 Size Cyc References Op Format 4502 4510 EA EOM - - - - X - 1 1 --------------------------------------------------------------------------------------------------- EOR Exclusive OR accumulator Description: .......................................................................... Exclusive Ors A with the value Flags: ................................................................................ nv-bdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. A ^= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 41 EOR ($ab,X) X X X X X 2 6 25,22,31,40,52 43 EOR $ab,S - - - - X 2 4 25 45 EOR $ab X X X X X 2 3 25,22,31,52 47 EOR [$ab] - - - - X 2 6 25,22 49 EOR #$ab X X X X X 2 2 25,24,52 4D EOR $abcd X X X X X 3 4 25,31,52 4F EOR $abcdef - - - - X 4 5 25 51 EOR ($ab),Y X X X X X 2 5 25,22,01,32,52,53 52 EOR ($ab) - X X - X 2 5 25,22,32 52 EOR ($ab),Z - - - X - 2 5 53 EOR ($ab,S),Y - - - - X 2 7 25 55 EOR $ab,X X X X X X 2 4 25,40,52 57 EOR [$ab],Y - - - - X 2 6 25,22 59 EOR $abcd,Y X X X X X 3 4 25,01,31,52,53 5D EOR $abcd,X X X X X X 3 4 25,01,31,52,53 5F EOR $abcdef,X - - - - X 4 5 25 --------------------------------------------------------------------------------------------------- HLT* HaLT aka CIM* Crash IMmediate aka JAM* JAM execution aka KIL* KILl execution [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... The CPU locks up and refuses to execute any further Needless to say, this instruction should be avoided It makes me wonder how someone got the CPU cycles for this instruction (though they probably guessed) (All documents agree on this one) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. CauseCPUToStop(); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 02 HLT* X - - - 1 2 Ill1 12 HLT* X - - - 1 2 Ill1 22 HLT* X - - - 1 2 Ill1 32 HLT* X - - - 1 2 Ill1 42 HLT* X - - - 1 2 Ill1 52 HLT* X - - - 1 2 Ill1 62 HLT* X - - - 1 2 Ill1 72 HLT* X - - - 1 2 Ill1 92 HLT* X - - - 1 2 Ill1 B2 HLT* X - - - 1 2 Ill1 D2 HLT* X - - - 1 2 Ill1 F2 HLT* X - - - 1 2 Ill1 --------------------------------------------------------------------------------------------------- ILL* ILLegal opcode [ILLEGAL OPCODE] Description: .......................................................................... This isn't actually an opcode. It is often used in listings where the opcode is undefined, though of course using the opcode actually does SOMETHING. Most emulators will just treat these like NOPs, though this can be for NOP, SKW, SKB, or any other illegal opcode. --------------------------------------------------------------------------------------------------- INA INcrement Accumulator aka INC A 65c02+ Only Description: .......................................................................... Increments A by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of A set? z - Was A 0? Code: ................................................................................. A++; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 1A INA - X X X 1 2 40,42 or INC A --------------------------------------------------------------------------------------------------- INC INCrement value Description: .......................................................................... Increments the specified value by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. operand++; n = operand & highbit; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References E6 INC $ab X X X X 2 5 22,26,31,40,42 EE INC $abcd X X X X 3 6 26,31,40,42 F6 INC $ab,X X X X X 2 6 22,26,41,42 FE INC $abcd,X X X X X 3 7 26,11,41,42 --------------------------------------------------------------------------------------------------- INS* INcrement then Subtract aka ISB* Increment then SuBtract with carry aka ISC* Increment then Subtract with Carry [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... Increment value then SBC with A (All documents agree on this one) Flags: ................................................................................ nv-bdizc **----** n - Was the high bit of the result set? v - Was there signed overflow? v is set only if one of the following is true: If both A and operand are negative and the result is positive If both A and operand are positive and the result is negative z - Was the result 0? c - Was there overflow? Code: ................................................................................. operand++; // Normal subtract if (!d || CPU == 2A03) { result = operand + !c; c = result <= A; result = (U8/16) (A - result); v = ((A ^ operand) & (A ^ result)) & highbit; n = result & highbit; z = !result; // 8bit BCD } else { result = operand + !c; c = result <= A; // 1st nybble temp1 = (A & 0x0F) - (result & 0x0F); // 2nd nybble temp2 = (A >> 4) - (result >> 4); // Was the lower nybble negative? if (temp1 & 0x10) { temp1 -= 6; // BCD fix temp2--; } // Was the upper nybble negative? if (temp2 & 0x10) temp2 -= 6; // BCD fix // We don't correct oversized values, because they never should happen // Get the result result = ((temp2 << 4) | (temp1 & 0x0F)); // Invalid 6502 flags (from [5]) temp0 = A - result; v = ((A ^ operand) & (A ^ temp0)) & highbit; n = temp0 & highbit; z = !temp0; } A = result; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References E3 INS* ($ab,X) X - - - 2 8 Ill1 E7 INS* $ab X - - - 2 5 Ill1 EF INS* $abcd X - - - 3 6 Ill1 F3 INS* ($ab),Y X - - - 2 8 Ill1 F7 INS* $ab,X X - - - 2 6 Ill1 FB INS* $abcd,Y X - - - 3 7 Ill1 FF INS* $abcd,X X - - - 3 7 Ill1 --------------------------------------------------------------------------------------------------- INW INcrement Word 65ce02 Only Description: .......................................................................... Increments a word in memory Flags: ................................................................................ nvebdizc *-----*- n - Was the high bit of the result set? Or does this just test bit 7??? z - Was the result 0? Code: ................................................................................. operand++; n = operand & 0x8000; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References E3 INW $ab - - - X - 2 5 42 --------------------------------------------------------------------------------------------------- INX INcrement X index Description: .......................................................................... Increments X by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of X set? z - Was X 0? Code: ................................................................................. X++; n = X & highbit; z = !X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References E8 INX X X X X 1 2 40,42 --------------------------------------------------------------------------------------------------- INY INcrement Y index Description: .......................................................................... Increments Y by 1, ignoring the Decimal flag Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of Y set? z - Was Y 0? Code: ................................................................................. Y++; n = Y & highbit; z = !Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References C8 INY X X X X 1 2 40,42 --------------------------------------------------------------------------------------------------- INZ INcrement Z index 65ce02 Only Description: .......................................................................... Increments Z Flags: ................................................................................ nvebdizc *-----*- n - Was the high bit of the result set? z - Was the result 0? Code: ................................................................................. Z++; n = Z & highbit; z = !Z; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 1B INZ - - - X - 1 1 42 --------------------------------------------------------------------------------------------------- ISB* Increment then SuBtract with carry [ILLEGAL OPCODE] 6502 Only See INS* --------------------------------------------------------------------------------------------------- ISC* Increment then Subtract with Carry [ILLEGAL OPCODE] 6502 Only See INS* --------------------------------------------------------------------------------------------------- JAM* JAM execution [ILLEGAL OPCODE] 6502 Only See HLT* --------------------------------------------------------------------------------------------------- JMP JuMP to a new location Description: .......................................................................... Jumps to the specified location. 6502: The Original 6502 had a bug in JMP (addr) [6C only] when addr crossed page boundary. If the low byte of the address is $FF, then the second byte "Rolls Over" into $00 of the same page instead of getting it from $00 of the next page. ie, wordvalue = (memory(address & ~0xff) << 8) | memory(address); Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. PC = operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 4C JMP $abcd X X X X 3 3 31,42 5C JMP $abcdef - - - X 4 4 6C JMP ($abcd) X X X X 3 5 03,32,42 7C JMP ($abcd,X) - X X X 3 6 31,40,42 DC JMP [$abcd] - - - X 3 6 --------------------------------------------------------------------------------------------------- JSR Jump to SubRoutine Description: .......................................................................... If this is opcode 22 on the 65c816 (aka JSL), first push PBR. Push the absolute address of the next instruction - 1 onto the stack. Jumps to the routine. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Opcode 22 on 65c816 StackPushByte(PBR); StackPushWord(PC - 1); PBR = (operand >> 16); PC = (U16) operand; // All other opcodes StackPushWord(PC - 1); PC = operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 M740 65c816 Size Cyc References 02 JSR ($ab) - - - - X - 2 7 20 JSR $abcd X X X X X X 3 6 31,40 22 JSR ($abcd) - - - X - - 3 7 22 JSR \$ab - - - - X - 2 7 22 JSR $abcdef - - - - - X 4 8 or JSL $abcdef 23 JSR ($abcd,X) - - - X - - 3 7 FC JSR ($abcd,X) - - - - - X 3 8 --------------------------------------------------------------------------------------------------- KIL* KILl execution [ILLEGAL OPCODE] 6502 Only See HLT* --------------------------------------------------------------------------------------------------- LAE* Load Accumulator Extended ??? [ILLEGAL OPCODE] 6502 Only See LAS* --------------------------------------------------------------------------------------------------- LAR* Load Accumulator and x index with stack after and [no clue where the R goes] [ILLEGAL OPCODE] 6502 Only See LAS* --------------------------------------------------------------------------------------------------- LAS* Load Accumulator and x index with Stack after and aka LAE* Load Accumulator Extended ??? aka LAR* Load Accumulator and x index with stack after and [no clue where the R goes] aka AST* And STack pointer and value then load into accumulator and x index [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... AND S with memory value (stores in S), then copies S to A and X (All documents agree on this one, except [5] doesn't add a cycle on crossing a page) Flags: ................................................................................ nv-bdizc *-----*- n - Is the highbit set in the result? z - Is the result 0? Code: ................................................................................. A = X = S &= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References BB LAS* $abcd,Y X - - - 3 4 01,Ill1 --------------------------------------------------------------------------------------------------- LAX* Load Accumulator and X index [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... Loads A and X with the specified value (All documents agree on this one, except [5] doesn't add a cycle on crossing a page for B3 and BF) Flags: ................................................................................ nv-bdizc *-----*- n - Is the highbit set in the result? z - Is the result 0? Code: ................................................................................. A = X = operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References A3 LAX* ($ab,X) X - - - 2 6 Ill1 A7 LAX* $ab X - - - 2 3 Ill1 AF LAX* $abcd X - - - 3 4 Ill1 B3 LAX* ($ab),Y X - - - 2 5 01,Ill1 B7 LAX* $ab,Y X - - - 2 4 Ill1 BF LAX* $abcd,Y X - - - 3 4 01,Ill1 --------------------------------------------------------------------------------------------------- LDA LoaD Accumulator with value Description: .......................................................................... Loads A with the specified value Flags: ................................................................................ nv-bdizc *-----*- n - Is the highbit set in the result? z - Is the result 0? Code: ................................................................................. A = operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References A1 LDA ($ab,X) X X X X X 2 6 25,22,31,40,51 A3 LDA $ab,S - - - - X 2 4 25 A5 LDA $ab X X X X X 2 3 25,22,31,51 A7 LDA [$ab] - - - - X 2 6 25,22 A9 LDA #$ab X X X X X 2 2 25,24,51 AD LDA $abcd X X X X X 3 4 25,31,51 AF LDA $abcdef - - - - X 4 5 25 B1 LDA ($ab),Y X X X X X 2 5 25,22,01,32,51,53 B2 LDA ($ab) - X X - X 2 5 25,22,32 B2 LDA ($ab),Z - - - X - 2 5 B3 LDA ($ab,S),Y - - - - X 2 7 25 B5 LDA $ab,X X X X X X 2 4 25,22,40,51 B7 LDA [$ab],Y - - - - X 2 6 25,22 B9 LDA $abcd,Y X X X X X 3 4 25,01,31,51,53 BD LDA $abcd,X X X X X X 3 4 25,01,31,51,53 BF LDA $abcdef,X - - - - X 4 5 25 E2 LDA ($ab,S),Y - - - X - 2 6 --------------------------------------------------------------------------------------------------- LDM Load Data to Memory M740 Only Description: .......................................................................... Loads an immediate value into the specified memory location Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. operand = value; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 3C LDM #$ab,$cd - - - X - 3 4 --------------------------------------------------------------------------------------------------- LDX LoaD X index with value Description: .......................................................................... Loads X with the specified value 65c816 & M7700: The x flag (Index Register) is used to determine if an 8 or 16bit value is passed to X in native mode Flags: ................................................................................ nv-bdizc *-----*- n - Is the highbit set in the result? z - Is the result 0? Code: ................................................................................. X = operand; n = X & highbit; z = !X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References A2 LDX #$ab X X X X 2 2 28,27 A6 LDX $ab X X X X 2 3 22,28,31 AE LDX $abcd X X X X 3 4 28,31 B6 LDX $ab,Y X X X X 2 4 22,28,40 BE LDX $abcd,Y X X X X 3 4 01,28,31,53 --------------------------------------------------------------------------------------------------- LDY LoaD Y index with value Description: .......................................................................... Loads Y with the specified value 65c816 & M7700: The x flag (Index Register) is used to determine if an 8 or 16bit value is passed to Y in native mode Flags: ................................................................................ nv-bdizc *-----*- n - Is the highbit set in the result? z - Is the result 0? Code: ................................................................................. Y = operand; n = Y & highbit; z = !Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References A0 LDY #$ab X X X X 2 2 28,27 A4 LDY $ab X X X X 2 3 22,28,31 AC LDY $abcd X X X X 3 4 28,31 B4 LDY $ab,X X X X X 2 4 22,28,40 BC LDY $abcd,X X X X X 3 4 01,28,31,53 --------------------------------------------------------------------------------------------------- LDZ LoaD Z index 65ce02 Only Description: .......................................................................... Loads Z with the specified value Flags: ................................................................................ nv-bdizc *-----*- n - Is the highbit set in the result? z - Is the result 0? Code: ................................................................................. Y = operand; n = Y & highbit; z = !Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References A3 LDZ #$ab - - - X - 2 2 AB LDZ $abcd - - - X - 3 4 BB LDZ $abcd,X - - - X - 3 4 --------------------------------------------------------------------------------------------------- LSE* Logical Shift right then Eor aka SRE* Shift Right then Eor [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... LSR operand then EOR with A (All documents agree on this one) Flags: ................................................................................ nv-bdizc *-----** n - Is the highbit set in the result? z - Is the result 0? c - Was the low bit of the operand 1 before the bit shift Code: ................................................................................. c = operand & 0x01; operand >>= 1; A ^= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 43 LSE* ($ab,X) X - - - 2 8 Ill1 47 LSE* $ab X - - - 2 5 Ill1 4F LSE* $abcd X - - - 3 6 Ill1 53 LSE* ($ab),Y X - - - 2 8 Ill1 57 LSE* $ab,X X - - - 2 6 Ill1 5B LSE* $abcd,Y X - - - 3 7 Ill1 5F LSE* $abcd,X X - - - 3 7 Ill1 --------------------------------------------------------------------------------------------------- LSR Logical Shift Right Description: .......................................................................... Shifts bits down one, moving bit 0 of the value into carry, and moving 0 into the high bit. Flags: ................................................................................ nv-bdizc 0-----** n - Alway 0 since the high bit of the result will always be 0. z - Is the result 0? c - Was bit 0 set before the bit shift? Code: ................................................................................. c = operand & 0x01; operand >>= 1; n = 0; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 46 LSR $ab X X X X 2 5 22,26,31,40,42 4A LSR A X X X X 1 2 40,42 or LSR 4E LSR $abcd X X X X 3 6 26,31,40,42 56 LSR $ab,X X X X X 2 6 22,26,41,42 5E LSR $abcd,X X X X X 3 7 26,11,41,42 --------------------------------------------------------------------------------------------------- LXA* Load X index and Accumulator with accumulator and value [ILLEGAL OPCODE] 6502 Only See ANX* --------------------------------------------------------------------------------------------------- MAP MAP update 4510 Only (65ce02) Description: .......................................................................... This opcode takes A, X, Y and Z and assigns them to LRAO, URAO and MMRF. Then it sets the Full Interrupt Disable flag, making it so no interrupts whatsoever can affect the processor. To clear the Full Interrupt Disable flag, use the EOM instruction (opcode EA). MAP reads in the following data from the A, X, Y and Z registers: Reg BITS Desc A 0 to 7 Bits 8 to 15 of LRAO X 0 to 3 Bits 16 to 19 of LRAO 4 to 7 Bits 0 to 3 of MMRF Y 0 to 7 Bits 8 to 15 for URAO Z 0 to 3 Bits 16 to 19 for URAO 4 to 7 Bits 4 to 7 of MMRF To calculate the values: LRAO = ((X & 0x0F) << 16) + (A << 8); URAO = ((Z & 0x0F) << 16) + (Y << 8); MMRF = (Z & 0xF0) + ((X & 0xF0) >> 4); See the LRAO, URAO and MMRF registers above for a full description on how they work Flags: ................................................................................ nvebdizc -------- Code: ................................................................................. LRAO = ((X & 0x0F) << 16) + (A << 8); URAO = ((Z & 0x0F) << 16) + (Y << 8); MMRF = (Z & 0xF0) + (X >> 4); fid = 1; Opcodes: .............................................................................. 6502 65c02 R65c02 65ce02 65ce02 65c816 Size Cyc References Op Format 4502 4510 5C MAP - - - - X - 1 2 42 --------------------------------------------------------------------------------------------------- MUL Multiply M740 Only Description: .......................................................................... Multiplies the Accumulator with the 8bit value in memory, storing the low byte in A and pushing the high byte on the stack. Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. result = A * operand; A = (U8) result; StackPushByte(result >> 8); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 62 MUL $ab,X - - - X - 2 15 --------------------------------------------------------------------------------------------------- MVN MoVe block Next 65c816 Family Only Description: .......................................................................... Copies a block of memory from one location to another. X = Source location, Y = Destination location, C = length - 1 (in bytes, a $0005 here would mean to move 6 bytes), parameter 1 = source data bank, parameter 2 = destination databank. For each iteration of the move, X and Y are incremented and C is decremented In assembly, the source is first, then the destination like this: MVN $ab, $cd but the processor actually stores this backwards like this: 54 cd ab Interrupts may occur while this instruction is running. When execution is complete, C will be $FFFF, X and Y will point to one byte past the end of the blocks they were pointing to, and DBR will hold the destination value. If the index registers are in 8bit mode (if x is set) OR the processor is in emulation mode, the blocks being moved must be in page zero since the high bytes of the index registers X and Y will both be 0. Flags: ................................................................................ nv-bdizc nvmxdizc -------- Code: [Full Version] .................................................................. param0 = GetByte(PC + 1); param1 = GetByte(PC + 2); PutByteLong(param0, Y++, GetByteLong(param1, X++)); // If we're done, we need to set DBR and move to the next instruction if (!C--) { DBR = param0; PC += 3; } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 54 MVN $ab,$cd - - - X 3 7n 21 --------------------------------------------------------------------------------------------------- MVP MoVe block Previous 65c816 Family Only Description: .......................................................................... Copies a block of memory from one location to another. X = End of the Source location, Y = End of the Destination location, C = length - 1 (in bytes, a $0005 here would mean to move 6 bytes), parameter 1 = source data bank, parameter 2 = destination databank. For each iteration of the move, X and Y are decremented and C is decremented In assembly, the source is first, then the destination like this: MVN $ab, $cd but the processor actually stores this backwards like this: 44 cd ab Interrupts may occur while this instruction is running. When execution is complete, C will be $FFFF, X and Y will point to one byte before the beginning of the blocks they were pointing to, and DBR will hold the destination value. If the index registers are in 8bit mode (if x is set) OR the processor is in emulation mode, the blocks being moved must be in page zero since the high bytes of the index registers X and Y will both be 0. Flags: ................................................................................ nv-bdizc nvmxdizc -------- Code: [Full Version] .................................................................. param0 = GetByte(PC++); param1 = GetByte(PC++); PutByteLong(param0, Y--, GetByteLong(param1, X--)); // If we're done, we need to set DBR and move to the next instruction if (!C--) { DBR = param0; PC += 3; } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 44 MVP $ab,$cd - - - X 3 7n 21 --------------------------------------------------------------------------------------------------- NEG NEGative accumulator 65ce02 Only Description: .......................................................................... This takes the two's complement of A. Flags: ................................................................................ nvebdizc *-----*- n - Was the highbit of the result set? z - Was the result 0? Code: ................................................................................. A = -A; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 42 NEG A - - - X - 1 2 --------------------------------------------------------------------------------------------------- NOP No OPeration On 65ce02, see EOM Description: .......................................................................... This simply does nothing. It is used as a placeholder in memory, or to add 2 cycles to a time critical operation. HuC6280: All undocumented instructions are NOPs on the HuC6280. These are not listed here. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Do nothing Opcodes: .............................................................................. 6502 65c02 R65c02 HuC6280 65ce02 65ce02 65c816 Size Cyc References Op Format 4502 4510 EA NOP X X X X X - X 1 2 40 Op Format 6502 65c02 R65c02 HuC6280 65ce02 65c816 Size Cyc References 03 NOP* - X X - - - 1 1 Ill2 13 NOP* - X X - - - 1 1 Ill2 1A NOP* X - - - - - 1 2 Ill1 23 NOP* - X X - - - 1 1 Ill2 33 NOP* - X X X - - 1 1 Ill2 3A NOP* X - - - - - 1 2 Ill1 5A NOP* X - - - - - 1 2 Ill1 7A NOP* X - - - - - 1 2 Ill1 DA NOP* X - - - - - 1 2 Ill1 FA NOP* X - - - - - 1 2 Ill1 --------------------------------------------------------------------------------------------------- OAL* Or accumulator, And with value then Load x index [ILLEGAL OPCODE] 6502 Only See ANX* --------------------------------------------------------------------------------------------------- ORA OR with Accumulator Description: .......................................................................... ORs A with the specified value Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of the result set? z - Was the result 0? Code: ................................................................................. A |= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 01 ORA ($ab,X) X X X X X 2 6 25,22,31,40,52 03 ORA $ab,S - - - - X 2 4 25 05 ORA $ab X X X X X 2 3 25,22,31,52 07 ORA [$ab] - - - - X 2 6 25,22 09 ORA #$ab X X X X X 2 2 25,24,52 0D ORA $abcd X X X X X 3 4 25,31,52 0F ORA $abcdef - - - - X 4 5 25 11 ORA ($ab),Y X X X X X 2 5 25,22,01,32,52,53 12 ORA ($ab) - X X - X 2 5 25,22,32 12 ORA ($ab),Z - - - X - 2 5 13 ORA ($ab,S),Y - - - - X 2 7 25 15 ORA $ab,X X X X X X 2 4 25,22,40,52 17 ORA [$ab],Y - - - - X 2 6 25,22 19 ORA $abcd,Y X X X X X 3 4 25,01,31,52,53 1D ORA $abcd,X X X X X X 3 4 25,01,31,52,53 1F ORA $abcdef,X - - - - X 4 5 25 --------------------------------------------------------------------------------------------------- PEA Push Effective Absolute address 65c816 Family Only Description: .......................................................................... Pushes the 16bit operand onto the stack, regardless of the m, x or e flags Though the assembly syntax for this opcode uses $abcd, that value is treated as an immediate value that is pushed onto the stack or as an effective address, as the opcode's name suggests. Flags: ................................................................................ nv-bdizc nvmxdizc -------- Code: [Full Version] .................................................................. address = GetWord(PC); PC += 2; StackPushWord(address); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References F4 PEA $abcd - - - X 3 5 --------------------------------------------------------------------------------------------------- PEI Push Effective Indirect address 65c816 Family Only Description: .......................................................................... Pushes the 16bit address located at the direct page address specified, regardless of the m, x or e flags. Though assembly shows this as direct page indirect, the address from the direct page is used as if it was a normal direct page access. Flags: ................................................................................ nv-bdizc nvmxdizc -------- Code: [Full Version] .................................................................. result = GetByte(PC++); StackPushWord(GetWord(result)); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References D4 PEI ($ab) - - - X 2 6 22 --------------------------------------------------------------------------------------------------- PER Push Effective program counter Relative indirect address 65c816 Family Only Description: .......................................................................... Pushes PC + the value to the stack. The PC value is, of course, after the instruction. The value is a signed 16bit value that is generated from Assembly via a far label. This allows programs to access regions of their code space (or data space) when they are loaded into memory dynamically. Flags: ................................................................................ nv-bdizc -------- Code: [Full Version] .................................................................. result = GetWord(PC); PC += 2; StackPushWord(PC + result); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 62 PER farlabel - - - X 3 6 --------------------------------------------------------------------------------------------------- PHA PusH Accumulator Description: .......................................................................... Pushes A onto the stack Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (CPU == 65c816 && !e && !m) { StackPushWord(A); } else { StackPushByte(A); } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 48 PHA X X X X 1 3 25 --------------------------------------------------------------------------------------------------- PHB PusH data Bank register 65c816 Family Only Description: .......................................................................... Pushes DBR onto the stack Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. StackPushByte(DBR); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 8B PHB - - - X 1 3 --------------------------------------------------------------------------------------------------- PHD PusH Data 65ce02 Only See PHW --------------------------------------------------------------------------------------------------- PHD PusH Direct page register 65c816 Family Only Description: .......................................................................... Pushes D onto the stack Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. StackPushWord(D); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 0B PHD - - - X 1 4 --------------------------------------------------------------------------------------------------- PHK PusH program banK register 65c816 Family Only Description: .......................................................................... Pushes PBR onto the stack Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. StackPushWord(PBR); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 4B PHK - - - X 1 3 --------------------------------------------------------------------------------------------------- PHP PusH Program flags register Description: .......................................................................... Pushes P onto the stack. For everything except the 65c816 native mode, the b flag is always set in the pushed value. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (CPU == 65c816 && !e) { StackPushByte(P); } else { StackPushByte(P | 0x10); } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 08 PHP X X X X 1 3 --------------------------------------------------------------------------------------------------- PHW PusH Word aka PHD PusH Data 65ce02 Only Description: .......................................................................... Pushes word data onto the stack Flags: ................................................................................ nvebdizc -------- Code: ................................................................................. StackPushWord(operand); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References F4 PHW #$abcd - - - X - 3 5 FC PHW $abcd - - - X - 3 7 --------------------------------------------------------------------------------------------------- PHX PusH X index Description: .......................................................................... Pushes X onto the stack Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (CPU == 65c816 && !e && !x) { StackPushWord(X); } else { StackPushByte(X); } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References DA PHX - X X X 1 3 28 --------------------------------------------------------------------------------------------------- PHY PusH Y index Description: .......................................................................... Pushes Y onto the stack Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (CPU == 65c816 && !e && !x) { StackPushWord(Y); } else { StackPushByte(Y); } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 5A PHY - X X X 1 3 28 --------------------------------------------------------------------------------------------------- PHZ PusH Z index 65ce02 Only Description: .......................................................................... Pushes Z onto the stack Flags: ................................................................................ nvebdizc -------- Code: ................................................................................. StackPushByte(Z); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References DB PHZ - - - X - 1 3 --------------------------------------------------------------------------------------------------- PLA PuLl Accumulator Description: .......................................................................... Pulls A from the stack Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of the value pulled set? z - Was the value pulled 0? Code: ................................................................................. if (CPU == 65c816 && !e && !m) { A = StackPopWord(); } else { A = StackPopByte(); } n = A & highbit; z = A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 68 PLA X X X X 1 4 25,40 --------------------------------------------------------------------------------------------------- PLB PuLl data Bank register 65c816 Family Only Description: .......................................................................... Pulls DBR from the stack Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of the value pulled set? z - Was the value pulled 0? Code: ................................................................................. DBR = StackPopByte(); n = DBR & highbit; z = DBR; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References AB PLB - - - X 1 4 --------------------------------------------------------------------------------------------------- PLD PuLl Direct page register 65c816 Family Only Description: .......................................................................... Pulls D from the stack Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of the value pulled set? z - Was the value pulled 0? Code: ................................................................................. D = StackPopWord(); n = D & highbit; z = D; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 2B PLD - - - X 1 5 --------------------------------------------------------------------------------------------------- PLP PuLl Program flags register Description: .......................................................................... Pulls P from the stack Flags: ................................................................................ 6502/65c02/65c816 in 8bit/emulation mode: nv-bdizc **--**** All flags are set according to the value of P pulled, ignoring b and bit 5 65ce02: nvebdizc ***-**** All flags are set according to the value of P pulled, ignoring b 65c816 in native mode: nvmxdizc ******** All flags are set according to the value of P pulled Code: ................................................................................. if (CPU == 65c816 && !e) P = StackPopByte(); else if (CPU == 65ce02) P = (P & 0x10) | (StackPopByte() & 0xEF); else P = (P & 0x30) | (StackPopByte() & 0xCF); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 28 PLP X X X X 1 4 40 --------------------------------------------------------------------------------------------------- PLX PuLl X index Description: .......................................................................... Pulls X from the stack Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of the value pulled set? z - Was the value pulled 0? Code: ................................................................................. if (CPU == 65c816 && !e && !x) { X = StackPopWord(); } else { X = StackPopByte(); } n = X & highbit; z = X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References FA PLX - X X X 1 4 28,40 --------------------------------------------------------------------------------------------------- PLY PuLl Y index Description: .......................................................................... Pulls Y from the stack Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of the value pulled set? z - Was the value pulled 0? Code: ................................................................................. if (CPU == 65c816 && !e && !x) { Y = StackPopWord(); } else { Y = StackPopByte(); } n = Y & highbit; z = Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 7A PLY - X X X 1 4 28,40 --------------------------------------------------------------------------------------------------- PLZ Pull Z index 65ce02 Only Description: .......................................................................... Pulls Z from the stack Flags: ................................................................................ nvebdizc *-----*- n - Was the highbit of the value pulled set? z - Was the value pulled 0? Code: ................................................................................. Z = StackPopByte(); n = Z & highbit; z = Z; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References FB PLZ - - - X - 1 3 --------------------------------------------------------------------------------------------------- REP REset Program flags register bits 65c816 Family Only Description: .......................................................................... For each bit set to 1 in the operand, the corresponding bit in the status register is set to 0. In 8bit/emulation mode, bits 5 and 4 (Break) are not affected Flags: ................................................................................ nv-bdizc **--**** Bits 5 and 4 are not affected in 8bit/emulation mode nvmxdizc ******** All bits are affected in native mode Code: ................................................................................. if (!e) P &= ~operand; else P &= ~(operand & 0xCF); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References C2 REP #$ab - - - X 2 3 --------------------------------------------------------------------------------------------------- RLA* Rotate Left then And [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... Rotate value left, with carry, then AND with A (All documents agree on this one) Flags: ................................................................................ nv-bdizc *-----** n - Was A's highbit set? z - Was A 0? c - Was the highbit set on the value before the rotate? Code: ................................................................................. if (c) { c = operand & highbit; operand <<= 1; operand++; } else { c = operand & highbit; operand <<= 1; } A &= operand; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 23 RLA* ($ab,X) X - - - 2 8 Ill1 27 RLA* $ab X - - - 2 5 Ill1 2F RLA* $abcd X - - - 3 6 Ill1 33 RLA* ($ab),Y X - - - 2 8 Ill1 37 RLA* $ab,X X - - - 2 6 Ill1 3B RLA* $abcd,Y X - - - 3 7 Ill1 3F RLA* $abcd,X X - - - 3 7 Ill1 --------------------------------------------------------------------------------------------------- RMBx Reset Memory Bit CLBx CLear Bit (M740 Family version) R65c02 Family and M740 Family Only Description: .......................................................................... Clears the specified bit (the x in RMBx/CLBx) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. operand &= ~(1 << bittouse); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 07 RMB0 $ab - - X - - 2 5 32,40 17 RMB1 $ab - - X - - 2 5 32 1B CLB0 A - - - X - 1 2 1F CLB0 $ab - - - X - 2 5 27 RMB2 $ab - - X - - 2 5 32,40 37 RMB3 $ab - - X - - 2 5 32,40 3B CLB1 A - - - X - 1 2 3F CLB1 $ab - - - X - 2 5 47 RMB4 $ab - - X - - 2 5 32,40 57 RMB5 $ab - - X - - 2 5 32,40 5B CLB2 A - - - X - 1 2 5F CLB2 $ab - - - X - 2 5 67 RMB6 $ab - - X - - 2 5 32,40 77 RMB7 $ab - - X - - 2 5 32,40 7B CLB3 A - - - X - 1 2 7F CLB3 $ab - - - X - 2 5 9B CLB4 A - - - X - 1 2 9F CLB4 $ab - - - X - 2 5 BB CLB5 A - - - X - 1 2 BF CLB5 $ab - - - X - 2 5 DB CLB6 A - - - X - 1 2 DF CLB6 $ab - - - X - 2 5 FB CLB7 A - - - X - 1 2 FF CLB7 $ab - - - X - 2 5 --------------------------------------------------------------------------------------------------- ROL ROtate bits Left Description: .......................................................................... Rotates the value left one bit with carry. Flags: ................................................................................ nv-bdizc *-----** n - Was the highbit of the result set? z - Was the result 0? c - Was the highbit of the operand set before the bit shift? Code: ................................................................................. if (c) { c = operand & highbit; operand <<= 1; operand++; } else { c = operand & highbit; operand <<= 1; } n = operand & highbit; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 26 ROL $ab X X X X 2 5 22,26,31,40 2A ROL A X X X X 1 2 40 or ROL 2E ROL $abcd X X X X 3 6 26,31,40 36 ROL $ab,X X X X X 2 6 22,26,41 3E ROL $abcd,X X X X X 3 7 26,11,41 --------------------------------------------------------------------------------------------------- ROR ROtate bits Right Description: .......................................................................... Rotates the value right one bit with carry Flags: ................................................................................ nv-bdizc *-----** n - Was the highbit set on the result? z - Was the result 0? c - Was bit 0 set on the operand before the bit shift? Code: ................................................................................. if (c) { c = operand & 1; operand >>= 1; operand += highbit; } else { c = operand & 1; operand >>= 1; } n = c; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 66 ROR $ab X X X X 2 5 25,31,40 6A ROR A X X X X 1 2 40 or ROR 6E ROR $abcd X X X X 3 6 26,31,40 76 ROR $ab,X X X X X 2 6 22,26,41 7E ROR $abcd,X X X X X 3 7 26,11,41 --------------------------------------------------------------------------------------------------- ROW ROtate Word left 65ce02 Only Description: .......................................................................... Rotates a word value 1 bit to the left, switching out to c and putting c into the lower bit. Flags: ................................................................................ nvebdizc *-----** n - Was the high bit set after the operation? z - Was the result 0? c - Was the high bit set before the operation? Code: ................................................................................. if (c) { c = operand & 0x8000; operand <<= 1; operand++; } else { c = operand & 0x8000; operand <<= 1; } z = !operand; n = operand & 0x8000; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References EB ROW $abcd - - - X - 3 6 --------------------------------------------------------------------------------------------------- RRA* Rotate Right, then Add w/ carry flag to the accumulator [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... RORs the value in memory, then ADCs it with the accumulator. Carry is set by the ROR operation before the ADC. (All documents agree on this one) Flags: ................................................................................ nv-bdizc **----** Code: ................................................................................. if (c) { c = operand & 1; operand >>= 1; operand += highbit; } else { c = operand & 1; operand >>= 1; } // Start ADC // Non-BCD version if (!d || CPU == 2A03) { result = A + operand + c; n = result & highbit; v = (~(A ^ operand) & (A ^ result)) & highbit; c = result > maxval; A = (U8) result; z = !A; // 8bit BCD Version } else { result = (A & 0x0F) + (operand & 0x0F) + c; // Invalid operands may not add up properly... if (result > 0x09) result = (result - 0x0A) | 0x10; result += (A & 0xF0) + (operand & 0xF0); // Bugged 6502 code, taken from [5] z = !(A + operand + c); n = result & highbit; v = (~(A ^ operand) & (A ^ result)) & highbit; // Test for overflow if (result > 0x9F) result += 0x60; c = result > 0xFF; A = (U8) result; } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 63 RRA* ($ab,X) X - - - 2 8 Ill1 67 RRA* $ab X - - - 2 5 Ill1 6F RRA* $abcd X - - - 3 6 Ill1 73 RRA* ($ab),Y X - - - 2 8 Ill1 77 RRA* $ab,X X - - - 2 6 Ill1 7B RRA* $abcd,Y X - - - 3 7 Ill1 7F RRA* $abcd,X X - - - 3 7 Ill1 --------------------------------------------------------------------------------------------------- RRF Rotate Right Four bits M740 Only Description: .......................................................................... Rotates the value 4 bits to the right. Essentially, this switches the low and high nibbles. Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. operand = (operand >> 4) + (operand << 4); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 82 RRF $ab - - - X - 2 8 --------------------------------------------------------------------------------------------------- RTI ReTurn from Interrupt Description: .......................................................................... Return from interrupt; 6502 Family/65c02 Family/R65c02 Family/M740 Family/65c816 Family in emulation mode: Pull P, then PC 65c816 in native mode: Pull P, then PC, then PBR Flags: ................................................................................ 6502 Family/65c02 Family/R65c02 Family/M740 Family/65c816 in emulation mode: nv-bdizc **--**** Flag values are set to the P value pulled from the stack, except that b and bit 5 are ignored 65ce02: nvebdizc **--**** e is not affected when RTI is used 65c816 in native mode: nvmxdizc ******** All flags are restored from the stack Code: ................................................................................. if (CPU == 65c816 && !e) { P = StackPopByte(); PC = StackPopWord(); PBR = StackPopByte(); } else { // Get P, but preserve bits 4 and 5 P = (P & 0x30) | (StackPopByte() & 0xCF); PC = StackPopWord(); } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 40 RTI X X X X 1 6 23,31,40 --------------------------------------------------------------------------------------------------- RTL ReTurn from subroutine Long 65c816 Family Only Description: .......................................................................... Return from subroutine. Pulls the absolute address off the stack, increases it by 1, then jumps to that address. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. PC = StackPopWord() + 1; PBR = StackPopByte(); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 6B RTL - - - X 1 6 --------------------------------------------------------------------------------------------------- RTN ReTurn from kerNal subroutine 65ce02 Only Description: .......................................................................... Return from subroutine. Pulls the absolute address off the stack, increases it by 1, increases the stack by the value specified, then jumps to the address. This is used for subroutines where a number of variables are pushed to the stack before calling the subroutine. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. PC = StackPopWord() + 1; S += operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 62 RTN #$ab - - - X - 2 7 --------------------------------------------------------------------------------------------------- RTS ReTurn from Subroutine Description: .......................................................................... Return from subroutine. Pulls the absolute address off the stack, increases it by 1, then jumps to that address. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. PC = StackPopWord() + 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 60 RTS X X X X 1 6 31,41 --------------------------------------------------------------------------------------------------- SAH* Store Accumulator anded with High byte and x index [ILLEGAL OPCODE] 6502 Only See SHA* --------------------------------------------------------------------------------------------------- SAX Swap Accumulator and X index HuC6280 Only Description: .......................................................................... Swaps the A and X registers Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. temp1 = A; A = X; X = temp1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 22 SAX - - - X - 1 3 --------------------------------------------------------------------------------------------------- SAX* Stores X index and Accumulator into memory aka AAX* Accumulator And X index store aka AXS* Accumulator and X index Store [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... Gets bitwise AND of X and A, then stores it into memory. (All documents agree on this one, except [7] states that N and Z are modified) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. operand = X & A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 83 SAX* ($ab,X) X - - - 2 6 Ill1 87 SAX* $ab X - - - 2 3 Ill1 8F SAX* $abcd X - - - 3 4 Ill1 97 SAX* $ab,Y X - - - 2 4 Ill1 --------------------------------------------------------------------------------------------------- SAX* Subtract from Accumulator anded with X index [ILLEGAL OPCODE] 6502 Only See SBX* --------------------------------------------------------------------------------------------------- SAY Swap Accumulator and Y index HuC6280 Only Description: .......................................................................... Swaps the A and Y registers Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. temp1 = A; A = Y; Y = temp1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 42 SAY - - - X - 1 3 --------------------------------------------------------------------------------------------------- SBC SuBtract with Carry Description: .......................................................................... Subtracts the value from A, with borrow from carry. Note that borrow is BACKWARDs from the way it works on other processors. If Carry is set, then we did NOT borrow. If it is clear, then we DID borrow. 6502: The flags are not set properly if in BCD mode. Also, opcode EB is illegal, use of E9 instead is highly recommended. HuC6280: The V flag is not modified in BCD mode Flags: ................................................................................ nv-bdizc **----** n - Was the high bit of the result set? v - Was there signed overflow? v is set only if one of the following is true: If both A and value are negative and the result is positive If both A and value are positive and the result is negative Note that the overflow is NOT set properly in any BCD mode z - Was the result 0? c - Was there overflow? Code: ................................................................................. temp = operand; if (!c) temp++; // Normal subtract if (!d || CPU == 2A03) { c = temp <= A; result = (U8/16) (A - temp); v = ((A ^ temp) & (A ^ result)) & highbit; n = result & highbit; z = !result; // 16bit BCD } else if (CPU == 65c816 && !e && !m) { // 1st nybble temp1 = (A & 0x0F) - (temp & 0x0F); // 2nd nybble temp2 = ((A >> 4) & 0x0F) - ((temp >> 4) & 0x0F); // 3rd nybble temp3 = ((A >> 8) & 0x0F) - ((temp >> 8) & 0x0F); // 4th nybble temp4 = (A >> 12) - (temp >> 12); // Was the lower nybble negative? if (temp1 & 0x80) { temp1 -= 6; // BCD fix temp2--; } // Was the 2nd nybble negative? if (temp2 & 0x80) { temp2 -= 6; // BCD fix temp3--; } // Was the 3rd nybble negative? if (temp3 & 0x80) { temp3 -= 6; // BCD fix temp4--; } // Was the 4th nybble negative? if (temp4 & 0x80) { temp4 -= 6; // BCD fix c = 0; } else { c = 1; } // We don't correct oversized values, because they never should happen // Get the result result = ((temp4 & 0x0F) << 12) | ((temp3 & 0x0F) << 8) | ((temp2 & 0x0F) << 4) | (temp1 & 0x0F); n = result & highbit; z = !result; v = ((A ^ temp) & (A ^ result)) & highbit; // 8bit BCD } else { // 1st nybble temp1 = (A & 0x0F) - (temp & 0x0F); // 2nd nybble temp2 = (A >> 4) - (temp >> 4); // Was the lower nybble negative? if (temp1 & 0x80) { temp1 -= 6; // BCD fix temp2--; } // Was the upper nybble negative? if (temp2 & 0x80) { temp2 -= 6; // BCD fix if (CPU != 6502) c = 0; } else if (CPU != 6502) { c = 1; } // Invalid 6502 flags (from [5]) if (CPU == 6502 || CPU == M740) { temp3 = A - temp; c = result <= A; v = ((A ^ temp) & (A ^ temp3)) & highbit; n = temp3 & highbit; z = !temp3; } // Get the final result result = ((temp2 & 0x0F) << 4) | (temp1 & 0x0F); if (CPU != 6502) { n = result & highbit; z = !result; if (CPU != HuC6280) v = ((A ^ temp) & (A ^ result)) & highbit; } } A = (U8/16) result; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References E1 SBC ($ab,X) X X X X X 2 6 25,22,10,31,40,42,52 E3 SBC $ab,S - - - - X 2 4 25 E5 SBC $ab X X X X X 2 3 25,22,10,31,42,52 E7 SBC [$ab] - - - - X 2 6 25,22 E9 SBC #$ab X X X X X 2 2 10,24,25,42,52 EB SBC* #$ab X - - - - 2 2 Ill1 ED SBC $abcd X X X X X 3 4 25,10,31,42,52 EF SBC $abcdef - - - - X 4 5 25 F1 SBC ($ab),Y X X X X X 2 5 25,22,01,10,32,42,52,53 F2 SBC ($ab) - X X - X 2 5 25,22,10,32 F2 SBC ($ab),Z - - - X - 2 5 42 F3 SBC ($ab,S),Y - - - - X 2 7 25,22 F5 SBC $ab,X X X X X X 2 4 25,22,10,40,42,52 F7 SBC [$ab],Y - - - - X 2 6 25,22 F9 SBC $abcd,Y X X X X X 3 4 25,01,10,31,42,52,53 FD SBC $abcd,X X X X X X 3 4 25,01,10,31,42,52,53 FF SBC $abcdef,X - - - - X 4 6 25 --------------------------------------------------------------------------------------------------- SBX* SuBtract from X index anded with accumulator aka ASX* And x index with accumulator then Subtract from X index aka AXS* And X index with accumulator then Subtract aka SAX* Subtract from Accumulator anded with X index [ILLEGAL OPCODE] 6502 Only Description: .......................................................................... SAX 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. 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. According to [5], it ignores the Decimal flag, and both [7] and [6] say nothing about the Decimal flag. (All documents agree on this one, except the ignoring d bit) Flags: ................................................................................ nv-bdizc *-----** n - Was the highbit set on the result? z - Was the result 0? c - Was X >= operand (ie. no borrow)? Code: ................................................................................. X &= A; c = X >= operand; X -= operand; n = X & highbit; z = !X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References CB SBX* #$ab X - - - 2 2 Ill1 --------------------------------------------------------------------------------------------------- SEBx SEt Bit M740 Family Only See SMBx --------------------------------------------------------------------------------------------------- SEC SEt Carry flag Description: .......................................................................... Sets the Carry flag Flags: ................................................................................ nv-bdizc -------1 Code: ................................................................................. c = 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 38 SEC X X X X 1 2 40,42 --------------------------------------------------------------------------------------------------- SED SEt Decimal flag Description: .......................................................................... Sets the Decimal flag Flags: ................................................................................ nv-bdizc ----1--- Code: ................................................................................. d = 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References F8 SED X X X X 1 2 40,42 --------------------------------------------------------------------------------------------------- SEE SEt Extended stack disable flag 65ce02 Only Description: .......................................................................... Sets e Flags: ................................................................................ nvebdizc --1----- Code: ................................................................................. e = 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 03 SEE - - - X - 1 2 --------------------------------------------------------------------------------------------------- SEI SEt Interrupt disable flag Description: .......................................................................... Sets the Interrupt disable flag Flags: ................................................................................ nv-bdizc -----1-- Code: ................................................................................. i = 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 78 SEI X X X X 1 2 42 --------------------------------------------------------------------------------------------------- SEP SEt Program flags register bits 65c816 Family Only Description: .......................................................................... For each bit in the operand byte, set the corresponding bit in P. 65c816 in 8bit/emulation mode does not set bits 5 or 4 (Break). Flags: ................................................................................ 65c816 in 8bit/emulation mode: nv-bdizc **--**** The bits are set according to the operand byte 65c816 in emulation mode: nvmxdizc ******** The bits are set according to the operand byte Code: ................................................................................. if (!e) P |= operand; else P |= (operand & 0xCF); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References E2 SEP #$ab - - - X 2 3 --------------------------------------------------------------------------------------------------- SET SEt the T flag HuC6280 and M740 Family Only Description: .......................................................................... Sets the t flag to 1. HuC6280- This only affects the next instruction, and only that if it only takes a single immediate parameter???. If there is such an instruction after this one, then that instruction will use the Zero Page value at X (ie, (X)) instead of A (or X or Y???). KERBLUH- I would really like to get a full description on this opcode, because I find this explanation unacceptable. I also have no clue how many cycles this adds to the next instruction, though it's probably 2 or 3. *NOTE: According to [16], they only support ADC, AND, ORA, EOR, but they have seen it used with SBC and even CPX! Flags: ................................................................................ nvtbdizc --1----- Code: ................................................................................. t = 1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 M740 65c816 Size Cyc References 32 SET - - - - X - 1 2 F4 SET - - - X - - 1 2 --------------------------------------------------------------------------------------------------- SHA* Store High byte anded with Accumulator and x index aka SAH* Store Accumulator anded with High byte and x index aka AXA* And X index and Accumulator [ILLEGAL OPCODE] 6502 Only [UNSTABLE] [DEFINITION DISCREPENCY] Description: .......................................................................... [5]: Get high byte in Zero page, AND that with A and X, place it at address at Y + address at ab [7]: AND X register with accumulator then AND result with 7 and store in memory [6]: This opcode stores the result of A AND X AND the high byte of the target address of the operand +1 in memory. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Taken from [5] value = GetByte((U8)(address + 1)); result = A & X & value; temp1 = GetWord(address) + Y; PutByte(temp1, result); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 93 SHA* ($ab),Y X - - - 2 6 Ill1 --------------------------------------------------------------------------------------------------- SHA* Store High byte + 1 anded with A and x index aka AXA* And X and A [ILLEGAL OPCODE] 6502 Only [UNSTABLE] [DEFINITION DISCREPENCY] Description: .......................................................................... [5] and [6]: Store (A AND X AND ([high byte of address] + 1)) at Y + address [7]: AND X register with accumulator then AND result with 7 and store in memory Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. result = A & X & ((address >> 8) + 1); PutByte(address + Y, result); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 9F SHA* $abcd,Y X - - - 3 5 Ill1 --------------------------------------------------------------------------------------------------- SHS* Store High byte + 1 anded with Stack after stack set to accumulator and x index aka SSH* Store Stack anded with Highbyte after stack set to accumulator and x index aka TAS* Transfer Accumulator anded with x index to S with high byte modification aka XAS* X index and Accumulator stored in Stack, then store stack and high byte [ILLEGAL OPCODE] 6502 Only [UNSTABLE] Description: .......................................................................... Transfer (A AND X) to S, then store (S AND ([high byte of address] + 1)) to Y + address (All documents agree on this one) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. S = A & X; result = S & ((address >> 8) + 1); PutByte(address + Y, result); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 9B SHS* $abcd,Y X - - - 3 5 Ill1 --------------------------------------------------------------------------------------------------- SHX* Store High byte pointer + 1 anded with X index aka SXA* Store X index And highbyte of address aka SXH* Store X index and Highbyte of address aka XAS* X index And address Store [ILLEGAL OPCODE] 6502 Only [POSSIBLY UNSTABLE] Description: .......................................................................... Store (X AND ([high byte of address] + 1)) at Y + address (All documents agree on this one, though the [6] is confused) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. result = X & (U8)((address >> 8) + 1); PutByte(address + Y, result); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 9E SHX* $abcd,Y X - - - 3 5 Ill1 --------------------------------------------------------------------------------------------------- SHY* Store High byte pointer + 1 anded with Y [ILLEGAL OPCODE] 6502 Only [POSSIBLY UNSTABLE] Description: .......................................................................... The high byte of the address before adding X, is incremented then anded with Y (not stored in Y), and placed in that address after adding X (All documents agree on this one, though [6] is confused about it) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. result = Y & (U8)((address >> 8) + 1); PutByte(address + X, result); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 9C SHY* $abcd,X X - - - 3 5 Ill1 --------------------------------------------------------------------------------------------------- SKB* SKip Byte aka DOP* Double no OPeration aka NOP [ILLEGAL OPCODE] All but 65c816 and 65ce02 Description: .......................................................................... Skips a byte and does nothing. However, depending on the opcode, a read operation MAY occur on the 6502. Also known as NOP, but they bypass a byte so they operate differently than NOP. (All documents agree on this one) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Do nothing Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65sc02 65c02S HuC6280 65ce02 65c816 Size Cyc References 02 SKB* #$ab - X X - - - - - 2 2 Ill2 04 SKB* $ab X - - - - - - - 2 3 Ill1 07 SKB* #$ab - X - - - - - - 2 5 Ill2 0B SKB* #$ab - X X X X X - - 2 2 Ill2 14 SKB* $ab,X X - - - - - - - 2 4 Ill1 17 SKB* #$ab - X - - - - - - 2 6 Ill2 22 SKB* #$ab - X X X X - - - 2 2 Ill2 27 SKB* #$ab - X - - - - - - 2 5 Ill2 2B SKB* #$ab - X X X X X - - 2 5 Ill2 34 SKB* $ab,X X - - - - - - - 2 4 Ill1 37 SKB* #$ab - X - - - - - - 2 6 Ill2 42 SKB* #$ab - X X X X - - - 2 2 Ill2 43 SKB* #$ab - X X X X - - - 2 8 Ill2 44 SKB* $ab X - - - - - - - 2 3 Ill1 44 SKB* #$ab - X X X X - - - 2 3 Ill2 47 SKB* #$ab - X - - - - - - 2 5 Ill2 4B SKB* #$ab - X X X X X - - 2 2 Ill2 53 SKB* #$ab - X X X X - - - 2 8 Ill2 54 SKB* $ab,X X - - - - - - - 2 4 Ill1 54 SKB* #$ab - X X X X - - - 2 4 Ill2 57 SKB* #$ab - X - - - - - - 2 6 Ill2 62 SKB* #$ab - X X X X - - - 2 2 Ill2 63 SKB* #$ab - X X - X X - - 2 8 Ill2 64 SKB* $ab X - - - - - - - 2 3 Ill1 67 SKB* #$ab - X - - - - - - 2 5 Ill2 6B SKB* #$ab - X X X X X - - 2 2 Ill2 73 SKB* #$ab - X X X X - - - 2 8 Ill2 74 SKB* $ab,X X - - - - - - - 2 4 Ill1 77 SKB* #$ab - X - - - - - - 2 6 Ill2 80 SKB* #$ab X - - - - - - - 2 2 Ill1 82 SKB* #$ab X - - - - - - - 2 2 Ill1 82 SKB* #$ab - X X X X - - - 2 2 Ill2 83 SKB* #$ab - X X X X - - - 2 6 Ill2 87 SKB* #$ab - X - - - - - - 2 3 Ill2 89 SKB* #$ab X - - - - - - - 2 2 Ill1 8B SKB* #$ab - X X X X X - - 2 2 Ill2 93 SKB* #$ab - X X X X - - - 2 6 Ill2 97 SKB* #$ab - X - - - - - - 2 4 Ill2 A3 SKB* #$ab - X X X X - - - 2 6 Ill2 A7 SKB* #$ab - X - - - - - - 2 3 Ill2 AB SKB* #$ab - X X X X X - - 2 2 Ill2 B3 SKB* #$ab - X X X X - - - 2 5 Ill2 B7 SKB* #$ab - X - - - - - - 2 4 Ill2 C2 SKB* #$ab X - - - - - - - 2 2 Ill1 C2 SKB* #$ab - X X X X - - - 2 2 Ill2 C3 SKB* #$ab - X X X X - - - 2 8 Ill2 C7 SKB* #$ab - X - - - - - - 2 5 Ill2 CB SKB* #$ab - X X X - X - - 2 2 Ill2 D3 SKB* #$ab - X X X X - - - 2 8 Ill2 D4 SKB* $ab,X X - - - - - - - 2 4 Ill1 D4 SKB* #$ab - X X X X - - - 2 4 Ill2 D7 SKB* #$ab - X - - - - - - 2 6 Ill2 E2 SKB* #$ab X - - - - - - - 2 2 Ill1 E2 SKB* #$ab - X X X X X - - 2 2 Ill2 E3 SKB* #$ab - X X X X - - - 2 8 Ill2 E7 SKB* #$ab - X - - - - - - 2 5 Ill2 EB SKB* #$ab - X X X X X - - 2 2 Ill2 F3 SKB* #$ab - X X X X - - - 2 8 Ill2 F4 SKB* $ab,X X - - - - - - - 2 4 Ill1 F4 SKB* #$ab - X X X X - - - 2 4 Ill2 F7 SKB* #$ab - X - - - - - - 2 6 Ill2 --------------------------------------------------------------------------------------------------- SKW* SKip a Word aka NOP aka TOP* Triple no-OPeration [ILLEGAL OPCODE] All but 65c816 and 65ce02 Description: .......................................................................... Skips a word and does nothing. However, depending on the opcode, a read operation MAY occur on the 6502. Also known as NOP, but they bypass a word so they operate differently than NOP. (All documents agree on this one) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. // Do nothing Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c02S HuC6280 65ce02 65c816 Size Cyc References 0C SKW* $abcd X - - - - - - 3 4 Ill1 0F SKW* $abcd - X - - - - - 3 6 Ill2 1B SKW* $abcd - X X X X - - 3 7 Ill2 1C SKW* $abcd,X X - - - - - - 3 4 01,Ill1 1F SKW* $abcd - X - - - - - 3 7 Ill2 2F SKW* $abcd - X - - - - - 3 6 Ill2 3B SKW* $abcd - X X X X - - 3 7 Ill2 3C SKW* $abcd,X X - - - - - - 3 4 01,Ill1 3F SKW* $abcd - X - - - - - 3 7 Ill2 4F SKW* $abcd - X - - - - - 3 6 Ill2 5B SKW* $abcd - X X X X - - 3 7 Ill2 5C SKW* $abcd,X X - - - - - - 3 4 01,Ill1 5C SKW* $abcd - X X X X - - 3 4 Ill2 5F SKW* $abcd - X - - - - - 3 7 Ill2 6F SKW* $abcd - X - - - - - 3 6 Ill2 7B SKW* $abcd - X X X X - - 3 7 Ill2 7C SKW* $abcd,X X - - - - - - 3 4 01,Ill1 7F SKW* $abcd - X - - - - - 3 7 Ill2 8F SKW* $abcd - X - - - - - 3 4 Ill2 9B SKW* $abcd - X X X X - - 3 5 Ill2 9F SKW* $abcd - X - - - - - 3 5 Ill2 AF SKW* $abcd - X - - - - - 3 4 Ill2 BB SKW* $abcd - X X X X - - 3 4 Ill2 BF SKW* $abcd - X - - - - - 3 4 Ill2 CF SKW* $abcd - X - - - - - 3 6 Ill2 DB SKW* $abcd - X X - X - - 3 7 Ill2 DC SKW* $abcd,X X - - - - - - 3 4 01,Ill1 DC SKW* $abcd - X X X X - - 3 4 Ill2 DF SKW* $abcd - X - - - - - 3 7 Ill2 EF SKW* $abcd - X - - - - - 3 6 Ill2 FB SKW* $abcd - X X X X - - 3 7 Ill2 FC SKW* $abcd,X X - - - - - - 3 4 01,Ill1 FC SKW* $abcd - X X X X - - 3 4 Ill2 FF SKW* $abcd - X - - - - - 3 7 Ill2 --------------------------------------------------------------------------------------------------- SLO* Shift Left then Or [ILLEGAL OPCODE] 6502 Only See ASO* --------------------------------------------------------------------------------------------------- SMBx Set Memory Bit SEBx SEt Bit (M740 Family version) R65c02 Family and M740 Family Only Description: .......................................................................... Sets the specific bit in memory (the x in SMBx/SEBx) Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. operand |= (1 << bittouse); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 0B SEB0 A - - - X - 1 2 0F SEB0 $ab - - - X - 2 5 2B SEB1 A - - - X - 1 2 2F SEB1 $ab - - - X - 2 5 4B SEB2 A - - - X - 1 2 4F SEB2 $ab - - - X - 2 5 6B SEB3 A - - - X - 1 2 6F SEB3 $ab - - - X - 2 5 87 SMB0 $ab - - X - - 2 5 32,40 8B SEB4 A - - - X - 1 2 8F SEB4 $ab - - - X - 2 5 97 SMB1 $ab - - X - - 2 5 32,40 A7 SMB2 $ab - - X - - 2 5 32,40 AB SEB5 A - - - X - 1 2 AF SEB5 $ab - - - X - 2 5 B7 SMB3 $ab - - X - - 2 5 32,40 C7 SMB4 $ab - - X - - 2 5 32,40 CB SEB6 A - - - X - 1 2 CF SEB6 $ab - - - X - 2 5 D7 SMB5 $ab - - X - - 2 5 32,40 E7 SMB6 $ab - - X - - 2 5 32,40 EB SEB7 A - - - X - 1 2 EF SEB7 $ab - - - X - 2 5 F7 SMB7 $ab - - X - - 2 5 32,40 --------------------------------------------------------------------------------------------------- SRE* Shift Right then Eor [ILLEGAL OPCODE] 6502 Only See LSE* --------------------------------------------------------------------------------------------------- SSH* Store Stack anded with Highbyte after stack set to accumulator and x index [ILLEGAL OPCODE] 6502 Only See SHS* --------------------------------------------------------------------------------------------------- ST0 STore at port 0 HuC6280 Only Description: .......................................................................... Stores a value to hardware register 0. On the TG16, this is located at $1FE000. Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // TG16 dependent PutByte($1FE000, operand); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 03 ST0 #$ab - - - X - 2 4 --------------------------------------------------------------------------------------------------- ST1 STore at port 1 HuC6280 Only Description: .......................................................................... Stores a value to hardware register 1. On the TG16, this is located at $1FE002. Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // TG16 dependent PutByte($1FE002, operand); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 13 ST1 #$ab - - - X - 2 4 --------------------------------------------------------------------------------------------------- ST2 STore at port 2 HuC6280 Only Description: .......................................................................... Stores a value to hardware register 2. On the TG16, this is located at $1FE003. Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // TG16 dependent PutByte($1FE003, operand); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 23 ST2 #$ab - - - X - 2 4 --------------------------------------------------------------------------------------------------- STA STore Accumulator into memory Description: .......................................................................... Stores A into memory Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. operand = A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 81 STA ($ab,X) X X X X X 2 6 25,22,31,40,53 82 STA ($ab,S),Y - - - X - 2 6 83 STA $ab,S - - - - X 2 4 25 85 STA $ab X X X X X 2 3 25,22,31,53 87 STA [$ab] - - - - X 2 6 25,22 8D STA $abcd X X X X X 3 4 25,31,53 8F STA $abcdef - - - - X 4 5 25 91 STA ($ab),Y X X X X X 2 6 25,22,31,40,53 92 STA ($ab) - X X - X 2 5 25,22,32 92 STA ($ab),Z - - - X - 2 5 93 STA ($ab,S),Y - - - - X 2 7 25 95 STA $ab,X X X X X X 2 4 25,22,40,53 97 STA [$ab],Y - - - - X 2 6 25,22 99 STA $abcd,Y X X X X X 3 5 25,40,53 9D STA $abcd,X X X X X X 3 5 25,40,53 9F STA $abcdef,X - - - - X 4 5 25 --------------------------------------------------------------------------------------------------- STP STop Processor 65c02S, 65c816 Family and M740 Family Only Description: .......................................................................... Stops the processor, effectively putting it into a sleep state until a reset occurs. This is designed for embedded or battery powered systems. M740- These processors stop in a "stand-by" state, meaning they are waiting for an external interrupt before the processor starts up again. On M740 CPUs that don't support STP, this instruction is a 2 cycle NOP. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. CauseCPUToStop(); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c02S M740 65c816 Size Cyc References 42 STP - - - - X - 1 2 DB STP - - - X - X 1 3 04 --------------------------------------------------------------------------------------------------- STX STore X index into memory Description: .......................................................................... Stores X into memory Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. operand = X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 86 STX $ab X X X X X 2 3 22,28,31,53 8E STX $abcd X X X X X 3 4 28,31,53 96 STX $ab,Y X X X X X 2 4 22,28,40,53 9B STX $abcd,Y - - - X - 3 4 --------------------------------------------------------------------------------------------------- STY STore Y index into memory Description: .......................................................................... Stores Y into memory Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. operand = Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 84 STY $ab X X X X X 2 3 22,28,31,53 8B STY $abcd,X - - - X - 3 4 8C STY $abcd X X X X X 3 4 28,31,53 94 STY $ab,X X X X X X 2 4 22,28,40,53 --------------------------------------------------------------------------------------------------- STZ STore Zero into memory 65c02+ STore Z index into memory 65ce02 Only Description: .......................................................................... Stores 0 at the specified address 65ce02: Stores Z at the specified address Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (CPU == 65ce02) operand = Z; else operand = 0; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 64 STZ $ab - X X X 2 3 25,22,31 74 STZ $ab,X - X X X 2 4 25,22,40 9C STZ $abcd - X X X 3 4 25,31 9E STZ $abcd,X - X X X 3 5 25,40 --------------------------------------------------------------------------------------------------- SXA* Store X index And highbyte of address [ILLEGAL OPCODE] 6502 Only See SHX* --------------------------------------------------------------------------------------------------- SXH* Store X index and Highbyte of address [ILLEGAL OPCODE] 6502 Only See SHX* --------------------------------------------------------------------------------------------------- SXY Swap X and Y HuC6280 Only Description: .......................................................................... Swaps the X and Y registers Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. temp1 = X; X = Y; Y = temp1; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 02 SXY - - - X - 1 3 --------------------------------------------------------------------------------------------------- TAB Transfer Accumulator to Base page register 65ce02 Only Description: .......................................................................... Transfers A to B Flags: ................................................................................ nvebdizc -------- Code: ................................................................................. B = A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 5B TAB - - - X - 1 1 --------------------------------------------------------------------------------------------------- TAI Transfer, from Alternating, to Incrementing HuC6280 Only Description: .......................................................................... TAI from,to,length First, pushes Y then A then X Transfers "length" bytes from "from" to "to", alterating the "from" pointer with it's initial value and "from" + 1 and increasing "to" each loop. At the end, pops X then A then Y Interrupts do *NOT* work during this instruction *NOTE: For emulation, this should either be run as a single instruction with a huge clock time, or as a special instruction outside of the normal opcode space because both pointers and the immediate are hard coded and it'd be hard to reenter a loop with it. If Length is 0, then 64KB is transfered Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // value1 = source // value2 = destination // value3 = length // value4 - Used for alternating StackPushByte(Y); StackPushByte(A); StackPushByte(X); value4 = 0; if (!value3) value3 = 0x010000; while (value3--) { PutByte(value2++, GetByte(value1 + value4)); value4 ^= 1; } StackPopByte(X); StackPopByte(A); StackPopByte(Y); Opcodes: .............................................................................. The data is stored in the order it's listed: From, To, Length For example, if the instruction is TAI $1234,$5678,#$9ABC, it is stored as: F3 34 12 78 56 BC 9A Op Format 6502 65c02 R65c02 HuC6280 65ce02 65c816 Size Cyc References F3 TAI $1234,$5678,#$9ABC - - - X - - 7 17+6n 30 --------------------------------------------------------------------------------------------------- TAM Transfer Accumulator to Memory mapper register aka TAMi HuC6280 Only Description: .......................................................................... Uses the immediate value to set memory mapper registers. Each bit corresponds to one of 0 to 7 in MPR. eg. If the immedate value was #$1C, which is %00011100 binary, then the result is: MPR2 = MPR3 = MPR4 = A; Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. if (value1) { LastMPRValue = A; if (value1 & 0x01) MPR0 = A; if (value1 & 0x02) MPR1 = A; if (value1 & 0x04) MPR2 = A; if (value1 & 0x08) MPR3 = A; if (value1 & 0x10) MPR4 = A; if (value1 & 0x20) MPR5 = A; if (value1 & 0x40) MPR6 = A; if (value1 & 0x80) MPR7 = A; } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 53 TAM #$ab - - - X - 2 5 --------------------------------------------------------------------------------------------------- TAS* Transfer Accumulator anded with x index to Stack with high byte modification [ILLEGAL OPCODE] 6502 Only See SHS* --------------------------------------------------------------------------------------------------- TAX Transfer Accumulator to X index Description: .......................................................................... Transfers A to X 65c816 in Native Mode: If x = 1, m = 1 Then: The value tranferred to X is 8bit, the low byte of A. If x = 0, m = 1 Then: The value transferred to X is 16bit. If x = 1, m = 0 Then: The value transferred to X is 8bit, the low byte of A. If x = 0, m = 0 Then: The full 16bit A is transferred to X. Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of A set? z - Was A 0? Code: ................................................................................. X = A; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References AA TAX X X X X 1 2 40 --------------------------------------------------------------------------------------------------- TAY Transfer Accumulator to Y index Description: .......................................................................... Transfers A to Y 65c816 in native mode: If x = 1, m = 1 Then: The value tranferred to Y is 8bit, the low byte of A. If x = 0, m = 1 Then: The value transferred to Y is 16bit. If x = 1, m = 0 Then: The value transferred to Y is 8bit, the low byte of A. If x = 0, m = 0 Then: The full 16bit A is transferred to Y. Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of A set? z - Was A 0? Code: ................................................................................. Y = A; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References A8 TAY X X X X 1 2 40 --------------------------------------------------------------------------------------------------- TAZ Transfer Accumulator to Z index 65ce02 Only Description: .......................................................................... Transfers A to Z Flags: ................................................................................ nvebdizc *-----*- n - Was the highbit of A set? z - Was A 0? Code: ................................................................................. Z = A; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 4B TAZ - - - X - 1 1 --------------------------------------------------------------------------------------------------- TBA Transfer Base page register to Accumulator 65ce02 Only Description: .......................................................................... Transfers A to B Flags: ................................................................................ nvebdizc *-----*- n - Was the highbit of A set? z - Was A 0? Code: ................................................................................. A = B; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 7B TBA - - - X - 1 1 --------------------------------------------------------------------------------------------------- TCD Transfer C (16bit accumulator) to Direct page register aka TAD 65c816 Family Only Description: .......................................................................... Transfers the 16bit accumulator to D Flags: ................................................................................ nv-bdizc nvmxdizc *-----*- n - Was the highbit of C set? z - Was C 0? Code: ................................................................................. D = C; n = C & 0x8000; z = !C; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 5B TCD - - - X 1 2 --------------------------------------------------------------------------------------------------- TCS Transfer C (16bit accumulator) to Stack register aka TAS 65c816 Family Only Description: .......................................................................... Transfers the 16bit accumulator to S if in native mode, only 8bit if in emulation mode. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (!e) S = C; else S = ((U8) C) + 0x0100; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 1B TCS - - - X 1 2 --------------------------------------------------------------------------------------------------- TDC Transfer Direct page register to C (16bit accumulator) aka TDA Transfer Direct page register to 16bit Accumulator 65c816 Family Only Description: .......................................................................... Transfers D to the 16bit accumulator Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of D set? z - Was D 0? Code: ................................................................................. C = D; n = C & 0x8000; z = !C; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 7B TDC - - - X 1 2 --------------------------------------------------------------------------------------------------- TDD Transfer, from Decrementing, to Decrementing HuC6280 Only Description: .......................................................................... TDD from,to,length First, pushes Y then A then X Transfers "length" bytes from "from" to "to", decrementing both pointers each move. At the end, pops X then A then Y Interrupts do *NOT* work during this instruction *NOTE: For emulation, this should either be run as a single instruction with a huge clock time, or as a special instruction outside of the normal opcode space because both pointers and the immediate are hard coded and it'd be hard to reenter a loop with it. If Length is 0, then 64KB is transfered Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // value1 = source // value2 = destination // value3 = length StackPushByte(Y); StackPushByte(A); StackPushByte(X); if (!value3) value3 = 0x010000; while (value3--) PutByte(value2--, GetByte(value1--)); StackPopByte(X); StackPopByte(A); StackPopByte(Y); Opcodes: .............................................................................. The data is stored in the order it's listed: From, To, Length For example, if the instruction is TDD $1234,$5678,#$9ABC, it is stored as: C3 34 12 78 56 BC 9A Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References C3 TDD $1234,$5678,#$9ABC - - - X - 7 17+6n 30 --------------------------------------------------------------------------------------------------- TIA Transfer, from Incrementing, to Alternating HuC6280 Only Description: .......................................................................... TIA from,to,length First, pushes Y then A then X Transfers "length" bytes from "from" to "to", incrementing the from pointer and alterating "to" pointer with it's initial value and "to" + 1. At the end, pops X then A then Y Interrupts do *NOT* work during this instruction *NOTE: For emulation, this should either be run as a single instruction with a huge clock time, or as a special instruction outside of the normal opcode space because both pointers and the immediate are hard coded and it'd be hard to reenter a loop with it. If Length is 0, then 64KB is transfered Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // value1 = source // value2 = destination // value3 = length // value4 - Used for alternating StackPushByte(Y); StackPushByte(A); StackPushByte(X); value4 = 0; if (!value3) value3 = 0x010000; while (value3--) { PutByte(value2 + value4, GetByte(value1++)); value4 ^= 1; } StackPopByte(X); StackPopByte(A); StackPopByte(Y); Opcodes: .............................................................................. The data is stored in the order it's listed: From, To, Length For example, if the instruction is TIA $1234,$5678,#$9ABC, it is stored as: E3 34 12 78 56 BC 9A Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References E3 TIA $1234,$5678,#$9ABC - - - X - 7 17+6n 30 --------------------------------------------------------------------------------------------------- TII Transfer, from Incrementing, to Incrementing HuC6280 Only Description: .......................................................................... TII from,to,length First, pushes Y then A then X Transfers "length" bytes from "from" to "to", incrementing both pointers each move. At the end, pops X then A then Y Interrupts do *NOT* work during this instruction *NOTE: For emulation, this should either be run as a single instruction with a huge clock time, or as a special instruction outside of the normal opcode space because both pointers and the immediate are hard coded and it'd be hard to reenter a loop with it. If Length is 0, then 64KB is transfered Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // value1 = source // value2 = destination // value3 = length StackPushByte(Y); StackPushByte(A); StackPushByte(X); if (!value3) value3 = 0x010000; while (value3--) PutByte(value2++, GetByte(value1++)); StackPopByte(X); StackPopByte(A); StackPopByte(Y); Opcodes: .............................................................................. The data is stored in the order it's listed: From, To, Length For example, if the instruction is TII $1234,$5678,#$9ABC, it is stored as: 73 34 12 78 56 BC 9A Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 73 TII $1234,$5678,#$9ABC - - - X - 7 17+6n 30 --------------------------------------------------------------------------------------------------- TIN Transfer, from Incrementing, to does Nothing HuC6280 Only Description: .......................................................................... TIN from,to,length First, pushes Y then A then X Transfers "length" bytes from "from" to "to", incrementing "from" pointers each move. At the end, pops X then A then Y Interrupts do *NOT* work during this instruction *NOTE: For emulation, this should either be run as a single instruction with a huge clock time, or as a special instruction outside of the normal opcode space because both pointers and the immediate are hard coded and it'd be hard to reenter a loop with it. If Length is 0, then 64KB is transfered Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. // value1 = source // value2 = destination // value3 = length StackPushByte(Y); StackPushByte(A); StackPushByte(X); if (!value3) value3 = 0x010000; while (value3--) PutByte(value2, GetByte(value1++)); StackPopByte(X); StackPopByte(A); StackPopByte(Y); Opcodes: .............................................................................. The data is stored in the order it's listed: From, To, Length For example, if the instruction is TIN $1234,$5678,#$9ABC, it is stored as: D3 34 12 78 56 BC 9A Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References D3 TIN $1234,$5678,#$9ABC - - - X - 7 17+6n 30 --------------------------------------------------------------------------------------------------- TMA Transfer Memory mapper register to Accumulator aka TMAx HuC6280 Only Description: .......................................................................... Uses the immediate value to retrieve a memory mapper register. The lowest bit set corresponds to which memory mapper register to grab. eg, if the immediate value was #$1C, which is %00011100 binary, then memory mapper register 2 is grabbed since bit 2 is the lowest If a value of $00 was used, the last value with a bit set in the operand from TAM or TMA is read in If multiple bits are used, it is unknown how the values are placed into A. For now, I am assuming they are OR'd together. Flags: ................................................................................ nvtbdizc -------- Code: ................................................................................. if (operand) { LastMPRValue = 0; for (q = 0; q < 8; q++) { if (operand & (1 << q)) LastMPRValue |= MPR[q]; } A = LastMPRValue; } else { A = LastMPRValue; } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 43 TMA #$ab - - - X - 2 4 --------------------------------------------------------------------------------------------------- TOP* Triple no-OPeration [ILLEGAL OPCODE] All but 65c816 and 65ce02 See SKW* --------------------------------------------------------------------------------------------------- TRB Test and Reset Bits against accumulator 65c02+ Only Description: .......................................................................... ANDs the complement of A with the value, changing the value in memory. Flags: ................................................................................ nv-bdizc ------*- z - Was the operand AND A zero? Code: ................................................................................. z = !(operand & A); operand &= ~A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 14 TRB $ab - X X X 2 5 22,26,31,40 1C TRB $abcd - X X X 3 6 26,31,40 --------------------------------------------------------------------------------------------------- TSB Test and Set Bits against accumulator 65c02+ Only Description: .......................................................................... ORs A with the value, changing the value in memory. Flags: ................................................................................ nv-bdizc ------*- z - Was the operand AND A zero? Code: ................................................................................. z = !(operand & A); operand |= A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 04 TSB $ab - X X X 2 5 22,26,31,40 0C TSB $abcd - X X X 3 6 26,31,40 --------------------------------------------------------------------------------------------------- TSC Transfer Stack pointer to C (16bit accumulator) aka TSA Transfer Stack pointer to 16bit Accumulator 65c816 Family Only Description: .......................................................................... Transfer S to C Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of S set? z - Was S 0? Code: ................................................................................. C = S; n = C & 0x8000; z = !C; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 3B TSC - - - X 1 2 --------------------------------------------------------------------------------------------------- TST TeST bit values HuC6280 Only Description: .......................................................................... This takes two parameters, an immediate and another value from memory. See the flags settings for the effects Flags: ................................................................................ nvtbdizc **----*- n - Was the high bit of the memory value set? v - Was the second highest bit of the memory value set? z - Set if no bits matched between the immediate and memory value, otherwise clear Code: ................................................................................. // operand1 = first operand (immediate) // operand2 = second operand (value read from memory) n = operand2 & 0x80; v = operand2 & 0x40; z = !(operand1 & operand2); Opcodes: .............................................................................. Note that the immediate value is stored before the second value in all cases Op Format 6502 65c02 R65c02 HuC6280 65c816 Size Cyc References 83 TST #$ab,$cd - - - X - 3 7 93 TST #$ab,$cdef - - - X - 4 8 A3 TST #$ab,$cd,X - - - X - 3 7 B3 TST #$ab,$cdef,X - - - X - 4 8 --------------------------------------------------------------------------------------------------- TST TeST for negative or zero M740 Only Description: .......................................................................... Sets the negative and zero flags based on the memory value. Flags: ................................................................................ nvtbdizc *-----*- n - Is the high bit set on the value? z - Is the value zero? Code: ................................................................................. n = operand & 0x80; z = !operand; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 M740 65c816 Size Cyc References 64 TST $ab - - - X - 2 3 --------------------------------------------------------------------------------------------------- TSX Transfer Stack pointer to X index Description: .......................................................................... Transfers S to X 65c816- 16bit S and X are used only if in native mode and x = 0 65ce02- Only the low byte of S is transferred Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of S set? z - Was S 0? Code: ................................................................................. if (CPU == 65ce02) X = Sl; else X = S; n = X & highbit; z = !X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References BA TSX X X X X 1 2 40 --------------------------------------------------------------------------------------------------- TSY Transfer Stack high byte to Y index 65ce02 Only Description: .......................................................................... Transfers Sh to Y Flags: ................................................................................ nvebdizc *-----*- n - Was the highbit of Y set? z - Was Y 0? Code: ................................................................................. Y = Sh; n = Y & highbit; z = !Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 0B TSY - - - X - 1 1 --------------------------------------------------------------------------------------------------- TXA Transfer X index to Accumulator Description: .......................................................................... Transfers X to A 65c816 in native mode: If x = 1, m = 1 Then: The value tranferred to A is 8bit, the low byte of X. If x = 0, m = 1 Then: The value transferred to A is 8bit, the low byte of X. If x = 1, m = 0 Then: The value transferred to A is 8bit zero extended X. If x = 0, m = 0 Then: The full 16bit X is transferred to A. Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of X set? z - Was X 0? Code: ................................................................................. if (CPU == 65c816 && !e && (x ^ m)) { if (x) { A = (U16) X; } else { A = (A & 0xFF00) + X; } } else { A = X; } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 8A TXA X X X X 1 2 40 --------------------------------------------------------------------------------------------------- TXS Transfer X index to Stack pointer Description: .......................................................................... Transfers X to S 65c816- If in native mode: If x = 1 Then: S becomes a zero extended X Else S becomes X 65ce02- Only the low byte is transferred Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. if (CPU == 65ce02) Sl = X; else if (CPU == 65c816 && !e && x) S = (U16) X; else S = X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 9A TXS X X X X 1 2 40 --------------------------------------------------------------------------------------------------- TXY Transfer X index to Y index 65c816 Family Only Description: .......................................................................... Transfers X to Y Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of X set? z - Was X 0? Code: ................................................................................. Y = X; n = Y & highbit; z = !Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 9B TXY - - - X 1 2 --------------------------------------------------------------------------------------------------- TYA Transfer Y index to Accumulator Description: .......................................................................... Transfers Y to A. 65c816- If in native mode: If x = 1, m = 1 Then: The value tranferred to A is 8bit, the low byte of Y. If x = 0, m = 1 Then: The value transferred to A is 8bit, the low byte of Y. If x = 1, m = 0 Then: The value transferred to A is 8bit zero extended Y. If x = 0, m = 0 Then: The full 16bit Y is transferred to A. Flags: ................................................................................ nv-bdizc *-----*- n - Was the highbit of Y set? z - Was Y 0? Code: ................................................................................. if (CPU == 65c816 && !e && (x ^ m)) { if (x) { A = (U16) Y; } else { A = (A & 0xFF00) + Y; } } else { A = Y; } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 98 TYA X X X X 1 2 40 --------------------------------------------------------------------------------------------------- TYS Transfer Y index to Stack high byte 65ce02 Only Description: .......................................................................... Transfers Y to Sh Flags: ................................................................................ nvebdizc -------- Code: ................................................................................. Sh = Y; n = Y & highbit; z = !Y; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 2B TYS - - - X - 1 1 --------------------------------------------------------------------------------------------------- TYX Transfer Y index to X index 65c816 Family Only Description: .......................................................................... Transfers Y to X Flags: ................................................................................ nvebdizc *-----*- n - Was the highbit of Y set? z - Was Y 0? Code: ................................................................................. X = Y; n = X & highbit; z = !X; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References BB TYX - - - X 1 2 --------------------------------------------------------------------------------------------------- TZA Transfer Z index to Accumulator 65ce02 Only Description: .......................................................................... Transfers Z to A Flags: ................................................................................ nvebdizc *-----*- n - Was the highbit of A set? z - Was A 0? Code: ................................................................................. A = Z; n = A & highbit; z = !A; Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65ce02 65c816 Size Cyc References 6B TZA - - - X - 1 1 --------------------------------------------------------------------------------------------------- WAI WAIt for interrupt aka WIT WaIT (Used on M740 Family) 65c02S, 65c816 Family, and M740 Family Only Description: .......................................................................... Causes the processor to go into a sleep mode until an external interrupt (NMI, IRQ, ABORT or RESET) occurs. After this interrupt is handled, the RTI will return control to the instruction following WAI. Flags: ................................................................................ nv-bdizc -------- Code: ................................................................................. StartWaitForInterrupt(); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c02S M740 65c816 Size Cyc References C2 WIT - - - - X - 1 2 CB WAI - - - X - X 1 3 05 --------------------------------------------------------------------------------------------------- WDM William D Mensch's extensible byte 65c816 Family Only Description: .......................................................................... This was designed for future expansion, but was never used. It acts just like a SKB from the 6502s and 65c02s Flags: ................................................................................ nv-bdizc nvmxdizc -------- Code: ................................................................................. // Do nothing Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References 42 WDM - - - X 2 2 20 --------------------------------------------------------------------------------------------------- WIT WaIT M740 Family Only See WAI --------------------------------------------------------------------------------------------------- XAA* X to A then And [ILLEGAL OPCODE] 6502 Only See ANE* --------------------------------------------------------------------------------------------------- XAS* X And address Store [ILLEGAL OPCODE] 6502 Only See SHX* --------------------------------------------------------------------------------------------------- XAS* X index and Accumulator stored in Stack, then store stack and high byte [ILLEGAL OPCODE] 6502 Only See SHS* --------------------------------------------------------------------------------------------------- XBA eXchange B (upper 8bits of accumulator) and A (lower 8bits of accumulator) 65c816 Family Only Description: .......................................................................... Exchanges B and A (high byte and low byte of the 16bit A) Flags: ................................................................................ nv-bdizc nvmxdizc *-----*- n - Is bit 7 of the new 8bit A is set? z - Is the new 8bit A is 0? Code: ................................................................................. // A ROR or ROL would work too, if C/C++ would let us... result = A & 0xFF; A = (A >> 8) + (result << 8); n = A & 0x80; z = !(A & 0xFF); Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References EB XBA - - - X 1 3 --------------------------------------------------------------------------------------------------- XCE eXchange Carry flag and Emulation flag 65c816 Family Only Description: .......................................................................... Exchanges c with e. This is the only means to affect the hidden flag. Switching to emulation mode causes the high bytes of X, Y to become 0 and the high byte of S to become 1. Flags: ................................................................................ If e changes from 0 to 1: nv-bdizc ---*---0 b - This is not changed, per se... c - This becomes the old value of e, 0 in this case If e changes from 1 to 0: nvmxdizc --11---1 m - Starts out as 1 when changed x - Starts out as 1 when changed c - Becomes 1 since that is the old value of e If e does not change: nv-bdizc nvmxdizc -------- Code: ................................................................................. // We only do something if e <> c if (e ^ c) { // Are we changing to 8bit/emulation mode? if (c) { // Remove the values set in m and x P &= 0xCF; e = 1; c = 0; Xh = 0; Yh = 0; Sh = 1; } else { x = 1; m = 1; e = 0; c = 1; } } Opcodes: .............................................................................. Op Format 6502 65c02 R65c02 65c816 Size Cyc References FB XCE - - - X 1 2 *************************************************************************************************** 5 Interrupts The following is a list of the vectors for various interrupt operations emulation/non-65c816 native (65c816 Family Only) IRQ $FFFE (b flag clear) $FFEE RESET $FFFC N/A (Reset will switch to 8bit/emulation mode first) NMI $FFFA $FFEA ABORT (65c816) $FFF8 $FFE8 BRK $FFFE (b flag set) $FFE6 COP (65c816) $FFF4 $FFE4 ___________________________________________________________________________________________________ 5.1 IRQ: Interrupt Request Can be called by hardware, and is maskable with the Interrupt Disable flag Interrupts take 7 cycles When an interrupt occurs, the following happens (in this order): PBR is pushed on the stack if in native mode on the 65c816 PC is pushed on the stack P is pushed on the stack with b set to 0 if in emulation mode (or non 65c816) d = 0 (except 6502 or 65c816 in emulation mode), i = 1 Set PC to the specific IRQ vector ___________________________________________________________________________________________________ 5.2 RESET: System Reset Called when RESET is caused on the CPU. If the CPU is a 65c816, it is changed to 8bit/emulation mode first. A reset causes the following (I *think* this is fairly close, but not 100% positive): 6502 Family- b = 1, i = 1, P bit 5 = 1 PC becomes the 16bit value at $FFFC 65c02 Family- Push PC Push P b = 1, d = 0, i = 1, P bit 5 = 1 PC becomes the 16bit value at $FFFC R65c02 Family- Push PC Push P b = 1, d = 0, i = 1, P bit 5 = 1 PC becomes the 16bit value at $FFFC HuC6280- MPR7 = 0 A = X = Y = S = MPR0 to MPR6 = random(256) cs = t = d = 0 i = b = 1 n = z = v = c = random(2) PC becomes the 16bit value at $00FFFC 65ce02- Z = 0 B = 0 b = 1, d = 0, i = 1, e = 1 LRAO = 0 URAO = 0 MMRF = $FF fid = 0 PC becomes the 16bit value at $FFFC 65c816 Family- Sh = $01 D = 0 Xh = 0 Yh = 0 PBR = 0 DBR = 0 b = 1, m = 1, x = 1, d = 0, i = 1, e = 1 PC becomes the 16bit value at $00FFFC M740 Family- i = 1 PC becomes the 16bit value at $FFFC ___________________________________________________________________________________________________ 5.3 NMI: Non-Maskable Interrupt Can be called by hardware and is not maskable even by i See IRQ for exactly what happens on an NMI (they also take 7 cycles just like IRQ) except this uses the address at a different location in memory ($FFFA or $FFEA). ___________________________________________________________________________________________________ 5.4 BRK: Break Called by software via the BRK ($00) opcode. This is identical to IRQ, except b is set to 1 instead of 0 and since this is called by an opcode instead of an interrupt, PC is pointing to the next instruction to execute after the BRK. ___________________________________________________________________________________________________ 5.5 ABORT: Abort 65c816 Family Only Can be called by hardware. This aborts the current instruction. It completes execution of the current opcode, but DOES NOT change any registers, effectively causing it to become a NOP. ___________________________________________________________________________________________________ 5.6 COP: Co-Processor 65c816 Family Only Called by software via the COP ($02) opcode ___________________________________________________________________________________________________ 5.7 SO: Set Overflow 65ce02 Only This simply sets the overflow flag (v) and does not execute any code or interrupts. Since the only system that the 65ce02 is on does not use this interrupt, I can only assume it was designed to work with a co-processor, such as a floating-point processor, and the overflow would be to let the program know about an overflow issue. *************************************************************************************************** 6 Pins *************************************************************************************************** 7 Quirks and Nuances *************************************************************************************************** A1 Miscellaneous Notes and Issues My data and information is only as good as it's sources. I have been writing a heavy data set testing utility to use on 6502 CPUs so I can test those illegal opcodes. I will be tested on a stock Atari 130XE (6502C) and if necessary, on an Apple IIGS (65c816). Hopefully, once and for all, I can solve the mysteries of the confusing illegal opcodes. Once this program is done, I'll make the source available to anybody that wants to port it to other computers. It abstracts all system-specific code to subroutines/function calls so it should be easy to port to any 8bit 65xx systems as necessary. I am using [12] (WLA Assembler). ___________________________________________________________________________________________________ A1.1 More 6502 things to consider (and a couple 65c02+ issues) 6502 Only Issues: The ROR instruction didn't exist in the very earliest (pre-'77) chips. Unlike most microprocessors, the 6502 does not make memory accesses on an "as needed" basis. It always does a fetch or store on every single clock cycle. There are a few cases, though, where there isn't anything to be fetched or stored, and a "garbage" fetch or store occurs. This is mainly of importance with the memory-mapped I/O devices: o When adding a carry to the MSB of an address, a fetch occurs at a garbage address. The CMOS chips refetch the last byte of the instruction. According to Western Design Center: A possible cause of interference with memory-mapped I/O devices on the 6502, is [...] an invalid address read while generating an indexed effective address when a page boundary is crossed o When doing a fetch-modify-store instruction (INC, DEC, ASL, LSR, ROL, ROR) garbage is stored into the location during the "modify" cycle, followed by the "real" store cycle which stores the correct data. The CMOS chips do a second fetch instead of a garbage store. ___________________________________________________________________________________________________ A1.2 65ce02 Issues [13] contains most, but not all, of the opcodes for the 65ce02, including timing and whatnot. Because it does not contain everything, the remainder of the data had to be filled in by guesswork. Fortunately, the most unique features/opcodes of the system were commented, at least enough to emulate the system. The timing on the 65ce02 is possibly a little off in places where documentation was not available, such as the BBRx and BBSx instructions (which are fortunately well described elsewhere). I have tried to guess as to their actual "final" timing. The following instructions were not in [13], and in parenthesis the # of cycles I have used and the reason: 03 SEE (2 - CLE is 2 cycles) 0F to 7F BBRx $ab,nearlabel (5 - Nothing to go by, though 4 is just as likely because of RMBx) 1A INA (1 - ASL A is 1 cycle) 1B INZ (1 - ASL A is 1 cycle) 24 BIT $ab (3 - Other simple read ZP instructions, such as CMP, are 3 cycles) 27 BIT $abcd (4 - Other simple read ABS instructions, such as CMP, are 4 cycles) 34 BIT $ab,X (3 - Other simple read ZP,X instructions, such as CMP, are 3 cycles) 38 SEC (1 - CLC is 1 cycle) 3A DEA (1 - ASL A is 1 cycle) 3B DEZ (1 - ASL A is 1 cycle) 3C BIT $abcd,X (4 - Other simple read ABS,X instructions, such as CMP, are 4 cycles) 46 LSR $ab (4 - ASL $ab is 4 cycles) 4A LSR A (1 - ASL A is 1 cycle) 4C JMP $abcd (3 - BRA farlabel is 3 cycles) 4E LSR $abcd (5 - ASL $abcd is 5 cycles) 56 LSR $ab,X (4 - ASL $ab,X is 4 cycles) 5C MAP (2 - Absolutely no clue, just a stab in the dark!) 5E LSR $abcd,X (5 - ASL $abcd,X is 5 cycles) 6C JMP ($abcd) (5 - Just a guess based on BRA farlabel vs JSR $abcd [2 cycles], then 2 cycles more for JSR ($abcd)) 78 SEI (2 - CLI is 2 cycles) 7C JMP ($abcd,X) (5 - same reason as 6C) 88 DEY (1 - ASL A is 1 cycle) 89 BIT #$ab (2 - Other simple read IMM instructions, such as CMP, are 2 cycles) 8F to FF BBSx $ab,nearlabel (5 - Nothing to go by, though 4 is just as likely because of SMBx) C3 DEW $ab (5 - Total guess based on ZP vs ABS, as in ROW $abcd) C6 DEC $ab (4 - ASL $ab is 4 cycles) C8 INY (1 - ASL A is 1 cycle) CA DEX (1 - ASL A is 1 cycle) CE DEC $abcd (5 - ASL $abcd is 5 cycles) D6 DEC $ab,X (4 - ASL $ab,X is 4 cycles) DE DEC $abcd,X (5 - ASL $abcd,X is 5 cycles) E1 SBC ($ab,X) (5 - ADC ($ab,X) is 5 cycles) E3 INW $ab (5 - Total guess based on ZP vs ABS, as in ROW $abcd) E5 SBC $ab (3 - ADC $ab is 3 cycles) E6 INC $ab (4 - ASL $ab is 4 cycles) E8 INX (1 - ASL A is 1 cycle) E9 SBC #$ab (2 - ADC #$ab is 2 cycles) ED SBC $abcd (4 - ADC $abcd is 4 cycles) EE INC $abcd (5 - ASL $abcd is 5 cycles) F1 SBC ($ab),Y (5 - ADC ($ab),Y is 5 cycles) F2 SBC ($ab) (5 - ADC ($ab) is 5 cycles) F5 SBC $ab,X (3 - ADC $ab,X is 3 cycles) F6 INC $ab,X (4 - ASL $ab,X is 4 cycles) F8 SED (1 - CLD is 1 cycle) F9 SBC $abcd,Y (4 - ADC $abcd,Y is 4 cycles) FD SBC $abcd,X (4 - ADC $abcd,X is 4 cycles) FE INC $abcd,X (5 - ASL $abcd,X is 5 cycles) As best as I can tell, the Base Page addressing works just like Zero Page addressing on the pre-65c816s, it's limited to a single page. So, if we use say "ADC $ab,X", where $ab is $E0 and X is $20, then we'd use the value at $00 in the Base Page (assigned by B). Though I'm not positive here, that's what I get when [13] says, "The second byte of the two-byte instruction is added to the X index register to form the low-order address byte, and the B register contains the high-order address byte of the memory location to be used by the operation." ??? What about Word operations that occur at $FF in the base page? Do they wrap around also? ??? It is also unknown what happens when reading a 16bit value at the end of a mapped page boundary. Does it read both bytes from the mapped location? Or does it recalculate the mapped location for the second byte??? For now, I am assuming it reads both from the mapped location of the first byte though I have a feeling that that is probably incorrect. ___________________________________________________________________________________________________ A1.3 HuC6280 Issues I will list issues with the HuC6280 emulation here later, when I have better documentation to be able to properly emulate it in the first place. In the mean time, I really have no clue how to handle the t flag completely (it makes no sense to me that it'd affect ADC and not SBC, for example). Some documentation says to add a cycle to the HuC6280 if a page boundary is crossed on a branch, others do not. I am currently not adding a cycle since the HuC6280 doesn't seem to add cycles anywhere else for page boundaries. ___________________________________________________________________________________________________ A1.4 M740 Issues [20] states that BRA (Opcode 80) takes 4 cycles but adds 2 cycles for the branch, whereas all condition based branches only take 2 cycles and add 2 cycles for branching. I believe this is a mistake and that BRA actually only takes 2 cycles + 2 for the branch (in effect 4 still). ___________________________________________________________________________________________________ A1.5 Emulation Notes The b (Break) flag seems to never actually change from 1 on the CPU. According to [1], you must POP the flags off of the stack to test if the b flag is set. This means that the real b flag may never actually change. Other documentation states that b is ALWAYS set when you push it onto the stack and pop it in, say A. For now, the emulator does not support modifying b at all, it simply never changes from 1! When an interrupt is used, calling the 8bit interrupt controller, P with bit 4 cleared is pushed onto the stack. PLP, RTI and REP in emulation mode are not permitted to change the flag. It simply is ALWAYS 1 until I find out otherwise. Addressing Modes 6502 ---------------------------------------------------------------------------------------------- JmpInd: Implements the 6502 JmpInd bug DPIndX: Forces 16bit read from zero page to stay in the zero page DPIndY: Same as DPIndX 65c02 --------------------------------------------------------------------------------------------- DPIndX: Forces 16bit read from zero page to stay in the zero page DPIndY: Same as DPIndX R65c02 -------------------------------------------------------------------------------------------- DPIndX: Forces 16bit read from zero page to stay in the zero page DPIndY: Same as DPIndX HuC6280 ------------------------------------------------------------------------------------------- NOT YET SUPPORTED 65ce02 -------------------------------------------------------------------------------------------- I have a gut feeling that the way I'm handling things is totally wrong, but I have to start somewhere. Imm: For 16bit reads/writes, does NOT check for overflow from one memory block to another. Unknown if it should or not Sample to duplicate problem: PHW #$1234 If this instruction happens on #$7FFE in memory, the immediate value would be at $7FFF and $8000 Does it re-check if $8000 is mapped the same as $7FFF? Or does it use $7FFF's memory map for both bytes? We're using $7FFF's memory map for both bytes Abs: For 16bit reads/writes, does NOT check for overflow from one memory block to another. Unknown if it should or not Sample to duplicate problem: PHW $7FFF Does it re-check if $8000 is mapped the same as $7FFF? Or does it use $7FFF's memory map for both bytes? We're using $7FFF's memory map for both bytes JmpInd: Again, 16bit read does NOT check for overflow from one block to another. Unknown if it should or not Sample to duplicate problem: JMP ($7FFF) Does it re-check if $8000 is mapped the same as $7FFF? Or does it use $7FFF's memory map for both bytes? We're using $7FFF's memory map for both bytes DP: For 16bit reads/writes, the data is forced inside the same page Unknown if it should or not Sample to duplicate problem: INW $FF If B is $7F, then the actual address accessed is $7FFF The read and write occur at $7FFF (low byte) and $7F00 (high byte) DPX: Data is forced in the same page, even after adding X, the same behavior as previous CPUs Unknown if it should or not DPY: Same as DPX DPIndX: Same as DPX DPIndY: Same as DPX Y is added BEFORE calculating the address with the mapped registers Unknown if it should or not Rel: No extra cycles for taking the branch, and no extra cycles for crossing a boundary JmpIndX: Same as JmpInd DPIndZ: Same as DPIndY DPAndRel: Same as DP No extra cycles for taking the branch, and no extra cycles for crossing a boundary 65c816 -------------------------------------------------------------------------------------------- Abs: Crosses over banks, as specified by [10] AbsX: Crosses over banks, as specified by [1] AbsY: Crosses over banks, as specified by [1] JmpInd: Grabs from bank 0 as specified by [1]. Wraps around in bank 0 if necessary. DP: Stays in bank 0 as specified by [1] 16bit reads/writes stay in bank 0, but can leave the direct page DPX: Wraps within page 0 if on a pre-65c816 instruction and D = 0 Otherwise, overflow can cross a page boundary 16bit reads/writes stay in bank 0 All specified by [1] DPY: Same as DPX DPIndX: Same as DPX for DP read Final address crosses over banks, as specified by [1] DPIndY: Same as DPX for DP read Final address crosses over banks, as specified by [1] JmpIndX: Grabs data from Program Bank. Wraps around inside the bank if necessary. All specified by [1] *************************************************************************************************** A2 List of systems that use these processors The CPUs are listed pretty much in order of release instead of in alphanumeric order, so a 6502 is later than a 6507. Almost all of this information is from [11]. This list is very much NOT COMPLETE! ___________________________________________________________________________________________________ A2.1 6502 Family CPU Systems ----------------------------------------------------------- 6507 Atari 2600 6502 Apple I/II/II+/IIe Commodore Pet 6502A Atari 400/800 Apple III/III+ 6502C Atari XL Series Atari XE Series Atari 65GS Atari 5200/7800 6510 Commodore 64/128/SX-64/DX-64 2A03 Nintendo Entertainment System (NES) ___________________________________________________________________________________________________ A2.2 65c02 Family CPU Systems ----------------------------------------------------------- 65c02 Apple IIc/IIc+/IIe Extended ___________________________________________________________________________________________________ A2.3 R65c02 Family CPU Systems ----------------------------------------------------------- R65c02 R65c102 Commodore LCD 65c02S 65sc02 Apple IIe+ HuC6280 Turbo Grafx-16 65ce02 Commodore 65 (aka C64-DX) ___________________________________________________________________________________________________ A2.4 65c816 Family CPU Systems ----------------------------------------------------------- 65c816 Apple IIGS Super Nintendo/Famicon *************************************************************************************************** A3 TO DO: Add a "Quirks/Nuances" section: Would list details in one location about the list of CPUs, such as: Memory addressing (Little Endian, how wrapping works, etc.) Hardware access Quirks/Bugs Other features to note Describes all of the CPU quirks for each version of the CPU in a single location. As far as I know, these quirks are documented already here, they're just scattered all over the place so it may be hard to find them all. These quirks would include things such as unexpected memory accesses, bugs such as the 6502 JMP ($12FF) bug, differences between various CPUs in the same family (such as 2A03 ignoring the d flag), etc. Add a "Pins" section: Add various high/low pin operations, such as Set Overflow, ABORT, etc. and how they affect the CPUs Possibly add a full 'clock for clock' description: What the processor is doing with each CPU cycle, for each addressing mode and each instruction. [1] has most of the information we need to be able to do this already. Add information for the Mitsubishi 7700 series Add information for the DECO16 ??? Currently the only source I've found for it is [15]. I hate having to use only one source! Hopefully get better documentation for: HuC6280, 65ce02 (probably not), DECO16 Now that opcode references are renumbered, they are out of order. Resorting them will be very time consuming, but will make cross-referencing easier. *************************************************************************************************** A4 Updates List v0.2b 2007-02-17 Additions: o Added Specifications Chart v0.2a 2006-12-30 to 2007-01-11 Corrections: o Completely reformatted the text file to fit at 100 characters wide instead of 120. o Fixed a couple typos o RTI improperly stated that on the 65ce02, it updated the e flag. o Moved Interrupts section to section 5 o Added place holder sections 6 (for Pins) and 7 (for Quirks and Nuances) o Updated Opcodes section to match other Processor Data files o Change "value" to "operand" in many places throughout the code snippets for better clarity o Fixed a tiny issue in the SBC and INS instructions v0.2 2006-11-05 to 2006-11-17 Additions: o Added M740 Opcodes and data Corrections: o Redid all references to a more logical order o Combined references 7 and 8 to a single reference (02) The only time 7 was not applied (add 1 cycle for taking a branch) is on the BRA instruction, and only then because it was already factored into the cycles for the instruction (3 instead of 2). BRA has been modified so it no longer factors in the extra cycle for the branch (it's now at 2 cycles), and the extra cycle should always be added to it. This is because some CPUs do not add a cycle for branching (65ce02) and others add 2 cycles instead of just 1 (HuC6280), and so will make it more accurate. o Removed a few reference 10s (4 in the old list) where they were completely ignored for 65c816 only opcodes o Opcode 55 incorrectly had a reference 01 (3 in the old list) value o Opcode 67 was missing a reference 22 (2 in the old list) value o Opcode E9 was missing references 10 and 25 (4 and 1 respectively in the old list) o In some places, I called the 65sc02 the 65cs02 instead. They are now all 65sc02 v0.1 2006-10-24 Initial release *************************************************************************************************** Sources Sources These are in no particular order, I just appended where things looked like they belonged when I added new sources until I numbered them, now all new sources appear at the end. I have to say that the "Programming Guide for the 6502, 65c02 and 65c816" by Western Design Center was by far the most useful single document I have found for those processors. The Atari800WIN emulator was great at describing exactly how many of the illegal opcodes for the 6502 worked, though the "Extra Instructions of the 65XX Series CPU" was also very helpful. The Rockwell guides would be far more useful for anybody wishing to design devices using the CPUs as it gives all sorts of pin outs, voltage information, etc. that is missing elsewhere; but for this documentation, about all I ascertained from them was differences between the 6502, 6503, etc. And my 65ce02 information comes solely from the C64DX System Specification, which is scanned and OCR'd, so it's not 100% accurate (plus many opcodes are missing from the docs). [1] Programming Guide for the 6502, 65c02 and 65c816 http://www.westerndesigncenter.com/wdc/ (c) (date unknown), The Western Design Center, Inc. * Used for just about everything that isn't mentioned elsewhere. This documentation is simply awesome for 65xx programming with WDC processors [2] W65C02S Microprocessor Data Sheet http://www.westerndesigncenter.com/wdc/ (c) Feb 2004, The Western Design Center, Inc. * Used to get details on the 65c02S, as well as descriptions for BBRx, BBSx, SMBx and RMBx opcodes [3] R650X and R651X Microprocessors. Document No. 29000D39, Order No. D39 Rev. B (c) Jun 1987, Rockwell * Used to get charts for the different 6502 CPUs [4] R65C02, R65C102 and R65C112 R65C00 Microprocessors. Document No. 29651N52, Order No. 2149 Rev. 6 (c) Jun 1987, Rockwell * Used to get charts for the different R65c02 CPUs [5] Atari800WIN PLuS v4.0 Emulator (c) 1995-1998 David Firth (c) 1998-2005 Atari800 development team http://atariarea.histeria.pl/PLus/index_us.htm * Used to get details of the illegal 6502 instructions, along with some timing issues Though unrelated, their emulator gave me some ideas of what to do (and not to do in some cases) for handling certain emulation issues [6] Extra Instructions of the 65XX Series CPU (c) Jun 1997, Adam Vardy (abe0084@infonet.st-johns.nf.ca) * Used to cross-compare illegal 6502 instructions [7] 6502 Undocumented Opcodes Version 3.0 (c) May 17th 1997, Freddy Offenga (offen300@hio.tem.nhl.nl) * Used to cross-compare illegal 6502 instructions [8] The 6502 Instruction Set Decoded http://www.llx.com/~nparker/a2/opcodes.html (c) May 3rd 2005 * Used to get 65c02 Illegal Opcodes details, as well as having handy charts to look at for comparison purposes [9] 6502 Bugs List (c) Nov 2nd 1994, Ivo van Poorten (www@cs.vu.nl) * Made me aware of some 6502 quirks that are not documented elsewhere [10] C=Hacking Issue #13 Article: 13. Exploiting the 65C816S CPU by Jim Brain http://www.ffd2.com/fridge/chacking/c=hacking13.txt (c) Jul 1996 * Used to get information about the 65c816's handling of wrap-around [11] The Machine Room (website) http://www.machine-room.org/ (c) Oct 2006 * Used to get a list of what computers used what CPUs [12] WLA DX Assembler http://users.tkk.fi/~vhelin/wla.html (c) Sep 10th, 2006, Ville Helin * Though I didn't really get much information from this assembler, I did a lot of coding using it to help me test various ideas, sets of code, etc. A very nice 65xx assembler though it doesn't assemble 65sc02, 65ce02, M740 or M7700 source natively. [13] C64DX System Specification (c) 1991, Commodore Business Machines, Inc. * Used to get the details on the 65ce02 (4510/4502) [14] Commodore Semiconductor Group CSG65CE02 Technical Reference (c) Jan 8th 1999, Michael Steil, (mist@c64.org, michael.steil@writeme.com) * Though this document is mostly speculation based mostly on just seeing a mnemonic chart of the 65ce02, it was both informative and made the 65ce02 seem mysterious enough for me to search and search to find more information on it. Without this document, I would never have found the full C64DX System Specification, since I'd have no clue it existed, nor that there was so much information on a vaporware system. [15] MAME Emulator Source Code http://www.mameworld.net/ and http://mamedev.org/ (c) 1998? - 2006, MAME * Used to cross-compare various misc opcodes and to get yet more oddball names for illegal 6502 opcodes It was also useful to complement the other sources of HuC6280 information [16] TGEMU v021601 Emulator http://cgfm2.emuviews.com (c) Feb 16th 2001, Charles MacDonald (cgfm2@hotmail.com) * Used to get HuC6280 Opcode Details and Timing [17] TurboGrafx-16 Hardware Notes http://cgfm2.emuviews.com (c) 2002, Charles MacDonald (cgfm2@hotmail.com) * Disagrees with his emulator quite a lot, but has more useful information on the TG16 and HuC6280 [18] Creating an Emulator for Turbo Grafx Systems A Handy Guide, Version 0.2 (c) April 30, 2005, Warren Wilkinson (wagwilk@telusplanet.net) * I haven't really used this guide for much, but because of it I found the Unofficial PC-Engine Reference which allows me to cross-check with Charles MacDonald's information [19] Unofficial PC-Engine Reference (c) June 8, 1997, Jens Ch. Restemeier (jchrr@hrz.uni-bielefeld.de) * Used to update HuC6280 Opcode details and timing In particular, this document seems to have far more realistic timing than TGEMU, MAME or "Creating an Emulator..." [20] Mitsubishi 740 Family Software Manual (c) August 29th, 1997, Mitsubishi and Renesas Technology Corp. (http://www.renesas.com/) * Used to get the M740 Family's opcodes, timing and information [21] Mitsubishi 7531 Group User's Manual (c) November 9th, 1999, Mitsubishi and Renesas Technology Corp. (http://www.renesas.com/) * Used to get further information on the M740 Family as well as specifics about the M375xx CPUs [22] Mitsubishi 7700 Family Software Manual (c) ???, Mitsubishi and Renesas Technology Corp. (http://www.renesas.com/) * Used to get detailed information on the M7700 Family, though every page has "EOL Announced" over the content, making some parts a little hard to read.