A NEW MNEMONIC INSRUCTION SET FOR THE PIC18 MICROCONTROLLERS (Including some new SFR name assignments) Author: Joseph Watson Date: 5-13-2014 This instruction set eliminates the need by the programmer to specify the Access Memory addressing mode (using ",A") as this can be determined automatically. It also effectively transfers the specification of the usual destination field (using ",W" or ",F") to the opcode itself. Another primary intent of this work is to adopt a more consistent philosophy in the mnemonic design of the opcodes themselves thereby requiring less rote memorization. The GPASM assembler is not case sensitive. Opcodes may be entered without regard to case. However, in "The Instruction Set" section below, case is used to improve readability. Due to the design of the PIC, only certain Special Function Registers can serve as pointers to memory and certain others must be used to perform indirect access through them. Therefore, they have been assigned alternate names to better reflect those assignments: Standard Name Alternate Name ------------- -------------- FSR0L Pt0L FSR0H Pt0H FSR1L Pt1L FSR1H Pt1H FSR2L Pt2L FSR2H Pt2H INDF0 I_Pt0 Using I_ to indicate indirectness INDF1 I_Pt1 in these references is a tip of INDF2 I_Pt2 the hat to the DEC PDP-8. POSTINC0 I_Pt0P The use of P (stands for +) and POSTDEC0 I_Pt0M M (stands for -) before or after PREINC0 I_PPt0 the pointer name signifies pre/post PLUSW0 I_Pt0W increment/decrement. W signifies indexing by the value in W. POSTINC1 I_Pt1P POSTDEC1 I_Pt1M PREINC1 I_PPt1 PLUSW1 I_Pt1W POSTINC2 I_Pt2P POSTDEC2 I_Pt2M PREINC2 I_PPt2 PLUSW2 I_Pt2W TBLPTRU RomPtU New name selected because this pointer TBLPTRH RomPtH can reference anything stored in ROM TBLPTRL RomPtL (Flash or EEPROM), not just tables. TABLAT RomData ==================================================================== = Aids to reading and understanding "The Instruction Set" below. = ==================================================================== Symbol Description ------ ----------- _ Used to represent "=" in opcodes. Opcodes are not permitted to use an equal sign (=) so underscore is the closest we have. Var Address in RAM or a Special Function Register. In an opcode this is represented by the letter V. W The W register which is the PIC's version of an accumulator. The full name of this register is WREG but it is often abbreviated as W. In an opcode, it is represented by the letter W. Z The Zero condition flag in the PIC's STATUS register which some instructions set or clear according to whether their result data is zero or not. In an opcode, it is represented by the letter Z. N The Negative condition flag in the PIC's STATUS register which some instructions set or clear according to whether their result data is negative or not. In an opcode, it is represented by the letter N. C The Carry condition flag in the PIC's STATUS register which some instructions set or clear according to whether a carry is produced or not. In an opcode, it is represented by the letter C. However, in the context of subtraction, the complement of the Carry condition serves as the Borrow condition. Therefore, in some opcodes involving subtraction, the letter B is used to represent Not(C). Ov The Overflow condition flag in the PIC's STATUS register which some instructions set or clear according to whether they produce an overflow or not. In an opcode, it is represented by Ov. Lit A literal value in the range (0x00 to 0xFF) which in an opcode is represented by the letter L. In one case, Lit is limited to 0x00 - 0x0F range for a bank number. Lbl A label in flash memory which is used to identify a target of program control transfers (via branch or Goto instructions) or an entry point to a subroutine. BitNo Number of a bit being addressed in the range 0 - 7 which in an opcode is represented by the letter B following either V or W to indicate whether it is a Var or WReg whose bit is being referenced. B also happens to be used in some subtraction opcodes to represent a borrow bit. (See description for C). However, no bit numbers are needed in subtraction instructions so there is no conflict. * To the right of an instruction's Action description, this indicates that the instruction is equivalent to the previous one and is really just an alternate spelling of the opcode. < > These symbols enclose one or more condition bits in Status that are affected by the instruction. ============================================= = Operation abbreviations used in opcodes = ============================================= Abbr Meaning ---- ------- Add Add Adc Add with carry Sub Subtract Sbb Subtract with borrow Mul Multiply Sqr Square Not Logical complement And Bitwise logical And Or Bitwise logical inclusive Or XOr Bitwise logical exclusive Or Inc Increment ISZ Increment, Skip if zero result ISN Increment, Skip if non-zero result Dec Decrement DSZ Decrement, Skip if zero result DSN Decrement, Skip if non-zero result Neg Negate RLN Rotate left no carry RLC Rotate left with carry RRN Rotate right no carry RRC Rotate right with carry Swp Swap nibbles DA Decimal adjust NOP No operation Tst Test to establish Z and N condition codes Sk Skip Bra Transfer program control, limited address range Goto Transfer program control, full address range Call Invoke a subroutine Ret Return Pop Pop an entry from the stack Push Push an entry onto the stack Rd Read Wr Write ========================= = The Instruction Set = ========================= Opcode Operand(s) Action Affected Flags ------ ---------- ------ -------------- W_V Var W = Var W_L Lit W = Lit V_W Var Var = W V1_V2 Vard,Vars Vard = Vars V_WAddV Var Var = (W + Var) V_VAddW Var Var = (Var + W) * W_WAddL Lit W = (W + Lit) W_LAddW Lit W = (Lit + W) * W_WAddV Var W = (W + Var) W_VAddW Var W = (Var + W) * W_WAdcV Var W = (W + Var + C) W_VAdcW Var W = (Var + W + C) * V_WAdcV Var Var = (W + Var + C) V_WAdcV Var Var = (Var + W + C) * V_VSubW Var Var = (Var - W) W_LSubW Lit W = (Lit - W) W_VSubW Var W = (Var - W) V_VSbbW Var Var = (Var - W - B) W_VSbbW Var W = (Var - W - B) V_WSbbV Var Var = (W - Var - B) W_WSbbV Var W = (W - Var - B) P_WMulV Var ProdH:ProdL = (W * Var) P_VMulW Var ProdH:ProdL = (Var * W) * P_WMulL Lit ProdH:ProdL = (W * Lit) P_LMulW Lit ProdH:ProdL = (Lit * W) * P_WMulW ProdH:ProdL = W * W P_SqrW ProdH:ProdL = W * W * V_0 Var Var = 0 W_0 W = 0 VB_0 Var,BitNo [Var,BitNo] = 0 WB_0 BitNo [W,BitNo] = 0 Z_0 Z = 0 N_0 N = 0 C_0 C = 0 B_1 B = 1 (B = /C) * Ov_0 OV = 0 DC_0 DC = 0 V_FF Var Var = 0xFF W_FF W = 0xFF VB_1 Var,BitNo [Var,BitNo] = 1 WB_1 BitNo [W,BitNo] = 1 Z_1 Z = 1 N_1 N = 1 C_1 C = 1 B_0 B = 0 (B = /C) * Ov_1 Ov = 1 DC_1 DC = 1 V_NotV Var Var = OnesComplement(Var) W_NotV Var W = OnesComplement(Var) W_NotW W = OnesComplement(W) VB_NotVB Var,BitNo [Var,BitNo] = NOT([Var,BitNo]) WB_NotWB BitNo [W,BitNo] = NOT([W,BitNo]) Z_NotZ Z = NOT(Z) N_NotN N = NOT(N) C_NotC C = NOT(C) Ov_NotOv Ov = NOT(Ov) W_WAndV Var W = (W AND Var) W_VAndW Var W = (Var AND W) * W_WAndL Lit W = (W AND Lit) W_LAndW Lit W = (Lit AND W) * V_WAndV Var Var = (W AND Var) V_VAndW Var Var = (Var AND W) * W_WOrV Var W = (W OR Var) W_VOrW Var W = (Var OR W) * W_WOrL Lit W = (W OR Lit) W_LOrW Lit W = (Lit OR W) * V_WOrV Var Var = (W OR Var) V_VOrW Var Var = (Var OR W) * W_WXOrV Var W = W XOR Var W_VXOrW Var W = Var XOR W * W_WXOrL Lit W = W XOR Lit W_LXOrW Lit W = Lit XOR W * V_WXOrV Var Var = W XOR Var V_VXOrW Var Var = Var XOR W * V_IncV Var Var = Var + 1 W_IncV Var W = Var + 1 W_IncW W = W + 1 V_ISZV Var Var = Var + 1, Skip if Var = 0 W_ISZV Var W = Var + 1, Skip if W = 0 W_ISZW W = W + 1, Skip if W = 0 V_ISNV Var Var = Var + 1, Skip if Var <> 0 W_ISNV Var W = Var + 1, Skip if W <> 0 W_ISZW W = W + 1, Skip if W <> 0 V_DecV Var Var = Var - 1 W_DecV Var W = Var - 1 W_DecW W = W - 1 V_DSZV Var Var = Var - 1, Skip if Var = 0 W_DSZV Var W = Var - 1, Skip if W = 0 W_DSZW W = W - 1, Skip if W = 0 V_DSNV Var Var = Var - 1, Skip if Var <> 0 W_DSNV Var W = Var - 1, Skip if W <> 0 W_DSNW W = W - 1, Skip if W <> 0 V_NegV Var Var = -Var W_NegW W = -W V_RLNV Var Var = RotateLeft(Var) W_RLNV Var W = RotateLeft(Var) W_RLNW W = RotateLeft(W) V_RLCV Var C:Var = RotateLeft(C:Var) W_RLCV Var C:W = RotateLeft(C:Var) W_RLCW C:W = RotateLeft(C:W) V_RRNV Var Var = RotateRight(Var) W_RRNV Var W = RotateRight(Var) W_RRNW W = RotateRight(W) V_RRCV Var C:Var = RotateRight(C:Var) W_RRCV Var C:W = RotateRight(C:Var) W_RRCW C:W = RotateRight(C:W) V_SwpV Var Var = NibbleSwap(Var) W_SwpV Var W = NibbleSwap(Var) W_SwpW W = NibbleSwap(W) DAW Decimal Adjust W NOP No operation ZN_TstV Var Set up Z & N according to Test(Var) ZN_TstW Set up Z & N according to Test(W) SkV_0 Var Skip if Var = 0 SkW_0 Skip if W = 0 SkVEQW Var Skip if Var = W SkWEQV Var Skip if W = Var * SkVGTW Var Skip if Var > W SkWLEV Var Skip if W <= Var * SkVLTW Var Skip if Var < W SkWGEV Var Skip if W >= Var * SkZ_1 Skip if Z = 1 SkN_1 Skip if N = 1 SkC_1 Skip if C = 1 SkB_0 Skip if B = 0 (B = /C) * SkOv_1 Skip if Ov = 1 SkDC_1 Skip if DC = 1 SkZ_0 Skip if Z = 0 SkN_0 Skip if N = 0 SkC_0 Skip if C = 0 SkB_1 Skip if B = 1 (B = /C) * SkOv_0 Skip if Ov = 0 SkDC_0 Skip if DC = 0 SkVB_0 Var,BitNo Skip if [Var,BitNo] = 0 SkWB_0 BitNo Skip if [W,BitNo] = 0 SkVB_1 Var,BitNo Skip if [Var,BitNo] = 1 SkWB_1 BitNo Skip if [W,BitNo] = 1 BraZ_1 Lbl Branch to Lbl if Z = 1 BraN_1 Lbl Branch to Lbl if N = 1 BraC_1 Lbl Branch to Lbl if C = 1 BraB_0 Lbl Branch to Lbl if B = 0 (B = /C) * BraOv_1 Lbl Branch to Lbl if Ov = 1 BraZ_0 Lbl Branch to Lbl if Z = 0 BraN_0 Lbl Branch to Lbl if N = 0 BraC_0 Lbl Branch to Lbl if C = 0 BraB_1 Lbl Branch to Lbl if B = 1 (B = /C) * BraOv_0 Lbl Branch to Lbl if Ov = 0 Bra Lbl Branch (unconditionally) GoTo Lbl Go to Lbl (2 words) Call Lbl Call subroutine at Lbl (2 words) CallS Lbl Call subroutine at Lbl with shadows (2 words) RCall Lbl Relative call subroutine at Lbl Ret Return from subroutine RetS Return from subroutine with shadows RetL Lit W = Lit, Return from subroutine RetI Return from interrupt RetIS Return from interrupt with shadows Pop Pop top of return stack (TOS) Push Push top of return stack (TOS) Pt0_V Var FSR0H:FSR0L = address (2 words) Pt1_V Var FSR1H:FSR1L = address (2 words) Pt2_V Var FSR2H:FSR2L = address (2 words) BSR_L Lit BSR = Lit (Lit in range 0x00 - 0x0F) RdIRomPt RomData = ROM(RomPt) RdIRomPtP RomData = ROM(RomPt), RomPt = RomPt + 1 RdIRomPtM RomData = ROM(RomPt), RomPt = RomPt - 1 RdIPRomPt RomPt = RomPt + 1, RomData = ROM(RomPt) WrIRomPt ROM(RomPt) = RomData WrIRomPtP ROM(RomPt) = RomData, RomPt = RomPt + 1 WrIRomPtM ROM(RomPt) = RomData, RomPt = RomPt - 1 WrIPRomPt RomPt = RomPt + 1, ROM(RomPt) = RomData Reset Software triggered reset ClrWDT Clear Watchdog Timer Sleep Go to Standby mode