Jump to content

Recommended Posts

What the Google is going on here? Line 10 is identical to line 7, but in line 10 the value is moved from BANK 0 to BANK 1 and then back to BANK 0.

 

1:                 #include <system.h>
2:                 
3:                 unsigned short tmr_val@0x20;
4:                 unsigned char fill[94]@0x22;
5:                 
6:                 void main(void) {
7:                 	tmr_val = tmr1h << 8;
 0003    1283     BCF 0x3, 0x5
 0004    1303     BCF 0x3, 0x6
 0005    01A0     CLRF 0x20
 0006    080F     MOVF 0xf, W
 0007    00A1     MOVWF 0x21
8:                 	tmr_val |= tmr1l;
 0008    080E     MOVF 0xe, W
 0009    04A0     IORWF 0x20, F
9:                 	if (tmr1h != (tmr_val >> 8)) {
 000A    0821     MOVF 0x21, W
 000B    060F     XORWF 0xf, W
 000C    1903     BTFSC 0x3, 0x2
10:               		 tmr_val = tmr1h << 8;
 000E    1683     BSF 0x3, 0x5
 000F    01A0     CLRF 0x20
 0010    1283     BCF 0x3, 0x5
 0011    080F     MOVF 0xf, W
 0012    1683     BSF 0x3, 0x5
 0013    00A1     MOVWF 0x21
 0014    0820     MOVF 0x20, W
 0015    1283     BCF 0x3, 0x5
 0016    00A0     MOVWF 0x20
 0017    1683     BSF 0x3, 0x5
 0018    0821     MOVF 0x21, W
 0019    1283     BCF 0x3, 0x5
 001A    00A1     MOVWF 0x21
11:               		 tmr_val |= tmr1l;
 001B    080E     MOVF 0xe, W
 001C    04A0     IORWF 0x20, F
12:               	 }
13:                }
 000D    0008     RETURN
 001D    0008     RETURN

Link to post
Share on other sites

edt,

 

What the Google is going on here?  Line 10 is identical to line 7, but in line 10 the value is moved from BANK 0 to BANK 1 and then back to BANK 0.

We need more information:

Which compiler version are you using?

What is the target PIC device?

 

Regards

Dave

Link to post
Share on other sites

edt,

Oh, sorry.  It's SourceBoost 6.60 on PIC16 (p16f877a), with or without aggressive optimization enabled.

Looks like optimisation is not being applied in the second case of the expression, then to add insulate to injury the bank of the temporary variable is not unfortunate.

 

I've added it to the bugs list.

 

Regards

Dave

Link to post
Share on other sites

edt,

 

Here is a hack that gets the compiler to generate better code:

#include <system.h>

unsigned short tmr_val@0x20;
unsigned char fill[94]@0x22;

inline void GetTmr1(void)
{
   tmr_val = tmr1h << 8;
   tmr_val |= tmr1l;
}

void main(void) 

{
   GetTmr1();
0003  1283 	 BCF STATUS, RP0
0004  1303 	 BCF STATUS, RP1
0005  01A0 	 CLRF gbl_tmr_val
0006  080F 	 MOVF gbl_tmr1h, W
0007  00A1 	 MOVWF gbl_tmr_val+D'1'
0008  080E 	 MOVF gbl_tmr1l, W
0009  04A0 	 IORWF gbl_tmr_val, F

   if (tmr1h != (tmr_val >> 8)) {
000A  0821 	 MOVF gbl_tmr_val+D'1', W
000B  060F 	 XORWF gbl_tmr1h, W
000C  1903 	 BTFSC STATUS,Z

	GetTmr1();
000E  01A0 	 CLRF gbl_tmr_val
000F  080F 	 MOVF gbl_tmr1h, W
0010  00A1 	 MOVWF gbl_tmr_val+D'1'
0011  080E 	 MOVF gbl_tmr1l, W
0012  04A0 	 IORWF gbl_tmr_val, F

   }
}
000D  0008 	 RETURN
0013  0008 	 RETURN

Link to post
Share on other sites

Here is code to read TIMER1 in assembly for BootC:

unsigned short tmr_val@0x20;

inline void ReadTmr1_asm(void)
{
   asm
   {   
	rlf   _intcon,W    ; /* save current interrupt state in carry */
	bcf   _intcon,GIE  ; /* disable all interrupts */
       
	movf  _tmr1h, W    ; /* read 16-bit timer */
	movwf _tmr_val+1
	movf  _tmr1l, W
	movwf _tmr_val

	movf  _tmr1h, W    ; /* test if MSB changed during read */
	xorwf _tmr_val+1, W
	btfsc _status,Z    ; /* skip if not zero */
	goto  done
	xorwf _tmr_val+1, F; /* MSB changed so read again */
	movf  _tmr1l, W
	movwf _tmr_val
done:
    btfsc _status,C    ; /* skip if interrupts were disabled */
    bsf   _intcon,GIE  ; /* enable interrupts */
   }
}

This covers the important issues like turning interrupts off, and on, and reading LSB again when MSB changes during a read.

Link to post
Share on other sites
Here is code to read TIMER1 in assembly for BootC

...

This covers the important issues like turning interrupts off, and on,  and reading LSB again when MSB changes during a read.

Oops, forgot about disabling interrupts... I looked straight at it in the datasheet, too: "; All interrupts are disabled". Thanks
Link to post
Share on other sites
        movf  _tmr1h, W  ; /* read 16-bit timer */
       movwf _tmr_val+1

Doesn't it make the code not portable to assume byte order? Is there a way around it?

This is an inline assembly hack that is specific to BoostC.

 

If you need portability use the slower, bigger version in C.

 

So the short answer is no, not portable.

Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...