User Tools

Site Tools


base:extra_instructions_of_the_65xx_series_cpu

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

base:extra_instructions_of_the_65xx_series_cpu [2015-04-17 04:31] (current)
Line 1: Line 1:
 +====== Extra Instructions Of The 65XX Series CPU ======
 +<code>
 +By: Adam Vardy (abe0084@infonet.st-johns.nf.ca)
 +
 +[File created: 22, Aug. 1995... 27, Sept. 1996]
 +
 +The following is a list of 65XX/85XX extra opcodes.  The operation codes 
 +for the 6502 CPU fit in a single byte; out of 256 possible combinations, 
 +only 151 are "legal."  This text describes the other 256-151= 105 operation 
 +codes.  These opcodes are not generally recognized as part of the 6502 
 +instruction set.  They are also referred to as undefined opcodes or 
 +undocumented opcodes or non-standard opcodes or unofficial opcodes.  In 
 +"The Commodore 64 Programmer's Reference Guide" their hexadecimal values 
 +are simply marked as future expansion.  This list of opcodes was compiled 
 +with help from "The Complete Inner Space Anthology" by Karl J. H. Hildon.
 +
 +I have marked off the beginning of the description of each opcode with a 
 +few asterisks.  At times, I also included an alternate name in parenthesis. 
 +All opcode values are given in hexadecimal.  These hexadecimal values are 
 +listed immediately to the right of any sample code.  The lowercase letters 
 +found in these examples represent the hex digits that you must provide as 
 +the instruction's immediate byte value or as the instruction's destination 
 +or source address.  Thus immediate values and zero page addresses are 
 +referred to as 'ab' For absolute addressing mode the two bytes of an 
 +absolute address are referred to as 'cd' and 'ab'.
 +
 +Execution times for all opcodes are given alongside to the very right of 
 +any sample code.  A number of the opcodes described here combine the 
 +operation of two regular 6502 instructions.  You can refer to a book on the 
 +6502 instruction set for more information, such as which flags a particular 
 +instruction affects.
 +</code>
 +====== ASO    ***    (SLO) ======
 +<code>
 +This opcode ASLs the contents of a memory location and then ORs the result 
 +with the accumulator.  
 +
 +Supported modes:
 +
 +ASO abcd        ;0F cd ab    ;No. Cycles= 6
 +ASO abcd,     ;1F cd ab    ;            7
 +ASO abcd,     ;1B cd ab    ;            7
 +ASO ab          ;07 ab       ;            5
 +ASO ab,X        ;17 ab       ;            6
 +ASO (ab,X)      ;03 ab       ;            8
 +ASO (ab),     ;13 ab       ;            8
 +
 +(Sub-instructions: ORA, ASL)
 +
 +Here is an example of how you might use this opcode:
 +
 +ASO $C010       ;0F 10 C0
 +
 +Here is the same code using equivalent instructions.
 +
 +ASL $C010
 +ORA $C010
 +</code>
 +====== RLA    *** ======
 +<code>
 +RLA ROLs the contents of a memory location and then ANDs the result with 
 +the accumulator.
 +
 +Supported modes:
 +
 +RLA abcd        ;2F cd ab    ;No. Cycles= 6
 +RLA abcd,     ;3F cd ab    ;            7
 +RLA abcd,     ;3B cd ab    ;            7
 +RLA ab          ;27 ab       ;            5
 +RLA ab,X        ;37 ab       ;            6
 +RLA (ab,X)      ;23 ab       ;            8
 +RLA (ab),     ;33 ab       ;            8
 +
 +(Sub-instructions: AND, ROL)
 +
 +Here's an example of how you might write it in a program.
 +
 +RLA $FC,X       ;37 FC
 +
 +Here's the same code using equivalent instructions.
 +
 +ROL $FC,X
 +AND $FC,X
 +</code>
 +====== LSE    ***   (SRE) ======
 +<code>
 +LSE LSRs the contents of a memory location and then EORs the result with 
 +the accumulator.
 +
 +Supported modes:
 +
 +LSE abcd        ;4F cd ab    ;No. Cycles= 6
 +LSE abcd,     ;5F cd ab    ;            7
 +LSE abcd,     ;5B cd ab    ;            7
 +LSE ab          ;47 ab       ;            5
 +LSE ab,X        ;57 ab       ;            6
 +LSE (ab,X)      ;43 ab       ;            8
 +LSE (ab),     ;53 ab       ;            8
 +
 +(Sub-instructions: EOR, LSR)
 +
 +Example:
 +
 +LSE $C100,    ;5F 00 C1
 +
 +Here's the same code using equivalent instructions.
 +
 +LSR $C100,X
 +EOR $C100,X
 +</code>
 +====== RRA    *** ======
 +<code>
 +RRA RORs the contents of a memory location and then ADCs the result with 
 +the accumulator.
 +
 +Supported modes:
 +
 +RRA abcd        ;6F cd ab    ;No. Cycles= 6
 +RRA abcd,     ;7F cd ab    ;            7
 +RRA abcd,     ;7B cd ab    ;            7
 +RRA ab          ;67 ab       ;            5
 +RRA ab,X        ;77 ab       ;            6
 +RRA (ab,X)      ;63 ab       ;            8
 +RRA (ab),     ;73 ab       ;            8
 +
 +(Sub-instructions: ADC, ROR)
 +
 +Example:
 +
 +RRA $030C       ;6F 0C 03
 +
 +Equivalent instructions:
 +
 +ROR $030C
 +ADC $030C
 +</code>
 +====== AXS    ***    (SAX) ======
 +<code>
 +AXS ANDs the contents of the A and X registers (without changing the 
 +contents of either register) and stores the result in memory.
 +AXS does not affect any flags in the processor status register.
 +
 +Supported modes:
 +
 +AXS abcd        ;8F cd ab    ;No. Cycles= 4
 +AXS ab          ;87 ab       ;            3
 +AXS ab,Y        ;97 ab       ;            4
 +AXS (ab,X)      ;83 ab       ;            6
 +
 +(Sub-instructions: STA, STX)
 +
 +Example:
 +
 +AXS $FE         ;87 FE
 +
 +Here's the same code using equivalent instructions.
 +
 +STX $FE
 +PHA
 +AND $FE
 +STA $FE
 +PLA
 +</code>
 +====== LAX    *** ======
 +<code>
 +This opcode loads both the accumulator and the X register with the contents 
 +of a memory location.
 +
 +Supported modes:
 +
 +LAX abcd        ;AF cd ab    ;No. Cycles= 4
 +LAX abcd,     ;BF cd ab    ;            4*
 +LAX ab          ;A7 ab       ;*=add 1     3
 +LAX ab,Y        ;B7 ab       ;if page     4
 +LAX (ab,X)      ;A3 ab       ;boundary    6
 +LAX (ab),     ;B3 ab       ;is crossed  5*
 +
 +(Sub-instructions: LDA, LDX)
 +
 +Example:
 +
 +LAX $8400,    ;BF 00 84
 +
 +Equivalent instructions:
 +
 +LDA $8400,Y
 +LDX $8400,Y
 +</code>
 +====== DCM    ***    (DCP) ======
 +<code>
 +This opcode DECs the contents of a memory location and then CMPs the result 
 +with the A register.
 +
 +Supported modes:
 +
 +DCM abcd        ;CF cd ab    ;No. Cycles= 6
 +DCM abcd,     ;DF cd ab    ;            7
 +DCM abcd,     ;DB cd ab    ;            7
 +DCM ab          ;C7 ab       ;            5
 +DCM ab,X        ;D7 ab       ;            6
 +DCM (ab,X)      ;C3 ab       ;            8
 +DCM (ab),     ;D3 ab       ;            8
 +
 +(Sub-instructions: CMP, DEC)
 +
 +Example:
 +
 +DCM $FF         ;C7 FF
 +
 +Equivalent instructions:
 +
 +DEC $FF
 +CMP $FF
 +</code>
 +====== INS    ***    (ISC) ======
 +<code>
 +This opcode INCs the contents of a memory location and then SBCs the result 
 +from the A register.
 +
 +Supported modes:
 +
 +INS abcd        ;EF cd ab    ;No. Cycles= 6
 +INS abcd,     ;FF cd ab    ;            7
 +INS abcd,     ;FB cd ab    ;            7
 +INS ab          ;E7 ab       ;            5
 +INS ab,X        ;F7 ab       ;            6
 +INS (ab,X)      ;E3 ab       ;            8
 +INS (ab),     ;F3 ab       ;            8
 +
 +(Sub-instructions: SBC, INC)
 +
 +Example:
 +
 +INS $FF         ;E7 FF
 +
 +Equivalent instructions:
 +
 +INC $FF
 +SBC $FF
 +</code>
 +====== ALR    *** ======
 +<code>
 +This opcode ANDs the contents of the A register with an immediate value and 
 +then LSRs the result.
 +
 +One supported mode:
 +
 +ALR #ab         ;4B ab       ;No. Cycles= 2
 +
 +Example:
 +
 +ALR #$FE        ;4B FE
 +
 +Equivalent instructions:
 +
 +AND #$FE
 +LSR A
 +</code>
 +====== ARR    *** ======
 +<code>
 +This opcode ANDs the contents of the A register with an immediate value and 
 +then RORs the result.
 +
 +One supported mode:
 +
 +ARR #ab         ;6B ab       ;No. Cycles= 2
 +
 +Here's an example of how you might write it in a program.
 +
 +ARR #$7F        ;6B 7F
 +
 +Here's the same code using equivalent instructions.
 +
 +AND #$7F
 +ROR A
 +</code>
 +====== XAA    *** ======
 +<code>
 +XAA transfers the contents of the X register to the A register and then 
 +ANDs the A register with an immediate value.
 +
 +One supported mode:
 +
 +XAA #ab         ;8B ab       ;No. Cycles= 2
 +
 +Example:
 +
 +XAA #$44        ;8B 44
 +
 +Equivalent instructions:
 +
 +TXA
 +AND #$44
 +</code>
 +====== OAL    *** ======
 +<code>
 +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.
 +
 +One supported mode:
 +
 +OAL #ab         ;AB ab       ;No. Cycles= 2
 +
 +Here's an example of how you might use this opcode:
 +
 +OAL #$AA        ;AB AA
 +
 +Here's the same code using equivalent instructions:
 +
 +ORA #$EE
 +AND #$AA
 +TAX
 +</code>
 +====== SAX    *** ======
 +<code>
 +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.
 +... A few points might be made about the action of subtracting an immediate 
 +value.  It actually works just like the CMP instruction, except that CMP 
 +does not store the result of the subtraction it performs in any register.  
 +This subtract operation is not affected by the state of the Carry flag, 
 +though it does affect the Carry flag.  It does not affect the Overflow 
 +flag.
 +
 +One supported mode:
 +
 +SAX #ab         ;CB ab       ;No. Cycles= 2
 +
 +Example:
 +
 +SAX #$5A        ;CB 5A
 +
 +Equivalent instructions:
 +
 +STA $02
 +TXA
 +AND $02
 +SEC
 +SBC #$5A
 +TAX
 +LDA $02
 +
 +Note: Memory location $02 would not be altered by the SAX opcode.
 +</code>
 +====== NOP    *** ======
 +<code>
 +NOP performs no operation.  Opcodes: 1A, 3A, 5A, 7A, DA, FA.
 +Takes 2 cycles to execute.
 +</code>
 +====== SKB    *** ======
 +<code>
 +SKB stands for skip next byte.
 +Opcodes: 80, 82, C2, E2, 04, 14, 34, 44, 54, 64, 74, D4, F4.
 +Takes 2, 3, or 4 cycles to execute.
 +</code>
 +====== SKW    *** ======
 +<code>
 +SKW skips next word (two bytes).
 +Opcodes: 0C, 1C, 3C, 5C, 7C, DC, FC.
 +Takes 4 cycles to execute.
 +
 +To be dizzyingly precise, SKW actually performs a read operation.  It'
 +just that the value read is not stored in any register.  Further, opcode 0C 
 +uses the absolute addressing mode.  The two bytes which follow it form the 
 +absolute address.  All the other SKW opcodes use the absolute indexed X 
 +addressing mode.  If a page boundary is crossed, the execution time of one 
 +of these SKW opcodes is upped to 5 clock cycles.
 +--------------------------------------------------------------------------
 +
 +The following opcodes were discovered and named exclusively by the author.
 +(Or so it was thought before.)
 +</code>
 +====== HLT    *** ======
 +<code>
 +HLT crashes the microprocessor.  When this opcode is executed, program 
 +execution ceases.  No hardware interrupts will execute either.  The author 
 +has characterized this instruction as a halt instruction since this is the 
 +most straightforward explanation for this opcode's behaviour.  Only a reset 
 +will restart execution.  This opcode leaves no trace of any operation 
 +performed!  No registers affected.
 +
 +Opcodes: 02, 12, 22, 32, 42, 52, 62, 72, 92, B2, D2, F2.
 +</code>
 +====== TAS    *** ======
 +<code>
 +This opcode ANDs the contents of the A and X registers (without changing 
 +the contents of either register) and transfers the result to the stack 
 +pointer.  It then ANDs that result with the contents of the high byte of 
 +the target address of the operand +1 and stores that final result in 
 +memory.  
 +
 +One supported mode:
 +
 +TAS abcd,     ;9B cd ab    ;No. Cycles= 5
 +
 +(Sub-instructions: STA, TXS)
 +
 +Here is an example of how you might use this opcode:
 +
 +TAS $7700,    ;9B 00 77
 +
 +Here is the same code using equivalent instructions.
 +
 +STX $02
 +STA $FB
 +AND $02
 +TAX
 +TXS
 +AND #$78
 +STA $7700,Y
 +LDA $FB
 +LDX $02
 +
 +Note: Memory locations $02 and $FB would not be altered by the TAS opcode.
 +
 +Above I used the phrase 'the high byte of the target address of the operand 
 ++1' By the words target address, I mean the unindexed address, the one 
 +specified explicitly in the operand.  The high byte is then the second byte 
 +after the opcode (ab).  So we'll shorten that phrase to AB+1.
 +</code>
 +====== SAY    *** ======
 +<code>
 +This opcode ANDs the contents of the Y register with <ab+1> and stores the 
 +result in memory.
 +
 +One supported mode:
 +
 +SAY abcd,     ;9C cd ab    ;No. Cycles= 5
 +
 +Example:
 +
 +SAY $7700,    ;9C 00 77
 +
 +Equivalent instructions:
 +
 +PHA
 +TYA
 +AND #$78
 +STA $7700,X
 +PLA
 +</code>
 +====== XAS    *** ======
 +<code>
 +This opcode ANDs the contents of the X register with <ab+1> and stores the 
 +result in memory.
 +
 +One supported mode:
 +
 +XAS abcd,     ;9E cd ab    ;No. Cycles= 5
 +
 +Example:
 +
 +XAS $6430,    ;9E 30 64
 +
 +Equivalent instructions:
 +
 +PHA
 +TXA
 +AND #$65
 +STA $6430,Y
 +PLA
 +</code>
 +====== AXA    *** ======
 +<code>
 +This opcode stores the result of A AND X AND the high byte of the target 
 +address of the operand +1 in memory.
 +
 +Supported modes:
 +
 +AXA abcd,     ;9F cd ab    ;No. Cycles= 5
 +AXA (ab),     ;93 ab       ;            6
 +
 +Example:
 +
 +AXA $7133,    ;9F 33 71
 +
 +Equivalent instructions:
 +
 +STX $02
 +PHA
 +AND $02
 +AND #$72
 +STA $7133,Y
 +PLA
 +LDX $02
 +
 +Note: Memory location $02 would not be altered by the AXA opcode.
 +
 +
 +The following notes apply to the above four opcodes: TAS, SAY, XAS, AXA.
 +
 +None of these opcodes affect the accumulator, the X register, the Y 
 +register, or the processor status register!
 +     The author has no explanation for the complexity of these 
 +instructions.  It is hard to comprehend how the microprocessor could handle 
 +the convoluted sequence of events which appears to occur while executing 
 +one of these opcodes.  A partial explanation for what is going on is that 
 +these instructions appear to be corruptions of other instructions.  For 
 +example, the opcode SAY would have been one of the addressing modes of the 
 +standard instruction STY (absolute indexed X) were it not for the fact that 
 +the normal operation of this instruction is impaired in this particular 
 +instance.
 +
 +One irregularity uncovered is that sometimes the actual value is stored in 
 +memory, and the AND with <ab+1> part drops off (ex. SAY becomes true STY).  
 +This happens very infrequently.  The behaviour appears to be connected with 
 +the video display.  For example, it never seems to occur if either the 
 +screen is blanked or C128 2MHz mode is enabled.
 +
 +--- Imported example ---
 +Here is a demo program to illustrate the above effect.  SYS 8200 to try it.  
 +There is no exit, so you'll have to hit Stop-Restore to quit.  And you may 
 +want to clear the screen before running it.  For contrast, there is a 
 +second routine which runs during idle state display.  Use SYS 8211 for it.  
 +After trying the second routine, check it out again using POKE 53269,255 to 
 +enable sprites.
 +
 +begin 640 say->sty
 +D"""B`*`@G``%Z$P,("P1T##[+!'0$/NB`*`@G``%Z-#Z3!,@
 +`
 +end
 +
 +--- Text import end ---
 +
 +WARNING: If the target address crosses a page boundary because of indexing, 
 +the instruction may not store at the intended address.  It may end up 
 +storing in zero page, or another address altogether (page=value stored). 
 +Apparently certain internal 65XX registers are being overridden.  The whole 
 +scheme behind this erratic behaviour is very complex and strange.  
 +
 +
 +And continuing with the list...
 +</code>
 +====== ANC    *** ======
 +<code>
 +ANC ANDs the contents of the A register with an immediate value and then 
 +moves bit 7 of A into the Carry flag.  This opcode works basically 
 +identically to AND #immed. except that the Carry flag is set to the same 
 +state that the Negative flag is set to.
 +
 +One supported mode:
 +
 +ANC #ab         ;2B ab       ;No. Cycles= 2
 +ANC #ab         ;0B ab
 +
 +(Sub-instructions: AND, ROL)
 +
 +OPCODE 89
 +Opcode 89 is another SKB instruction.  It requires 2 cycles to execute.
 +</code>
 +====== LAS    *** ======
 +<code>
 +This opcode ANDs the contents of a memory location with the contents of the 
 +stack pointer register and stores the result in the accumulator, the X 
 +register, and the stack pointer.  Affected flags: N Z.
 +
 +One supported mode:
 +
 +LAS abcd,     ;BB cd ab    ;No. Cycles= 4*
 +
 +OPCODE EB
 +Opcode EB seems to work exactly like SBC #immediate.  Takes 2 cycles.
 +</code>
 +====== That is the end of the list. ======
 +<code>
 +This list is a full and complete list of all undocumented opcodes, every 
 +last hex value.  It provides complete and thorough information and it also 
 +corrects some incorrect information found elsewhere.  The opcodes MKA and 
 +MKX (also known as TSTA and TSTX) as described in "The Complete Commodore 
 +Inner Space Anthology" do not exist.  Also, it is erroneously indicated 
 +there that the instructions ASO, RLA, LSE, RRA have an immediate addressing 
 +mode.  (RLA #ab would be ANC #ab.)
 +</code>
 +====== [Recent additions to this text file] ======
 +<code>
 +Here are some other more scrutinizing observations.
 +
 +The opcode ARR operates more complexily than actually described in the list 
 +above.  Here is a brief rundown on this.  The following assumes the decimal 
 +flag is clear.  You see, the sub-instruction for ARR ($6B) is in fact ADC 
 +($69), not AND.  While ADC is not performed, some of the ADC mechanics are 
 +evident.  Like ADC, ARR affects the overflow flag.  The following effects 
 +occur after ANDing but before RORing.  The V flag is set to the result of 
 +exclusive ORing bit 7 with bit 6.  Unlike ROR, bit 0 does not go into the 
 +carry flag.  The state of bit 7 is exchanged with the carry flag.  Bit 0 is 
 +lost.  All of this may appear strange, but it makes sense if you consider 
 +the probable internal operations of ADC itself.  
 +
 +SKB opcodes 82, C2, E2 may be HLTs.  Since only one source claims this, and 
 +no other sources corroborate this, it must be true on very few machines.  
 +On all others, these opcodes always perform no operation.
 +
 +LAS is suspect.  This opcode is possibly unreliable.
 +
 +OPCODE BIT-PATTERN: 10x0 1011
 +Now it is time to discuss XAA ($8B) and OAL ($AB).  A fair bit of 
 +controversy has surrounded these two opcodes.  There are two good reasons 
 +for this.  1 - They are rather weird in operation.  2 - They do operate 
 +differently on different machines.  Highly variable.
 +
 +Here is the basic operation.
 +OAL
 +This opcode ORs the A register with #xx, ANDs the result with an immediate 
 +value, and then stores the result in both A and X.
 +
 +On my 128, xx may be EE,EF,FE, OR FF.  These possibilities appear to depend 
 +on three factors: the X register, PC, and the previous instruction 
 +executed.  Bit 0 is ORed from x, and also from PCH.  As for XAA, on my 128 
 +this opcode appears to work exactly as described in the list.
 +
 +On my 64, OAL produces all sorts of values for xx: 00,04,06,80, etc... A 
 +rough scenario I worked out to explain this is here.  The constant value EE 
 +disappears entirely.  Instead of ORing with EE, the accumulator is ORed 
 +with certain bits of X and also ORed with certain bits of another 
 +"register" (nature unknown, whether it be the data bus, or something else).  
 +However, if OAL is preceded by certain other instructions like NOP, the 
 +constant value EE reappears and the foregoing does not take place.
 +
 +On my 64, XAA works like this.  While X is transfered to A, bit 0 and bit 4 
 +are not.  Instead, these bits are ANDed with those bits from A, and the 
 +result is stored in A.
 +
 +There may be many variations in the behaviour of both opcodes.  XAA #$00 or 
 +OAL #$00 are likely quite reliable in any case.  It seems clear that the 
 +video chip (i.e., VIC-II) bears responsibility for some small part of the 
 +anomalousness, at least.  Beyond that, the issue is unclear.   
 +
 +One idea I'll just throw up in the air about why the two opcodes behave as 
 +they do is this observation.  While other opcodes like 4B and 6B perform 
 +AND as their first step, 8B and AB do not.  Perhaps this difference leads 
 +to some internal conflict in the microprocessor.  Besides being subject to 
 +"noise", the actual base operations do not vary.
 +
 +All of the opcodes in this list (at least up to the dividing line) use the 
 +naming convention from the CCISA Anthology book.  There is another naming 
 +convention used, for example in the first issue of C=Hacking.  The only 
 +assembler I know of that supports undocumented opcodes is Power Assembler.  
 +And it uses the same naming conventions as used here.
 +
 +One note on a different topic.  A small error has been pointed out in the 
 +64 Programmers Reference Guide with the instruction set listing.  In the 
 +last row, in the last column of the two instructions AND and ORA there 
 +should be an asterisk, just as there is with ADC.  That is the indirect,
 +addressing mode.  In another table several pages later correct information 
 +is given.
 +
 +(A correction:  There was one error in this document originally.  One
 +addressing mode for LAX was given as LAX ab,X.  This should have been
 +LAX ab,Y (B7).  Also note that Power Assembler apparently has this same
 +error, likely because both it and this document derive first from the same
 +source as regards these opcodes.  Coding LAX $00,X is accepted and
 +produces the output B7 00.)
 +</code>
 +====== References ======
 +  * Joel Shepherd. "Extra Instructions" COMPUTE!, October 1983.
 +  * Jim Butterfield. "Strange Opcodes" COMPUTE, March 1993.
 +  * Raymond Quirling. "6510 Opcodes" The Transactor, March 1986.
 +  * John West, Marko Mäkelä. '64doc' file, 1994/06/03.
  
base/extra_instructions_of_the_65xx_series_cpu.txt · Last modified: 2015-04-17 04:31 (external edit)