CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

trouble with #inline directive

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mcb
Guest







trouble with #inline directive
PostPosted: Thu Mar 01, 2007 3:45 pm     Reply with quote

this is my c code

Code:
#include <16f84.h>
#device      *=16
#FUSES NOWDT,hs,NOPUT,NOPROTECT//,NOBROWNOUT,NOCPD,NOLVP,NOCPD,//MCLR


#build(reset = 0x30, interrupt = 0x34)

#org 0, 0x2f {}


int zc;
#locate zc=17

int cb;
#locate cb=18

int rdon[58];


#inline
 turbo()
{
   cb = cb*10;
   zc = zc*80;
   cb=cb+3;
}

#org 0x36 , 0x85
 main()
     {
       
       turbo();

     }
#ORG default

and this is the disassembled ccs c hex code
Code:

; Generated by WinDis84, (c) Nigel Goodwin 1998.

            LIST      P=16F84, F=INHX8M
            include "P16FXX.inc"
            ORG     0x0000

            ORG     0x0030
            MOVLW   0x00
            MOVWF   PCLATH
            GOTO    Label_0001
            NOP
            ORG     0x0036
Label_0001  CLRF    FSR
            BCF     STATUS    , IRP
            MOVLW   0x1F
            ANDWF   STATUS    , f
            MOVF    0x13      , W
            MOVWF   0x4E
            MOVLW   0x0A
            MOVWF   0x4F
            CALL    Label_0002
            MOVF    0x0D      , W
            MOVWF   0x13
            MOVF    0x12      , W
            MOVWF   0x4E
            MOVLW   0x50
            MOVWF   0x4F
            CALL    Label_0002
            MOVF    0x0D      , W
            MOVWF   0x12
            MOVLW   0x03
            ADDWF   0x13      , f
            SLEEP
            ORG     0x0086
Label_0002  CLRF    0x0C
            CLRF    0x0D
            MOVF    0x4E      , W
            BCF     STATUS    , C
            BTFSC   0x4F      , 00
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4F      , 01
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4F      , 02
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4F      , 03
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4F      , 04
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4F      , 05
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4F      , 06
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4F      , 07
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            RETLW   0x00

Code:
           ORG     0x0086
Label_0002  CLRF    0x0C
there is something wrong...
but if i would write only cb++; or cb--; rather than cb=cb+1; or cb=cb-1; it will be ok.why? what is the difference between two code for inlining.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 01, 2007 4:22 pm     Reply with quote

The compiler is calling the CCS 8-bit multiplication routines, which
are located at address 0x86.

To prevent it from calling those routines, you could substitute your
own code to do the multiplication. You can multiply by 10 or
multiply by 80 by doing a sequence of shifts and adds.
mcb
Guest







PostPosted: Thu Mar 01, 2007 4:45 pm     Reply with quote

why does compiler use this method? is there any way to use these multiplication routines without calling any subroutine.i dont wanna write my own code Very Happy , at least i will copy multiplication section below org 0x86 and use them with #asm-endasm.but i hope they will fix or add new directive to use embeded routines with inline.
thank you very much.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Mar 01, 2007 5:29 pm     Reply with quote

Just curious, but why do you care so much? Your workaround by copying the assembly code is a lot of work and looks ugly and that only for saving a few bytes and neglectable speed gain.

If speed and code size are that important to you than follow PCM's suggestion and rewrite the multiplications by a combination of shift and add instructions.
Code:
#inline  turbo()
{
   // cb = cb * 10;
   // cb = cb * (8 + 2);
   cb = cb<<3 + cb<<1;

   // zc = zc * 80;
   // zc = zc * (64 + 16);
   zc = zc<<6 + zc<<4;

   cb=cb+3;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Mar 01, 2007 5:30 pm     Reply with quote

I would have told him that, but he didn't want to write any code so I bailed.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Mar 01, 2007 6:01 pm     Reply with quote

Hi PCM,
I know you would have helped him if he wanted to write the code. It's just that I was curious why someone would go into all this trouble of copying asm code and I hope mcb will return to enlighten us.

Posting this question I decided to write the example code as an exercise for myself. I'm glad to be using PIC18 processors with hardware multiplier.
mcb
Guest







PostPosted: Fri Mar 02, 2007 2:40 am     Reply with quote

hi all, that is my example code on 16f84.i m trying to understand behaviour of compiler.i will write a program like a bootloader so i wanna get full of control over system as possible as with minimum asm code.
but i cant locate some code part like this.i have one more problem which is ccs c multiplication routines dont obey #org directives. my own subroutine ,turbo(), is on the correct location but it calls multiplication routines from prevented area.

Code:
#include <16f84.h>
#device      *=16
#FUSES NOWDT,hs,NOPUT,NOPROTECT//,NOBROWNOUT,NOCPD,NOLVP,NOCPD,//MCLR
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_a0, rcv=PIN_a1)

#define status 0x03
#define c      0x00
#define f      0x00
#define w      0x00

#build(reset = 0x30, interrupt = 0x34)
#org 0, 0x2f {}
#org 0x96,0x3fe{}


int zc;
#locate zc = 0x11

int cb;
#locate cb = 0x12

int rdon[55];
#locate rdon=0x13

#org 0x86 , 0x95
void turbo()
{
 cb = cb*22;
}


#org 0x36 , 0x85
 main()
     {
       zc=1;
       cb=2;
       
       turbo();     
       rdon[0]=1;
       rdon[54]=2;
     
     }
#ORG default


and this is result.

Code:
            ORG     0x0000

      Label_0004  CLRF    0x0C
            CLRF    0x0D
            MOVF    0x4B      , W
            BCF     STATUS    , C
            BTFSC   0x4C      , 00
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4C      , 01
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4C      , 02
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4C      , 03
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4C      , 04
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4C      , 05
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4C      , 06
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            BTFSC   0x4C      , 07
            ADDWF   0x0C      , f
            RRF     0x0C      , f
            RRF     0x0D      , f
            GOTO    Label_0001

            ORG     0x0030
            MOVLW   0x00
            MOVWF   PCLATH
            GOTO    Label_0002
            NOP

            ORG     0x0036
Label_0002  CLRF    FSR
            BCF     STATUS    , IRP
            MOVLW   0x1F
            ANDWF   STATUS    , f
            BSF     STATUS    , RP0
            BCF     TRISA     , 00
            BCF     STATUS    , RP0
            BSF     PORTA     , 00
            MOVLW   0x01
            MOVWF   0x11
            MOVLW   0x02
            MOVWF   0x12
            CALL    Label_0003
            MOVLW   0x01
            MOVWF   0x13
            MOVLW   0x02
            MOVWF   0x49
            SLEEP

            ORG     0x0086
Label_0003  MOVF    0x12      , W
            MOVWF   0x4B
            MOVLW   0x16
            MOVWF   0x4C
            GOTO    Label_0004

Label_0001  MOVF    0x0D      , W
            MOVWF   0x12
            RETLW   0x00

there is enought rom between (0x36 , 0x85) but compiler dont locate multiplication routines there.it choses different location where is prevented by org directive.

this is just a example , my own code is larger so i must solve these memory - ram problems.

thank you all
mcb
Guest







PostPosted: Fri Mar 02, 2007 2:57 am     Reply with quote

this is more clear
Code:
#include <16f84.h>
#device      *=16
#FUSES NOWDT,hs,NOPUT,NOPROTECT//,NOBROWNOUT,NOCPD,NOLVP,NOCPD,//MCLR
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_a0, rcv=PIN_a1)

#define status 0x03
#define c      0x00
#define f      0x00
#define w      0x00

#build(reset = 0x30, interrupt = 0x34)
#org 0, 0x2f {}
#org 0x106,0x3ff{}


int zc;
#locate zc = 0x11

int cb;
#locate cb = 0x12

int rdon[55];
#locate rdon=0x13


#org 0x35 , 0x105
 main()
     {
       zc=1;
       cb=2;
       
       cb = cb*15;
       
       rdon[0]=1;
       rdon[54]=2;
     
     }
#ORG default


Code:
            ORG     0x0000

            ORG     0x0030
            MOVLW   0x00
            MOVWF   PCLATH
            GOTO    Label_0001
            NOP

            ORG     0x0035
Label_0001  CLRF    FSR
            BCF     STATUS    , IRP
            MOVLW   0x1F
            ANDWF   STATUS    , f
            BSF     STATUS    , RP0
            BCF     TRISA     , 00
            BCF     STATUS    , RP0
            BSF     PORTA     , 00
            MOVLW   0x01
            MOVWF   0x11
            MOVLW   0x02
            MOVWF   0x12
            MOVF    0x12      , W
            MOVWF   0x4B
            MOVLW   0x0F
            MOVWF   0x4C
            GOTO    Label_0002
            MOVF    0x0D      , W
            MOVWF   0x12
            MOVLW   0x01
            MOVWF   0x13
            MOVLW   0x02
            MOVWF   0x49
            SLEEP
 
            ORG     0x03FF

Label_0002 CLRF 0x0C


and there is no multiplication routines correctly.i think compiler wanna its own location, and wont locate multiplication routines in main function
Ttelmah
Guest







PostPosted: Fri Mar 02, 2007 3:28 am     Reply with quote

Hint. This is what the 'default' keyword does. This forces 'system' routines to be placed in the area.
If you declare your code as:
Code:

org 0x36, 0x85 default

#inline
void turbo(void) {
   cb = cb*10;
   zc = zc*80;
   cb=cb+3;
}

void main(void) {
   turbo();
}

With the other declarations obviously, then the 'main', and the functions called 'inline', together with 'turbo', will all be placed in the required area. You can also use a #org, with a different range, and a 'default' keyword, to force the maths routines alone to be relocated, using:
Code:

#org 0x60, 0x85 default
#inline
void turbo(void) {
   cb = cb*10;
   zc = zc*80;
   cb=cb+3;
}

#org 0x35, 0x5F
void main(void) {
   turbo();
}
#org default

The 'turbo' routine, is flagged as 'inline', so does not itself get put at 0x60, but the _maths_ routines it calls, are located here.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Mar 02, 2007 3:48 am     Reply with quote

Just a remark: in CCS it is very unusual to have this many #org statements, it now looks like you are rewriting code originally designed for another compiler. In many other PIC compilers you have to specify the addresses for variables but the CCS compiler is more smart in this respect; you specify the memory range and then have the CCS compiler decide where to put everything. The advantage of giving control to the CCS compiler is that the compiler can re-use RAM as often as it can and you won't run into problems with new compiler versions which are 'improved' and have other memory requirements.

I get the idea you are putting way to much effort in saving a few bytes and you are missing the larger picture. If this is a new design, choose a PIC with more memory as that will turn out to be much cheaper. If you are upgrading an existing project than reconsider another bootloader approach, for example the Tiny Bootloader is very small and proven code.
mcb
Guest







PostPosted: Fri Mar 02, 2007 1:03 pm     Reply with quote

Ttelmah thank you for your good expressions,i understand that compiler make a multiplication subroutine and uses it for different variables.this is very good.i will use "default" directive .this is very useful.

thank you all
3dfx



Joined: 24 Mar 2007
Posts: 6

View user's profile Send private message

PostPosted: Sun Apr 01, 2007 11:20 am     Reply with quote

hi,is there any way to using #inline directive with #asm directive?
Code:

#inline
void goto_xy(int x)
{
   #locate x  = ram_location
   
   #asm
   call rom_adress
   #endasm
}


this is the result ;
Code:

....................       goto_xy(0x10);
006D:  MOVLW  10
006E:  MOVWF  21


compiler pass asm codes.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group