// GENERATING SINGLE INSTRUCTIONS USING C SYNTAX #pragma chip PIC18C242 // select device char i, a, b; bit flag, semi; void fx1( void); char fx2( void); #include "int18XXX.h" void _highPriorityInt(void); #pragma origin 0x8 interrupt highPriorityIntServer(void) { // W, STATUS and BSR are saved to shadow registers // handle the interrupt // 8 code words available including call and RETFIE _highPriorityInt(); // restore W, STATUS and BSR from shadow registers #pragma fastMode } #pragma origin 0x18 interrupt lowPriorityIntServer(void) { // W, STATUS and BSR are saved by the next macro. int_save_registers /* NOTE : shadow registers are updated, but will be overwritten in case of a high-priority interrupt. Therefore #pragma fastMode should not be used on low-priority interrupts. */ // save remaining registers on demand (error/warning) //uns16 sv_FSR0 = FSR0; //uns16 sv_FSR1 = FSR1; //uns16 sv_FSR2 = FSR2; //uns8 sv_PCLATH = PCLATH; //uns8 sv_PCLATU = PCLATU; //uns8 sv_PRODL = PRODL; //uns8 sv_PRODH = PRODH; //uns24 sv_TBLPTR = TBLPTR; //uns8 sv_TABLAT = TABLAT; // handle the interrupt // .. // restore registers that are saved //FSR0 = sv_FSR0; //FSR1 = sv_FSR1; //FSR2 = sv_FSR2; //PCLATH = sv_PCLATH; //PCLATU = sv_PCLATU; //PRODL = sv_PRODL; //PRODH = sv_PRODH; //TBLPTR = sv_TBLPTR; //TABLAT = sv_TABLAT; int_restore_registers // W, STATUS and BSR } /* IMPORTANT : GIEH/GIE or GIEL should normally NOT be set or cleared in the interrupt routine. GIEH/GIEL are AUTOMATICALLY cleared on interrupt entry by the CPU and set to 1 on exit (by RETFIE). Setting GIEH/GIEL to 1 inside the interrupt service routine will cause nested interrupts if an interrupt is pending. Too deep nesting may crash the program ! */ void _highPriorityInt(void) { // save registers on demand // restore registers on demand } char singleInstr( void) { nop(); // NOP ; No operation i = W; // MOVWF f ; Move W to f i = 0; // CLRF f ; Clear f W = i - W; // SUBWF f,W ; Subtract W from f i = i - W; // SUBWF f ; Subtract W from f W = i - 1; // DECF f,W ; Decrement f i = i - 1; // DECF f ; Decrement f W = i | W; // IORWF f,W ; Inclusiv OR W and f i = i | W; // IORWF f ; Inclusiv OR W and f W = i & W; // ANDWF f,W ; AND W and f i = i & W; // ANDWF f ; AND W and f W = i ^ W; // XORWF f,W ; Exclusiv OR W and f i = i ^ W; // XORWF f ; Exclusiv OR W and f W = i + W; // ADDWF f,W ; Add W and f i = i + W; // ADDWF f ; Add W and f W = i; // MOVF f,W ; Move f W = i ^ 255; // COMF f,W ; Complement f i = i ^ 255; // COMF f ; Complement f W = i + 1; // INCF f,W ; Increment f i = i + 1; // INCF f ; Increment f W = decsz(i); // DECFSZ f,W ; Decrement f, skip if zero i = decsz(i); // DECFSZ f ; Decrement f, skip if zero W = rr( i); // RRCF f,W ; Rotate right f i = rr( i); // RRCF f ; Rotate right f W = rl( i); // RLCF f,W ; Rotate left f i = rl( i); // RLCF f ; Rotate left f W = swap( i); // SWAPF f,W ; Swap halves f i = swap( i); // SWAPF f ; Swap halves f W = incsz(i); // INCFSZ f,W ; Increment f, skip if zero i = incsz(i); // INCFSZ f ; Increment f, skip if zero flag = 0; // BCF f,b ; Bit clear f semi = 1; // BSF f,b ; Bit set f btsc( flag); // BTFSC f,b ; Bit test f, skip if clear btss( flag); // BTFSS f,b ; Bit test f, skip if set sleep(); // SLEEP ; Go into standby mode clrwdt(); // CLRWDT ; Clear watchdog timer return 5; // RETLW 5 ; Return, put literal in W fx1(); // CALL fx1 ; Call subroutine W = fx2(); // CALL fx2 ; Call subroutine goto X; // GOTO X ; Go to address W = 45; // MOVLW 45 ; Move literal to W W = W | 23; // IORLW 23 ; Incl. OR literal and W W = W & 53; // ANDLW 53 ; AND literal and W W = W ^ 12; // XORLW 12 ; Excl. OR literal and W W += 33; // ADDLW 33 return W; // RETURN W = 23 - W; // SUBLW 23 W = addWFC(i); // ADDWFC f,W,0 i = addWFC(i); W = subFWB(i); // SUBFWB i,W,0 i = subFWB(i); W = subWFB(i); // SUBWFB i,W,0 i = subWFB(i); W = rrnc(i); // RRNCF i,W,0 i = rrnc(i); W = rlnc(i); // RLNCF i,W,0 i = rlnc(i); W = decsnz(i); // DCFSNZ i,W,0 i = decsnz(i); W = incsnz(i); // INFSNZ i,W,0 i = incsnz(i); pushStack(); // PUSH popStack(); // POP softReset(); // RESET tableRead(); // TBLRD * tableReadInc(); // TBLRD *+ tableReadDec(); // TBLRD *- tableReadPreInc(); // TBLRD +* tableWrite(); // TBLWT * tableWriteInc(); // TBLWT *+ tableWriteDec(); // TBLWT *- tableWritePreInc(); // TBLWT +* b = negate(b); // NEGF b,0 W = decadj(W); // DAW flag = !flag; // BTG 0x03,flag BSR = 2; // MOVLB 2 multiply( 50); // MULLW 50 multiply( i); // MULWF i,0 i = 0xFF; // SETF i,0 FSR2 = 0x345; // NOTE: LFSR may be disabled skipIfEQ(a); // CPFSEQ a,0 goto X; if (a == W) // CPFSEQ a,0 i += b; skipIfLT(b); // CPFSLT b,0 nop(); if (b < W) // CPFSLT b,0 i += b; skipIfGT(b); // CPFSGT b,0 nop(); if (b > W) // CPFSGT b,0 i += b; skipIfZero(b); // TSTFSZ b,0 nop(); if (!b) // TSTFSZ b,0 i += b; if (Carry) // BNC m006 i += b; if (!Carry) // BC m007 i += b; if (Negative) // BNN m008 i += b; if (!Negative) // BN m009 i += b; if (Overflow) // BNOV m010 i += b; if (!Overflow) // BOV m011 i += b; if (Zero_) // BNZ m012 i += b; if (!Zero_) // BZ m013 i += b; X: return 0; } char sub( void) { singleInstr(); return 88; } #pragma origin 4000 char lsub( void) { singleInstr(); return 88; } void fx1( void) { } char fx2( void) { return 9; } void main(void) { sub(); lsub(); }