; CC8E Version 1.3, Copyright (c) B Knudsen Data ; C compiler for the PIC18 microcontrollers ; ************ 24. Jun 2009 9:08 ************* processor PIC18C242 radix DEC BSR EQU 0xFE0 FSR2 EQU 0xFD9 STATUS EQU 0xFD8 i EQU 0x03 a EQU 0x04 b EQU 0x05 flag EQU 0 semi EQU 1 svrSTATUS EQU 0x00 svrBSR EQU 0x01 svrWREG EQU 0x02 GOTO main ; FILE 18\demo-ins.c ;// 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 ORG 0x0008 ;interrupt highPriorityIntServer(void) ;{ highPriorityIntServer ; // W, STATUS and BSR are saved to shadow registers ; ; // handle the interrupt ; // 8 code words available including call and RETFIE ; _highPriorityInt(); RCALL _highPriorityInt ; ; // restore W, STATUS and BSR from shadow registers ; #pragma fastMode ;} RETFIE 1 ; ;#pragma origin 0x18 ORG 0x0018 ;interrupt lowPriorityIntServer(void) ;{ lowPriorityIntServer ; // W, STATUS and BSR are saved by the next macro. ; int_save_registers MOVFF STATUS,svrSTATUS MOVFF BSR,svrBSR MOVWF svrWREG,0 ; ; /* 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 MOVFF svrBSR,BSR MOVFF svrSTATUS,STATUS ;} RETFIE ; ;/* 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) ;{ _highPriorityInt ; // save registers on demand ; ; // restore registers on demand ;} RETURN ; ; ; ; ;char singleInstr( void) ;{ singleInstr ; nop(); // NOP ; No operation NOP ; ; i = W; // MOVWF f ; Move W to f MOVWF i,0 ; ; i = 0; // CLRF f ; Clear f CLRF i,0 ; ; W = i - W; // SUBWF f,W ; Subtract W from f SUBWF i,W,0 ; i = i - W; // SUBWF f ; Subtract W from f SUBWF i,1,0 ; ; W = i - 1; // DECF f,W ; Decrement f DECF i,W,0 ; i = i - 1; // DECF f ; Decrement f DECF i,1,0 ; ; W = i | W; // IORWF f,W ; Inclusiv OR W and f IORWF i,W,0 ; i = i | W; // IORWF f ; Inclusiv OR W and f IORWF i,1,0 ; ; W = i & W; // ANDWF f,W ; AND W and f ANDWF i,W,0 ; i = i & W; // ANDWF f ; AND W and f ANDWF i,1,0 ; ; W = i ^ W; // XORWF f,W ; Exclusiv OR W and f XORWF i,W,0 ; i = i ^ W; // XORWF f ; Exclusiv OR W and f XORWF i,1,0 ; ; W = i + W; // ADDWF f,W ; Add W and f ADDWF i,W,0 ; i = i + W; // ADDWF f ; Add W and f ADDWF i,1,0 ; ; W = i; // MOVF f,W ; Move f MOVF i,W,0 ; ; W = i ^ 255; // COMF f,W ; Complement f COMF i,W,0 ; i = i ^ 255; // COMF f ; Complement f COMF i,1,0 ; ; W = i + 1; // INCF f,W ; Increment f INCF i,W,0 ; i = i + 1; // INCF f ; Increment f INCF i,1,0 ; ; W = decsz(i); // DECFSZ f,W ; Decrement f, skip if zero DECFSZ i,W,0 ; i = decsz(i); // DECFSZ f ; Decrement f, skip if zero DECFSZ i,1,0 ; ; W = rr( i); // RRCF f,W ; Rotate right f RRCF i,W,0 ; i = rr( i); // RRCF f ; Rotate right f RRCF i,1,0 ; ; W = rl( i); // RLCF f,W ; Rotate left f RLCF i,W,0 ; i = rl( i); // RLCF f ; Rotate left f RLCF i,1,0 ; ; W = swap( i); // SWAPF f,W ; Swap halves f SWAPF i,W,0 ; i = swap( i); // SWAPF f ; Swap halves f SWAPF i,1,0 ; ; W = incsz(i); // INCFSZ f,W ; Increment f, skip if zero INCFSZ i,W,0 ; i = incsz(i); // INCFSZ f ; Increment f, skip if zero INCFSZ i,1,0 ; ; flag = 0; // BCF f,b ; Bit clear f BCF 0x06,flag,0 ; ; semi = 1; // BSF f,b ; Bit set f BSF 0x06,semi,0 ; ; btsc( flag); // BTFSC f,b ; Bit test f, skip if clear BTFSC 0x06,flag,0 ; ; btss( flag); // BTFSS f,b ; Bit test f, skip if set BTFSS 0x06,flag,0 ; ; sleep(); // SLEEP ; Go into standby mode SLEEP ; ; clrwdt(); // CLRWDT ; Clear watchdog timer CLRWDT ; ; return 5; // RETLW 5 ; Return, put literal in W RETLW 5 ; ; fx1(); // CALL fx1 ; Call subroutine CALL fx1 ; W = fx2(); // CALL fx2 ; Call subroutine CALL fx2 ; ; goto X; // GOTO X ; Go to address BRA m012 ; ; W = 45; // MOVLW 45 ; Move literal to W MOVLW 45 ; ; W = W | 23; // IORLW 23 ; Incl. OR literal and W IORLW 23 ; ; W = W & 53; // ANDLW 53 ; AND literal and W ANDLW 53 ; ; W = W ^ 12; // XORLW 12 ; Excl. OR literal and W XORLW 12 ; ; W += 33; // ADDLW 33 ADDLW 33 ; ; return W; // RETURN RETURN ; ; W = 23 - W; // SUBLW 23 SUBLW 23 ; ; W = addWFC(i); // ADDWFC f,W,0 ADDWFC i,W,0 ; i = addWFC(i); ADDWFC i,1,0 ; ; W = subFWB(i); // SUBFWB i,W,0 SUBFWB i,W,0 ; i = subFWB(i); SUBFWB i,1,0 ; ; W = subWFB(i); // SUBWFB i,W,0 SUBWFB i,W,0 ; i = subWFB(i); SUBWFB i,1,0 ; ; W = rrnc(i); // RRNCF i,W,0 RRNCF i,W,0 ; i = rrnc(i); RRNCF i,1,0 ; ; W = rlnc(i); // RLNCF i,W,0 RLNCF i,W,0 ; i = rlnc(i); RLNCF i,1,0 ; ; W = decsnz(i); // DCFSNZ i,W,0 DCFSNZ i,W,0 ; i = decsnz(i); DCFSNZ i,1,0 ; ; W = incsnz(i); // INFSNZ i,W,0 INFSNZ i,W,0 ; i = incsnz(i); INFSNZ i,1,0 ; ; pushStack(); // PUSH PUSH ; popStack(); // POP POP ; ; softReset(); // RESET RESET ; ; tableRead(); // TBLRD * TBLRD * ; tableReadInc(); // TBLRD *+ TBLRD *+ ; tableReadDec(); // TBLRD *- TBLRD *- ; tableReadPreInc(); // TBLRD +* TBLRD +* ; tableWrite(); // TBLWT * TBLWT * ; tableWriteInc(); // TBLWT *+ TBLWT *+ ; tableWriteDec(); // TBLWT *- TBLWT *- ; tableWritePreInc(); // TBLWT +* TBLWT +* ; ; b = negate(b); // NEGF b,0 NEGF b,0 ; W = decadj(W); // DAW DAW ; ; flag = !flag; // BTG 0x03,flag BTG 0x06,flag,0 ; ; BSR = 2; // MOVLB 2 ; ; multiply( 50); // MULLW 50 MULLW 50 ; multiply( i); // MULWF i,0 MULWF i,0 ; ; i = 0xFF; // SETF i,0 SETF i,0 ; ; FSR2 = 0x345; // NOTE: LFSR may be disabled MOVLW 69 MOVWF FSR2,0 MOVLW 3 MOVWF FSR2+1,0 ; ; skipIfEQ(a); // CPFSEQ a,0 CPFSEQ a,0 ; goto X; BRA m012 ; if (a == W) // CPFSEQ a,0 CPFSEQ a,0 BRA m001 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; skipIfLT(b); // CPFSLT b,0 m001 CPFSLT b,0 ; nop(); NOP ; if (b < W) // CPFSLT b,0 CPFSLT b,0 BRA m002 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; skipIfGT(b); // CPFSGT b,0 m002 CPFSGT b,0 ; nop(); NOP ; if (b > W) // CPFSGT b,0 CPFSGT b,0 BRA m003 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; skipIfZero(b); // TSTFSZ b,0 m003 TSTFSZ b,0 ; nop(); NOP ; if (!b) // TSTFSZ b,0 TSTFSZ b,0 BRA m004 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (Carry) // BNC m006 m004 BNC m005 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (!Carry) // BC m007 m005 BC m006 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (Negative) // BNN m008 m006 BNN m007 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (!Negative) // BN m009 m007 BN m008 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (Overflow) // BNOV m010 m008 BNOV m009 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (!Overflow) // BOV m011 m009 BOV m010 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (Zero_) // BNZ m012 m010 BNZ m011 ; i += b; MOVF b,W,0 ADDWF i,1,0 ; ; if (!Zero_) // BZ m013 m011 BZ m012 ; i += b; MOVF b,W,0 ADDWF i,1,0 ;X: ; return 0; m012 RETLW 0 ;} ; ; ;char sub( void) ;{ sub ; singleInstr(); RCALL singleInstr ; return 88; RETLW 88 ;} ; ;#pragma origin 4000 ORG 0x0FA0 ; ;char lsub( void) ;{ lsub ; singleInstr(); CALL singleInstr ; return 88; RETLW 88 ;} ; ;void fx1( void) ;{ fx1 ;} RETURN ; ;char fx2( void) ;{ fx2 ; return 9; RETLW 9 ;} ; ;void main(void) ;{ main ; sub(); CALL sub ; lsub(); RCALL lsub ;} SLEEP RESET END ; *** KEY INFO *** ; 0x000FA6 1 word(s) 0 % : fx1 ; 0x000FA8 1 word(s) 0 % : fx2 ; 0x00002C 1 word(s) 0 % : _highPriorityInt ; 0x000008 2 word(s) 0 % : highPriorityIntServer ; 0x000018 10 word(s) 0 % : lowPriorityIntServer ; 0x00002E 133 word(s) 1 % : singleInstr ; 0x000138 2 word(s) 0 % : sub ; 0x000FA0 3 word(s) 0 % : lsub ; 0x000FAA 5 word(s) 0 % : main ; RAM usage: 7 bytes (3 local), 505 bytes free ; Maximum call level: 3 (+2 for interrupt) ; Total of 160 code words (1 %)