Jump to content

PIC instruction listings: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
ELAN Microelectronics clones (13 bit): PAGE k instruction is like MOVLP k
Removed (MOVW 0,W) note from some NOP opcodes. The encoding is unique to NOP, it is not a variation of MOVW 0,W.
 
(42 intermediate revisions by 21 users not shown)
Line 1: Line 1:
The [[PIC microcontroller|PIC]] [[instruction set]] refers to the set of instructions that a [[Microchip Technology]] PIC or dsPIC [[microcontroller]] supports. The instructions are usually programmed into the [[Flash memory]] of the processor, and automatically executed by the microcontroller on startup.
The [[PIC microcontroller|PIC]] [[instruction set]] refers to the set of instructions that [[Microchip Technology]] PIC or dsPIC [[microcontroller]] supports. The instructions are usually programmed into the [[Flash memory]] of the processor, and automatically executed by the microcontroller on startup.


PICmicro chips have a [[Harvard architecture]], and instruction words are unusual sizes. Originally, 12-bit instructions included 5 address bits to specify the memory operand, and 9-bit branch destinations. Later revisions added opcode bits, allowing additional address bits.
PICmicro chips have a [[Harvard architecture]] and instruction words have unusual sizes. Originally, 12-bit instructions included 5 address bits to specify the memory operand, and 9-bit branch destinations. Later revisions added opcode bits, allowing additional address bits.


They are [[accumulator machine]]s, with a common accumulator "W" being one operand in all 2-operand instructions.
In the instruction set tables that follow, register numbers are referred to as "f", while constants are referred to as "k". Bit numbers (0–7) are selected by "b". The "d" bit selects the destination: 0 indicates W, while 1 indicates that the result is written back to source register f. The C and Z status flags may be set based on the result; otherwise they are unmodified. Add and subtract (but not rotate) instructions that set C also set the DC (digit carry) flag, the carry from bit 3 to bit 4, which is useful for [[binary-coded decimal|BCD]] arithmetic.


In the instruction set tables that follow, register numbers are referred to as "f", while constants are referred to as "k". Bit numbers (0–7) are selected by "b". Arithmetic instructions write their result to one of the inputs selected by the "d" bit: 0 indicates W, while 1 indicates that the result is written back to source register f. The C and Z status flags may be set based on the result; otherwise they are unmodified. Add and subtract (but not rotate) instructions that set C also set the DC (digit carry) flag, the carry from bit 3 to bit 4, which is useful for [[binary-coded decimal|BCD]] arithmetic.


==Architecture==
==Architecture==


Memory operands are also referred to as "registers". Most are simply general-purpose storage (RAM), while some locations are reserved for ''special function registers''. Except for a single accumulator (called <code>W</code>), almost all other registers are memory-mapped, even registers like the [[program counter]] and ALU [[status register]]. (The other exceptions, which are not memory-mapped, are the return address stack, and the [[Three-state logic|tri-state]] registers used to configure the [[GPIO]] pins.)
Memory operands are also referred to as "registers". Most are simply general-purpose storage (RAM), while some locations are reserved for ''special function registers''. Except for a single accumulator (called <code>W</code>), almost all other registers are memory-mapped, even registers like the [[program counter]] and ALU [[status register]]. (The other exceptions, which are not memory-mapped, are the return address stack, and the [[Three-state logic|tri-state]] registers used to configure the [[GPIO]] pins.)

Some arithmetic instructions only use one of their inputs, but still use a <code>d</code>bit. For example, <code>MOVW</code> copies the value of <code>W</code> to the destination. When used with <code>d</code> = 1, this stores <code>W</code> to <code>f</code>. There is a matching <code>MOVF</code> instruction which outputs the value of <code>f</code>. When used with <code>d</code> = 0, this loads <code>f</code> into <code>W</code>. When used with <code>d</code> = 1, the only visible effect is to set the [[zero flag]] depending on the value of <code>f</code>.


The instruction set does not contain conditional branch instructions. Instead, it contains conditional skip instructions which cause the following instruction to be ignored. A conditional skip followed by an unconditional branch performs a conditional branch. The skip instructions test any bit of any register. The ALU status register is one possibility.
The instruction set does not contain conditional branch instructions. Instead, it contains conditional skip instructions which cause the following instruction to be ignored. A conditional skip followed by an unconditional branch performs a conditional branch. The skip instructions test any bit of any register. The ALU status register is one possibility.
Line 16: Line 19:
* The ''indirect file'' register (<code>INDF</code>) becomes an [[Aliasing (computing)|alias]] for the operand [[pointer (computer programming)|pointed to]] by the FSR.
* The ''indirect file'' register (<code>INDF</code>) becomes an [[Aliasing (computing)|alias]] for the operand [[pointer (computer programming)|pointed to]] by the FSR.


This mechanism also allows up to 256 bytes of memory to be addressed, even when the instruction set only allows 5- or 7-bit memory operands. Models with more registers (special function registers plus RAM) than fit into the instruction provide multiple banks of memory, and use one of two mechanisms for accessing them:
This mechanism also allows up to 256 bytes of memory to be addressed, even when the instruction set only allows 5- or 7-bit absolute addresses. Models with more registers (special function registers plus RAM) than fit into the instruction provide multiple banks of memory, and use one of two mechanisms for accessing them:
# Most baseline core devices, and some mid-range core devices, use the high-order bits of the file select register to select the current register bank.
# Most baseline core devices, and some mid-range core devices, use the high-order bits of the file select register to select the current register bank.
# More recent models have a separate ''bank select register'', and a <code>MOVLB</code> instruction to set it.
# More recent models have a separate ''bank select register'', and a <code>MOVLB</code> instruction to set it.


PIC processors with more than 256 words of program use paged memory. The internal program counter and return stack are as wide as necessary to address all memory, but only the low 8 bits are visible to software in the <code>PCL</code> ("PC low") register. There is an additional <code>PCLATH</code> ("PC latch high") register which is only modified by software. Any operation which does not specify the full destination address (such as a 9-bit <code>GOTO</code> or an 8-bit write to the PC register) fills in the additional high bits from the corresponding part of PCLATH. (Some PIC18 processors extend this beyond 16 bits with a PCLATU register to supply bits 16–23.)
PIC processors with more than 256 words of program use paged memory. The internal program counter and return stack are as wide as necessary to address all memory, but only the low 8 bits are visible to software in the <code>PCL</code> ("PC low") register. There is an additional <code>PCLATH</code> ("PC latch high") register which is only modified by software. Any operation which does not specify the full destination address (such as a 9-bit <code>GOTO</code> or an 8-bit write to the PCL register) fills in the additional high bits from the corresponding part of PCLATH. (Some PIC18 processors extend this beyond 16 bits with a PCLATU register to supply bits 16–23.)


==Baseline core devices (12 bit)==
==Baseline core devices (12 bit)==

This is the original 1976 instruction set, introduced in the [[General Instrument]] PIC1640 and PIC1650,<ref>{{cite book
|title=Computer Structures: Principles and Examples
|editor-first1=Daniel P. |editor-last1=Siewiorek
|editor-first2=C. Gordon |editor-last2=Bell |editor-link2=Gordon Bell
|editor-first3=Allen |editor-last3=Newell
|isbn=0-07-057302-6
|year=1982 |publisher=McGraw-Hill
|chapter=Chapter 35 PIC1650: Chip Architecture and Operation
|first=Frank M. |last=Gruppuso
|url=http://archive.computerhistory.org/resources/text/bell_gordon/bell.computer_structures_principles_and_examples.1982.102630397.pdf
|chapter-url=https://gordonbell.azurewebsites.net/tcmwebpage/computertimeline/chap35_pic1650_cs2.pdf
|access-date=2024-08-18
}}</ref> with the only additions since then being the miscellaneous instructions other than NOP.


{|class="wikitable" style="text-align:center"
{|class="wikitable" style="text-align:center"
Line 32: Line 49:
! 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=5| ''opcode'' ||colspan=4| Miscellaneous instructions
! 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=5| ''opcode'' ||colspan=4| Miscellaneous instructions
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP || || ||align=left| No operation (MOVW 0,W)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP || || ||align=left| No operation
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||align=left| OPTION || || ||align=left| Copy W to OPTION register
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||align=left| OPTION || || ||align=left| Copy W to OPTION register
Line 52: Line 69:
! 0 || 0 ||colspan=4| ''opcode'' || ''d'' || colspan=5| ''register'' ||colspan=4| ALU operations: dest ← OP(f,W)
! 0 || 0 ||colspan=4| ''opcode'' || ''d'' || colspan=5| ''register'' ||colspan=4| ALU operations: dest ← OP(f,W)
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=5| ''f'' ||align=left| MOVWF ''f'' || || ||align=left| dest ← W
| 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=5| ''f'' ||align=left| MOVWF ''f'' || || ||align=left| f ← W
|-
|-
| 0 || 0 || 0 || 0 || 0 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| CLR ''f'',''d'' || || Z ||align=left| dest ← 0, usually written CLRW or CLRF ''f''
| 0 || 0 || 0 || 0 || 0 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| CLR ''f'',''d'' || || Z ||align=left| dest ← 0, usually written CLRW or CLRF ''f''
Line 60: Line 77:
| 0 || 0 || 0 || 0 || 1 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| DECF ''f'',''d'' || || Z ||align=left| dest ← f−1
| 0 || 0 || 0 || 0 || 1 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| DECF ''f'',''d'' || || Z ||align=left| dest ← f−1
|-
|-
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' ||colspan=5| ''f'' ||align=left| IORWF ''f'',''d'' || || Z ||align=left| dest ← f &#124; W, logical inclusive or
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' ||colspan=5| ''f'' ||align=left| IORWF ''f'',''d'' || || Z ||align=left| dest ← f {{pipe}} W, logical inclusive or
|-
|-
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| ANDWF ''f'',''d'' || || Z ||align=left| dest ← f & W, logical and
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| ANDWF ''f'',''d'' || || Z ||align=left| dest ← f & W, logical and
Line 76: Line 93:
| 0 || 0 || 1 || 0 || 1 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| DECFSZ ''f'',''d'' || || ||align=left| dest ← f−1, then skip if zero
| 0 || 0 || 1 || 0 || 1 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| DECFSZ ''f'',''d'' || || ||align=left| dest ← f−1, then skip if zero
|-
|-
| 0 || 0 || 1 || 1 || 0 || 0 || ''d'' ||colspan=5| ''f'' ||align=left| RRF ''f'',''d'' || C || ||align=left| dest ← CARRY<<7 &#124; f>>1, rotate right through carry
| 0 || 0 || 1 || 1 || 0 || 0 || ''d'' ||colspan=5| ''f'' ||align=left| RRF ''f'',''d'' || C || ||align=left| dest ← CARRY<<7 {{pipe}} f>>1, rotate right through carry
|-
|-
| 0 || 0 || 1 || 1 || 0 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| RLF ''f'',''d'' || C || ||align=left| dest ← F<<1 &#124; CARRY, rotate left through carry
| 0 || 0 || 1 || 1 || 0 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| RLF ''f'',''d'' || C || ||align=left| dest ← F<<1 {{pipe}} CARRY, rotate left through carry
|-
|-
| 0 || 0 || 1 || 1 || 1 || 0 || ''d'' ||colspan=5| ''f'' ||align=left| SWAPF ''f'',''d'' || || ||align=left| dest ← f<<4 &#124; f>>4, swap nibbles
| 0 || 0 || 1 || 1 || 1 || 0 || ''d'' ||colspan=5| ''f'' ||align=left| SWAPF ''f'',''d'' || || ||align=left| dest ← f<<4 {{pipe}} f>>4, swap nibbles
|-
|-
| 0 || 0 || 1 || 1 || 1 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| INCFSZ ''f'',''d'' || || ||align=left| dest ← f+1, then skip if zero
| 0 || 0 || 1 || 1 || 1 || 1 || ''d'' ||colspan=5| ''f'' ||align=left| INCFSZ ''f'',''d'' || || ||align=left| dest ← f+1, then skip if zero
Line 104: Line 121:
| 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| CALL ''k'' || || ||align=left| Call subroutine, 8-bit address k
| 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| CALL ''k'' || || ||align=left| Call subroutine, 8-bit address k
|-
|-
| 1 || 0 || 1 ||colspan=9| ''k'' ||align=left| GOTO ''k'' || || ||align=left| Jump to 9-bit address k<ref>{{Cite book
| 1 || 0 || 1 ||colspan=9| ''k'' ||align=left| GOTO ''k'' || || ||align=left| Jump to 9-bit address k<ref>{{Cite book
|publisher=Microchip Technology
|publisher=Microchip Technology
|year=2007
|year=2007
|url=http://ww1.microchip.com/downloads/en/DeviceDoc/41239D.pdf
|url=http://ww1.microchip.com/downloads/en/DeviceDoc/41239D.pdf
|title=PIC10F200/202/204/206 Data Sheet
|title=PIC10F200/202/204/206 Data Sheet
|page=52
|page=52
|access-date=2015-01-15
}}</ref>
|archive-url=https://web.archive.org/web/20150811030147/http://ww1.microchip.com/downloads/en/DeviceDoc/41239D.pdf
|archive-date=2015-08-11
|url-status=dead
}}</ref>
|-
|-
|colspan=16|
|colspan=16|
Line 118: Line 139:
| 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| MOVLW ''k'' || || ||align=left| W ← k
| 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| MOVLW ''k'' || || ||align=left| W ← k
|-
|-
| 1 || 1 || 0 || 1 ||colspan=8| ''k'' ||align=left| IORLW ''k'' || || Z ||align=left| W ← k &#124; W, bitwise logical or
| 1 || 1 || 0 || 1 ||colspan=8| ''k'' ||align=left| IORLW ''k'' || || Z ||align=left| W ← k {{pipe}} W, bitwise logical or
|-
|-
| 1 || 1 || 1 || 0 ||colspan=8| ''k'' ||align=left| ANDLW ''k'' || || Z ||align=left| W ← k & W, bitwise and
| 1 || 1 || 1 || 0 ||colspan=8| ''k'' ||align=left| ANDLW ''k'' || || Z ||align=left| W ← k & W, bitwise and
Line 130: Line 151:
<nowiki/>*: Extended instruction, not available on most 12-bit PICs. Of the models with extended RAM, most (e.g. 16C5x, 16F5x) extend the register address space using the high-order bits of the FSR. A few (e.g. PIC12F529T39A) have a separate bank select register which can be set with this instruction.<br/>
<nowiki/>*: Extended instruction, not available on most 12-bit PICs. Of the models with extended RAM, most (e.g. 16C5x, 16F5x) extend the register address space using the high-order bits of the FSR. A few (e.g. PIC12F529T39A) have a separate bank select register which can be set with this instruction.<br/>
†: Extended instruction, only available on "enhanced baseline" PICs. Only the very few models (16F527, 16F570, MCV20A) with interrupt support (and a 4-level stack) include these instructions. All such models also include MOVLB.
†: Extended instruction, only available on "enhanced baseline" PICs. Only the very few models (16F527, 16F570, MCV20A) with interrupt support (and a 4-level stack) include these instructions. All such models also include MOVLB.

==General Instrument PIC1670 (13 bit, obsolete)==
Introduced in 1979, this expanded PIC supported 64 bytes of register space (16 special function registers and 48 bytes of RAM), 1024 words of ROM, a 6-level hardware stack, and interrupt handling. The PIC1665 was a variant with external ROM used for developing firmware for the [[mask ROM]] 1670.

It added a signed overflow bit to the status register (bit 3). Status register bits 4 and 5 provided read-only access to the high 2 bits of the 10-bit program counter.

The instruction set is mostly the same as the 12-bit PIC with the address field enlarged. However, the 8-bit immediate instructions gain an additional opcode bit. Rather than adding an additional four instructions with an 8-bit immediate operand, the instruction set adds two instructions with 8-bit operands, two instructions with 7-bit operands (6-bit address plus direction bit), and four instructions with 6-bit operands (6-bit address):
* The 8-bit immediate group grows to 6 instructions by adding ADDLW and RETLW. The latter is moved out of the control transfer group, allowing a full 10-bit address in the CALL instruction.
* The ALU operations group gains add/subtract with carry (ADCWF, SUBBWF) instructions (7-bit operands).
* The CLRW instruction is deleted (it wastes a 6-bit memory address and duplicates MOVLW 0).
* Five new instructions with a 6-bit memory address operands are added. These do not have a destination select bit, and include three "compare and skip" instructions which do not write a result, and two "rotate without carry" instructions.

This instruction set is not used in any currently manufactured part and is of historical interest only.

{|class="wikitable" style="text-align:center"
|+ 13-bit PIC1670 instruction set (obsolete)<ref>{{cite tech report
|type=Data Sheet
|title=PIC1670 8-bit Microcomputer
|author=General Instrument
|url=http://www.t-es-t.hu/download/microchip/gi_pic1670.pdf
|access-date=2024-08-18
}}</ref>
! 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 ||<br/>8 ||<br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || C<br/>? || Z<br/>? || Description
|-
|colspan=17|
|-
! 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=6| ''opcode'' ||colspan=4| Miscellaneous instructions
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP || || ||align=left| No operation
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||align=left| HALT || || ||align=left| Halt processor (PIC1665 only)
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||align=left| RETFI || || ||align=left| Return from interrupt
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 ||align=left| RETFS || || ||align=left| Return from subroutine, W unmodified
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 ||align=left| DAW || || ||align=left| Decimal Adjust W
|-
|colspan=17|
|-
! 0 || 0 ||colspan=4| ''opcode'' || ''d'' ||colspan=6| ''register'' ||colspan=4| ALU operations same as 12- and 14-bit PIC except
|-
| 0 || 0 || 0 || 0 || 0 || 1 || ''d'' ||colspan=6| ''f'' ||align=left| SUBBWF&nbsp;''f'',''d'' || C || Z ||align=left| dest ← f−W−{{overline|C}} = f+~W+C (not {{s|CLR ''f'',''d''}})
|-
| 0 || 0 || 1 || 0 || 0 || 0 || ''d'' ||colspan=6| ''f'' ||align=left| ADCWF ''f'',''d'' || C || Z ||align=left| dest ← f+W+C (not {{s|MOVF ''f'',''d''}})
|-
|colspan=17|
|-
! 0 || 1 ||colspan=2| ''opc'' ||colspan=3| ''bit'' ||colspan=6| ''register'' ||colspan=4| Bit operations same as 12- and 14-bit PIC
|-
|colspan=17|
|-
! 1 || 0 || 0 || 0 ||colspan=3| ''opcode'' ||colspan=6| ''register'' ||colspan=4| Additional ALU operations, no choice of destination
|-
| 1 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=6| ''f'' ||align=left| MOVFW ''f'' || || Z ||align=left| W ← f (= MOVF ''f'',0)
|-
| 1 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=6| ''f'' ||align=left| CLRF ''f'' || || Z ||align=left| f ← 0 (for CLRW, use MOVLW 0)
|-
| 1 || 0 || 0 || 0 || 0 || 1 || 0 ||colspan=6| ''f'' ||align=left| RRNC ''f'' || || ||align=left| f ← f<<7 {{pipe}} f>>1, rotate right no carry
|-
| 1 || 0 || 0 || 0 || 0 || 1 || 1 ||colspan=6| ''f'' ||align=left| RLNC ''f'' || || ||align=left| f ← f<<1 {{pipe}} f>>7, rotate left no carry
|-
| 1 || 0 || 0 || 0 || 1 || 0 || 0 ||colspan=6| ''f'' ||align=left| CPFSLT ''f'' || || ||align=left| Compare and skip if f &lt; W (unsigned)
|-
| 1 || 0 || 0 || 0 || 1 || 0 || 1 ||colspan=6| ''f'' ||align=left| CPFSEQ ''f'' || || ||align=left| Compare and skip if f = W
|-
| 1 || 0 || 0 || 0 || 1 || 1 || 0 ||colspan=6| ''f'' ||align=left| CPFSGT ''f'' || || ||align=left| Compare and skip if f > W (unsigned)
|-
| 1 || 0 || 0 || 0 || 1 || 1 || 1 ||colspan=6| ''f'' ||align=left| TESTF ''f'' || || Z ||align=left| f ← f (= MOVF ''f'',1)
|-
|colspan=17|
|-
! 1 || 0 ||colspan=3| ''opcode'' ||colspan=8| ''8-bit immediate'' ||colspan=4| Operations with W and 8-bit literal: W ← OP(k,W)
|-
| 1 || 0 || 0 || 1 || 0 ||colspan=8| ''k'' ||align=left| MOVLW ''k'' || || ||align=left| W ← k
|-
| 1 || 0 || 0 || 1 || 1 ||colspan=8| ''k'' ||align=left| ADDLW ''k'' || C || Z ||align=left| W ← k+W
|-
| 1 || 0 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| IORLW ''k'' || || Z ||align=left| W ← k {{pipe}} W, bitwise logical or
|-
| 1 || 0 || 1 || 0 || 1 ||colspan=8| ''k'' ||align=left| ANDLW ''k'' || || Z ||align=left| W ← k & W, bitwise and
|-
| 1 || 0 || 1 || 1 || 0 ||colspan=8| ''k'' ||align=left| XORLW ''k'' || || Z ||align=left| W ← k ^ W, bitwise exclusive or
|-
| 1 || 0 || 1 || 1 || 1 ||colspan=8| ''k'' ||align=left| RETLW ''k'' || || ||align=left| W ← k, then return from subroutine
|-
|colspan=17|
|-
! 1 || 1 || ''c'' ||colspan=10| ''k'' ||colspan=4| Control transfers
|-
| 1 || 1 || 0 ||colspan=10| ''k'' ||align=left| GOTO ''k'' || || ||align=left| Jump to address k
|-
| 1 || 1 || 1 ||colspan=10| ''k'' ||align=left| CALL ''k'' || || ||align=left| Call subroutine
|-
|colspan=17|
|-
! 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || C<br/>? || Z<br/>? || Description
|}


==ELAN Microelectronics clones (13 bit)==
==ELAN Microelectronics clones (13 bit)==
[[List of common microcontrollers#ELAN Microelectronics Corp.|ELAN Microelectronics Corp.]] make a series of PICmicro-like microcontrollers with a 13-bit instruction word.<ref>http://www.emc.com.tw/eng/products.asp</ref> The instructions are mostly compatible with the mid-range 14-bit instruction set, but limited to a 6-bit register address (16 special-purpose registers and 48 bytes of RAM) and a 10-bit (1024 word) program space.
[[List of common microcontrollers#ELAN Microelectronics Corp.|ELAN Microelectronics Corp.]] make a series of PICmicro-like microcontrollers with a 13-bit instruction word.<ref>{{Cite web|url=http://www.emc.com.tw/eng/products.asp|title = 義隆電子股份有限公司義隆電子,再創未來!}}</ref> The instructions are mostly compatible with the mid-range 14-bit instruction set, but limited to a 6-bit register address (16 special-purpose registers and 48 bytes of RAM) and a 10-bit (1024 word) program space.


The 10-bit program counter is accessible as R2. Reads access only the low bits, and writes clear the high bits. An exception is the TBL instruction, which modifies the low byte while preserving bits 8 and 9.
The 10-bit program counter is accessible as R2. Reads access only the low bits, and writes clear the high bits. An exception is the TBL instruction, which modifies the low byte while preserving bits 8 and 9.
Line 141: Line 260:


{|class="wikitable" style="text-align:center"
{|class="wikitable" style="text-align:center"
|+ 13-bit EM78 instruction set<ref>{{Citation |url=http://www.emc.com.tw/eng/database/Data_Sheet/8BIT/EM78P157N.pdf |title=EM78P157N 8-bit microcontroller with OTP ROM Product Specification |date=September 2005 |author=ELAN Microelectronics Corp. |accessdate=2012-04-02}}</ref><ref name=EM78P143>{{Citation |url=http://www.emc.com.tw/chs/database/Data_Sheet/8BIT/EM78P143.pdf#page=83 |title=EM78P143 8-bit microprocessor with OTP ROM Product Specification |date=April 2016 |author=ELAN Microelectronics Corp. |accessdate=2019-07-11 |page=77}}</ref>
|+ 13-bit EM78 instruction set<ref>{{Citation |url=http://www.emc.com.tw/upload/2019_01_15(0_0)b2/EM78P157N.pdf#page=36 |title=EM78P157N 8-bit microcontroller with OTP ROM Product Specification |version=version 1.3 |date=26 April 2016 |author=ELAN Microelectronics Corp. |access-date=2020-06-06 |archive-url=https://web.archive.org/web/20160304054645/http://www.emc.com.tw/eng/database/Data_Sheet/8BIT/EM78P157N.pdf#page=36 |archive-date=2016-03-04 |url-status=live}}</ref><ref name=EM78P143>{{Citation |url=http://www.emc.com.tw/upload/2019_01_15(0_0)b2/EM78P143.pdf#page=83 |title=EM78P143 8-bit microprocessor with OTP ROM Product Specification |version=version 1.7 |date=25 April 2016 |author=ELAN Microelectronics Corp. |access-date=2020-06-06 |page=77}}</ref>
! 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || C<br/>? || Z<br/>? || Description
! 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || C<br/>? || Z<br/>? || Description
|-
|-
Line 148: Line 267:
! 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=6| ''opcode'' ||colspan=4| Miscellaneous instructions
! 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=6| ''opcode'' ||colspan=4| Miscellaneous instructions
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP<sup>*</sup> || || ||align=left| No operation (MOVW 0,W)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP<sup>*</sup> || || ||align=left| No operation
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||align=left| DAA<sup>†</sup> || C || ||align=left| [[Intel BCD opcode#Adding|Decimal Adjust after Addition]]
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||align=left| DAA<sup>†</sup> || C || ||align=left| [[Intel BCD opcodes#Adding|Decimal Adjust after Addition]]
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||align=left| CONTW<sup>*</sup> || || ||align=left| Write CONT register (CONT ← W)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||align=left| CONTW<sup>*</sup> || || ||align=left| Write CONT register (CONT ← W)
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 ||align=left| SLEEP<sup>*</sup> || || ||align=left| Go into standby mode (WDT ← 0, stop clock)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 ||align=left| SLEP<sup>*</sup> || || ||align=left| Go into standby mode (WDT ← 0, stop clock)
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 ||align=left| CLRWDT<sup>*</sup> || || ||align=left| Restart watchdog timer (WDT ← 0)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 ||align=left| WDTC<sup>*</sup> || || ||align=left| Restart watchdog timer (WDT ← 0)
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=4| ''f'' ||align=left| IOW ''f''<sup>*</sup> || || ||align=left| Copy W to I/O control register (''f'' = 5–7, 11–15)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=4| ''f'' ||align=left| IOW ''f''{{prime||f|c=<sup></sup>}} || || ||align=left| Copy W to I/O control register (''f'' = 5–7, 11–15)
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 || 0 ||align=left| ENI<sup>†</sup> || || ||align=left| Enable interrupts
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 || 0 ||align=left| ENI<sup>†</sup> || || ||align=left| Enable interrupts
Line 170: Line 289:
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 || 0 || 0 ||align=left| CONTR<sup>†</sup> || || ||align=left| Read CONT register (W ← CONT)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 || 0 || 0 ||align=left| CONTR<sup>†</sup> || || ||align=left| Read CONT register (W ← CONT)
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=4| ''f'' ||align=left| IOR ''f''<sup>†</sup> || || ||align=left| Copy I/O control register to W (''f'' = 5–7, 11–15)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=4| ''f'' ||align=left| IOR ''f''{{prime||f|c=<sup>†</sup>}} || || ||align=left| Copy I/O control register to W (''f'' = 5–7, 11–15)
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 || 0 || 0 ||align=left| TBL<sup>†</sup> || C || Z ||align=left| PCL += W, preserve PC bits 8 & 9
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 || 0 || 0 ||align=left| TBL<sup>†</sup> || C || Z ||align=left| PCL += W, preserve PC bits 8 & 9
Line 187: Line 306:
|-
|-
| 1 || 1 || 0 ||colspan=2| ''op'' ||colspan=8| ''k'' ||colspan=4| MOV/IOR/AND/XOR, same as 12-bit PIC
| 1 || 1 || 0 ||colspan=2| ''op'' ||colspan=8| ''k'' ||colspan=4| MOV/IOR/AND/XOR, same as 12-bit PIC

|-
|-
| 1 || 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| RETLW ''k'' || || ||align=left| W ← k, then return from subroutine
| 1 || 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| RETLW ''k'' || || ||align=left| W ← k, then return from subroutine
Line 199: Line 317:
|colspan=17|
|colspan=17|
|-
|-
! 1 || 1 || 1 || 1 || 0 || 1 ||colspan=3| ''opcode'' ||colspan=4| ''k'' ||colspan=4| Extensions (replacing INT ''k'' for ''k''≥128 on later models){{r|EM78P143}}<ref>{{Citation |url=http://www.emc.com.tw/Twn/database/Data_Sheet/8BIT/EM78P346N.pdf#page=85 |title=EM78P346N 8-bit microprocessor with OTP ROM Product Specification |version=version 1.5 |date=April 2016 |author=ELAN Microelectronics Corp. |accessdate=2019-07-11 |page=77}}</ref><ref>{{Citation |url=http://www.emc.com.tw/twn/database/Data_Sheet/COM/EM78860.pdf#page=17 |title=EM78860 8-bit Micro-controller |date=17 April 2000 |author=ELAN Microelectronics Corp. |accessdate=2019-07-11 |page=17}}</ref>
! 1 || 1 || 1 || 1 || 0 || 1 ||colspan=3| ''opcode'' ||colspan=4| ''k'' ||colspan=4| Extensions (replacing INT ''k'' for ''k''≥128 on later models){{r|EM78P143}}<ref>{{Citation |url=http://www.emc.com.tw/Twn/database/Data_Sheet/8BIT/EM78P346N.pdf#page=85 |title=EM78P346N 8-bit microprocessor with OTP ROM Product Specification |version=version 1.5 |date=April 2016 |author=ELAN Microelectronics Corp. |access-date=2019-07-11 |page=77}}</ref><ref>{{Citation |url=http://www.emc.com.tw/twn/database/Data_Sheet/COM/EM78860.pdf#page=17 |title=EM78860 8-bit Micro-controller |date=17 April 2000 |author=ELAN Microelectronics Corp. |access-date=2019-07-11 |page=17}}</ref>
|-
|-
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 0 || 0 ||colspan=4| ''k'' ||align=left| PAGE ''k'' || || ||align=left| Select ROM page ''k'' (like MOVLP ''k'')
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 0 || 0 ||colspan=4| ''k'' ||align=left| PAGE ''k'' || || ||align=left| Select ROM page ''k'' (like MOVLP ''k'')
Line 209: Line 327:
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 1 || 1 ||colspan=4| ''k'' ||align=left| LJMP ''k''<sup>†</sup> || || ||align=left| Long jump with 17-bit address (2-word instruction)
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 1 || 1 ||colspan=4| ''k'' ||align=left| LJMP ''k''<sup>†</sup> || || ||align=left| Long jump with 17-bit address (2-word instruction)
|-
|-
| 1 || 1 || 1 || 1 || 0 || 1 || 1 ||colspan=6| ''register'' ||align=left| TBRD ''reg''<sup>†</sup> || || ||align=left| Read ROM at TBHP:TBLP into specified register
| 1 || 1 || 1 || 1 || 0 || 1 || 1 ||colspan=6| ''f'' ||align=left| TBRD ''f''{{prime||f|c=<sup>†</sup>}} || || ||align=left| Read ROM at TBHP:TBLP into specified register
|-
|-
|colspan=17|
|colspan=17|
Line 220: Line 338:
Some models support multiple ROM or RAM banks, in a manner similar to other PIC microcontrollers.
Some models support multiple ROM or RAM banks, in a manner similar to other PIC microcontrollers.


There is also a 15-bit variant of the instruction set, which is almost identical except that the register numbers are enlarged to 8 bits and the call and jump addresses are enlarged to 12 bits. Other differences:<ref>{{Citation |url=http://www.emc.com.tw/twn/database/Data_Sheet/8BIT/EM78F641N.pdf#page=174 |title=EM78F648/644/642/641N/548/544/542/541N Flash Series 8-Bit Microcontroller Product Specification |version=version 1.2 |date=15 March 2013 |author=ELAN Microelectronics Corp. |accessdate=2019-07-11 |pages=162–165}}</ref>
There is also a 15-bit variant of the instruction set, which is almost identical except that the register numbers are enlarged to 8 bits and the call and jump addresses are enlarged to 12 bits. Other differences:<ref>{{Citation |url=http://www.emc.com.tw/twn/database/Data_Sheet/8BIT/EM78F641N.pdf#page=174 |title=EM78F648/644/642/641N/548/544/542/541N Flash Series 8-Bit Microcontroller Product Specification |version=version 1.2 |date=15 March 2013 |author=ELAN Microelectronics Corp. |access-date=2019-07-11 |pages=162–165}}</ref>
* The CONTW, IOW, CONTR, IOR and INT instructions are deleted,
* The CONTW, IOW, CONTR, IOR and INT instructions are deleted,
* Operations with an 8-bit literal have two 0 bits added as bits 8 and 9,
* Operations with an 8-bit literal have two 0 bits added as bits 8 and 9,
* Extensions with a 4-bit literal have two 0 bits added as bits 4 and 5, and
* Extensions with a 4-bit literal have two 0 bits added as bits 4 and 5, and
* The PAGE and BANK instructions are renamed SBANK and GBANK and perform bank switching on special function registers and general-purpose RAM, respectively.
* The PAGE and BANK instructions are renamed SBANK and GBANK and perform bank switching on special function registers and general-purpose RAM, respectively.

<!--TODO: Extended 15-bit instruction set as described in http://www.emc.com.tw/eng/database/Data_Sheet/8BIT/EM88F758N.pdf Additions:
A second generation 15-bit instruction set includes several additional instructions:
* RESET: Software reset
{|class="wikitable" style="text-align:center"
* TBWR: flash write
|+ 15-bit EM78/EM88 instruction set extensions<ref>Derived from instruction encoding tables in Elan [http://www.emc.com.tw/eng/database/Sa2/Gp/Dt/eUIDEII_v2.19.60.14.rar eUIDE II v2.19.60.14], released 2019-05-01, accessed 2019-07-13. Specifically the <code>Bin/*.cfg</code> files.</ref><ref>{{Citation |url=http://www.emc.com.tw/eng/database/Sa2/Gp/PG/EM78xxx15-bit%20Instruction%20Set%20_20140114_.pdf |title=EM78XXX 15-Bit Instruction Set |date=2014-01-14 |author=ELAN Microelectronics Corp. |access-date=2019-07-13}}</ref>
* BTG r,b: bit toggle
! 1<br/>4 || 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || C<br/>? || Z<br/>? || Description
* JE r, JGE r, JLE r: compare r with accumulator & skip
|-
* TBRDA r: Read ROM into r (low byte) and accumulator (high 7 bits)
|colspan=19|
* SJC k, SJNC k, SJZ k, SJNZ k: 8-bit relative jump on C or Z flag
|-
* XCH r: Exchange r and accumulator
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=7| ''opcode'' ||colspan=4| Miscellaneous instructions
* NEG r: Negate (complement & add 1)
|-
* ADC r, SUBB r: Add and subtract with carry
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP<sup>*</sup> || || ||align=left| No operation
* RR r, RL r: Rotate without carry
-->
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||align=left| DAA<sup>*</sup> || C || ||align=left| [[Intel BCD opcodes#Adding|Decimal Adjust after Addition]]
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 ||align=left| SLEP<sup>*</sup> || || ||align=left| Go into standby mode (WDT ← 0, stop clock)
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 ||align=left| WDTC<sup>*</sup> || || ||align=left| Restart watchdog timer (WDT ← 0)
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 ||align=left| MULW<sup>†</sup> || || ||align=left| 8×8 → 16-bit multiply
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 ||align=left| DIVW<sup>†</sup> || || ||align=left| 8÷8 → 8,8-bit divide
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 || 0 ||align=left| ENI<sup>*</sup> || || ||align=left| Enable interrupts
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 || 1 ||align=left| DISI<sup>*</sup> || || ||align=left| Disable interrupts
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 1 || 0 ||align=left| RET<sup>*</sup> || || ||align=left| Return from subroutine, W unmodified
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 1 || 1 ||align=left| RETI<sup>*</sup> || || ||align=left| Return from interrupt; return & enable interrupts
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 || 1 || 0 ||align=left| RESET || || ||align=left| Software reset
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 || 1 || 1 ||align=left| TBWR || || ||align=left| Flash ROM write
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=6| ''k'' ||align=left| INT ''k'' || || ||align=left| Software interrupt at address 2×k
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=3| ''bit'' ||colspan=4| ''f'' ||align=left| BTG ''f'',''b'' || || ||align=left| Invert (toggle) bit b of f (limited address range)
|-
|colspan=19|
|-
! 0 || 0 ||colspan=4| ''opcode'' || ''d'' ||colspan=8| ''register'' ||colspan=4| ALU operations same as EM78 and PIC
|-
! 0 || 1 ||colspan=2| ''opc'' ||colspan=3| ''bit'' ||colspan=8| ''register'' ||colspan=4| Bit operations same as EM78 and PIC
|-
! 1 || 0 || ''c'' ||colspan=12| ''k'' ||colspan=4| Control transfers same as EM78 and 14-bit PIC
|-
|colspan=19|
|-
! 1 || 1 ||colspan=3| ''opcode'' || 0 || 0 ||colspan=8| ''8-bit immediate'' ||colspan=4| Operations with 8-bit literal same as EM78 (except INT)
|-
! 1 || 1 ||colspan=5| ''opcode'' ||colspan=8| ''register or immediate'' ||colspan=4| Instruction set extensions
|-
| 1 || 1 || 0 || 0 || 0 || 0 || 1 ||colspan=8| ''f'' ||align=left| JE ''r'' || || ||align=left| Skip if W = f
|-
| 1 || 1 || 0 || 0 || 0 || 1 || 0 ||colspan=8| ''f'' ||align=left| JGE ''r'' || || ||align=left| Skip if W > f
|-
| 1 || 1 || 0 || 0 || 0 || 1 || 1 ||colspan=8| ''f'' ||align=left| JLE ''r'' || || ||align=left| Skip if W < f
|-
| 1 || 1 || 0 || 0 || 1 || 0 || 1 ||colspan=8| ''k'' ||align=left| JE ''k'' || || ||align=left| Skip if W = k
|-bgcolor=lightgrey
| 1 || 1 || 0 || 0 || 1 || 1 || 0 ||colspan=8| ''k'' ||align=left colspan=4| ''(reserved)''
|-
| 1 || 1 || 0 || 0 || 1 || 1 || 1 ||colspan=8| ''f'' ||align=left| TBRDA ''f'' || || ||align=left| Read ROM at TBHP:TBLP into f; msbits into W
|-
| 1 || 1 || 0 || 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| SJC ''address'' || || ||align=left| Jump to PC + sext(''k'') if carry set
|-
| 1 || 1 || 0 || 1 || 0 || 1 || 0 ||colspan=8| ''k'' ||align=left| SJNC ''address'' || || ||align=left| Jump to PC + sext(''k'') if carry clear
|-
| 1 || 1 || 0 || 1 || 0 || 1 || 1 ||colspan=8| ''k'' ||align=left| SJZ ''address'' || || ||align=left| Jump to PC + sext(''k'') if zero flag set
|-
| 1 || 1 || 0 || 1 || 1 || 0 || 1 ||colspan=8| ''k'' ||align=left| SJNZ ''address'' || || ||align=left| Jump to PC + sext(''k'') if zero flag clear
|-
| 1 || 1 || 0 || 1 || 1 || 1 || ''d'' ||colspan=8| ''f'' ||align=left| RR ''f''/RRA || || ||align=left| dest ← f<<7 | f>>1, rotate right without carry
|-
| 1 || 1 || 1 || 0 || 0 || 0 || 1 ||colspan=8| ''f'' ||align=left| XCH ''f'' || || ||align=left| Exchange f ↔ W
|-
| 1 || 1 || 1 || 0 || 0 || 1 || ''d'' ||colspan=8| ''f'' ||align=left| RL ''f''/RLA || || ||align=left| dest ← f<<1 | f>>7, rotate left without carry
|-
| 1 || 1 || 1 || 0 || 1 || 0 || 1 ||colspan=8| ''f'' ||align=left| MUL ''f''{{prime||f|c=<sup>‡</sup>}} || || ||align=left| PRODH:PRODL ← f × W
|-bgcolor=lightgrey
| 1 || 1 || 1 || 0 || 1 || 1 || ''x'' ||colspan=8| ''k'' ||colspan=4 align=left| ''(reserved)''
|-
| 1 || 1 || 1 || 1 || 0 || 0 || ''d'' ||colspan=8| ''f'' ||align=left| SUBB || C || Z ||align=left| dest ← f + ~W + C, subtract with carry
|-
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 0 || 0 || 0 || 0 ||colspan=4| ''k'' ||align=left| SBANK ''k''<sup>*</sup> || || ||align=left| Select special function register bank ''k''
|-
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 0 || 1 || 0 || 0 ||colspan=4| ''k'' ||align=left| GBANK ''k''<sup>*</sup> || || ||align=left| Select RAM bank ''k''
|-
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 1 || 0 || 0 || 0 ||colspan=4| ''k'' ||align=left| LCALL ''k''<sup>*</sup> || || ||align=left| Long call with 19-bit address (2-word instruction)
|-
| 1 || 1 || 1 || 1 || 0 || 1 || 0 || 1 || 1 || 0 || 0 ||colspan=4| ''k'' ||align=left| LJMP ''k''<sup>*</sup> || || ||align=left| Long jump with 19-bit address (2-word instruction)
|-
| 1 || 1 || 1 || 1 || 0 || 1 || 1 ||colspan=8| ''f'' ||align=left| TBRD ''f''{{prime||f|c=<sup>*</sup>}} || || ||align=left| Read ROM at TBHP:TBLP into f
|-
| 1 || 1 || 1 || 1 || 1 || 0 || 1 ||colspan=8| ''f'' ||align=left| NEG ''f'' || C || Z ||align=left| f ← −f (f ← ~f + 1), negate
|-
| 1 || 1 || 1 || 1 || 1 || 1 || ''d'' ||colspan=8| ''f'' ||align=left| ADC ''f'' || C || Z ||align=left| dest ← f + W + C, add with carry
|-
|}
<nowiki/>*: Same opcode as 13-bit EM78<br/>
†: Only on EM89F768N; operands and results in special registers<br/>
‡: Only on EM88F794N, MTF213 and MTF351


==Mid-range core devices (14 bit)==
==Mid-range core devices (14 bit)==
Line 249: Line 457:
! 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=7| ''opcode'' ||colspan=4| Miscellaneous instructions
! 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=7| ''opcode'' ||colspan=4| Miscellaneous instructions
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP || || ||align=left| No operation (MOVW 0,W)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP || || ||align=left| No operation
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 ||align=left| RETURN || || ||align=left| Return from subroutine, W unmodified
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 ||align=left| RETURN || || ||align=left| Return from subroutine, W unmodified
Line 275: Line 483:
| 0 || 0 || 0 || 0 || 1 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| DECF ''f'',''d'' || || Z ||align=left| dest ← f−1
| 0 || 0 || 0 || 0 || 1 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| DECF ''f'',''d'' || || Z ||align=left| dest ← f−1
|-
|-
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' ||colspan=7| ''f'' ||align=left| IORWF ''f'',''d'' || || Z ||align=left| dest ← f &#124; W, logical inclusive or
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' ||colspan=7| ''f'' ||align=left| IORWF ''f'',''d'' || || Z ||align=left| dest ← f {{pipe}} W, logical inclusive or
|-
|-
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| ANDWF ''f'',''d'' || || Z ||align=left| dest ← f & W, logical and
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| ANDWF ''f'',''d'' || || Z ||align=left| dest ← f & W, logical and
Line 291: Line 499:
| 0 || 0 || 1 || 0 || 1 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| DECFSZ ''f'',''d'' || || ||align=left| dest ← f−1, then skip if zero
| 0 || 0 || 1 || 0 || 1 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| DECFSZ ''f'',''d'' || || ||align=left| dest ← f−1, then skip if zero
|-
|-
| 0 || 0 || 1 || 1 || 0 || 0 || ''d'' ||colspan=7| ''f'' ||align=left| RRF ''f'',''d'' || C || ||align=left| dest ← CARRY<<7 &#124; f>>1, rotate right through carry
| 0 || 0 || 1 || 1 || 0 || 0 || ''d'' ||colspan=7| ''f'' ||align=left| RRF ''f'',''d'' || C || ||align=left| dest ← CARRY<<7 {{pipe}} f>>1, rotate right through carry
|-
|-
| 0 || 0 || 1 || 1 || 0 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| RLF ''f'',''d'' || C || ||align=left| dest ← f<<1 &#124; CARRY, rotate left through carry
| 0 || 0 || 1 || 1 || 0 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| RLF ''f'',''d'' || C || ||align=left| dest ← f<<1 {{pipe}} CARRY, rotate left through carry
|-
|-
| 0 || 0 || 1 || 1 || 1 || 0 || ''d'' ||colspan=7| ''f'' ||align=left| SWAPF ''f'',''d'' || || ||align=left| dest ← f<<4 &#124; f>>4, swap nibbles
| 0 || 0 || 1 || 1 || 1 || 0 || ''d'' ||colspan=7| ''f'' ||align=left| SWAPF ''f'',''d'' || || ||align=left| dest ← f<<4 {{pipe}} f>>4, swap nibbles
|-
|-
| 0 || 0 || 1 || 1 || 1 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| INCFSZ ''f'',''d'' || || ||align=left| dest ← f+1, then skip if zero
| 0 || 0 || 1 || 1 || 1 || 1 || ''d'' ||colspan=7| ''f'' ||align=left| INCFSZ ''f'',''d'' || || ||align=left| dest ← f+1, then skip if zero
Line 327: Line 535:
| 1 || 1 || 0 || 1 || style="background:lightgrey;"| ''x'' || style="background:lightgrey;"| ''x'' ||colspan=8| ''k'' ||align=left| RETLW ''k'' || || ||align=left| W ← k, then return from subroutine
| 1 || 1 || 0 || 1 || style="background:lightgrey;"| ''x'' || style="background:lightgrey;"| ''x'' ||colspan=8| ''k'' ||align=left| RETLW ''k'' || || ||align=left| W ← k, then return from subroutine
|-
|-
| 1 || 1 || 1 || 0 || 0 || 0 ||colspan=8| ''k'' ||align=left| IORLW ''k'' || || Z ||align=left| W ← k &#124; W, bitwise logical or
| 1 || 1 || 1 || 0 || 0 || 0 ||colspan=8| ''k'' ||align=left| IORLW ''k'' || || Z ||align=left| W ← k {{pipe}} W, bitwise logical or
|-
|-
| 1 || 1 || 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| ANDLW ''k'' || || Z ||align=left| W ← k & W, bitwise and
| 1 || 1 || 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| ANDLW ''k'' || || Z ||align=left| W ← k & W, bitwise and
Line 405: Line 613:
|}
|}


==Holtek clones (14 or 16 bit)==
==Holtek clones (14, 15 or 16 bit)==
[[Holtek]] make numerous 8-bit microcontrollers with a 14-bit instruction word equivalent to the (non-enhanced) mid-range core. The instruction encodings all fit into 14 bits and provide 7-bit operand addresses, but models with 4K or 8K words of program ROM provide 15- or 16-bit wide ROM and extend the basic 11-bit destination address using bits 14–15 of the instruction as bits 11–12 of the address. Some models extend the 7-bit RAM addresses by using bit 14 of the instruction as bit 7 of the operand address.
[[Holtek]] make numerous 8-bit microcontrollers with a 14-bit instruction word equivalent to the (non-enhanced) mid-range core. The instruction encodings all fit into 14 bits and provide 7-bit operand addresses.


The instruction format is identical to Microchip's, but the opcodes are assigned in a different order, and the manufacturer uses different instruction mnemonics. The accumulator is called ACC rather than W, and the destination is specified by a suffix to the instruction mnemonic rather than an operand.
The instruction format is identical to Microchip's, but the opcodes are assigned in a different order, and the manufacturer uses different instruction mnemonics. The accumulator is called ACC rather than W, and the destination is specified by a suffix to the instruction mnemonic rather than an operand. (Instructions which do not use the accumulator by default write back to memory, and use an A suffix to indicate the destination is the accumulator. Two-operand instructions by default write to the accumulator, and use an M suffix to indicate a memory destination.)


In addition to the opcode assignment, there are semantic differences in a few instructions:
In addition to the different opcode assignment, there are semantic differences in a few instructions:
* The subtract instructions subtract the operand from the accumulator, while Microchip's subtract instructions do the reverse. (This makes the subtract immediate instruction redundant, as it is equivalent to an add of the negative.)
* The subtract instructions subtract the operand from the accumulator, while Microchip's subtract instructions do the reverse. (This makes the subtract immediate instruction redundant, as it is equivalent to an add of the negative.)
* The move-to-accumulator and clear instructions do not modify any flags.
* The move-to-accumulator and clear instructions do not modify any flags.
* In addition to the zero, carry, and [[Half-carry flag|digit carry]] flags (called AC by Holtek), there an [[overflow flag]] which is set by the same add and subtract instructions which set AC.


Several operations have been added to the 14-bit PICmicro repertoire:
Several operations have been added to the 14-bit PICmicro repertoire:
Line 418: Line 627:
* Set operand to all-ones,
* Set operand to all-ones,
* Skip if operand is zero (without incrementing or decrementing it first),
* Skip if operand is zero (without incrementing or decrementing it first),
* Skip if operand is non-zero (some models),
* Add and subtract with carry,
* Add and subtract with carry,
* Decimal adjust after addition, for [[binary coded decimal]] arithmetic, and
* Decimal adjust after addition, for [[binary-coded decimal]] arithmetic, and
* Read from program ROM, for table lookup. This uses TBHP and TBLP registers as a 16-bit pointer, fetches the word there, and stores the low byte in a specified location. The high 6–8 bits of the fetched word are stored in the TBLH register. A second form uses only TBLP and reads from the highest 256-byte page in ROM.
* Read from program ROM, for table lookup. This uses TBHP and TBLP registers as a 16-bit pointer, fetches the word there, and stores the low byte in a specified location. The high 6–8 bits of the fetched word are stored in the TBLH register. A second form uses only TBLP and reads from the highest 256-byte page in ROM. Some models include a variant which pre-increments TBLP.
* Most models<!--Only the HT82K69E, HT82K70A, HT82K70E and HT82M98 do not--> support a second instruction to reset the watchdog timer, which must alternate with the first; repetitions of one instruction are ignored. This permits two independent watchdog routines to run, and failure of either will trigger the watchdog.
* Most models<!--Only the HT82K69E, HT82K70A, HT82K70E and HT82M98 do not--> support a second instruction to reset the watchdog timer, which must alternate with the first; repetitions of one instruction are ignored. This permits two independent watchdog routines to run, and failure of either will trigger the watchdog.
* Holtek provide two indirect addressing registers, like the enhanced 14-bit PIC. Some models (e.g. HT66F70A) provide three. The first indirect addressing register (IAR0) uses an 8-bit address register (MP0), and always addresses the low bank of RAM. IAR1 and IAR2 provide additional RAM address bits (MP1H and MP2H) and allow access to additional banks of RAM.<ref name=an0407e>{{Citation |url=https://www.holtek.com.tw/webapi/116745/an0407e.pdf |title=HT8 MCU Extended Instruction Set Applications |type=Application Note |id=AN0407E |date=11 December 2016 |author=Holtek Semiconductor Inc. |access-date=2024-02-09}}</ref>
* Holtek provide two indirect addressing registers, like the enhanced 14-bit PIC. Some models (e.g HT66F70A) provide three.

15-bit models use bit 14 of the instruction as an 8th operand address bit and a 12th CALL/JMP target address bit. 16-bit models add a 13th CALL/JMP target address bit, but do not add a 9th operand addresses bit.<ref>{{Citation |url=https://buybestelectronic.com/part-image/7300/datasheet/7300.pdf#page=32 |title=2.4GHz 8-Bit Flash RF TX/RX MCU BC66F840/BC66F850/BC66F860 |type=Data sheet |version=version 1.60 |page=32 |date=26 November 2019 |author=Holtek Semiconductor Inc. |access-date=2024-02-09 |postscript=.}} Note that operand addresses only go to 0xFF, with additional RAM addressed by banking.</ref>

Instead, some 16-bit models support an extended instruction set. This adds a few new instructions (skip on byte without inc/decrement, subtract immediate with carry, ROM read with address increment), but also adds 2-word "long" variants of all memory instructions. When bit 15 of the opcode is set, it indicates that the 8-bit operand address in opcode bits 0–6 and 14 is extended to 16 bits using bits 0–7 of the following instruction word. Such instructions are written with an L prefix (LADD vs. ADD) and take an extra cycle to execute.<ref name=an0407e/>


{|class="wikitable" style="text-align:center"
{|class="wikitable" style="text-align:center"
|+ 14-bit Holtek instruction set<ref>{{cite web |title=Mouse Adventures #3: Writing a Disassembler |first=Ash "Ninji" |last=Wolf |date=12 December 2018 |access-date=8 July 2019 |url=https://wuffs.org/blog/mouse-adventures-part-3}}</ref>
|+ 14-bit Holtek instruction set<ref>{{cite web |title=Mouse Adventures #3: Writing a Disassembler |first=Ash "Ninji" |last=Wolf |date=12 December 2018 |access-date=8 July 2019 |url=https://wuffs.org/blog/mouse-adventures-part-3}}</ref>
! 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 ||<br/>8 ||<br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC equiv. || C<br/>? || Z<br/>? || Description
! 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 ||<br/>8 ||<br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC<br/>equivalent || C<br/>? || Z<br/>? || Description
|-
|-
|colspan=19|
|colspan=19|
Line 432: Line 646:
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=3| ''opcode'' ||colspan=5| Miscellaneous instructions
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=3| ''opcode'' ||colspan=5| Miscellaneous instructions
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP ||align=left| NOP || || ||align=left| No operation (MOV A,A)
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP ||align=left| NOP || || ||align=left| No operation
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||align=left| CLR WDT1 ||align=left| CLRWDT || || ||align=left| Restart watchdog timer
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||align=left| CLR WDT1 ||align=left| CLRWDT || || ||align=left| Restart watchdog timer
Line 442: Line 656:
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 ||align=left| RETI ||align=left| RETFIE || || ||align=left| Return from interrupt
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 ||align=left| RETI ||align=left| RETFIE || || ||align=left| Return from interrupt
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 ||align=left| CLR WDT2 ||bgcolor=lightgrey| || || ||align=left| Restart watchdog timer
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 ||align=left| CLR WDT2 ||bgcolor=lightgrey align=left| ≈CLRWDT || || ||align=left| Restart watchdog timer
|- style="background:lightgrey;"
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || ''x'' || style="text-align:left;" colspan="5"| ''(reserved)''
|- style="background:lightgrey;"
| 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=4| ≠0 || ''x'' || ''x'' || ''x'' || style="text-align:left;" colspan="5"| ''(reserved)''
|-
|-
|colspan=19|
|colspan=19|
|-
|-
! 0 || 0 ||colspan=4| ''opcode'' || ''d'' ||colspan=7| ''address'' ||colspan=5| ALU operations: dest ← OP(ACC,[m])
! 0 || 0 || 0 ||colspan=3| ''opcode'' || ''d'' ||colspan=7| ''address'' ||colspan=5| ALU operations part 1: dest ← OP(ACC,[m])<sup>*</sup>
|-
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=7| ''m'' ||align=left| MOV [''m''],A ||align=left| MOVWF ''m'' || || ||align=left| [m] ← ACC
| 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=7| ''m'' ||align=left| MOV [''m''],A ||align=left| MOVWF ''m'' || || ||align=left| [m] ← ACC
Line 452: Line 670:
| 0 || 0 || 0 || 0 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| CPLA/CPL [''m''] ||align=left| COMF ''m'',''d'' || || Z ||align=left| dest ← ~[m], bitwise complement
| 0 || 0 || 0 || 0 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| CPLA/CPL [''m''] ||align=left| COMF ''m'',''d'' || || Z ||align=left| dest ← ~[m], bitwise complement
|-
|-
| 0 || 0 || 0 || 0 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| SUB/SUBM A,[''m''] ||bgcolor=lightgrey align=left| ≠SUBWF ''m'',''d'' || C || Z ||align=left| dest ← ACC − [m] (dest ← ACC+~[m]+1)
| 0 || 0 || 0 || 0 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| {{nobr|SUB/SUBM A,[''m'']}} ||bgcolor=lightgrey align=left| ≠SUBWF ''m'',''d'' || C || Z ||align=left| dest ← ACC − [m] (dest ← ACC+~[m]+1)
|-
|-
| 0 || 0 || 0 || 0 || 1 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| ADD/ADDM A,[''m''] ||align=left| ADDWF ''m'',''d'' || C || Z ||align=left| dest ← ACC + [m]
| 0 || 0 || 0 || 0 || 1 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| ADD/ADDM A,[''m''] ||align=left| ADDWF ''m'',''d'' || C || Z ||align=left| dest ← ACC + [m]
|-
|-
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| XORA/XOR [''m''] ||align=left| XORWF ''m'',''d'' || || Z ||align=left| dest ← ACC ^ [m], logical exclusive or
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| XOR/XORM [''m''] ||align=left| XORWF ''m'',''d'' || || Z ||align=left| dest ← ACC ^ [m], logical exclusive or
|-
|-
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| ORA/OR [''m''] ||align=left| IORWF ''m'',''d'' || || Z ||align=left| dest ← ACC {{!}} [m], logical inclusive or
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| OR/ORM [''m''] ||align=left| IORWF ''m'',''d'' || || Z ||align=left| dest ← ACC {{!}} [m], logical inclusive or
|-
|-
| 0 || 0 || 0 || 1 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| ANDA/AND [''m''] ||align=left| ANDWF ''m'',''d'' || || Z ||align=left| dest ← ACC & [m], logical and
| 0 || 0 || 0 || 1 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| AND/ANDM [''m''] ||align=left| ANDWF ''m'',''d'' || || Z ||align=left| dest ← ACC & [m], logical and
|-
|-
| 0 || 0 || 0 || 1 || 1 || 1 || 0 ||colspan=7| ''m'' ||align=left| MOV A,[''m''] ||bgcolor=lightgrey align=left| ≈MOVF ''m'',0 || || ||align=left| ACC ← [m]
| 0 || 0 || 0 || 1 || 1 || 1 || 0 ||colspan=7| ''m'' ||align=left| MOV A,[''m''] ||bgcolor=lightgrey align=left| ≈MOVF ''m'',0 || || ||align=left| ACC ← [m]
Line 466: Line 684:
| 0 || 0 || 0 || 1 || 1 || 1 || 1 ||colspan=7| ''m'' || — ||align=left| ≈MOVF ''m'',1 || || ||align=left| [m] ← [m]
| 0 || 0 || 0 || 1 || 1 || 1 || 1 ||colspan=7| ''m'' || — ||align=left| ≈MOVF ''m'',1 || || ||align=left| [m] ← [m]
|-
|-
|colspan=18|
|colspan=19|
|-
|-
! 0 || 0 || 1 ||colspan=3| ''opcode'' ||colspan=8| ''8-bit immediate'' ||colspan=5| Operations with 8-bit literal: ACC ← OP(ACC,k)
! 0 || 0 || 1 ||colspan=3| ''opcode'' ||colspan=8| ''8-bit immediate'' ||colspan=5| Operations with 8-bit literal: ACC ← OP(ACC,k)
|-
|- style="background:lightgrey;"
| 0 || 0 || 1 || 0 || 0 || 0 ||colspan=8| ''k'' || style="text-align:left;" colspan="5"| ''(reserved)''
| 0 || 0 || 1 || 0 || 0 || 0 ||colspan=8| ''k'' ||align=left| SBC A,''k''<sup>†</sup> ||bgcolor=lightgrey| — || C || Z ||align=left| ACC ← ACC + ~[m] + C, subtract with carry
|-
|-
| 0 || 0 || 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| RET A,''k'' ||align=left| RETLW ''k'' || || ||align=left| ACC ← k, then return from subroutine
| 0 || 0 || 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| RET A,''k'' ||align=left| RETLW ''k'' || || ||align=left| ACC ← k, then return from subroutine
Line 480: Line 698:
| 0 || 0 || 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| XOR A,''k'' ||align=left| XORLW ''k'' || || Z ||align=left| ACC ← ACC ^ k, logical exclusive or
| 0 || 0 || 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| XOR A,''k'' ||align=left| XORLW ''k'' || || Z ||align=left| ACC ← ACC ^ k, logical exclusive or
|-
|-
| 0 || 0 || 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| OR A,''k'' ||align=left| IORLW ''k'' || || Z ||align=left| ACC ← ACC {{!}} k, logical inclusive or
| 0 || 0 || 1 || 1 || 0 || 1 ||colspan=8| ''k'' ||align=left| OR A,''k'' ||align=left| IORLW ''k'' || || Z ||align=left| ACC ← ACC {{!}} k, logical inclusive or
|-
|-
| 0 || 0 || 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| AND A,''k'' ||align=left| ANDLW ''k'' || || Z ||align=left| ACC ← ACC & k, logical and
| 0 || 0 || 1 || 1 || 1 || 0 ||colspan=8| ''k'' ||align=left| AND A,''k'' ||align=left| ANDLW ''k'' || || Z ||align=left| ACC ← ACC & k, logical and
|-
|-
| 0 || 0 || 1 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| MOV A,''k'' ||align=left| MOVLW ''k'' || || ||align=left| ACC ← k
| 0 || 0 || 1 || 1 || 1 || 1 ||colspan=8| ''k'' ||align=left| MOV A,''k'' ||align=left| MOVLW ''k'' || || ||align=left| ACC ← k
|-
|-
|colspan=19|
|colspan=19|
|-
|-
! 0 || 1 ||colspan=4| ''opcode'' || ''d'' ||colspan=7| ''address'' ||colspan=5| ALU operations: dest ← OP(ACC,[m])
! 0 || 1 ||colspan=4| ''opcode'' || ''d'' ||colspan=7| ''address'' ||colspan=5| ALU operations part 2: dest ← OP(ACC,[m])<sup>*</sup>
|-
|-
| 0 || 1 || 0 || 0 || 0 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| SZA/SZ [''m''] ||bgcolor=lightgrey| — || || ||align=left| dest ← [m], skip next instruction if zero
| 0 || 1 || 0 || 0 || 0 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| SZA/SZ [''m''] ||bgcolor=lightgrey| — || || ||align=left| dest ← [m], skip next instruction if zero
|-
|-
| 0 || 1 || 0 || 0 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| SWAPA/SWAP [''m''] ||align=left| SWAPF ''m'',''d'' || || ||align=left| dest ← [m]<<4 {{!}} [m]>>4, swap nibbles
| 0 || 1 || 0 || 0 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| {{nobr|SWAPA/SWAP [''m'']}} ||align=left| SWAPF ''m'',''d'' || || ||align=left| dest ← [m]<<4 {{!}} [m]>>4, swap nibbles
|-
|-
| 0 || 1 || 0 || 0 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| SBC/SBCM A,[''m''] ||bgcolor=lightgrey align=left| ≠SUBWFB ''m'',''d'' || C || Z ||align=left| dest ← ACC + ~[m] + C, subtract with carry
| 0 || 1 || 0 || 0 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| SBC/SBCM A,[''m''] ||bgcolor=lightgrey align=left| ≠SUBWFB ''m'',''d'' || C || Z ||align=left| dest ← ACC + ~[m] + C, subtract with carry
Line 506: Line 724:
| 0 || 1 || 0 || 1 || 1 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| SDZA/SDZ [''m''] ||align=left| DECFSZ ''m'',''d'' || || ||align=left| dest ← [m] − 1, then skip if zero
| 0 || 1 || 0 || 1 || 1 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| SDZA/SDZ [''m''] ||align=left| DECFSZ ''m'',''d'' || || ||align=left| dest ← [m] − 1, then skip if zero
|-
|-
| 0 || 1 || 1 || 0 || 0 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| RLA/RL [''m''] ||bgcolor=lightgrey| — || || ||align=left| dest ← [m] << 1 {{!}} [[m]] >> 7, rotate left 1 bit
| 0 || 1 || 1 || 0 || 0 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| RLA/RL [''m''] ||bgcolor=lightgrey| — || || ||align=left| dest ← [m] << 1 {{!}} [m] >> 7, rotate left 1 bit
|-
|-
| 0 || 1 || 1 || 0 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| RRA/RR [''m''] ||bgcolor=lightgrey| — || || ||align=left| dest ← [m] << 7 {{!}} [[m]] >> 1, rotate right 1 bit
| 0 || 1 || 1 || 0 || 0 || 1 || ''d'' ||colspan=7| ''m'' ||align=left| RRA/RR [''m''] ||bgcolor=lightgrey| — || || ||align=left| dest ← [m] << 7 {{!}} [m] >> 1, rotate right 1 bit
|-
|-
| 0 || 1 || 1 || 0 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| RLCA/RLC [''m''] ||align=left| RLF ''m'',''d'' || C || ||align=left| dest ← [m] << 1 {{!}} C, rotate left through carry
| 0 || 1 || 1 || 0 || 1 || 0 || ''d'' ||colspan=7| ''m'' ||align=left| RLCA/RLC [''m''] ||align=left| RLF ''m'',''d'' || C || ||align=left| dest ← [m] << 1 {{!}} C, rotate left through carry
Line 516: Line 734:
|colspan=19|
|colspan=19|
|-
|-
! 0 || 1 || 1 || 1 ||colspan=3| ''opcode'' ||colspan=7| ''address'' ||colspan=5| Sepcial operations: [m] ← special
! 0 || 1 || 1 || 1 ||colspan=3| ''opcode'' ||colspan=7| ''address'' ||colspan=5| Special operations: [m] ← special<sup>*</sup>
|- style="background:lightgrey;"
| 0 || 1 || 1 || 1 || 0 || 0 || ''x'' ||colspan=7| ''m'' || style="text-align:left;" colspan="5"| ''(reserved)''
|-
|-
| 0 || 1 || 1 || 1 || 0 || 1 || 0 ||colspan=7| ''m'' ||align=left| TABRDC [''m''] ||bgcolor=lightgrey| — || || ||align=left| TBLH:[m] ← ROM memory at TBHP:TBLP, table lookup
| 0 || 1 || 1 || 1 || 0 || 0 || 0 ||colspan=7| ''m'' ||align=left| ITABRD [''m'']<sup>†</sup> ||bgcolor=lightgrey| — || || ||align=left| TBLH:[m] ← ROM[TBHP:++TBLP], with pre-increment
|-
|-
| 0 || 1 || 1 || 1 || 0 || 1 || 1 ||colspan=7| ''m'' ||align=left| TABRDL [''m''] ||bgcolor=lightgrey| — || || ||align=left|
| 0 || 1 || 1 || 1 || 0 || 0 || 1 ||colspan=7| ''m'' ||align=left| ITABRDL [''m'']<sup>†</sup> ||bgcolor=lightgrey| — || || ||align=left| TBLH:[m] ← ROM[0xff:++TBLP], with pre-increment
|-
Read from last page of ROM at 0xff:TBLP
| 0 || 1 || 1 || 1 || 0 || 1 || 0 ||colspan=7| ''m'' ||align=left| TABRD [''m''] ||bgcolor=lightgrey| — || || ||align=left| TBLH:[m] ← ROM[TBHP:TBLP], table lookup
|- style="background:lightgrey;"
|-
| 0 || 1 || 1 || 1 || 1 || 0 || 0 ||colspan=7| ''m'' || style="text-align:left;" colspan="5"| ''(reserved)''
| 0 || 1 || 1 || 1 || 0 || 1 || 1 ||colspan=7| ''m'' ||align=left| TABRDL [''m''] ||bgcolor=lightgrey| — || || ||align=left| TBLH:[m] ← ROM[0xff:TBLP], read from last page of ROM
|-
| 0 || 1 || 1 || 1 || 1 || 0 || 0 ||colspan=7| ''m'' ||align=left| SNZ [''m'']<sup>†</sup> ||bgcolor=lightgrey| — || || ||align=left| [m] ← [m], skip next instruction if non-zero
|-
|-
| 0 || 1 || 1 || 1 || 1 || 0 || 1 ||colspan=7| ''m'' ||align=left| DAA [''m''] ||bgcolor=lightgrey| — || C || ||align=left| [m] ← DAA(ACC), decimal adjust after BCD addition
| 0 || 1 || 1 || 1 || 1 || 0 || 1 ||colspan=7| ''m'' ||align=left| DAA [''m''] ||bgcolor=lightgrey| — || C || ||align=left| [m] ← DAA(ACC), decimal adjust after BCD addition
Line 541: Line 760:
| 1 || 0 || 1 ||colspan=11| ''k'' ||align=left| JMP ''k'' ||align=left| GOTO ''k'' || || ||align=left| Jump to address k
| 1 || 0 || 1 ||colspan=11| ''k'' ||align=left| JMP ''k'' ||align=left| GOTO ''k'' || || ||align=left| Jump to address k
|-
|-
|colspan=18|
|colspan=19|
|-
|-
! 1 || 1 ||colspan=2| ''opc'' ||colspan=3| ''bit'' ||colspan=7| ''address'' ||colspan=5| Bit operations
! 1 || 1 ||colspan=2| ''opc'' ||colspan=3| ''bit'' ||colspan=7| ''address'' ||colspan=5| Bit operations<sup>*</sup>
|-
|-
| 1 || 1 || 0 || 0 ||colspan=3| ''bit'' ||colspan=7| ''m'' ||align=left| SET [''m''].''b'' ||align=left| BSF ''m'',''b'' || || ||align=left| Set bit b of [m]
| 1 || 1 || 0 || 0 ||colspan=3| ''bit'' ||colspan=7| ''m'' ||align=left| SET [''m''].''b'' ||align=left| BSF ''m'',''b'' || || ||align=left| Set bit b of [m]
Line 555: Line 774:
|colspan=19|
|colspan=19|
|-
|-
! 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC equiv. || C<br/>? || Z<br/>? || Description
! 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC<br/>equivalent || C<br/>? || Z<br/>? || Description
|}
<nowiki/>*: Instructions available in long forms on 16-bit models with extended instruction set.<br/>
†: Instruction only available on 16-bit models with extended instruction set.

==Padauk microcontrollers (13, 14, 15 or 16 bit)==
[[Padauk Technology]] make a series of PIC-like microcontrollers notable for their extremely low cost, beginning at {{USD|0.033}} in quantity,<ref>{{cite web
|title=What's up with these 3-cent microcontrollers? (A review of the Padauk PMS150C and friends)
|first=Jay |last=Carlson
|url=https://jaycarlson.net/2019/09/06/whats-up-with-these-3-cent-microcontrollers/
|date=6 September 2019 |access-date=2020-05-18
}}</ref> with many models costing less than {{USD|0.10}}.<ref name="tim" >{{cite web
|title=The "terrible" 3 cent MCU – a short survey of sub $0.10 microcontrollers.
|website=Tim's blog
|url=https://cpldcpu.word-press.com/2019/08/12/the-terrible-3-cent-mcu/
|date=12 August 2019 |access-date=2020-05-18
}}</ref><ref>
{{cite web
|title= Free PDK Documentation
|url=https://free-pdk.github.io/
|quote=Padauk µCs sport an interesting architecture that can be a seen as a ... extension of the Microchip PIC architecture.
}}
</ref><ref>
{{cite web
|title= Chiptunes on an ATtiny4 and the 3 Cent Micro: Porting to Padauk
|url=https://gir.st/chiptunes.html
|quote=According to some, Padauk's instruction set is heavily inspired by older PICs, with most operations taking place on a single accumulator register.
}}</ref>

Although clearly derived from the Microchip PIC12 series,<ref name="tim" /><ref>
Jenny List
[https://hackaday.com/2019/08/28/everything-you-want-to-know-about-the-cheapest-processors-available/ "Everything you want to know about the cheapest processors available"].
2019.
</ref>
there are some significant differences:
* They do not use the FSR/INDF mechanism for performing indirect memory access, instead having indirect load and store instructions which use an arbitrary RAM location as a pointer;
* they use a RAM-based call stack, with a stack pointer register;
* the [[carry flag]] uses a "borrow bit" convention for subtracts, rather than the "carry bit" convention used by Microchip;
* they also include a signed [[overflow flag]], which like the digit carry, is set by add, subtract and compare instructions (every instruction which sets the carry flag ''except'' for shift instructions);
* they have separate RAM and I/O register addresses spaces (64 and 32 bytes, respectively, in the 13-bit instruction set);
* bit operations are limited to the I/O space and first 16 RAM addresses;
* the single-operand instructions with a memory source and accumulator destination are omitted;
* single-operand instructions with accumulator source and destination are provided;
* subtraction operations compute destination − source, exchanging input operands depending on the destination;
* they operate faster, requiring 1 cycle for most instructions and 2 cycles for control transfers; and
* some models support [[temporal multithreading]], having multiple execution contexts whose execution is interleaved.

{|class="wikitable" style="text-align:center"
|+ 13-bit Padauk instruction set<ref>{{cite web |title=Documentation for PADAUK FPPA MCUs |first=Ash "Ninji" |last=Wolf |website=[[GitHub]] |date=12 December 2018 |access-date=2020-05-18 |url=https://github.com/free-pdk/fppa-pdk-documentation}}</ref><ref>{{cite web |url=http://www.padauk.com.tw/upload/doc/PMC150,%20PMS150%20datasheet%20V108_EN_20181211.pdf#page=38 |title=PMC150/PMS150 8-bit OTP Type IO Controller |type=data sheet |version=Version 1.8 |date=11 December 2018 |pages=38–51 |access-date=2020-06-08 |author=Padauk Technology Co. Ltd. |id=PDK-DS-PMX150-EN-V108}}</ref>
! 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 ||<br/>8 ||<br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC<br/>equivalent || C<br/>? || Z<br/>? || Description
|-
|colspan=18|
|-
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=4| ''opcode'' ||colspan=5| Miscellaneous instructions
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||align=left| NOP ||align=left| NOP || || ||align=left| No operation
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=5 align=left| ''(reserved)''
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || ''x'' ||colspan=5 align=left| ''(reserved)''
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || ''x'' ||colspan=5 align=left| ''(reserved)''
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 ||align=left| LDSPTL ||bgcolor=lightgrey| — || || ||align=left rowspan=2| A ← ROM[<nowiki/>[SP]], load low/high byte of ROM word using 16-bit pointer on top of stack
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 ||align=left| LDSPTH ||bgcolor=lightgrey| — || ||
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=3| — ||colspan=5 align=left| ''(reserved)''
|-
|colspan=18|
|-
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=4| ''opcode'' ||colspan=5| One-operand instructions on accumulator<br>Same as one-operand instructions on memory (below) except
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 || 1 || 1 ||align=left| PCADD A ||bgcolor=lightgrey align=left| ≈ADDWF PCL,1 || || ||align=left| PC ← PC + A, add to program counter (not {{s|XCH A}})
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 1 || 0 ||align=left| SWAP A ||bgcolor=lightgrey| — || || ||align=left| A ← A<<4 | A>>4, swap nibbles (not {{s|CEQSN A}})
|-
|colspan=18|
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||colspan=4| — ||colspan=5 align=left| ''(reserved)''
|-
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 ||colspan=4| ''opcode'' ||colspan=5| System control instructions
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 0 || 0 || 0 ||align=left| WDRESET ||align=left| CLRWDT || || ||align=left| Restart watchdog timer
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 0 || 0 || 1 ||colspan=5 align=left| ''(reserved)''
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 0 || 1 || 0 ||align=left| PUSHAF ||bgcolor=lightgrey| — || || ||align=left| Push A then flags on top of stack
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 0 || 1 || 1 ||align=left| POPAF ||bgcolor=lightgrey| — || C || Z ||align=left| Pop flags then A from top of stack
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0 || 0 ||colspan=5 align=left| ''(reserved)''
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 0 || 1 ||align=left| RESET ||align=left| RESET || || ||align=left| Software reset
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 1 || 0 ||align=left| STOPSYS ||align=left| SLEEP || || ||align=left| Go into standby mode (clock stopped)
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 || 1 || 1 || 1 ||align=left| STOPEXE ||bgcolor=lightgrey| — || || ||align=left| Go into standby mode (clock running)
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 0 || 0 || 0 ||align=left| ENGINT ||align=left| BSF&nbsp;INTCON,GIE || || ||align=left| Enable interrupts
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 0 || 0 || 1 ||align=left| DISGINT ||align=left| BCF&nbsp;INTCON,GIE || || ||align=left| Disable interrupts
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 0 || 1 || 0 ||align=left| RET ||align=left| RETURN || || ||align=left| Return from subroutine, A unmodified
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 0 || 1 || 1 ||align=left| RETI ||align=left| RETFIE || || ||align=left| Return from interrupt
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 1 || 0 || 0 ||align=left| MUL ||bgcolor=lightgrey| — || || ||align=left| MULRH:A ← A × MULOP (not all models)
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 1 || 0 || 1 ||colspan=5 align=left| ''(reserved)''
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 || 1 || 1 || ''x'' ||colspan=5 align=left| ''(reserved)''
|-
|colspan=18|
|-
! 0 || 0 || 0 || 0 || 0 ||colspan=3| ''opcode'' ||colspan=5| ''ioaddr'' ||colspan=5| Byte-wide I/O operations
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 ||colspan=5| ''ioaddr'' ||align=left| XOR ''ioaddr'',A ||bgcolor=lightgrey| — || || ||align=left| IO[ioaddr] ← A ^ IO[address]
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 0 || 0 ||colspan=5| ''ioaddr'' ||align=left| MOV ''ioaddr'',A ||bgcolor=lightgrey| — || || ||align=left| IO[ioaddr] ← A
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 0 || 1 ||colspan=5| ''ioaddr'' ||align=left| MOV A,''ioaddr'' ||bgcolor=lightgrey| — || || Z ||align=left| A ← IO[ioaddr]
|-
|colspan=18|
|-
! 0 || 0 || 0 || 0 || 0 || 1 || 1 || ''c'' ||colspan=4| ''address'' || ''c'' ||colspan=5| 16-bit operations (RAM address limited, even)
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 ||colspan=4| ''address'' || 0 ||align=left| STT16 ''addr'' ||bgcolor=lightgrey| — || || ||align=left| Timer16 ← [address]
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 ||colspan=4| ''address'' || 1 ||align=left| LDT16 ''addr'' ||bgcolor=lightgrey| — || || ||align=left| [address] ← Timer16
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 ||colspan=4| ''address'' || 0 ||align=left| IDXM ''addr'',A ||bgcolor=lightgrey| — || || ||align=left| [<nowiki/>[address]] ← A, indirect memory address
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 ||colspan=4| ''address'' || 1 ||align=left| IDXM A,''addr'' ||bgcolor=lightgrey| — || || ||align=left| A ← [<nowiki/>[address]], indirect memory address
|-
|colspan=18|
|-
! 0 || 0 || 0 || 0 || 1 ||colspan=8| ''k'' ||colspan=5| Return literal constant
|-
| 0 || 0 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| RET ''k'' ||align=left| RETLW ''k'' || || ||align=left| A ← ''k'', then return from subroutine
|-
|colspan=18|
|-
! 0 || 0 || 0 || 1 || ''c'' ||colspan=3| ''bit'' || ''c'' ||colspan=4| ''address'' ||colspan=5| Bit operations with RAM (first 16 bytes only)
|-
| 0 || 0 || 0 || 1 || 0 ||colspan=3| ''bit'' || 0 ||colspan=4| ''address'' ||align=left| T0SN ''addr''.''b'' ||align=left| BTFSC ''addr'',''b'' || || ||align=left| Skip if bit ''b'' of [''addr''] is clear
|-
| 0 || 0 || 0 || 1 || 0 ||colspan=3| ''bit'' || 1 ||colspan=4| ''address'' ||align=left| T1SN ''addr''.''b'' ||align=left| BTFSS ''addr'',''b'' || || ||align=left| Skip if bit ''b'' of [''addr''] is set
|-
| 0 || 0 || 0 || 1 || 1 ||colspan=3| ''bit'' || 0 ||colspan=4| ''address'' ||align=left| SET0 ''addr''.''b'' ||align=left| BCF ''addr'',''b'' || || ||align=left| Clear bit ''b'' of [''addr'']
|-
| 0 || 0 || 0 || 1 || 1 ||colspan=3| ''bit'' || 1 ||colspan=4| ''address'' ||align=left| SET1 ''addr''.''b'' ||align=left| BSF ''addr'',''b'' || || ||align=left| Set bit ''b'' of [''addr'']
|-
|colspan=18|
|-
! 0 || 0 || 1 || ''d'' ||colspan=3| ''opcode'' ||colspan=6| ''address'' ||colspan=5| ALU operations between A and memory
|-
| 0 || 0 || 1 || 0 || 0 || 0 || 0 ||colspan=6| ''address'' ||align=left| ADD ''addr'',A ||align=left| ADDWF ''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] + A
|-
| 0 || 0 || 1 || 0 || 0 || 0 || 1 ||colspan=6| ''address'' ||align=left| SUB ''addr'',A ||align=left| SUBWF ''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] − A
|-
| 0 || 0 || 1 || 0 || 0 || 1 || 0 ||colspan=6| ''address'' ||align=left| ADDC&nbsp;''addr'',A ||aligh=left| ADDWFC ''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] + A + C
|-
| 0 || 0 || 1 || 0 || 0 || 1 || 1 ||colspan=6| ''address'' ||align=left| SUBC&nbsp;''addr'',A ||bgcolor=lightgrey align=left| ≈SUBWFB&nbsp;''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] − A − C
|-
| 0 || 0 || 1 || 0 || 1 || 0 || 0 ||colspan=6| ''address'' ||align=left| AND ''addr'',A ||align=left| ANDWF ''addr'',1 || || Z ||align=left| [''addr''] ← [''addr''] & A, logical and
|-
| 0 || 0 || 1 || 0 || 1 || 0 || 1 ||colspan=6| ''address'' ||align=left| OR ''addr'',A ||align=left| IORWF ''addr'',1 || || Z ||align=left| [''addr''] ← [''addr''] {{!}} A, logical inclusive or
|-
| 0 || 0 || 1 || 0 || 1 || 1 || 0 ||colspan=6| ''address'' ||align=left| XOR ''addr'',A ||align=left| XORWF ''addr'',1 || || Z ||align=left| [''addr''] ← [''addr''] ^ A, logical exclusive or
|-
| 0 || 0 || 1 || 0 || 1 || 1 || 1 ||colspan=6| ''address'' ||align=left| MOV ''addr'',A ||align=left| MOVWF ''addr'' || || ||align=left| [''addr''] ← A
|-
| 0 || 0 || 1 || 1 || 0 || 0 || 0 ||colspan=6| ''address'' ||align=left| ADD A,''addr'' ||align=left| ADDWF ''addr'',0 || C || Z ||align=left| A ← A + [''addr'']
|-
| 0 || 0 || 1 || 1 || 0 || 0 || 1 ||colspan=6| ''address'' ||align=left| SUB A,''addr'' ||bgcolor=lightgrey align=left| ≠SUBWF ''addr'',0 || C || Z ||align=left| A ← A − [''addr'']
|-
| 0 || 0 || 1 || 1 || 0 || 1 || 0 ||colspan=6| ''address'' ||align=left| ADDC&nbsp;A,''addr'' ||aligh=left| ADDWFC ''addr'',0 || C || Z ||align=left| A ← A + [''addr''] + C
|-
| 0 || 0 || 1 || 1 || 0 || 1 || 1 ||colspan=6| ''address'' ||align=left| SUBC&nbsp;A,''addr'' ||bgcolor=lightgrey align=left| ≠SUBWFB&nbsp;''addr'',0 || C || Z ||align=left| A ← A − [''addr''] − C
|-
| 0 || 0 || 1 || 1 || 1 || 0 || 0 ||colspan=6| ''address'' ||align=left| AND A,''addr'' ||align=left| ANDWF ''addr'',0 || || Z ||align=left| A ← [A] & [''addr''], logical and
|-
| 0 || 0 || 1 || 1 || 1 || 0 || 1 ||colspan=6| ''address'' ||align=left| OR A,''addr'' ||align=left| IORWF ''addr'',0 || || Z ||align=left| A ← A {{!}} [''addr''], logical inclusive or
|-
| 0 || 0 || 1 || 1 || 1 || 1 || 0 ||colspan=6| ''address'' ||align=left| XOR A,''addr'' ||align=left| XORWF ''addr'',0 || || Z ||align=left| A ← A ^ [''addr''], logical exclusive or
|-
| 0 || 0 || 1 || 1 || 1 || 1 || 1 ||colspan=6| ''address'' ||align=left| MOV A,''addr'' ||align=left| MOVF ''addr'',0 || || Z ||align=left| A ← [''addr'']
|-
|colspan=18|
|-
! 0 || 1 || 0 ||colspan=4| ''opcode'' ||colspan=6| ''address'' ||colspan=5| One-operand operations on memory
|-
| 0 || 1 || 0 || 0 || 0 || 0 || 0 ||colspan=6| ''address'' ||align=left| ADDC ''addr'' ||bgcolor=lightgrey| — || C || Z ||align=left| [''addr''] ← [''addr''] + C
|-
| 0 || 1 || 0 || 0 || 0 || 0 || 1 ||colspan=6| ''address'' ||align=left| SUBC ''addr'' ||bgcolor=lightgrey| — || C || Z ||align=left| [''addr''] ← [''addr''] − C
|-
| 0 || 1 || 0 || 0 || 0 || 1 || 0 ||colspan=6| ''address'' ||align=left| IZSN ''addr'' ||align=left| INCFSZ ''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] + 1, then skip if zero
|-
| 0 || 1 || 0 || 0 || 0 || 1 || 1 ||colspan=6| ''address'' ||align=left| DZSN ''addr'' ||align=left| DECFSZ ''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] − 1, then skip if zero
|-
| 0 || 1 || 0 || 0 || 1 || 0 || 0 ||colspan=6| ''address'' ||align=left| INC ''addr'' ||align=left| INCF ''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] + 1
|-
| 0 || 1 || 0 || 0 || 1 || 0 || 1 ||colspan=6| ''address'' ||align=left| DEC ''addr'' ||align=left| DECF ''addr'',1 || C || Z ||align=left| [''addr''] ← [''addr''] − 1
|-
| 0 || 1 || 0 || 0 || 1 || 1 || 0 ||colspan=6| ''address'' ||align=left| CLEAR ''addr'' ||bgcolor=lightgrey align=left| ≈CLRF ''addr'' || || ||align=left| [''addr''] ← 0
|-
| 0 || 1 || 0 || 0 || 1 || 1 || 1 ||colspan=6| ''address'' ||align=left| XCH ''addr'' ||bgcolor=lightgrey| — || || ||align=left| A ← [''addr''], [''addr''] ← A
|-
| 0 || 1 || 0 || 1 || 0 || 0 || 0 ||colspan=6| ''address'' ||align=left| NOT ''addr'' ||align=left| COMF ''addr'',1 || || Z ||align=left| [''addr''] ← ~[''addr''], bitwise complement
|-
| 0 || 1 || 0 || 1 || 0 || 0 || 1 ||colspan=6| ''address'' ||align=left| NEG ''addr'' ||bgcolor=lightgrey| — || || Z ||align=left| [''addr''] ← −[''addr''], negate
|-
| 0 || 1 || 0 || 1 || 0 || 1 || 0 ||colspan=6| ''address'' ||align=left| SR ''addr'' ||bgcolor=lightgrey align=left| ≈LSRF ''addr'',1 || C || ||align=left| [''addr''] ← [''addr''] >> 1, logical shift right
|-
| 0 || 1 || 0 || 1 || 0 || 1 || 1 ||colspan=6| ''address'' ||align=left| SL ''addr'' ||bgcolor=lightgrey align=left| ≈LSLF ''addr'',1 || C || ||align=left| [''addr''] ← [''addr''] << 1, shift left
|-
| 0 || 1 || 0 || 1 || 1 || 0 || 0 ||colspan=6| ''address'' ||align=left| SRC ''addr'' ||align=left| RRF ''addr'',1 || C || ||align=left| [''addr''] ← C << 7 {{!}} [''addr''] >> 1, rotate right through carry
|-
| 0 || 1 || 0 || 1 || 1 || 0 || 1 ||colspan=6| ''address'' ||align=left| SLC ''addr'' ||align=left| RLF ''addr'',1 || C || ||align=left| [''addr''] ← [''addr''] << 1 {{!}} C, rotate left through carry
|-
| 0 || 1 || 0 || 1 || 1 || 1 || 0 ||colspan=6| ''address'' ||align=left| CEQSN ''addr'' ||bgcolor=lightgrey| — || C || Z ||align=left| Compute A − [''addr''], then skip if zero
|-bgcolor=lightgrey
| 0 || 1 || 0 || 1 || 1 || 1 || 1 ||colspan=6| ''address'' ||align=left colspan=5| ''(reserved for CNEQSN)''
|-
|colspan=18|
|-
! 0 || 1 || 1 ||colspan=2| ''opc'' ||colspan=3| ''bit'' ||colspan=5| ''address'' ||colspan=5| Bit operations with I/O
|-
| 0 || 1 || 1 || 0 || 0 ||colspan=3| ''bit'' ||colspan=5| ''address'' ||align=left| T0SN&nbsp;''ioaddr''.''b'' ||align=left| BTFSC ''ioaddr'',''b'' || || ||align=left| Skip if bit ''b'' of [''ioaddr''] is clear
|-
| 0 || 1 || 1 || 0 || 1 ||colspan=3| ''bit'' ||colspan=5| ''address'' ||align=left| T1SN&nbsp;''ioaddr''.''b'' ||align=left| BTFSS ''ioaddr'',''b'' || || ||align=left| Skip if bit ''b'' of [''ioaddr''] is set
|-
| 0 || 1 || 1 || 1 || 0 ||colspan=3| ''bit'' ||colspan=5| ''address'' ||align=left| SET0 ''ioaddr''.''b'' ||align=left| BCF ''ioaddr'',''b'' || || ||align=left| Clear bit ''b'' of [''ioaddr'']
|-
| 0 || 1 || 1 || 1 || 1 ||colspan=3| ''bit'' ||colspan=5| ''address'' ||align=left| SET1 ''ioaddr''.''b'' ||align=left| BSF ''ioaddr'',''b'' || || ||align=left| Set bit ''b'' of [''ioaddr'']
|-
|colspan=18|
|-
! 1 || 0 ||colspan=3| ''opcode'' ||colspan=8| ''literal'' ||colspan=5| Literal operations: A ← OP(A,''k'')
|-
| 1 || 0 || 0 || 0 || 0 ||colspan=8| ''k'' ||align=left| ADD A,''k'' ||align=left| ADDLW ''k'' || C || Z ||align=left| A ← A + ''k''
|-
| 1 || 0 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| SUB A,''k'' ||bgcolor=lightgrey align=left| ≠SUBLW ''k'' || C || Z ||align=left| A ← A − ''k''
|-
| 1 || 0 || 0 || 1 || 0 ||colspan=8| ''k'' ||align=left| CEQSN A,''k'' ||bgcolor=lightgrey| — || C || Z ||align=left| Compute A − ''k'', then skip if zero
|-bgcolor=lightgrey
| 1 || 0 || 0 || 1 || 1 ||colspan=8| ''k'' ||align=left colspan=5| ''(reserved for CNEQSN)''
|-
| 1 || 0 || 1 || 0 || 0 ||colspan=8| ''k'' ||align=left| AND A,''k'' ||bgcolor=lightgrey align=left| ≈ANDLW ''k'' || || Z ||align=left| A ← A & k
|-
| 1 || 0 || 1 || 0 || 1 ||colspan=8| ''k'' ||align=left| OR A,''k'' ||bgcolor=lightgrey align=left| ≈IORLW ''k'' || || Z ||align=left| A ← A {{!}} k
|-
| 1 || 0 || 1 || 1 || 0 ||colspan=8| ''k'' ||align=left| XOR A,''k'' ||bgcolor=lightgrey align=left| ≈XORLW ''k'' || || Z ||align=left| A ← A ^ k
|-
| 1 || 0 || 1 || 1 || 1 ||colspan=8| ''k'' ||align=left| MOV A,''k'' ||align=left| MOVLW ''k'' || || ||align=left| A ← k
|-
|colspan=18|
|-
! 1 || 1 || ''c'' ||colspan=10| ''k'' ||colspan=5| Control transfers: PC ← ''k''
|-
| 1 || 1 || 0 ||colspan=10| ''k'' ||align=left| GOTO ''k'' ||align=left| GOTO ''k'' || || ||align=left| PC ← ''k''
|-
| 1 || 1 || 1 ||colspan=10| ''k'' ||align=left| CALL ''k'' ||align=left| CALL ''k'' || || ||align=left| Push PC, then PC ← ''k''
|-
|colspan=18|
|-
! 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 ||<br/>8 ||<br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC<br/>equivalent || C<br/>? || Z<br/>? || Description
|}

The 14-, 15- and 16-bit instruction sets primarily differ in having wider address fields, although some encoding changes are made to allow a few additional instructions (such as {{code|CNEQSN}}, which performs a compare and skip if ''not'' equal.)

{|class="wikitable" style="text-align:center"
|+ 14-bit Padauk instruction set<ref>{{cite web |title=PADAUK FPPA core devices (14 bit) instruction set |first=Ash "Ninji" |last=Wolf |date=23 May 2020 |access-date=2020-06-08 |url=https://free-pdk.github.io/PADAUK_FPPA_14_bit_instruction_set.html}}</ref><ref>{{cite web |url=http://www.padauk.com.tw/upload/doc/PFS154%20datasheet_v104_EN_20190618.pdf#page=71 |title=PFS154 8bit MTP Type IO controller Data Sheet |version=Version 1.04 |date=18 June 2019 |pages=71–84 |access-date=2020-06-09 |author=Padauk Technology Co. Ltd. |id=PDK-DS-PFS154_RN_V104}}</ref>
! 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 ||<br/>8 ||<br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC<br/>equivalent || C<br/>? || Z<br/>? || Description
|-
|colspan=19|
|-
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 ||colspan=4| ''opcode'' ||colspan=5| Miscellaneous instructions same as 13-bit
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=4| — ||colspan=5 align=left| ''(reserved)''
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 ||colspan=5| — ||colspan=5 align=left| ''(reserved)''
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||colspan=5| — ||colspan=5 align=left| ''(reserved)''
|-
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 ||colspan=4| ''opcode'' ||colspan=5| One-operand instructions on A same as 13-bit
|-
! 0 || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 ||colspan=4| ''opcode'' ||colspan=5| System control instructions same as 13-bit
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 0 || 1 || 0 ||colspan=6| — ||colspan=5 align=left| ''(reserved)''
|-
|colspan=18|
|-
! 0 || 0 || 0 || 0 || 0 ||colspan=3| ''opcode'' ||colspan=6| ''address'' ||colspan=5| Byte-wide I/O operations same as 13-bit, but opcodes changed
|-
| 0 || 0 || 0 || 0 || 0 || 0 || 1 || 1 ||colspan=6| ''ioaddr'' ||align=left| XOR ''ioaddr'',A ||bgcolor=lightgrey| — || || ||align=left| IO[ioaddr] ← A ^ IO[address]
|-bgcolor=lightgrey
| 0 || 0 || 0 || 0 || 0 || 1 || 0 ||colspan=7| — ||colspan=5 align=left| ''(reserved)''
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 1 || 0 ||colspan=6| ''ioaddr'' ||align=left| MOV ''ioaddr'',A ||bgcolor=lightgrey| — || || ||align=left| IO[ioaddr] ← A
|-
| 0 || 0 || 0 || 0 || 0 || 1 || 1 || 1 ||colspan=6| ''ioaddr'' ||align=left| MOV A,''ioaddr'' ||bgcolor=lightgrey| — || || Z ||align=left| A ← IO[ioaddr]
|-
|colspan=19|
|-
! 0 || 0 || 0 || 0 || 1 || 0 ||colspan=8| ''k'' ||colspan=5| Return literal constant same as 13-bit
|-
! 0 || 0 || 0 || 0 || 1 || 1 || ''c'' ||colspan=6| ''address'' || ''c'' ||colspan=5| 16-bit operations same as 13-bit, but 128-byte range
|-
|colspan=19|
|-
! 0 || 0 || 0 || 1 || 0 ||colspan=3| ''bit'' ||colspan=6| ''address'' ||colspan=5| Copy bit to I/O
|-
| 0 || 0 || 0 || 1 || 0 ||colspan=3| ''bit'' ||colspan=6| ''address'' ||align=left| SWAPC&nbsp;''ioaddr''.''b'' ||bgcolor=lightgrey| — || C || ||align=left| Swap carry with [''ioaddr''] bit ''b''
|-
|colspan=19|
|-
! 0 || 0 || 0 || 1 || 1 || ''c'' || ''d'' ||colspan=7| ''address'' ||colspan=5| Additional 2-operand operations
|-
| 0 || 0 || 0 || 1 || 1 || 0 || 0 ||colspan=7| ''address'' ||align=left| COMP A,''addr'' ||bgcolor=lightgrey| — || C || Z ||align=left| A − [''addr''], flags set, result discarded
|-
| 0 || 0 || 0 || 1 || 1 || 0 || 1 ||colspan=7| ''address'' ||align=left| COMP ''addr'',A ||bgcolor=lightgrey| — || C || Z ||align=left| [''addr''] − A, flags set, result discarded
|-
| 0 || 0 || 0 || 1 || 1 || 1 || 0 ||colspan=7| ''address'' ||align=left| NADD A,''addr'' ||align=left| SUBWF&nbsp;''addr'',0 || C || Z ||align=left| A ← [''addr''] + −A (A ← [''addr''] + ~A + 1)
|-
| 0 || 0 || 0 || 1 || 1 || 1 || 1 ||colspan=7| ''address'' ||align=left| NADD ''addr'',A ||bgcolor=lightgrey| — || C || Z ||align=left| [''addr''] ← A + −[''addr''] ([''addr''] ← A + ~[''addr''] + 1)
|-
|colspan=19|
|-
! 0 || 0 || 1 || ''d'' ||colspan=3| ''opcode'' ||colspan=7| ''address'' ||colspan=5| 2-operand instructions same as 13-bit
|-
|colspan=19|
|-
! 0 || 1 || 0 ||colspan=4| ''opcode'' ||colspan=7| ''address'' ||colspan=5| One-operand operations on memory same as 13-bit, plus CNEQSN
|-
| 0 || 1 || 0 || 1 || 1 || 1 || 1 ||colspan=7| ''address'' ||align=left| CNEQSN ''addr'' ||bgcolor=lightgrey| — || C || Z ||align=left| Compute A − [''addr''], then skip if non-zero
|-
|colspan=19|
|-
! 0 || 1 || 1 ||colspan=2| ''opc'' ||colspan=3| ''bit'' ||colspan=6| ''ioaddr'' ||colspan=5| Bit operations with I/O same as 13-bit, but 64-byte range
|-
! 1 || 0 || 0 ||colspan=2| ''opc'' ||colspan=3| ''bit'' ||colspan=6| ''address'' ||colspan=5| Bit operations with memory same as 13-bit, but 64-byte range
|-
|colspan=19|
|-
! 1 || 0 || 1 ||colspan=3| ''opcode'' ||colspan=8| ''literal'' ||colspan=5| Literal operations same as 13-bit, plus CNEQSN
|-
| 1 || 0 || 1 || 0 || 1 || 1 ||colspan=8| ''k'' ||align=left| CNEQSN A,''k'' ||bgcolor=lightgrey| — || C || Z ||align=left| Compute A − ''k'', then skip if non-zero
|-
|colspan=19|
|-
! 1 || 1 || ''c'' ||colspan=11| ''k'' ||colspan=5| Control transfers same as 13-bit
|-
|colspan=19|
|-
! 1<br/>13 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 ||<br/>8 ||<br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || PIC<br/>equivalent || C<br/>? || Z<br/>? || Description
|}
|}
<!--
Not yet documented:
* TABRDL instruction (table read last page) uses all-ones rather than TBHP
* ITABRD and ITABRDL, which add a pre-increent of TBLP
* Long instructions as described in https://www.holtek.com/documents/10179/116745/an0334e.pdf
-->


==PIC18 high end core devices (16 bit)==
==PIC18 high end core devices (16 bit)==
In 2000, Microchip introduced the PIC18 architecture.[http://mdubuc.freeshell.org/Sdcc/] Unlike the 17 series, it has proven to be very popular, with a large number of device variants presently in manufacture. In contrast to earlier devices, which were more often than not programmed in assembly, C has become the predominant development language.<ref>http://www.microchipc.com/sourcecode/</ref>
In 2000, Microchip introduced the PIC18 architecture.[http://mdubuc.freeshell.org/Sdcc/] Unlike the 17 series, it has proven to be very popular, with a large number of device variants presently in manufacture. In contrast to earlier devices, which were more often than not programmed in assembly, C has become the predominant development language.<ref>{{Cite web|url=http://www.microchipc.com/sourcecode/|title = Microchip PIC micros and C - source and sample code}}</ref>


The PIC18 has a 12-bit RAM address space, divided into 16 pages of 256 bytes. The 8-bit <code>f</code> field determines the address in combination with the <code>a</code> bit and the 4-bit bank select register (<code>BSR</code>). If <code>a</code>=0, the <code>BSR</code> is ignored and the <code>f</code> field is sign-extended to the range 0x000&ndash;0x07F (global RAM) or 0xF80&ndash;0xFFF (special function registers). If <code>a</code>=1, the <code>f</code> field is extended with the <code>BSR</code> to generate the 12-bit address.
The PIC18 has a 12-bit RAM address space, divided into 16 pages of 256 bytes. The 8-bit <code>f</code> field determines the address in combination with the <code>a</code> bit and the 4-bit bank select register (<code>BSR</code>). If <code>a</code>=0, the <code>BSR</code> is ignored and the <code>f</code> field is sign-extended to the range 0x000&ndash;0x07F (global RAM) or 0xF80&ndash;0xFFF (special function registers). If <code>a</code>=1, the <code>f</code> field is extended with the <code>BSR</code> to generate the 12-bit address.


The PIC18 extends the <code>FSR</code>/<code>INDF</code> mechanism used in previous PICmicro processors for indirect addressing in two ways. First, it provides ''three'' file select registers. The <code>FSR''n''</code> registers are 12 bits long (each split into two 8-bit portions <code>FSR0L</code> through <code>FSR2H</code>), and access to the corresponding <code>INDF''n''</code> register (<code>INDF0</code> through <code>INDF2</code>) acts as an alias for the addressed byte.
The PIC18 extends the <code>FSR</code>/<code>INDF</code> mechanism used in previous PICmicro processors for indirect addressing in two ways:
First, it provides ''three'' file select registers. The <code>FSR''n''</code> registers are 12 bits long (each split into two 8-bit portions <code>FSR0L</code> through <code>FSR2H</code>), and access to the corresponding <code>INDF''n''</code> register (<code>INDF0</code> through <code>INDF2</code>) acts as an alias for the addressed byte.


Second, there are addressing modes. For each of the three, there is not just one <code>INDF''n''</code> register, but five, and the one used determines the addressing mode:
Second, there are addressing modes. For each of the three, there is not just one <code>INDF''n''</code> register, but five, and the one used determines the addressing mode:
Line 576: Line 1,147:
* <code>POSTINC''n''</code>: Access the byte at <code>FSR''n''</code>, then increment <code>FSR''n''</code>
* <code>POSTINC''n''</code>: Access the byte at <code>FSR''n''</code>, then increment <code>FSR''n''</code>
* <code>PREINC''n''</code>: Increment <code>FSR''n''</code>, then access the byte at the incremented <code>FSR''n''</code>
* <code>PREINC''n''</code>: Increment <code>FSR''n''</code>, then access the byte at the incremented <code>FSR''n''</code>
* <code>PLUSW''n''</code>: Access the byte at <code>FSR''n'' + W</code> (indexed addressing)
* <code>PLUSW''n''</code>: Access the byte at <code>FSR''n'' + W</code> (indexed addressing).


There are also instructions to directly load an FSR pair with a 12-bit address, and a <code>MOVFF</code> instruction that moves a byte between two 12-bit addresses.
There are also instructions to directly load an FSR pair with a 12-bit address, and a <code>MOVFF</code> instruction that moves a byte between two 12-bit addresses.


{|class="wikitable" style="text-align:center"
{|class="wikitable" style="text-align:center"
|+ PIC18 16-bit instruction set<ref>{{Citation |url=http://ww1.microchip.com/downloads/en/DeviceDoc/39605F.pdf |title=PIC18F1220/1320 Data Sheet |year=2007 |author=Microchip Technology, Inc. |accessdate=2012-04-02}}</ref>
|+ PIC18 16-bit instruction set<ref>{{Citation |url=http://ww1.microchip.com/downloads/en/DeviceDoc/39605F.pdf |title=PIC18F1220/1320 Data Sheet |year=2007 |author=Microchip Technology, Inc. |access-date=2012-04-02}}</ref>
|-
|-
! 1<br/>5 || 1<br/>4 || 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || C<br/>? || Z<br/>? || N<br/>? || Description
! 1<br/>5 || 1<br/>4 || 1<br/>3 || 1<br/>2 || 1<br/>1 || 1<br/>0 || <br/>9 || <br/>8 || <br/>7 || <br/>6 || <br/>5 || <br/>4 || <br/>3 || <br/>2 || <br/>1 || <br/>0 || Mnemonic || C<br/>? || Z<br/>? || N<br/>? || Description
Line 627: Line 1,198:
| 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 ||colspan=8| ''k'' ||align=left| SUBLW ''k'' || || || ||align=left| W ← k − W
| 0 || 0 || 0 || 0 || 1 || 0 || 0 || 0 ||colspan=8| ''k'' ||align=left| SUBLW ''k'' || || || ||align=left| W ← k − W
|-
|-
| 0 || 0 || 0 || 0 || 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| IORLW ''k'' || || || ||align=left| W ← k &#124; W, logical inclusive or
| 0 || 0 || 0 || 0 || 1 || 0 || 0 || 1 ||colspan=8| ''k'' ||align=left| IORLW ''k'' || || || ||align=left| W ← k {{pipe}} W, logical inclusive or
|-
|-
| 0 || 0 || 0 || 0 || 1 || 0 || 1 || 0 ||colspan=8| ''k'' ||align=left| XORLW ''k'' || || || ||align=left| W ← k ^ W, exclusive or
| 0 || 0 || 0 || 0 || 1 || 0 || 1 || 0 ||colspan=8| ''k'' ||align=left| XORLW ''k'' || || || ||align=left| W ← k ^ W, exclusive or
Line 649: Line 1,220:
| 0 || 0 || 0 || 0 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| DECF ''f'',''d'',''a'' || C || Z || N ||align=left| dest ← f − 1
| 0 || 0 || 0 || 0 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| DECF ''f'',''d'',''a'' || C || Z || N ||align=left| dest ← f − 1
|-
|-
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| IORWF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f &#124; W, logical inclusive or
| 0 || 0 || 0 || 1 || 0 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| IORWF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f {{pipe}} W, logical inclusive or
|-
|-
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| ANDWF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f & W, logical and
| 0 || 0 || 0 || 1 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| ANDWF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f & W, logical and
Line 665: Line 1,236:
| 0 || 0 || 1 || 0 || 1 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| DECFSZ ''f'',''d'',''a'' || || || ||align=left| dest ← f − 1, skip if 0
| 0 || 0 || 1 || 0 || 1 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| DECFSZ ''f'',''d'',''a'' || || || ||align=left| dest ← f − 1, skip if 0
|-
|-
| 0 || 0 || 1 || 1 || 0 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RRCF ''f'',''d'',''a'' || C || Z || N ||align=left| dest ← f>>1 &#124; C<<7, rotate right through carry
| 0 || 0 || 1 || 1 || 0 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RRCF ''f'',''d'',''a'' || C || Z || N ||align=left| dest ← f>>1 {{pipe}} C<<7, rotate right through carry
|-
|-
| 0 || 0 || 1 || 1 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RLCF ''f'',''d'',''a'' || C || Z || N ||align=left| dest ← f<<1 &#124; C, rotate left through carry
| 0 || 0 || 1 || 1 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RLCF ''f'',''d'',''a'' || C || Z || N ||align=left| dest ← f<<1 {{pipe}} C, rotate left through carry
|-
|-
| 0 || 0 || 1 || 1 || 1 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| SWAPF ''f'',''d'',''a'' || || || ||align=left| dest ← f<<4 &#124; f>>4, swap nibbles
| 0 || 0 || 1 || 1 || 1 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| SWAPF ''f'',''d'',''a'' || || || ||align=left| dest ← f<<4 {{pipe}} f>>4, swap nibbles
|-
|-
| 0 || 0 || 1 || 1 || 1 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| INCFSZ ''f'',''d'',''a'' || || || ||align=left| dest ← f + 1, skip if 0
| 0 || 0 || 1 || 1 || 1 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| INCFSZ ''f'',''d'',''a'' || || || ||align=left| dest ← f + 1, skip if 0
|-
|-
| 0 || 1 || 0 || 0 || 0 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RRNCF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f>>1 &#124; f<<7, rotate right (no carry)
| 0 || 1 || 0 || 0 || 0 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RRNCF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f>>1 {{pipe}} f<<7, rotate right (no carry)
|-
|-
| 0 || 1 || 0 || 0 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RLNCF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f<<1 &#124; f>>7, rotate left (no carry)
| 0 || 1 || 0 || 0 || 0 || 1 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| RLNCF ''f'',''d'',''a'' || || Z || N ||align=left| dest ← f<<1 {{pipe}} f>>7, rotate left (no carry)
|-
|-
| 0 || 1 || 0 || 0 || 1 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| INFSNZ ''f'',''d'',''a'' || || || ||align=left| dest ← f + 1, skip if not 0
| 0 || 1 || 0 || 0 || 1 || 0 || ''d'' || ''a'' ||colspan=8| ''f'' ||align=left| INFSNZ ''f'',''d'',''a'' || || || ||align=left| dest ← f + 1, skip if not 0
Line 769: Line 1,340:
| 1 || 1 || 1 || 0 || 1 || 0 || 1 || 0 ||colspan=8| ''k'' ||align=left| PUSHL ''k''<sup>*</sup> || || || ||align=left| [FSR2] ← k, decrement FSR2
| 1 || 1 || 1 || 0 || 1 || 0 || 1 || 0 ||colspan=8| ''k'' ||align=left| PUSHL ''k''<sup>*</sup> || || || ||align=left| [FSR2] ← k, decrement FSR2
|-
|-
| 1 || 1 || 1 || 0 || 1 || 0 || 1 || 1 || 0 ||colspan=7| ''s'' ||rowspan=2 align=left| MOVSF ''src'',''f''&thinsp;<sup>*</sup> ||rowspan=2| ||rowspan=2| ||rowspan=2| ||rowspan=2 align=left| f ← FSR2[s]
| 1 || 1 || 1 || 0 || 1 || 0 || 1 || 1 || 0 ||colspan=7| ''s'' ||rowspan=2 align=left| MOVSF ''src'',''f''{{hair space}}<sup>*</sup> ||rowspan=2| ||rowspan=2| ||rowspan=2| ||rowspan=2 align=left| f ← FSR2[s]
|-
|-
| 1 || 1 || 1 || 1 ||colspan=12| ''f''
| 1 || 1 || 1 || 1 ||colspan=12| ''f''
Line 804: Line 1,375:


==PIC24 and dsPIC 16-bit microcontrollers==
==PIC24 and dsPIC 16-bit microcontrollers==
In 2001, Microchip introduced the dsPIC series of chips,<ref>
In 2001, Microchip introduced the dsPIC series of chips,<ref>[http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2018&mcparam=en013529]</ref> which entered mass production in late 2004. They are Microchip's first inherently 16-bit microcontrollers. PIC24 devices are designed as general purpose microcontrollers. dsPIC devices include [[digital signal processing]] capabilities in addition.
{{Cite web
|url=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2018&mcparam=en013529
|title = Microchip Technology debuts world's highest performing 16-bit microcontrollers: dsPIC
|archive-url=https://web.archive.org/web/20041213035811/http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2018&mcparam=en013529
|archive-date=2004-12-13
}}</ref>
which entered mass production in late 2004. They are Microchip's first inherently 16-bit microcontrollers. PIC24 devices are designed as general purpose microcontrollers. dsPIC devices include [[digital signal processing]] capabilities in addition.


Instructions come in two main varieties. One is like the classic one-operand PIC instructions, with an operation between W0 and a value in a specified f register (i.e. the first 8K of RAM), and a destination select bit selecting which is updated with the result. The W registers are memory-mapped, so the f operand may specify a W register.
Instructions come in two main varieties. One is like the classic one-operand PIC instructions, with an operation between W0 and a value in a specified f register (i.e. the first 8K of RAM), and a destination select bit selecting which is updated with the result. The W registers are memory-mapped, so the f operand may specify a W register.
Line 840: Line 1,418:


{|class="wikitable" style="text-align:center"
{|class="wikitable" style="text-align:center"
|+ PIC24 24-bit instruction set<ref name="dsPIC30F">{{Citation |url=http://ww1.microchip.com/downloads/en/DeviceDoc/70157C.pdf |title=dsPIC30F Programmer's Reference Manual |year=2008 |publisher=Microchip Technology |id=DS70157C |accessdate=2012-07-02}}</ref>
|+ PIC24 24-bit instruction set<ref name="dsPIC30F">{{Citation |url=http://ww1.microchip.com/downloads/en/DeviceDoc/70157C.pdf |title=dsPIC30F Programmer's Reference Manual |year=2008 |publisher=Microchip Technology |id=DS70157C |access-date=2012-07-02}}</ref>
|-
|-


Line 900: Line 1,478:
| 0 || 0 || 0 || 0 || 1 || 0 || 1 ||colspan=17| — || colspan="5" style="text-align:left;"| (Reserved)
| 0 || 0 || 0 || 0 || 1 || 0 || 1 ||colspan=17| — || colspan="5" style="text-align:left;"| (Reserved)
|-
|-
| 0 || 0 || 0 || 0 || 1 || 1 || 0 || ''a'' ||colspan=16| ''n'' ||align=left| BRA O''a'', addr || || || ||rowspan=2 align=left| If accumulator a overflowed/saturated, PC += 2×simm16
| 0 || 0 || 0 || 0 || 1 || 1 || 0 || ''a'' ||colspan=16| ''n'' ||align=left| BRA O''a'', addr || || || ||rowspan=2 align=left| If accumulator an overflowed/saturated, PC += 2×simm16
|-
|-
| 0 || 0 || 0 || 0 || 1 || 1 || 1 || ''a'' ||colspan=16| ''n'' ||align=left| BRA S''a'', addr || || ||
| 0 || 0 || 0 || 0 || 1 || 1 || 1 || ''a'' ||colspan=16| ''n'' ||align=left| BRA S''a'', addr || || ||
Line 966: Line 1,544:
| 0 || 1 || 1 || 0 || 1 ||colspan=4| ''w'' || ''B'' ||colspan=3| ''q'' ||colspan=4| ''d'' ||colspan=3| ''p'' ||colspan=4| ''s'' ||align=left| XOR[.B] W''w'',''src'',''dst'' || || Z || N ||align=left| dst ← Ww ^ src
| 0 || 1 || 1 || 0 || 1 ||colspan=4| ''w'' || ''B'' ||colspan=3| ''q'' ||colspan=4| ''d'' ||colspan=3| ''p'' ||colspan=4| ''s'' ||align=left| XOR[.B] W''w'',''src'',''dst'' || || Z || N ||align=left| dst ← Ww ^ src
|-
|-
| 0 || 1 || 1 || 1 || 0 ||colspan=4| ''w'' || ''B'' ||colspan=3| ''q'' ||colspan=4| ''d'' ||colspan=3| ''p'' ||colspan=4| ''s'' ||align=left| IOR[.B] W''w'',''src'',''dst'' || || Z || N ||align=left| dst ← Ww &#124; src
| 0 || 1 || 1 || 1 || 0 ||colspan=4| ''w'' || ''B'' ||colspan=3| ''q'' ||colspan=4| ''d'' ||colspan=3| ''p'' ||colspan=4| ''s'' ||align=left| IOR[.B] W''w'',''src'',''dst'' || || Z || N ||align=left| dst ← Ww {{pipe}} src
|-
|-
| 0 || 1 || 1 || 1 || 1 ||colspan=4| ''w'' || ''B'' ||colspan=3| ''q'' ||colspan=4| ''d'' ||colspan=3| ''p'' ||colspan=4| ''s'' ||align=left| MOV[.B] ''src'',''dst'' || || Z || N ||align=left| dst ← src (offset mode allowed)
| 0 || 1 || 1 || 1 || 1 ||colspan=4| ''w'' || ''B'' ||colspan=3| ''q'' ||colspan=4| ''d'' ||colspan=3| ''p'' ||colspan=4| ''s'' ||align=left| MOV[.B] ''src'',''dst'' || || Z || N ||align=left| dst ← src (offset mode allowed)
Line 1,038: Line 1,616:
| 1 || 0 || 1 || 1 || 0 || 0 || 1 || 0 || 1 || ''B'' ||colspan=10| ''k'' ||colspan=4| ''d'' ||align=left| XOR[.B] #''u10'',W''d'' || || Z || N ||align=left| Wd ← Wd ^ k
| 1 || 0 || 1 || 1 || 0 || 0 || 1 || 0 || 1 || ''B'' ||colspan=10| ''k'' ||colspan=4| ''d'' ||align=left| XOR[.B] #''u10'',W''d'' || || Z || N ||align=left| Wd ← Wd ^ k
|-
|-
| 1 || 0 || 1 || 1 || 0 || 0 || 1 || 1 || 0 || ''B'' ||colspan=10| ''k'' ||colspan=4| ''d'' ||align=left| IOR[.B] #''u10'',W''d'' || || Z || N ||align=left| Wd ← Wd &#124; k
| 1 || 0 || 1 || 1 || 0 || 0 || 1 || 1 || 0 || ''B'' ||colspan=10| ''k'' ||colspan=4| ''d'' ||align=left| IOR[.B] #''u10'',W''d'' || || Z || N ||align=left| Wd ← Wd {{pipe}} k
|-
|-
| 1 || 0 || 1 || 1 || 0 || 0 || 1 || 1 || 1 || ''B'' ||colspan=10| ''k'' ||colspan=4| ''d'' ||align=left| MOV[.B] #''u10'',W''d'' || || || ||align=left| Wd ← k
| 1 || 0 || 1 || 1 || 0 || 0 || 1 || 1 || 1 || ''B'' ||colspan=10| ''k'' ||colspan=4| ''d'' ||align=left| MOV[.B] #''u10'',W''d'' || || || ||align=left| Wd ← k
Line 1,058: Line 1,636:
| 1 || 0 || 1 || 1 || 0 || 1 || 1 || 0 || 1 || ''B'' || ''D'' ||colspan=13| ''f'' ||align=left| XOR[.B] ''f''[,WREG] || || Z || N ||align=left| dest ← f ^ W0
| 1 || 0 || 1 || 1 || 0 || 1 || 1 || 0 || 1 || ''B'' || ''D'' ||colspan=13| ''f'' ||align=left| XOR[.B] ''f''[,WREG] || || Z || N ||align=left| dest ← f ^ W0
|-
|-
| 1 || 0 || 1 || 1 || 0 || 1 || 1 || 1 || 0 || ''B'' || ''D'' ||colspan=13| ''f'' ||align=left| IOR[.B] ''f''[,WREG] || || Z || N ||align=left| dest ← f &#124; W0
| 1 || 0 || 1 || 1 || 0 || 1 || 1 || 1 || 0 || ''B'' || ''D'' ||colspan=13| ''f'' ||align=left| IOR[.B] ''f''[,WREG] || || Z || N ||align=left| dest ← f {{pipe}} W0
|-
|-
| 1 || 0 || 1 || 1 || 0 || 1 || 1 || 1 || 1 || ''B'' || 1 ||colspan=13| ''f'' ||align=left| MOV[.B] WREG,''f'' || || || ||align=left| f ← W0
| 1 || 0 || 1 || 1 || 0 || 1 || 1 || 1 || 1 || ''B'' || 1 ||colspan=13| ''f'' ||align=left| MOV[.B] WREG,''f'' || || || ||align=left| f ← W0

Latest revision as of 17:46, 6 September 2024

The PIC instruction set refers to the set of instructions that Microchip Technology PIC or dsPIC microcontroller supports. The instructions are usually programmed into the Flash memory of the processor, and automatically executed by the microcontroller on startup.

PICmicro chips have a Harvard architecture and instruction words have unusual sizes. Originally, 12-bit instructions included 5 address bits to specify the memory operand, and 9-bit branch destinations. Later revisions added opcode bits, allowing additional address bits.

They are accumulator machines, with a common accumulator "W" being one operand in all 2-operand instructions.

In the instruction set tables that follow, register numbers are referred to as "f", while constants are referred to as "k". Bit numbers (0–7) are selected by "b". Arithmetic instructions write their result to one of the inputs selected by the "d" bit: 0 indicates W, while 1 indicates that the result is written back to source register f. The C and Z status flags may be set based on the result; otherwise they are unmodified. Add and subtract (but not rotate) instructions that set C also set the DC (digit carry) flag, the carry from bit 3 to bit 4, which is useful for BCD arithmetic.

Architecture

[edit]

Memory operands are also referred to as "registers". Most are simply general-purpose storage (RAM), while some locations are reserved for special function registers. Except for a single accumulator (called W), almost all other registers are memory-mapped, even registers like the program counter and ALU status register. (The other exceptions, which are not memory-mapped, are the return address stack, and the tri-state registers used to configure the GPIO pins.)

Some arithmetic instructions only use one of their inputs, but still use a dbit. For example, MOVW copies the value of W to the destination. When used with d = 1, this stores W to f. There is a matching MOVF instruction which outputs the value of f. When used with d = 0, this loads f into W. When used with d = 1, the only visible effect is to set the zero flag depending on the value of f.

The instruction set does not contain conditional branch instructions. Instead, it contains conditional skip instructions which cause the following instruction to be ignored. A conditional skip followed by an unconditional branch performs a conditional branch. The skip instructions test any bit of any register. The ALU status register is one possibility.

Memory operands are specified by absolute address; the location is fixed at compile time. To provide indirect addressing, a pair of special function registers are provided:

  • The file select register (FSR) is written with the address of the desired memory operand, after which
  • The indirect file register (INDF) becomes an alias for the operand pointed to by the FSR.

This mechanism also allows up to 256 bytes of memory to be addressed, even when the instruction set only allows 5- or 7-bit absolute addresses. Models with more registers (special function registers plus RAM) than fit into the instruction provide multiple banks of memory, and use one of two mechanisms for accessing them:

  1. Most baseline core devices, and some mid-range core devices, use the high-order bits of the file select register to select the current register bank.
  2. More recent models have a separate bank select register, and a MOVLB instruction to set it.

PIC processors with more than 256 words of program use paged memory. The internal program counter and return stack are as wide as necessary to address all memory, but only the low 8 bits are visible to software in the PCL ("PC low") register. There is an additional PCLATH ("PC latch high") register which is only modified by software. Any operation which does not specify the full destination address (such as a 9-bit GOTO or an 8-bit write to the PCL register) fills in the additional high bits from the corresponding part of PCLATH. (Some PIC18 processors extend this beyond 16 bits with a PCLATU register to supply bits 16–23.)

Baseline core devices (12 bit)

[edit]

This is the original 1976 instruction set, introduced in the General Instrument PIC1640 and PIC1650,[1] with the only additions since then being the miscellaneous instructions other than NOP.

12-bit PIC instruction set
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description
0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 NOP No operation
0 0 0 0 0 0 0 0 0 0 1 0 OPTION Copy W to OPTION register
0 0 0 0 0 0 0 0 0 0 1 1 SLEEP Go into standby mode
0 0 0 0 0 0 0 0 0 1 0 0 CLRWDT Restart watchdog timer
0 0 0 0 0 0 0 0 0 1 f TRIS f Copy W to tri-state register (f = 1, 2 or 3)
0 0 0 0 0 0 0 1 0 k MOVLB k* Set bank select register to k
0 0 0 0 0 0 0 1 1 1 1 0 RETURN Return from subroutine, W unmodified
0 0 0 0 0 0 0 1 1 1 1 1 RETFIE Return from interrupt; return & enable interrupts
0 0 opcode d register ALU operations: dest ← OP(f,W)
0 0 0 0 0 0 1 f MOVWF f f ← W
0 0 0 0 0 1 d f CLR f,d Z dest ← 0, usually written CLRW or CLRF f
0 0 0 0 1 0 d f SUBWF f,d C Z dest ← f−W (dest ← f+~W+1)
0 0 0 0 1 1 d f DECF f,d Z dest ← f−1
0 0 0 1 0 0 d f IORWF f,d Z dest ← f | W, logical inclusive or
0 0 0 1 0 1 d f ANDWF f,d Z dest ← f & W, logical and
0 0 0 1 1 0 d f XORWF f,d Z dest ← f ^ W, logical exclusive or
0 0 0 1 1 1 d f ADDWF f,d C Z dest ← f+W
0 0 1 0 0 0 d f MOVF f,d Z dest ← f
0 0 1 0 0 1 d f COMF f,d Z dest ← ~f, bitwise complement
0 0 1 0 1 0 d f INCF f,d Z dest ← f+1
0 0 1 0 1 1 d f DECFSZ f,d dest ← f−1, then skip if zero
0 0 1 1 0 0 d f RRF f,d C dest ← CARRY<<7 | f>>1, rotate right through carry
0 0 1 1 0 1 d f RLF f,d C dest ← F<<1 | CARRY, rotate left through carry
0 0 1 1 1 0 d f SWAPF f,d dest ← f<<4 | f>>4, swap nibbles
0 0 1 1 1 1 d f INCFSZ f,d dest ← f+1, then skip if zero
0 1 opc bit register Bit operations
0 1 0 0 bit f BCF f,b Clear bit b of f
0 1 0 1 bit f BSF f,b Set bit b of f
0 1 1 0 bit f BTFSC f,b Skip if bit b of f is clear
0 1 1 1 bit f BTFSS f,b Skip if bit b of f is set
1 0 opc k Control transfers
1 0 0 0 k RETLW k Set W ← k, then return from subroutine
1 0 0 1 k CALL k Call subroutine, 8-bit address k
1 0 1 k GOTO k Jump to 9-bit address k[2]
1 1 opc 8-bit immediate Operations with W and 8-bit literal: W ← OP(k,W)
1 1 0 0 k MOVLW k W ← k
1 1 0 1 k IORLW k Z W ← k | W, bitwise logical or
1 1 1 0 k ANDLW k Z W ← k & W, bitwise and
1 1 1 1 k XORLW k Z W ← k ^ W, bitwise exclusive or
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description

*: Extended instruction, not available on most 12-bit PICs. Of the models with extended RAM, most (e.g. 16C5x, 16F5x) extend the register address space using the high-order bits of the FSR. A few (e.g. PIC12F529T39A) have a separate bank select register which can be set with this instruction.
†: Extended instruction, only available on "enhanced baseline" PICs. Only the very few models (16F527, 16F570, MCV20A) with interrupt support (and a 4-level stack) include these instructions. All such models also include MOVLB.

General Instrument PIC1670 (13 bit, obsolete)

[edit]

Introduced in 1979, this expanded PIC supported 64 bytes of register space (16 special function registers and 48 bytes of RAM), 1024 words of ROM, a 6-level hardware stack, and interrupt handling. The PIC1665 was a variant with external ROM used for developing firmware for the mask ROM 1670.

It added a signed overflow bit to the status register (bit 3). Status register bits 4 and 5 provided read-only access to the high 2 bits of the 10-bit program counter.

The instruction set is mostly the same as the 12-bit PIC with the address field enlarged. However, the 8-bit immediate instructions gain an additional opcode bit. Rather than adding an additional four instructions with an 8-bit immediate operand, the instruction set adds two instructions with 8-bit operands, two instructions with 7-bit operands (6-bit address plus direction bit), and four instructions with 6-bit operands (6-bit address):

  • The 8-bit immediate group grows to 6 instructions by adding ADDLW and RETLW. The latter is moved out of the control transfer group, allowing a full 10-bit address in the CALL instruction.
  • The ALU operations group gains add/subtract with carry (ADCWF, SUBBWF) instructions (7-bit operands).
  • The CLRW instruction is deleted (it wastes a 6-bit memory address and duplicates MOVLW 0).
  • Five new instructions with a 6-bit memory address operands are added. These do not have a destination select bit, and include three "compare and skip" instructions which do not write a result, and two "rotate without carry" instructions.

This instruction set is not used in any currently manufactured part and is of historical interest only.

13-bit PIC1670 instruction set (obsolete)[3]
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description
0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 NOP No operation
0 0 0 0 0 0 0 0 0 0 0 0 1 HALT Halt processor (PIC1665 only)
0 0 0 0 0 0 0 0 0 0 0 1 0 RETFI Return from interrupt
0 0 0 0 0 0 0 0 0 0 0 1 1 RETFS Return from subroutine, W unmodified
0 0 0 0 0 0 0 0 0 0 1 0 0 DAW Decimal Adjust W
0 0 opcode d register ALU operations same as 12- and 14-bit PIC except
0 0 0 0 0 1 d f SUBBWF f,d C Z dest ← f−W−C = f+~W+C (not CLR f,d)
0 0 1 0 0 0 d f ADCWF f,d C Z dest ← f+W+C (not MOVF f,d)
0 1 opc bit register Bit operations same as 12- and 14-bit PIC
1 0 0 0 opcode register Additional ALU operations, no choice of destination
1 0 0 0 0 0 0 f MOVFW f Z W ← f (= MOVF f,0)
1 0 0 0 0 0 1 f CLRF f Z f ← 0 (for CLRW, use MOVLW 0)
1 0 0 0 0 1 0 f RRNC f f ← f<<7 | f>>1, rotate right no carry
1 0 0 0 0 1 1 f RLNC f f ← f<<1 | f>>7, rotate left no carry
1 0 0 0 1 0 0 f CPFSLT f Compare and skip if f < W (unsigned)
1 0 0 0 1 0 1 f CPFSEQ f Compare and skip if f = W
1 0 0 0 1 1 0 f CPFSGT f Compare and skip if f > W (unsigned)
1 0 0 0 1 1 1 f TESTF f Z f ← f (= MOVF f,1)
1 0 opcode 8-bit immediate Operations with W and 8-bit literal: W ← OP(k,W)
1 0 0 1 0 k MOVLW k W ← k
1 0 0 1 1 k ADDLW k C Z W ← k+W
1 0 1 0 0 k IORLW k Z W ← k | W, bitwise logical or
1 0 1 0 1 k ANDLW k Z W ← k & W, bitwise and
1 0 1 1 0 k XORLW k Z W ← k ^ W, bitwise exclusive or
1 0 1 1 1 k RETLW k W ← k, then return from subroutine
1 1 c k Control transfers
1 1 0 k GOTO k Jump to address k
1 1 1 k CALL k Call subroutine
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description

ELAN Microelectronics clones (13 bit)

[edit]

ELAN Microelectronics Corp. make a series of PICmicro-like microcontrollers with a 13-bit instruction word.[4] The instructions are mostly compatible with the mid-range 14-bit instruction set, but limited to a 6-bit register address (16 special-purpose registers and 48 bytes of RAM) and a 10-bit (1024 word) program space.

The 10-bit program counter is accessible as R2. Reads access only the low bits, and writes clear the high bits. An exception is the TBL instruction, which modifies the low byte while preserving bits 8 and 9.

The 7 accumulator-immediate instructions are renumbered relative to the 14-bit PICmicro, to fit into 3 opcode bits rather than 4, but they are all there, as well as an additional software interrupt instruction.

There are a few additional miscellaneous instructions, and there are some changes to the terminology (the PICmicro OPTION register is called the CONTrol register; the PICmicro TRIS registers 1–3 are called I/O control registers 5–7), but the equivalents are obvious.

13-bit EM78 instruction set[5][6]
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description
0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 NOP* No operation
0 0 0 0 0 0 0 0 0 0 0 0 1 DAA C Decimal Adjust after Addition
0 0 0 0 0 0 0 0 0 0 0 1 0 CONTW* Write CONT register (CONT ← W)
0 0 0 0 0 0 0 0 0 0 0 1 1 SLEP* Go into standby mode (WDT ← 0, stop clock)
0 0 0 0 0 0 0 0 0 0 1 0 0 WDTC* Restart watchdog timer (WDT ← 0)
0 0 0 0 0 0 0 0 0 f IOW f Copy W to I/O control register (f = 5–7, 11–15)
0 0 0 0 0 0 0 0 1 0 0 0 0 ENI Enable interrupts
0 0 0 0 0 0 0 0 1 0 0 0 1 DISI Disable interrupts
0 0 0 0 0 0 0 0 1 0 0 1 0 RET Return from subroutine, W unmodified
0 0 0 0 0 0 0 0 1 0 0 1 1 RETI Return from interrupt; return & enable interrupts
0 0 0 0 0 0 0 0 1 0 1 0 0 CONTR Read CONT register (W ← CONT)
0 0 0 0 0 0 0 0 1 f IOR f Copy I/O control register to W (f = 5–7, 11–15)
0 0 0 0 0 0 0 1 0 0 0 0 0 TBL C Z PCL += W, preserve PC bits 8 & 9
0 0 opcode d register ALU operations same as 12- and 14-bit PIC
0 1 opc bit register Bit operations same as 12- and 14-bit PIC
1 0 c k Control transfers same as 14-bit PIC
1 1 opcode 8-bit immediate Operations with W and 8-bit literal: W ← OP(k,W)
1 1 0 op k MOV/IOR/AND/XOR, same as 12-bit PIC
1 1 1 0 0 k RETLW k W ← k, then return from subroutine
1 1 1 0 1 k SUBLW k C Z W ← k−W (W ← k+~W+1)
1 1 1 1 0 0 k INT k Push PC, PC ← k (software interrupt, usually k=1)
1 1 1 1 1 k ADDLW k C Z W ← k+W
1 1 1 1 0 1 opcode k Extensions (replacing INT k for k≥128 on later models)[6][7][8]
1 1 1 1 0 1 0 0 0 k PAGE k Select ROM page k (like MOVLP k)
1 1 1 1 0 1 0 0 1 k BANK k Select RAM bank k
1 1 1 1 0 1 0 1 0 k LCALL k Long call with 17-bit address (2-word instruction)
1 1 1 1 0 1 0 1 1 k LJMP k Long jump with 17-bit address (2-word instruction)
1 1 1 1 0 1 1 f TBRD f Read ROM at TBHP:TBLP into specified register
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description

*: Same opcode as 12-bit PIC
†: Instruction unique to EM78 instruction set with no PIC equivalent

Some models support multiple ROM or RAM banks, in a manner similar to other PIC microcontrollers.

There is also a 15-bit variant of the instruction set, which is almost identical except that the register numbers are enlarged to 8 bits and the call and jump addresses are enlarged to 12 bits. Other differences:[9]

  • The CONTW, IOW, CONTR, IOR and INT instructions are deleted,
  • Operations with an 8-bit literal have two 0 bits added as bits 8 and 9,
  • Extensions with a 4-bit literal have two 0 bits added as bits 4 and 5, and
  • The PAGE and BANK instructions are renamed SBANK and GBANK and perform bank switching on special function registers and general-purpose RAM, respectively.

A second generation 15-bit instruction set includes several additional instructions:

15-bit EM78/EM88 instruction set extensions[10][11]
1
4
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description
0 0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 NOP* No operation
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 DAA* C Decimal Adjust after Addition
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 SLEP* Go into standby mode (WDT ← 0, stop clock)
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 WDTC* Restart watchdog timer (WDT ← 0)
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 MULW 8×8 → 16-bit multiply
0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 DIVW 8÷8 → 8,8-bit divide
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 ENI* Enable interrupts
0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 DISI* Disable interrupts
0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 RET* Return from subroutine, W unmodified
0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 RETI* Return from interrupt; return & enable interrupts
0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 RESET Software reset
0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 TBWR Flash ROM write
0 0 0 0 0 0 0 0 1 k INT k Software interrupt at address 2×k
0 0 0 0 0 0 0 1 bit f BTG f,b Invert (toggle) bit b of f (limited address range)
0 0 opcode d register ALU operations same as EM78 and PIC
0 1 opc bit register Bit operations same as EM78 and PIC
1 0 c k Control transfers same as EM78 and 14-bit PIC
1 1 opcode 0 0 8-bit immediate Operations with 8-bit literal same as EM78 (except INT)
1 1 opcode register or immediate Instruction set extensions
1 1 0 0 0 0 1 f JE r Skip if W = f
1 1 0 0 0 1 0 f JGE r Skip if W > f
1 1 0 0 0 1 1 f JLE r Skip if W < f
1 1 0 0 1 0 1 k JE k Skip if W = k
1 1 0 0 1 1 0 k (reserved)
1 1 0 0 1 1 1 f TBRDA f Read ROM at TBHP:TBLP into f; msbits into W
1 1 0 1 0 0 1 k SJC address Jump to PC + sext(k) if carry set
1 1 0 1 0 1 0 k SJNC address Jump to PC + sext(k) if carry clear
1 1 0 1 0 1 1 k SJZ address Jump to PC + sext(k) if zero flag set
1 1 0 1 1 0 1 k SJNZ address Jump to PC + sext(k) if zero flag clear
1 1 0 1 1 1 d f RR f/RRA dest ← f<<7 | f>>1, rotate right without carry
1 1 1 0 0 0 1 f XCH f Exchange f ↔ W
1 1 1 0 0 1 d f RL f/RLA dest ← f<<1 | f>>7, rotate left without carry
1 1 1 0 1 0 1 f MUL f PRODH:PRODL ← f × W
1 1 1 0 1 1 x k (reserved)
1 1 1 1 0 0 d f SUBB C Z dest ← f + ~W + C, subtract with carry
1 1 1 1 0 1 0 0 0 0 0 k SBANK k* Select special function register bank k
1 1 1 1 0 1 0 0 1 0 0 k GBANK k* Select RAM bank k
1 1 1 1 0 1 0 1 0 0 0 k LCALL k* Long call with 19-bit address (2-word instruction)
1 1 1 1 0 1 0 1 1 0 0 k LJMP k* Long jump with 19-bit address (2-word instruction)
1 1 1 1 0 1 1 f TBRD f* Read ROM at TBHP:TBLP into f
1 1 1 1 1 0 1 f NEG f C Z f ← −f (f ← ~f + 1), negate
1 1 1 1 1 1 d f ADC f C Z dest ← f + W + C, add with carry

*: Same opcode as 13-bit EM78
†: Only on EM89F768N; operands and results in special registers
‡: Only on EM88F794N, MTF213 and MTF351

Mid-range core devices (14 bit)

[edit]

These devices feature a 14-bit wide code memory, and an improved 8 level deep call stack. The instruction set differs very little from the baseline devices, but the 2 additional opcode bits allow 128 registers and 2048 words of code to be directly addressed. There are a few additional miscellaneous instructions, and two additional 8-bit literal instructions, add and subtract. The mid-range core is available in the majority of devices labeled PIC12 and PIC16.

14-bit PIC instruction set
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description
0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 0 NOP No operation
0 0 0 0 0 0 0 0 0 0 1 0 0 0 RETURN Return from subroutine, W unmodified
0 0 0 0 0 0 0 0 0 0 1 0 0 1 RETFIE Return from interrupt
0 0 0 0 0 0 0 1 1 0 0 0 1 0 OPTION Copy W to OPTION register (deprecated)
0 0 0 0 0 0 0 1 1 0 0 0 1 1 SLEEP Go into standby mode
0 0 0 0 0 0 0 1 1 0 0 1 0 0 CLRWDT Restart watchdog timer
0 0 0 0 0 0 0 1 1 0 0 1 f TRIS f Copy W to tri-state register (f = 1, 2 or 3) (deprecated)
0 0 opcode d register ALU operations: dest ← OP(f,W)
0 0 0 0 0 0 1 f MOVWF f f ← W
0 0 0 0 0 1 d f CLR f,d Z dest ← 0, usually written CLRW or CLRF f
0 0 0 0 1 0 d f SUBWF f,d C Z dest ← f−W (dest ← f+~W+1)
0 0 0 0 1 1 d f DECF f,d Z dest ← f−1
0 0 0 1 0 0 d f IORWF f,d Z dest ← f | W, logical inclusive or
0 0 0 1 0 1 d f ANDWF f,d Z dest ← f & W, logical and
0 0 0 1 1 0 d f XORWF f,d Z dest ← f ^ W, logical exclusive or
0 0 0 1 1 1 d f ADDWF f,d C Z dest ← f+W
0 0 1 0 0 0 d f MOVF f,d Z dest ← f
0 0 1 0 0 1 d f COMF f,d Z dest ← ~f, bitwise complement
0 0 1 0 1 0 d f INCF f,d Z dest ← f+1
0 0 1 0 1 1 d f DECFSZ f,d dest ← f−1, then skip if zero
0 0 1 1 0 0 d f RRF f,d C dest ← CARRY<<7 | f>>1, rotate right through carry
0 0 1 1 0 1 d f RLF f,d C dest ← f<<1 | CARRY, rotate left through carry
0 0 1 1 1 0 d f SWAPF f,d dest ← f<<4 | f>>4, swap nibbles
0 0 1 1 1 1 d f INCFSZ f,d dest ← f+1, then skip if zero
0 1 opc bit register Bit operations
0 1 0 0 bit f BCF f,b Clear bit b of f
0 1 0 1 bit f BSF f,b Set bit b of f
0 1 1 0 bit f BTFSC f,b Skip if bit b of f is clear
0 1 1 1 bit f BTFSS f,b Skip if bit b of f is set
1 0 c k Control transfers
1 0 0 k CALL k Call subroutine
1 0 1 k GOTO k Jump to address k
1 1 opcode 8-bit immediate Operations with W and 8-bit literal: W ← OP(k,W)
1 1 0 0 x x k MOVLW k W ← k
1 1 0 1 x x k RETLW k W ← k, then return from subroutine
1 1 1 0 0 0 k IORLW k Z W ← k | W, bitwise logical or
1 1 1 0 0 1 k ANDLW k Z W ← k & W, bitwise and
1 1 1 0 1 0 k XORLW k Z W ← k ^ W, bitwise exclusive or
1 1 1 0 1 1 k (reserved)
1 1 1 1 0 x k SUBLW k C Z W ← k−W (dest ← k+~W+1)
1 1 1 1 1 x k ADDLW k C Z W ← k+W
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description

Enhanced mid-range core devices (14 bit)

[edit]

Enhanced mid-range core devices introduce a deeper hardware stack, additional reset methods, 14 additional instructions and C programming language optimizations.[12] In particular. there are two INDF registers (INDF0 and INDF1), and two corresponding FSR register pairs (FSRnL and FSRnH). Special instructions use FSRn registers like address registers, with a variety of addressing modes.

14-bit enhanced PIC additional instructions
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description
0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 1 RESET Software reset
0 0 0 0 0 0 0 0 0 0 1 0 1 0 CALLW Push PC, then jump to PCLATH:W
0 0 0 0 0 0 0 0 0 0 1 0 1 1 BRW PC ← PC + W, relative jump using W
0 0 0 0 0 0 0 0 0 1 0 n 0 0 MOVIW ++FSRn Z Increment FSRn, then W ← INDFn
0 0 0 0 0 0 0 0 0 1 0 n 0 1 MOVIW −−FSRn Z Decrement FSRn, then W ← INDFn
0 0 0 0 0 0 0 0 0 1 0 n 1 0 MOVIW FSRn++ Z W ← INDFn, then increment FSRn
0 0 0 0 0 0 0 0 0 1 0 n 1 1 MOVIW FSRn−− Z W ← INDFn, then decrement FSRn
0 0 0 0 0 0 0 0 0 1 1 n m MOVWI using FSRn INDFn ← W, same modes as MOVIW
0 0 0 0 0 0 0 0 1 k MOVLB k BSR ← k, move literal to bank select register
1 1 opcode d register ALU operations: dest ← OP(f,W)
1 1 0 1 0 1 d f LSLF f,d C Z dest ← f << 1, logical shift left
1 1 0 1 1 0 d f LSRF f,d C Z dest ← f >> 1, logical shift right
1 1 0 1 1 1 d f ASRF f,d C Z dest ← f >> 1, arithmetic shift right
1 1 1 0 1 1 d f SUBWFB f,d C Z dest ← f + ~W + C, subtract with carry
1 1 1 1 0 1 d f ADDWFC f,d C Z dest ← f + W + C, add with carry
1 1 opcode k Operations with literal k
1 1 0 0 0 1 0 n k ADDFSR FSRn,k FSRn ← FSRn + k, add 6-bit signed offset
1 1 0 0 0 1 1 k MOVLP k PCLATH ← k, move 7-bit literal to PC latch high
1 1 0 0 1 k BRA k PC ← PC + k, branch relative using 9-bit signed offset
1 1 1 1 1 1 0 n k MOVIW k[FSRn] Z W ← [FSRn+k], 6-bit signed offset
1 1 1 1 1 1 1 n k MOVWI k[FSRn] [FSRn+k] ← W, 6-bit signed offset
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
Description

Holtek clones (14, 15 or 16 bit)

[edit]

Holtek make numerous 8-bit microcontrollers with a 14-bit instruction word equivalent to the (non-enhanced) mid-range core. The instruction encodings all fit into 14 bits and provide 7-bit operand addresses.

The instruction format is identical to Microchip's, but the opcodes are assigned in a different order, and the manufacturer uses different instruction mnemonics. The accumulator is called ACC rather than W, and the destination is specified by a suffix to the instruction mnemonic rather than an operand. (Instructions which do not use the accumulator by default write back to memory, and use an A suffix to indicate the destination is the accumulator. Two-operand instructions by default write to the accumulator, and use an M suffix to indicate a memory destination.)

In addition to the different opcode assignment, there are semantic differences in a few instructions:

  • The subtract instructions subtract the operand from the accumulator, while Microchip's subtract instructions do the reverse. (This makes the subtract immediate instruction redundant, as it is equivalent to an add of the negative.)
  • The move-to-accumulator and clear instructions do not modify any flags.
  • In addition to the zero, carry, and digit carry flags (called AC by Holtek), there an overflow flag which is set by the same add and subtract instructions which set AC.

Several operations have been added to the 14-bit PICmicro repertoire:

  • Rotate one bit left and right without carry,
  • Set operand to all-ones,
  • Skip if operand is zero (without incrementing or decrementing it first),
  • Skip if operand is non-zero (some models),
  • Add and subtract with carry,
  • Decimal adjust after addition, for binary-coded decimal arithmetic, and
  • Read from program ROM, for table lookup. This uses TBHP and TBLP registers as a 16-bit pointer, fetches the word there, and stores the low byte in a specified location. The high 6–8 bits of the fetched word are stored in the TBLH register. A second form uses only TBLP and reads from the highest 256-byte page in ROM. Some models include a variant which pre-increments TBLP.
  • Most models support a second instruction to reset the watchdog timer, which must alternate with the first; repetitions of one instruction are ignored. This permits two independent watchdog routines to run, and failure of either will trigger the watchdog.
  • Holtek provide two indirect addressing registers, like the enhanced 14-bit PIC. Some models (e.g. HT66F70A) provide three. The first indirect addressing register (IAR0) uses an 8-bit address register (MP0), and always addresses the low bank of RAM. IAR1 and IAR2 provide additional RAM address bits (MP1H and MP2H) and allow access to additional banks of RAM.[13]

15-bit models use bit 14 of the instruction as an 8th operand address bit and a 12th CALL/JMP target address bit. 16-bit models add a 13th CALL/JMP target address bit, but do not add a 9th operand addresses bit.[14]

Instead, some 16-bit models support an extended instruction set. This adds a few new instructions (skip on byte without inc/decrement, subtract immediate with carry, ROM read with address increment), but also adds 2-word "long" variants of all memory instructions. When bit 15 of the opcode is set, it indicates that the 8-bit operand address in opcode bits 0–6 and 14 is extended to 16 bits using bits 0–7 of the following instruction word. Such instructions are written with an L prefix (LADD vs. ADD) and take an extra cycle to execute.[13]

14-bit Holtek instruction set[15]
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic PIC
equivalent
C
?
Z
?
Description
0 0 0 0 0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 0 NOP NOP No operation
0 0 0 0 0 0 0 0 0 0 0 0 0 1 CLR WDT1 CLRWDT Restart watchdog timer
0 0 0 0 0 0 0 0 0 0 0 0 1 0 HALT SLEEP Go into low-power mode
0 0 0 0 0 0 0 0 0 0 0 0 1 1 RET RETURN Return from subroutine
0 0 0 0 0 0 0 0 0 0 0 1 0 0 RETI RETFIE Return from interrupt
0 0 0 0 0 0 0 0 0 0 0 1 0 1 CLR WDT2 ≈CLRWDT Restart watchdog timer
0 0 0 0 0 0 0 0 0 0 0 1 1 x (reserved)
0 0 0 0 0 0 0 ≠0 x x x (reserved)
0 0 0 opcode d address ALU operations part 1: dest ← OP(ACC,[m])*
0 0 0 0 0 0 1 m MOV [m],A MOVWF m [m] ← ACC
0 0 0 0 0 1 d m CPLA/CPL [m] COMF m,d Z dest ← ~[m], bitwise complement
0 0 0 0 1 0 d m SUB/SUBM A,[m] ≠SUBWF m,d C Z dest ← ACC − [m] (dest ← ACC+~[m]+1)
0 0 0 0 1 1 d m ADD/ADDM A,[m] ADDWF m,d C Z dest ← ACC + [m]
0 0 0 1 0 0 d m XOR/XORM [m] XORWF m,d Z dest ← ACC ^ [m], logical exclusive or
0 0 0 1 0 1 d m OR/ORM [m] IORWF m,d Z dest ← ACC | [m], logical inclusive or
0 0 0 1 1 0 d m AND/ANDM [m] ANDWF m,d Z dest ← ACC & [m], logical and
0 0 0 1 1 1 0 m MOV A,[m] ≈MOVF m,0 ACC ← [m]
0 0 0 1 1 1 1 m ≈MOVF m,1 [m] ← [m]
0 0 1 opcode 8-bit immediate Operations with 8-bit literal: ACC ← OP(ACC,k)
0 0 1 0 0 0 k SBC A,k C Z ACC ← ACC + ~[m] + C, subtract with carry
0 0 1 0 0 1 k RET A,k RETLW k ACC ← k, then return from subroutine
0 0 1 0 1 0 k SUB A,k ≠SUBLW k C Z ACC ← ACC − k (ACC ← ACC+~k+1)
0 0 1 0 1 1 k ADD A,k ADDLW k C Z ACC ← ACC + k
0 0 1 1 0 0 k XOR A,k XORLW k Z ACC ← ACC ^ k, logical exclusive or
0 0 1 1 0 1 k OR A,k IORLW k Z ACC ← ACC | k, logical inclusive or
0 0 1 1 1 0 k AND A,k ANDLW k Z ACC ← ACC & k, logical and
0 0 1 1 1 1 k MOV A,k MOVLW k ACC ← k
0 1 opcode d address ALU operations part 2: dest ← OP(ACC,[m])*
0 1 0 0 0 0 d m SZA/SZ [m] dest ← [m], skip next instruction if zero
0 1 0 0 0 1 d m SWAPA/SWAP [m] SWAPF m,d dest ← [m]<<4 | [m]>>4, swap nibbles
0 1 0 0 1 0 d m SBC/SBCM A,[m] ≠SUBWFB m,d C Z dest ← ACC + ~[m] + C, subtract with carry
0 1 0 0 1 1 d m ADC/ADCM A,[m] ADDWFC m,d C Z dest ← ACC + [m] + C, add with carry
0 1 0 1 0 0 d m INCA/INC [m] INCF m,d Z dest ← [m] + 1
0 1 0 1 0 1 d m DECA/DEC [m] DECF m,d Z dest ← [m] − 1
0 1 0 1 1 0 d m SIZA/SIZ [m] INCFSZ m,d dest ← [m] + 1, then skip if zero
0 1 0 1 1 1 d m SDZA/SDZ [m] DECFSZ m,d dest ← [m] − 1, then skip if zero
0 1 1 0 0 0 d m RLA/RL [m] dest ← [m] << 1 | [m] >> 7, rotate left 1 bit
0 1 1 0 0 1 d m RRA/RR [m] dest ← [m] << 7 | [m] >> 1, rotate right 1 bit
0 1 1 0 1 0 d m RLCA/RLC [m] RLF m,d C dest ← [m] << 1 | C, rotate left through carry
0 1 1 0 1 1 d m RRCA/RRC [m] RRF m,d C dest ← C << 7 | [m] >> 1, rotate right through carry
0 1 1 1 opcode address Special operations: [m] ← special*
0 1 1 1 0 0 0 m ITABRD [m] TBLH:[m] ← ROM[TBHP:++TBLP], with pre-increment
0 1 1 1 0 0 1 m ITABRDL [m] TBLH:[m] ← ROM[0xff:++TBLP], with pre-increment
0 1 1 1 0 1 0 m TABRD [m] TBLH:[m] ← ROM[TBHP:TBLP], table lookup
0 1 1 1 0 1 1 m TABRDL [m] TBLH:[m] ← ROM[0xff:TBLP], read from last page of ROM
0 1 1 1 1 0 0 m SNZ [m] [m] ← [m], skip next instruction if non-zero
0 1 1 1 1 0 1 m DAA [m] C [m] ← DAA(ACC), decimal adjust after BCD addition
0 1 1 1 1 1 0 m CLR [m] ≈CLRF m [m] ← 0
0 1 1 1 1 1 1 m SET [m] [m] ← 255
1 0 c k Control transfers
1 0 0 k CALL k CALL k Call subroutine
1 0 1 k JMP k GOTO k Jump to address k
1 1 opc bit address Bit operations*
1 1 0 0 bit m SET [m].b BSF m,b Set bit b of [m]
1 1 0 1 bit m CLR [m].b BCF m,b Clear bit b of [m]
1 1 1 0 bit m SNZ [m].b BTFSS m,b Skip if bit b of [m] is set
1 1 1 1 bit m SZ [m].b BTFSC m,b Skip if bit b of [m] is clear
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic PIC
equivalent
C
?
Z
?
Description

*: Instructions available in long forms on 16-bit models with extended instruction set.
†: Instruction only available on 16-bit models with extended instruction set.

Padauk microcontrollers (13, 14, 15 or 16 bit)

[edit]

Padauk Technology make a series of PIC-like microcontrollers notable for their extremely low cost, beginning at US$0.033 in quantity,[16] with many models costing less than US$0.10.[17][18][19]

Although clearly derived from the Microchip PIC12 series,[17][20] there are some significant differences:

  • They do not use the FSR/INDF mechanism for performing indirect memory access, instead having indirect load and store instructions which use an arbitrary RAM location as a pointer;
  • they use a RAM-based call stack, with a stack pointer register;
  • the carry flag uses a "borrow bit" convention for subtracts, rather than the "carry bit" convention used by Microchip;
  • they also include a signed overflow flag, which like the digit carry, is set by add, subtract and compare instructions (every instruction which sets the carry flag except for shift instructions);
  • they have separate RAM and I/O register addresses spaces (64 and 32 bytes, respectively, in the 13-bit instruction set);
  • bit operations are limited to the I/O space and first 16 RAM addresses;
  • the single-operand instructions with a memory source and accumulator destination are omitted;
  • single-operand instructions with accumulator source and destination are provided;
  • subtraction operations compute destination − source, exchanging input operands depending on the destination;
  • they operate faster, requiring 1 cycle for most instructions and 2 cycles for control transfers; and
  • some models support temporal multithreading, having multiple execution contexts whose execution is interleaved.
13-bit Padauk instruction set[21][22]
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic PIC
equivalent
C
?
Z
?
Description
0 0 0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 NOP NOP No operation
0 0 0 0 0 0 0 0 0 0 0 0 1 (reserved)
0 0 0 0 0 0 0 0 0 0 0 1 x (reserved)
0 0 0 0 0 0 0 0 0 0 1 0 x (reserved)
0 0 0 0 0 0 0 0 0 0 1 1 0 LDSPTL A ← ROM[[SP]], load low/high byte of ROM word using 16-bit pointer on top of stack
0 0 0 0 0 0 0 0 0 0 1 1 1 LDSPTH
0 0 0 0 0 0 0 0 0 1 (reserved)
0 0 0 0 0 0 0 0 1 opcode One-operand instructions on accumulator
Same as one-operand instructions on memory (below) except
0 0 0 0 0 0 0 0 1 0 1 1 1 PCADD A ≈ADDWF PCL,1 PC ← PC + A, add to program counter (not XCH A)
0 0 0 0 0 0 0 0 1 1 1 1 0 SWAP A A ← A<<4 | A>>4, swap nibbles (not CEQSN A)
0 0 0 0 0 0 0 1 0 (reserved)
0 0 0 0 0 0 0 1 1 opcode System control instructions
0 0 0 0 0 0 0 1 1 0 0 0 0 WDRESET CLRWDT Restart watchdog timer
0 0 0 0 0 0 0 1 1 0 0 0 1 (reserved)
0 0 0 0 0 0 0 1 1 0 0 1 0 PUSHAF Push A then flags on top of stack
0 0 0 0 0 0 0 1 1 0 0 1 1 POPAF C Z Pop flags then A from top of stack
0 0 0 0 0 0 0 1 1 0 1 0 0 (reserved)
0 0 0 0 0 0 0 1 1 0 1 0 1 RESET RESET Software reset
0 0 0 0 0 0 0 1 1 0 1 1 0 STOPSYS SLEEP Go into standby mode (clock stopped)
0 0 0 0 0 0 0 1 1 0 1 1 1 STOPEXE Go into standby mode (clock running)
0 0 0 0 0 0 0 1 1 1 0 0 0 ENGINT BSF INTCON,GIE Enable interrupts
0 0 0 0 0 0 0 1 1 1 0 0 1 DISGINT BCF INTCON,GIE Disable interrupts
0 0 0 0 0 0 0 1 1 1 0 1 0 RET RETURN Return from subroutine, A unmodified
0 0 0 0 0 0 0 1 1 1 0 1 1 RETI RETFIE Return from interrupt
0 0 0 0 0 0 0 1 1 1 1 0 0 MUL MULRH:A ← A × MULOP (not all models)
0 0 0 0 0 0 0 1 1 1 1 0 1 (reserved)
0 0 0 0 0 0 0 1 1 1 1 1 x (reserved)
0 0 0 0 0 opcode ioaddr Byte-wide I/O operations
0 0 0 0 0 0 1 1 ioaddr XOR ioaddr,A IO[ioaddr] ← A ^ IO[address]
0 0 0 0 0 1 0 0 ioaddr MOV ioaddr,A IO[ioaddr] ← A
0 0 0 0 0 1 0 1 ioaddr MOV A,ioaddr Z A ← IO[ioaddr]
0 0 0 0 0 1 1 c address c 16-bit operations (RAM address limited, even)
0 0 0 0 0 1 1 0 address 0 STT16 addr Timer16 ← [address]
0 0 0 0 0 1 1 0 address 1 LDT16 addr [address] ← Timer16
0 0 0 0 0 1 1 1 address 0 IDXM addr,A [[address]] ← A, indirect memory address
0 0 0 0 0 1 1 1 address 1 IDXM A,addr A ← [[address]], indirect memory address
0 0 0 0 1 k Return literal constant
0 0 0 0 1 k RET k RETLW k A ← k, then return from subroutine
0 0 0 1 c bit c address Bit operations with RAM (first 16 bytes only)
0 0 0 1 0 bit 0 address T0SN addr.b BTFSC addr,b Skip if bit b of [addr] is clear
0 0 0 1 0 bit 1 address T1SN addr.b BTFSS addr,b Skip if bit b of [addr] is set
0 0 0 1 1 bit 0 address SET0 addr.b BCF addr,b Clear bit b of [addr]
0 0 0 1 1 bit 1 address SET1 addr.b BSF addr,b Set bit b of [addr]
0 0 1 d opcode address ALU operations between A and memory
0 0 1 0 0 0 0 address ADD addr,A ADDWF addr,1 C Z [addr] ← [addr] + A
0 0 1 0 0 0 1 address SUB addr,A SUBWF addr,1 C Z [addr] ← [addr] − A
0 0 1 0 0 1 0 address ADDC addr,A ADDWFC addr,1 C Z [addr] ← [addr] + A + C
0 0 1 0 0 1 1 address SUBC addr,A ≈SUBWFB addr,1 C Z [addr] ← [addr] − A − C
0 0 1 0 1 0 0 address AND addr,A ANDWF addr,1 Z [addr] ← [addr] & A, logical and
0 0 1 0 1 0 1 address OR addr,A IORWF addr,1 Z [addr] ← [addr] | A, logical inclusive or
0 0 1 0 1 1 0 address XOR addr,A XORWF addr,1 Z [addr] ← [addr] ^ A, logical exclusive or
0 0 1 0 1 1 1 address MOV addr,A MOVWF addr [addr] ← A
0 0 1 1 0 0 0 address ADD A,addr ADDWF addr,0 C Z A ← A + [addr]
0 0 1 1 0 0 1 address SUB A,addr ≠SUBWF addr,0 C Z A ← A − [addr]
0 0 1 1 0 1 0 address ADDC A,addr ADDWFC addr,0 C Z A ← A + [addr] + C
0 0 1 1 0 1 1 address SUBC A,addr ≠SUBWFB addr,0 C Z A ← A − [addr] − C
0 0 1 1 1 0 0 address AND A,addr ANDWF addr,0 Z A ← [A] & [addr], logical and
0 0 1 1 1 0 1 address OR A,addr IORWF addr,0 Z A ← A | [addr], logical inclusive or
0 0 1 1 1 1 0 address XOR A,addr XORWF addr,0 Z A ← A ^ [addr], logical exclusive or
0 0 1 1 1 1 1 address MOV A,addr MOVF addr,0 Z A ← [addr]
0 1 0 opcode address One-operand operations on memory
0 1 0 0 0 0 0 address ADDC addr C Z [addr] ← [addr] + C
0 1 0 0 0 0 1 address SUBC addr C Z [addr] ← [addr] − C
0 1 0 0 0 1 0 address IZSN addr INCFSZ addr,1 C Z [addr] ← [addr] + 1, then skip if zero
0 1 0 0 0 1 1 address DZSN addr DECFSZ addr,1 C Z [addr] ← [addr] − 1, then skip if zero
0 1 0 0 1 0 0 address INC addr INCF addr,1 C Z [addr] ← [addr] + 1
0 1 0 0 1 0 1 address DEC addr DECF addr,1 C Z [addr] ← [addr] − 1
0 1 0 0 1 1 0 address CLEAR addr ≈CLRF addr [addr] ← 0
0 1 0 0 1 1 1 address XCH addr A ← [addr], [addr] ← A
0 1 0 1 0 0 0 address NOT addr COMF addr,1 Z [addr] ← ~[addr], bitwise complement
0 1 0 1 0 0 1 address NEG addr Z [addr] ← −[addr], negate
0 1 0 1 0 1 0 address SR addr ≈LSRF addr,1 C [addr] ← [addr] >> 1, logical shift right
0 1 0 1 0 1 1 address SL addr ≈LSLF addr,1 C [addr] ← [addr] << 1, shift left
0 1 0 1 1 0 0 address SRC addr RRF addr,1 C [addr] ← C << 7 | [addr] >> 1, rotate right through carry
0 1 0 1 1 0 1 address SLC addr RLF addr,1 C [addr] ← [addr] << 1 | C, rotate left through carry
0 1 0 1 1 1 0 address CEQSN addr C Z Compute A − [addr], then skip if zero
0 1 0 1 1 1 1 address (reserved for CNEQSN)
0 1 1 opc bit address Bit operations with I/O
0 1 1 0 0 bit address T0SN ioaddr.b BTFSC ioaddr,b Skip if bit b of [ioaddr] is clear
0 1 1 0 1 bit address T1SN ioaddr.b BTFSS ioaddr,b Skip if bit b of [ioaddr] is set
0 1 1 1 0 bit address SET0 ioaddr.b BCF ioaddr,b Clear bit b of [ioaddr]
0 1 1 1 1 bit address SET1 ioaddr.b BSF ioaddr,b Set bit b of [ioaddr]
1 0 opcode literal Literal operations: A ← OP(A,k)
1 0 0 0 0 k ADD A,k ADDLW k C Z A ← A + k
1 0 0 0 1 k SUB A,k ≠SUBLW k C Z A ← A − k
1 0 0 1 0 k CEQSN A,k C Z Compute A − k, then skip if zero
1 0 0 1 1 k (reserved for CNEQSN)
1 0 1 0 0 k AND A,k ≈ANDLW k Z A ← A & k
1 0 1 0 1 k OR A,k ≈IORLW k Z A ← A | k
1 0 1 1 0 k XOR A,k ≈XORLW k Z A ← A ^ k
1 0 1 1 1 k MOV A,k MOVLW k A ← k
1 1 c k Control transfers: PC ← k
1 1 0 k GOTO k GOTO k PC ← k
1 1 1 k CALL k CALL k Push PC, then PC ← k
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic PIC
equivalent
C
?
Z
?
Description

The 14-, 15- and 16-bit instruction sets primarily differ in having wider address fields, although some encoding changes are made to allow a few additional instructions (such as CNEQSN, which performs a compare and skip if not equal.)

14-bit Padauk instruction set[23][24]
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic PIC
equivalent
C
?
Z
?
Description
0 0 0 0 0 0 0 0 0 0 opcode Miscellaneous instructions same as 13-bit
0 0 0 0 0 0 0 0 0 1 (reserved)
0 0 0 0 0 0 0 0 1 (reserved)
0 0 0 0 0 0 0 1 0 (reserved)
0 0 0 0 0 0 0 1 1 0 opcode One-operand instructions on A same as 13-bit
0 0 0 0 0 0 0 1 1 1 opcode System control instructions same as 13-bit
0 0 0 0 0 0 1 0 (reserved)
0 0 0 0 0 opcode address Byte-wide I/O operations same as 13-bit, but opcodes changed
0 0 0 0 0 0 1 1 ioaddr XOR ioaddr,A IO[ioaddr] ← A ^ IO[address]
0 0 0 0 0 1 0 (reserved)
0 0 0 0 0 1 1 0 ioaddr MOV ioaddr,A IO[ioaddr] ← A
0 0 0 0 0 1 1 1 ioaddr MOV A,ioaddr Z A ← IO[ioaddr]
0 0 0 0 1 0 k Return literal constant same as 13-bit
0 0 0 0 1 1 c address c 16-bit operations same as 13-bit, but 128-byte range
0 0 0 1 0 bit address Copy bit to I/O
0 0 0 1 0 bit address SWAPC ioaddr.b C Swap carry with [ioaddr] bit b
0 0 0 1 1 c d address Additional 2-operand operations
0 0 0 1 1 0 0 address COMP A,addr C Z A − [addr], flags set, result discarded
0 0 0 1 1 0 1 address COMP addr,A C Z [addr] − A, flags set, result discarded
0 0 0 1 1 1 0 address NADD A,addr SUBWF addr,0 C Z A ← [addr] + −A (A ← [addr] + ~A + 1)
0 0 0 1 1 1 1 address NADD addr,A C Z [addr] ← A + −[addr] ([addr] ← A + ~[addr] + 1)
0 0 1 d opcode address 2-operand instructions same as 13-bit
0 1 0 opcode address One-operand operations on memory same as 13-bit, plus CNEQSN
0 1 0 1 1 1 1 address CNEQSN addr C Z Compute A − [addr], then skip if non-zero
0 1 1 opc bit ioaddr Bit operations with I/O same as 13-bit, but 64-byte range
1 0 0 opc bit address Bit operations with memory same as 13-bit, but 64-byte range
1 0 1 opcode literal Literal operations same as 13-bit, plus CNEQSN
1 0 1 0 1 1 k CNEQSN A,k C Z Compute A − k, then skip if non-zero
1 1 c k Control transfers same as 13-bit
1
13
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic PIC
equivalent
C
?
Z
?
Description

PIC18 high end core devices (16 bit)

[edit]

In 2000, Microchip introduced the PIC18 architecture.[1] Unlike the 17 series, it has proven to be very popular, with a large number of device variants presently in manufacture. In contrast to earlier devices, which were more often than not programmed in assembly, C has become the predominant development language.[25]

The PIC18 has a 12-bit RAM address space, divided into 16 pages of 256 bytes. The 8-bit f field determines the address in combination with the a bit and the 4-bit bank select register (BSR). If a=0, the BSR is ignored and the f field is sign-extended to the range 0x000–0x07F (global RAM) or 0xF80–0xFFF (special function registers). If a=1, the f field is extended with the BSR to generate the 12-bit address.

The PIC18 extends the FSR/INDF mechanism used in previous PICmicro processors for indirect addressing in two ways:

First, it provides three file select registers. The FSRn registers are 12 bits long (each split into two 8-bit portions FSR0L through FSR2H), and access to the corresponding INDFn register (INDF0 through INDF2) acts as an alias for the addressed byte.

Second, there are addressing modes. For each of the three, there is not just one INDFn register, but five, and the one used determines the addressing mode:

  • INDFn: Access the byte at location FSRn
  • POSTDECn: Access the byte at FSRn, then decrement FSRn
  • POSTINCn: Access the byte at FSRn, then increment FSRn
  • PREINCn: Increment FSRn, then access the byte at the incremented FSRn
  • PLUSWn: Access the byte at FSRn + W (indexed addressing).

There are also instructions to directly load an FSR pair with a 12-bit address, and a MOVFF instruction that moves a byte between two 12-bit addresses.

PIC18 16-bit instruction set[26]
1
5
1
4
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
N
?
Description
0 0 0 0 0 0 0 0 opcode Miscellaneous instructions
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 NOP No operation
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 SLEEP Go into standby mode
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 CLRWDT Restart watchdog timer
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 PUSH Push PC on top of stack
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 POP Pop (and discard) top of stack
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 DAW C Decimal adjust W
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 TBLRD∗ Table read: TABLAT ← mem[TBLPTR]
0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 TBLRD∗+ Table read with postincrement
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 TBLRD∗− Table read with postdecrement
0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 TBLRD+∗ Table read with pre-increment
0 0 0 0 0 0 0 0 0 0 0 0 1 1 mod TBLWR Table write, same modes as TBLRD
0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 s RETFIE [, FAST] Return from interrupt
0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 s RETURN [, FAST] Return from subroutine
0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 CALLW* Push PC, jump to PCLATU:PCLATH:W
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 RESET 0 0 0 Software reset
0 0 0 0 0 0 0 1 —0— k MOVLB Move literal k to bank select register
0 0 0 0 1 opcode literal Literal operations: W ← OP(k,W)
0 0 0 0 1 0 0 0 k SUBLW k W ← k − W
0 0 0 0 1 0 0 1 k IORLW k W ← k | W, logical inclusive or
0 0 0 0 1 0 1 0 k XORLW k W ← k ^ W, exclusive or
0 0 0 0 1 0 1 1 k ANDLW k W ← k & W, logical and
0 0 0 0 1 1 0 0 k RETLW k RETURN W ← k
0 0 0 0 1 1 0 1 k MULLW k W ← k × W
0 0 0 0 1 1 1 0 k MOVLW k W ← k
0 0 0 0 1 1 1 1 k ADDLW k W ← k + W
0 opcode d a register ALU operations: dest ← OP(f,W)
0 0 0 0 0 0 1 a f MULWF f,a PRODH:PRODL ← W × f (unsigned)
0 0 0 0 0 1 d a f DECF f,d,a C Z N dest ← f − 1
0 0 0 1 0 0 d a f IORWF f,d,a Z N dest ← f | W, logical inclusive or
0 0 0 1 0 1 d a f ANDWF f,d,a Z N dest ← f & W, logical and
0 0 0 1 1 0 d a f XORWF f,d,a Z N dest ← f ^ W, exclusive or
0 0 0 1 1 1 d a f COMF f,d,a Z N dest ← ~f, bitwise complement
0 0 1 0 0 0 d a f ADDWFC f,d,a C Z N dest ← f + W + C
0 0 1 0 0 1 d a f ADDWF f,d,a C Z N dest ← f + W
0 0 1 0 1 0 d a f INCF f,d,a C Z N dest ← f + 1
0 0 1 0 1 1 d a f DECFSZ f,d,a dest ← f − 1, skip if 0
0 0 1 1 0 0 d a f RRCF f,d,a C Z N dest ← f>>1 | C<<7, rotate right through carry
0 0 1 1 0 1 d a f RLCF f,d,a C Z N dest ← f<<1 | C, rotate left through carry
0 0 1 1 1 0 d a f SWAPF f,d,a dest ← f<<4 | f>>4, swap nibbles
0 0 1 1 1 1 d a f INCFSZ f,d,a dest ← f + 1, skip if 0
0 1 0 0 0 0 d a f RRNCF f,d,a Z N dest ← f>>1 | f<<7, rotate right (no carry)
0 1 0 0 0 1 d a f RLNCF f,d,a Z N dest ← f<<1 | f>>7, rotate left (no carry)
0 1 0 0 1 0 d a f INFSNZ f,d,a dest ← f + 1, skip if not 0
0 1 0 0 1 1 d a f DCFSNZ f,d,a dest ← f − 1, skip if not 0
0 1 0 1 0 0 d a f MOVF f,d,a Z N dest ← f
0 1 0 1 0 1 d a f SUBFWB f,d,a C Z N dest ← W + ~f + C (dest ← W − f − C̅)
0 1 0 1 1 0 d a f SUBWFB f,d,a C Z N dest ← f + ~W + C (dest ← f − W − C̅)
0 1 0 1 1 1 d a f SUBWF f,d,a C Z N dest ← f − W (dest ← f + ~W + 1)
0 1 1 0 opcode a register ALU operations, do not write to W
0 1 1 0 0 0 0 a f CPFSLT f,a skip if f < W (unsigned)
0 1 1 0 0 0 1 a f CPFSEQ f,a skip if f == W
0 1 1 0 0 1 0 a f CPFSGT f,a skip if f > W (unsigned)
0 1 1 0 0 1 1 a f TSTFSZ f,a skip if f == 0
0 1 1 0 1 0 0 a f SETF f,a f ← 0xFF
0 1 1 0 1 0 1 a f CLRF f,a 1 f ← 0, PSR.Z ← 1
0 1 1 0 1 1 0 a f NEGF f,a C Z N f ← −f
0 1 1 0 1 1 1 a f MOVWF f,a f ← W
0 1 1 1 bit a f BTG f,b,a Toggle bit b of f
1 0 opc bit a register Bit operations
1 0 0 0 bit a f BSF f,b,a Set bit b of f
1 0 0 1 bit a f BCF f,b,a Clear bit b of f
1 0 1 0 bit a f BTFSS f,b,a Skip if bit b of f is set
1 0 1 1 bit a f BTFSC f,b,a Skip if bit b of f is clear
1 1 0 opc address Large-address operations
1 1 0 0 source MOVFF s,d Move absolute
1 1 1 1 destination
1 1 0 1 0 n BRA n Branch to PC + 2n
1 1 0 1 1 n RCALL n Subroutine call to PC + 2n
1 1 1 0 0 cond n Conditional branch (to PC+2n)
1 1 1 0 0 0 0 0 n BZ n Branch if PSR.Z is set
1 1 1 0 0 0 0 1 n BNZ n Branch if PSR.Z is clear
1 1 1 0 0 0 1 0 n BC n Branch if PSR.C is set
1 1 1 0 0 0 1 1 n BNC n Branch if PSR.C is clear
1 1 1 0 0 1 0 0 n BOV n Branch if PSR.V is set
1 1 1 0 0 1 0 1 n BNOV n Branch if PSR.V is clear
1 1 1 0 0 1 1 0 n BN n Branch if PSR.N is set
1 1 1 0 0 1 1 1 n BNN n Branch if PSR.N is clear
1 1 1 0 1 0 opc k Extensions for using FSR2 as software stack pointer*
1 1 1 0 1 0 0 0 n k ADDFSR n,k* FSRn += k
1 1 1 0 1 0 0 0 1 1 k ADDULNK k* FSR2 += k, pop PC
1 1 1 0 1 0 0 1 n k SUBFSR n,k* FSRn −= k
1 1 1 0 1 0 0 1 1 1 k SUBULNK k* FSR2 −= k, pop PC
1 1 1 0 1 0 1 0 k PUSHL k* [FSR2] ← k, decrement FSR2
1 1 1 0 1 0 1 1 0 s MOVSF src,f* f ← FSR2[s]
1 1 1 1 f
1 1 1 0 1 0 1 1 1 s MOVSS src,dst* FSR2[d] ← FSR2[s]
1 1 1 1 —0— d
1 1 1 0 1 1 opc k 2-word instructions
1 1 1 0 1 1 0 s k (lsbits) CALL k[, FAST] Call subroutine (20-bit address)
1 1 1 1 k (msbits)
1 1 1 0 1 1 1 0 0 0 f k (msb) LFSR f,k Move 12-bit literal to FSRf
1 1 1 1 0 0 0 0 k (lsbits)
1 1 1 0 1 1 1 1 k (lsbits) GOTO k Absolute jump, PC ← k (20-bit address)
1 1 1 1 k (msbits)
1 1 1 1 k No operation, second word of 2-word instructions
1
5
1
4
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
N
?
Description

*: These extended instructions are only available on some models, and then only if the XINST configuration bit is set.

PIC24 and dsPIC 16-bit microcontrollers

[edit]

In 2001, Microchip introduced the dsPIC series of chips,[27] which entered mass production in late 2004. They are Microchip's first inherently 16-bit microcontrollers. PIC24 devices are designed as general purpose microcontrollers. dsPIC devices include digital signal processing capabilities in addition.

Instructions come in two main varieties. One is like the classic one-operand PIC instructions, with an operation between W0 and a value in a specified f register (i.e. the first 8K of RAM), and a destination select bit selecting which is updated with the result. The W registers are memory-mapped, so the f operand may specify a W register.

The other form, new to the PIC24, specifies three W register operands, two of which allow a 3-bit addressing mode specification:

PIC24 addressing modes
source operand destination operand Description
ppp Reg Syntax qqq Reg Syntax
000 ssss Ws 000 dddd Wd Register direct
001 ssss [Ws] 001 dddd [Wd] Indirect
010 ssss [Ws−−] 010 dddd [Wd−−] Indirect with postdecrement
011 ssss [Ws++] 011 dddd [Wd++] Indirect with postincrement
100 ssss [−−Ws] 100 dddd [−−Wd] Indirect with predecrement
101 ssss [++Ws] 101 dddd [++Wd] Indirect with preincrement
11k kkkk #u5 (Unused, illegal) 5-bit unsigned immediate
11x ssss [Ws+Ww] 11x dddd [Wd+Ww] Indirect with register offset

The register offset addressing mode is only available for the MOV src,dst instruction, where the Ww register may be used as a register offset for the source, destination, or both. All other instructions use this encoding for an unsigned 5-bit immediate source instead.

For the operands to TBLRD and TBLWT which access program memory, only the indirect modes are allowed, and refer to addresses in code memory.

A few instructions are 2 words long. The second word is a NOP, which includes up to 16 bits of additional immediate operand.

PIC24 24-bit instruction set[28]
2
3
2
2
2
1
2
0
1
9
1
8
1
7
1
6
1
5
1
4
1
3
1
2
1
1
1
0

9

8

7

6

5

4

3

2

1

0
Mnemonic C
?
Z
?
N
?
Description
0 0 0 0 opcode offset Control transfers
0 0 0 0 0 0 0 0 NOP No operation
0 0 0 0 0 0 0 0 —0— n<22:16> CALL/GOTO addr23 (second word)
0 0 0 0 0 0 0 0 n DO #k,addr (second word)
0 0 0 0 0 0 0 1 0 opc —0— a Computed control transfer (to 16-bit Wa)
0 0 0 0 0 0 0 1 0 0 0 —0— a CALL Ra Push PC, jump to Wa
0 0 0 0 0 0 0 1 0 0 1 —0— a RCALL Ra Push PC, jump to PC+2×Wa
0 0 0 0 0 0 0 1 0 1 0 —0— a GOTO Ra Jump to Wa
0 0 0 0 0 0 0 1 0 1 1 —0— a BRA Ra Jump to PC+2×Wa
0 0 0 0 0 0 1 0 n<15:1> 0 CALL addr23 Push PC, jump to absolute address
—0— —0— n<22:16>
0 0 0 0 0 0 1 1 (Reserved)
0 0 0 0 0 1 0 0 n 0 GOTO addr23 Jump to absolute address
—0— —0— n<22:16>
0 0 0 0 0 1 0 1 0 B k d RETLW[.B] #k,Wd Wd = k, pop PC
0 0 0 0 0 1 1 0 0 0 —0— RETURN pop PC
0 0 0 0 0 1 1 0 0 1 —0— RETFIE C Z N pop SR, PC
0 0 0 0 0 1 1 1 n RCALL address Push PC, PC += 2×s16
0 0 0 0 1 0 0 0 0 0 k DO #k,addr Zero-overhead loop: k+1 is repeat count, PC+2×n last instruction
—0— n
0 0 0 0 1 0 0 0 0 0 k REPEAT #k Repeat next instruction k+1 times
0 0 0 0 1 0 0 0 n RCALL address Push PC, PC += 2×s16
0 0 0 0 1 0 1 (Reserved)
0 0 0 0 1 1 0 a n BRA Oa, addr If accumulator an overflowed/saturated, PC += 2×simm16
0 0 0 0 1 1 1 a n BRA Sa, addr
0 opcode w B q d p s Reverse subtract: destsource − Ww
0 0 0 1 0 w B q d p s SUBR[.B] Ww,src,dst C Z N dst ← src − Ww = src + ~Ww + 1)
0 0 0 1 1 w B q d p s SUBBR[.B] Ww,src,dst C Z N dst ← src − Ww − C̅ = src + ~Ww + C
0 0 1 0 k d MOV #k,Wd Wd ← #imm16
0 0 1 1 cond n Conditional branch to PC+2×n
0 0 1 1 0 0 0 0 n BRA OV,addr ...if PSR.V is set
0 0 1 1 0 0 0 1 n BRA C,addr ...if PSR.C is set
0 0 1 1 0 0 1 0 n BRA Z,addr ...if PSR.Z is set
0 0 1 1 0 0 1 1 n BRA N,addr ...if PSR.N is set
0 0 1 1 0 1 0 0 n BRA LE,addr ...if PSR.Z, or PSR.N ≠ PSR.V
0 0 1 1 0 1 0 1 n BRA LT,addr ...if PSR.N ≠ PSR.V
0 0 1 1 0 1 1 0 n BRA LEU,addr ...if PSR.Z is set, or PSR.C is clear
0 0 1 1 0 1 1 1 n BRA addr ...unconditionally
0 0 1 1 1 0 0 0 n BRA NOV,addr ...if PSR.V is clear
0 0 1 1 1 0 0 1 n BRA NC,addr ...if PSR.C is clear
0 0 1 1 1 0 1 0 n BRA NZ,addr ...if PSR.Z is clear
0 0 1 1 1 0 1 1 n BRA NN,addr ...if PSR.N is clear
0 0 1 1 1 1 0 0 n BRA GT,addr ...if PSR.Z is clear, and PSR.N = PSR.V
0 0 1 1 1 1 0 1 n BRA GE,addr ...if PSR.N = PSR.V
0 0 1 1 1 1 1 0 n BRA GTU,addr ...if PSR.Z is clear, and PSR.C is set
0 0 1 1 1 1 1 1 n (Reserved)
0 opcode w B q d p s ALU operations: dest ← OP(Ww,source)
0 1 0 0 0 w B q d p s ADD[.B] Ww,src,dst C Z N dst ← Ww + src
0 1 0 0 1 w B q d p s ADDC[.B] Ww,src,dst C Z N dst ← Ww + src + C
0 1 0 1 0 w B q d p s SUB[.B] Ww,src,dst C Z N dst ← Ww − src
0 1 0 1 1 w B q d p s SUBB[.B] Ww,src,dst C Z N dst ← Ww − ~src − C̅ = Ww + ~src + C
0 1 1 0 0 w B q d p s AND[.B] Ww,src,dst Z N dst ← Ww & src
0 1 1 0 1 w B q d p s XOR[.B] Ww,src,dst Z N dst ← Ww ^ src
0 1 1 1 0 w B q d p s IOR[.B] Ww,src,dst Z N dst ← Ww | src
0 1 1 1 1 w B q d p s MOV[.B] src,dst Z N dst ← src (offset mode allowed)
1 0 0 0 0 f d MOV f,Wd Wd ← f
1 0 0 0 1 f s MOV Ws,f f ← Ws
1 0 0 1 0 k B k d k s MOV[.B] [Ws+s10],Wd Load with 10-bit offset
1 0 0 1 1 k B k d k s MOV[.B] Ws,[Wd+s10] Store with 10-bit offset
1 0 1 0 0 opcode b Z B —0— p s Bit operations on source
1 0 1 0 0 0 0 0 b 0 B —0— p s BSET[.B] #b,src Set bit b of src
1 0 1 0 0 0 0 1 b 0 B —0— p s BCLR[.B] #b,src Clear bit b of src
1 0 1 0 0 0 1 0 b 0 B —0— p s BTG[.B] #b,src Toggle bit b of src
1 0 1 0 0 0 1 1 b 0 0 —0— p s BTST.C #b,src C Set PSR.C = bit b of src
1 0 1 0 0 0 1 1 b 1 0 —0— p s BTST.Z #b,src Z Set PSR.Z = bit b of src
1 0 1 0 0 1 0 0 b Z 0 —0— p s BTSTS.z #b,src C/Z Test bit b of src (into C or Z), then set
1 0 1 0 0 1 0 1 Z w 0 —0— p s BTST.z Ww,src C/Z Test bit Ww of src
1 0 1 0 0 1 1 0 b 0 0 —0— p s BTSS #b,src Test bit, skip if set
1 0 1 0 0 1 1 1 b 0 0 —0— p s BTS #b,src Test bit, skip if clear
1 0 1 0 1 opcode b f Bit operations on f
1 0 1 0 1 0 0 0 b f b BSET[.B] f,#b Set bit b of f
1 0 1 0 1 0 0 1 b f BCLR.B f,#b Clear bit b of f
1 0 1 0 1 0 1 0 b f BTG.B f,#b Toggle bit b of f
1 0 1 0 1 0 1 1 b f BTST.B f,#b Z Test bit b of f
1 0 1 0 1 1 0 0 b f BTSTS.B f,#b Z Test bit b of f, then set
1 0 1 0 1 1 0 1 Z w 0 —0— p s BSW.z src,Ww Copy PSW.C or PSW.Z to bit Ww of src
1 0 1 0 1 1 1 0 b f BTSS f,#b Test bit, skip if set
1 0 1 0 1 1 1 1 b f BTSC f,#b Test bit, skip if clear
1 0 1 1 0 0 opcode B k d Register-immediate operations: Wd ← OP(Wd,k)
1 0 1 1 0 0 0 0 0 B k d ADD[.B] #u10,Wd C Z N Wd ← Wd + k
1 0 1 1 0 0 0 0 1 B k d ADC[.B] #u10,Wd C Z N Wd ← Wd + k + C
1 0 1 1 0 0 0 1 0 B k d SUB[.B] #u10,Wd C Z N Wd ← Wd − k
1 0 1 1 0 0 0 1 1 B k d SUBB[.B] #u10,Wd C Z N Wd ← Wd − k − C̅
1 0 1 1 0 0 1 0 0 B k d AND[.B] #u10,Wd Z N Wd ← Wd & k
1 0 1 1 0 0 1 0 1 B k d XOR[.B] #u10,Wd Z N Wd ← Wd ^ k
1 0 1 1 0 0 1 1 0 B k d IOR[.B] #u10,Wd Z N Wd ← Wd | k
1 0 1 1 0 0 1 1 1 B k d MOV[.B] #u10,Wd Wd ← k
1 0 1 1 0 1 opcode B D f ALU operations: dest ← OP(f,W0)
1 0 1 1 0 1 0 0 0 B D f ADD[.B] f[,WREG] C Z N dest ← f + W0
1 0 1 1 0 1 0 0 1 B D f ADC[.B] f[,WREG] C Z N dest ← f + W0 + C
1 0 1 1 0 1 0 1 0 B D f SUB[.B] f[,WREG] C Z N dest ← f − W0
1 0 1 1 0 1 0 1 1 B D f SUBB[.B] f[,WREG] C Z N dest ← f − W0 + C̅
1 0 1 1 0 1 1 0 0 B D f AND[.B] f[,WREG] Z N dest ← f & W0
1 0 1 1 0 1 1 0 1 B D f XOR[.B] f[,WREG] Z N dest ← f ^ W0
1 0 1 1 0 1 1 1 0 B D f IOR[.B] f[,WREG] Z N dest ← f | W0
1 0 1 1 0 1 1 1 1 B 1 f MOV[.B] WREG,f f ← W0
1 0 1 1 1 0 0 opc w d 0 p s 16×16→32 multiplication
1 0 1 1 1 0 0 0 0 w d 0 p s MUL.UU Ww,src,Wd Wd+1:Wd ← Ww × src (unsigned)
1 0 1 1 1 0 0 0 1 w d 0 p s MUL.US Ww,src,Wd Wd+1:Wd ← Ww × src (src signed)
1 0 1 1 1 0 0 1 0 w d 0 p s MUL.SU Ww,src,Wd Wd+1:Wd ← Ww × src (Ww signed)
1 0 1 1 1 0 0 1 1 w d 0 p s MUL.SS Ww,src,Wd Wd+1:Wd ← Ww × src (signed)
1 0 1 1 1 0 1 opc B q d p s Program memory access (indirect modes only)
1 0 1 1 1 0 1 0 0 B q d p s TBLRDL[.B] src,dst dst ← ROM[TBLPAG:src] (bits 15:0)
1 0 1 1 1 0 1 0 1 B q d p s TBLRDH[.B] src,dst dst ← ROM[TBLPAG:src] (bits 23:16)
1 0 1 1 1 0 1 1 0 B q d p s TBLWTL[.B] src,dst ROM[TBLPAG:dst] ← src (bits 15:0)
1 0 1 1 1 0 1 1 1 B q d p s TBLWTH[.B] src,dst ROM[TBLPAG:dst] ← src (bits 23:16)
1 0 1 1 1 1 0 0 0 B 0 f MUL[.B] f W3:W2 ← f × W0 (unsigned)
1 0 1 1 1 1 0 0 0 B 1 (Reserved)
1 0 1 1 1 1 0 0 1 (Reserved)
1 0 1 1 1 1 0 1 (Reserved)
1 0 1 1 1 1 1 0 0 0 —0— d 0 p s MOV.D src,Wd Load register pair
1 0 1 1 1 1 1 0 1 0 q d —0— s 0 MOV.D Ws,dst Store register pair
1 0 1 1 1 1 1 1 (Reserved)
1 1 0 0 0 m A S x y i j a DSP MAC (dsPIC only)
1 1 0 0 1 Other DSP instructions (dsPIC only)
1 1 0 0 1 1 1 1 0 0 —0— d p s FF1R src,Wd C Find first one from right (lsb)
1 1 0 0 1 1 1 1 1 0 —0— d p s FF1L src,Wd C Find first one from left (msb)
1 1 0 1 0 0 opcode B q d p s Shift/rotate general operand
1 1 0 1 0 0 0 0 0 B q d p s SL[.B] src,dst C Z N dst ← src << 1, shift left (into carry)
1 1 0 1 0 0 0 1 0 B q d p s LSR[.B] src,dst C Z N dst ← src >> 1, logical shift right
1 1 0 1 0 0 0 1 1 B q d p s ASR[.B] src,dst C Z N dst ← src >> 1, arithmetic shift right
1 1 0 1 0 0 1 0 0 B q d p s RLNC[.B] src,dst Z N dst ← src <<< 1, rotate left (no carry)
1 1 0 1 0 0 1 0 1 B q d p s RLC[.B] src,dst C Z N C:dst ← src:C << 1, rotate left through carry
1 1 0 1 0 0 1 1 0 B q d p s RRNC[.B] src,dst Z N dst ← src >>> 1, rotate right (no carry)
1 1 0 1 0 0 1 1 1 B q d p s RRC[.B] src,dst C Z N dst:C ← C:src >> 1, rotate right through carry
1 1 0 1 0 1 opcode B D f Shift/rotate f
1 1 0 1 0 1 0 0 0 B D f SL[.B] f[,WREG] C Z N dest ← f << 1, shift left (into carry)
1 1 0 1 0 1 0 1 0 B D f LSR[.B] f[,WREG] C Z N dest ← f >> 1, logical shift right
1 1 0 1 0 1 0 1 1 B D f ASR[.B] f[,WREG] C Z N dest ← f >> 1, arithmetic shift right
1 1 0 1 0 1 1 0 0 B D f RLNC[.B] f[,WREG] Z N dest ← f <<< 1, rotate left (no carry)
1 1 0 1 0 1 1 0 1 B D f RLC[.B] f[,WREG] C Z N C:dest ← f:C << 1, rotate left through carry
1 1 0 1 0 1 1 1 0 B D f RRNC[.B] f[,WREG] Z N dest ← f >>> 1, rotate right (no carry)
1 1 0 1 0 1 1 1 1 B D f RRC[.B] f[,WREG] C Z N dest:C ← C:f >> 1, rotate right through carry
1 1 0 1 1 0 0 0 U t d D 0 0 s Divide step (prefix with REPEAT #17)
1 1 0 1 1 0 0 0 0 —0— d 0 0 0 s DIV.S Wd,Ws C Z N W0 ← Wd/Ws, W1 ← remainder
1 1 0 1 1 0 0 0 0 t d 1 0 0 s DIV.SD Wd,Ws C Z N W0 ← Wt:Wd/Ws, W1 ← remainder
1 1 0 1 1 0 0 0 1 —0— d 0 0 0 s DIV.U Wd,Ws C Z N W0 ← Wd/Ws, W1 ← remainder
1 1 0 1 1 0 0 0 1 t d 1 0 0 s DIV.UD Wd,Ws C Z N W0 ← Wt:Wd/Ws, W1 ← remainder
1 1 0 1 1 0 0 1 0 t —0— 0 0 0 s DIVF Wt,Ws C Z N W0 ← Wt:0/Ws, W1 ← remainder
1 1 0 1 1 0 0 1 1 (Reserved)
1 1 0 1 1 0 1 (Reserved)
1 1 0 1 1 1 opcode w d i 0 0 s Shift/rotate multiple
1 1 0 1 1 1 0 0 0 w d 0 0 0 s SL Ww,Ws,Wd Z N Wd ← Ww << Ws
1 1 0 1 1 1 0 0 0 w d 1 0 0 k SL Wv,#u4,Wd Z N Wd ← Ww << k
1 1 0 1 1 1 1 0 0 w d 0 0 0 s LSR Ww,Ws,Wd Z N Wd ← Ww >> Ws, logical shift right
1 1 0 1 1 1 1 0 0 w d 1 0 0 k LSR Wv,#u4,Wd Z N Wd ← Ww >> k, logical shift right
1 1 0 1 1 1 1 0 1 w d 0 0 0 s ASR Ww,Ws,Wd Z N Wd ← Ww >> Ws, arithmetic shift right
1 1 0 1 1 1 1 0 1 w d 1 0 0 k ASR Wv,#u4,Wd Z N Wd ← Ww >> k, arithmetic shift right
1 1 0 1 1 1 1 1 0 —0— d p s FBCL src,Wd C Find permissible arithmetic normalization shift
1 1 1 0 0 0 0 0 0 —0— B 0 0 0 p s CP0[.B] src C Z N Compare with zero, src − 0
1 1 1 0 0 0 0 1 0 w B 0 0 0 p s CP[.B] Ww,src C Z N Compare, Ww − src (Ww + ~src + 1)
1 1 1 0 0 0 0 1 1 w B 0 0 0 p s CPB[.B] Ww,src C Z N Compare with borrow, Ww − src − C̅ (Ww + ~src + C)
1 1 1 0 0 0 1 0 0 B 0 f CP0[.B] f C Z N Compare with zero, f − 0
1 1 1 0 0 0 1 1 0 B 0 f CP[.B] f C Z N Compare, f − W0
1 1 1 0 0 0 1 1 1 B 0 f CPB[.B] f C Z N Compare with borrow, f − W0 − C̅ (f + ~W0 + C)
1 1 1 0 0 1 0 (Reserved)
1 1 1 0 0 1 1 opc w B —0— s Compare and skip
1 1 1 0 0 1 1 0 0 w B —0— s CPSGT[.B] Ww,Ws ...if Ww > Ws, signed
1 1 1 0 0 1 1 0 1 w B —0— s CPSLT[.B] Ww,Ws ...if Ww < Ws, signed
1 1 1 0 0 1 1 1 0 w B —0— s CPSNE[.B] Ww,Ws ...if Ww ≠ Ws
1 1 1 0 0 1 1 1 1 w B —0— s CPSNE[.B] Ww,Ws ...if Ww = Ws
1 1 1 0 1 0 0 0 0 B q d p s INC[.B] src,dst C Z N dst ← src+1
1 1 1 0 1 0 0 0 1 B q d p s INC2[.B] src,dst C Z N dst ← src+2
1 1 1 0 1 0 0 1 0 B q d p s DEC[.B] src,dst C Z N dst ← src−1
1 1 1 0 1 0 0 1 1 B q d p s DEC2[.B] src,dst C Z N dst ← src−2
1 1 1 0 1 0 1 0 0 B q d p s NEG[.B] src,dst C Z N dst ← ~src+1
1 1 1 0 1 0 1 0 1 B q d p s COM[.B] src,dst Z N dst ← ~src
1 1 1 0 1 0 1 1 0 B q d —0— CLR[.B] dst dst ← 0
1 1 1 0 1 0 1 1 1 B q d —0— SETM[.B] dst dst ← ~0
1 1 1 0 1 1 0 0 0 B D f INC[.B] f[,WREG] C Z N dest ← f+1
1 1 1 0 1 1 0 0 1 B D f INC2[.B] f[,WREG] C Z N dest ← f+2
1 1 1 0 1 1 0 1 0 B D f DEC[.B] f[,WREG] C Z N dest ← f−1
1 1 1 0 1 1 0 1 1 B D f DEC[.B] f[,WREG] C Z N dest ← f−2
1 1 1 0 1 1 1 0 0 B D f NEG[.B] f[,WREG] C Z N dest ← ~f+1
1 1 1 0 1 1 1 0 1 B D f COM[.B] f[,WREG] Z N dest ← ~f
1 1 1 0 1 1 1 1 0 B D f CLR[.B] f[,WREG] dest ← 0
1 1 1 0 1 1 1 1 1 B D f SETM[.B] f[,WREG] dest ← ~0
1 1 1 1 0 0 m A 1 x y i j opc DSP MPY/MAC/ED/EDAC (dsPIC only)
1 1 1 1 0 1 (Reserved)
1 1 1 1 1 0 0 0 f 0 PUSH f Push f on top of stack
1 1 1 1 1 0 0 1 f 0 POP f Pop f from top of stack
1 1 1 1 1 0 1 0 0 0 k LNK #u14 Push W14, W14 ← W15, W15 += k
1 1 1 1 1 0 1 0 1 0 —0— ULNK W15 ← W14, pop W14
1 1 1 1 1 0 1 1 0 0 000 d p s SE src,dst C Z N dst ← sign_extend(src), copy bit 7 to bits 15:8
1 1 1 1 1 0 1 1 1 0 000 d p s ZE src,dst 1 Z 0 dst ← zero_extend(src), clear bits 15:8
1 1 1 1 1 1 0 0 0 0 k DISI #u14 Disable interrupt for k+1 cycles
1 1 1 1 1 1 0 1 0 0 000 d 000 s EXCH Ws,Wd Swap contents of registers Ws, Wd
1 1 1 1 1 1 0 1 0 1 000 0000 000 s DAW.B Ws C Decimal adjust based on C, DC
1 1 1 1 1 1 0 1 1 B 000 0000 000 s SWAP[.B] Ws Swap halves of Ws
1 1 1 1 1 1 1 0 0 0 —0— RESET Software reset
1 1 1 1 1 1 1 0 0 1 0 —0— k PWRSAV #u1 Go into sleep or idle mode
1 1 1 1 1 1 1 0 0 1 1 —0— CLRWDT Clear watchdog timer
1 1 1 1 1 1 1 0 1 0 0 —0— POP.S Pop shadow registers (W0–3, part of PSR)
1 1 1 1 1 1 1 0 1 0 1 —0— PUSH.S Push shadow registers (W0–3, part of PSR)
1 1 1 1 1 1 1 0 1 1 (Reserved)
1 1 1 1 1 1 1 1 NOPR No operation (version #2)

References

[edit]
  1. ^ Gruppuso, Frank M. (1982). "Chapter 35 PIC1650: Chip Architecture and Operation" (PDF). In Siewiorek, Daniel P.; Bell, C. Gordon; Newell, Allen (eds.). Computer Structures: Principles and Examples (PDF). McGraw-Hill. ISBN 0-07-057302-6. Retrieved 2024-08-18.
  2. ^ PIC10F200/202/204/206 Data Sheet (PDF). Microchip Technology. 2007. p. 52. Archived from the original (PDF) on 2015-08-11. Retrieved 2015-01-15.
  3. ^ General Instrument. PIC1670 8-bit Microcomputer (PDF) (Data Sheet). Retrieved 2024-08-18.
  4. ^ "義隆電子股份有限公司義隆電子,再創未來!".
  5. ^ ELAN Microelectronics Corp. (26 April 2016), EM78P157N 8-bit microcontroller with OTP ROM Product Specification (PDF), version 1.3, archived (PDF) from the original on 2016-03-04, retrieved 2020-06-06
  6. ^ a b ELAN Microelectronics Corp. (25 April 2016), EM78P143 8-bit microprocessor with OTP ROM Product Specification (PDF), version 1.7, p. 77, retrieved 2020-06-06
  7. ^ ELAN Microelectronics Corp. (April 2016), EM78P346N 8-bit microprocessor with OTP ROM Product Specification (PDF), version 1.5, p. 77, retrieved 2019-07-11
  8. ^ ELAN Microelectronics Corp. (17 April 2000), EM78860 8-bit Micro-controller (PDF), p. 17, retrieved 2019-07-11
  9. ^ ELAN Microelectronics Corp. (15 March 2013), EM78F648/644/642/641N/548/544/542/541N Flash Series 8-Bit Microcontroller Product Specification (PDF), version 1.2, pp. 162–165, retrieved 2019-07-11
  10. ^ Derived from instruction encoding tables in Elan eUIDE II v2.19.60.14, released 2019-05-01, accessed 2019-07-13. Specifically the Bin/*.cfg files.
  11. ^ ELAN Microelectronics Corp. (2014-01-14), EM78XXX 15-Bit Instruction Set (PDF), retrieved 2019-07-13
  12. ^ "Introducing the Enhanced Mid-Range Architecture" (PDF). Microchip.
  13. ^ a b Holtek Semiconductor Inc. (11 December 2016), HT8 MCU Extended Instruction Set Applications (PDF) (Application Note), AN0407E, retrieved 2024-02-09
  14. ^ Holtek Semiconductor Inc. (26 November 2019), 2.4GHz 8-Bit Flash RF TX/RX MCU BC66F840/BC66F850/BC66F860 (PDF) (Data sheet), version 1.60, p. 32, retrieved 2024-02-09. Note that operand addresses only go to 0xFF, with additional RAM addressed by banking.
  15. ^ Wolf, Ash "Ninji" (12 December 2018). "Mouse Adventures #3: Writing a Disassembler". Retrieved 8 July 2019.
  16. ^ Carlson, Jay (6 September 2019). "What's up with these 3-cent microcontrollers? (A review of the Padauk PMS150C and friends)". Retrieved 2020-05-18.
  17. ^ a b "The "terrible" 3 cent MCU – a short survey of sub $0.10 microcontrollers". Tim's blog. 12 August 2019. Retrieved 2020-05-18.
  18. ^ "Free PDK Documentation". Padauk µCs sport an interesting architecture that can be a seen as a ... extension of the Microchip PIC architecture.
  19. ^ "Chiptunes on an ATtiny4 and the 3 Cent Micro: Porting to Padauk". According to some, Padauk's instruction set is heavily inspired by older PICs, with most operations taking place on a single accumulator register.
  20. ^ Jenny List "Everything you want to know about the cheapest processors available". 2019.
  21. ^ Wolf, Ash "Ninji" (12 December 2018). "Documentation for PADAUK FPPA MCUs". GitHub. Retrieved 2020-05-18.
  22. ^ Padauk Technology Co. Ltd. (11 December 2018). "PMC150/PMS150 8-bit OTP Type IO Controller" (PDF) (data sheet). Version 1.8. pp. 38–51. PDK-DS-PMX150-EN-V108. Retrieved 2020-06-08.
  23. ^ Wolf, Ash "Ninji" (23 May 2020). "PADAUK FPPA core devices (14 bit) instruction set". Retrieved 2020-06-08.
  24. ^ Padauk Technology Co. Ltd. (18 June 2019). "PFS154 8bit MTP Type IO controller Data Sheet" (PDF). Version 1.04. pp. 71–84. PDK-DS-PFS154_RN_V104. Retrieved 2020-06-09.
  25. ^ "Microchip PIC micros and C - source and sample code".
  26. ^ Microchip Technology, Inc. (2007), PIC18F1220/1320 Data Sheet (PDF), retrieved 2012-04-02
  27. ^ "Microchip Technology debuts world's highest performing 16-bit microcontrollers: dsPIC". Archived from the original on 2004-12-13.
  28. ^ dsPIC30F Programmer's Reference Manual (PDF), Microchip Technology, 2008, DS70157C, retrieved 2012-07-02