CHRISTMAS LITES OPTIMIZATION

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

CHRISTMAS LITES OPTIMIZATION

Post by xor » Thu Dec 21, 2006 10:53 pm

There was an optimization challenge that I proposed for mikroBasic a year ago for P16's. It moves a single LED back and forth on the PORTB pins starting at PORTB.0. The best mB code that I recently came up with was 25 Words. TimB blew me away with his PDS optimization last year which was as good as assembler at 16 Words.

Now on to P18's. In mB I was able to compile to 58 Words. Swordfish compiles to 51 Words with the following code. Anyone is welcome to optimize it. Please note that I cheated a bit because Swordfish doesn't have the SLEEP instruction as a Basic keyword.

Code: Select all

Device = 18F452
Clock = 8
Config WDT = ON

Dim hbit As LATB.booleans(7)
Dim lbit As LATB.booleans(0)

TRISB = 0
LATB = 1

Repeat
Repeat
   ASM
      SLEEP
   End ASM
   LATB = LATB << 1
Until hbit
Repeat
   ASM
      SLEEP
   End ASM
   LATB = LATB >> 1
Until lbit
Until 0=1

TimB
Posts: 262
Joined: Wed Oct 04, 2006 7:25 am
Location: London UK

Post by TimB » Fri Dec 22, 2006 12:10 am

To be fair to Swordfish my original had asm in it as well and PDS does not do the all thet initialisations SF does.

But here's it a little smaller at 47 if you look at the core asm its the same size as Proton

Code: Select all


Device = 18F452
Clock = 8
Config WDT = ON

Dim hbit As LATB.booleans(7)
Dim lbit As LATB.booleans(0)


 Inline Sub ShiftLedRight()
    ASM
    rrncf LATB
    End ASM
    End Sub

Inline Sub ShiftLedLeft()
    ASM
    rlncf LATB
    End ASM
    End Sub

TRISB = 0
LATB = 1    

Repeat
Repeat
   ASM
      SLEEP
   End ASM
   ShiftLedLeft ()
Until hbit
Repeat
   ASM
      SLEEP
   End ASM
   ShiftLedRight ()
Until lbit
Until 0=1

Bruce
Posts: 16
Joined: Sun Oct 29, 2006 5:54 pm
Contact:

Post by Bruce » Sun Dec 24, 2006 2:46 pm

Not much BASIC, but here's one at 43 words.

Code: Select all

Device = 18F452 
Clock = 20 
Config WDT = ON,
       WDTPS = 4 

Inline Sub Sweep()
    ASM
 left
      sleep
      rlcf LATD
      bnc left
 right
      sleep
      rrcf LATD
      bnc right
    End ASM    
End Sub

LATD = 1
TRISD = 0

{
  Main program
}

While True
    Sweep()
Wend
Regards,

Bruce
http://www.rentron.com

User avatar
Darrel Taylor
Posts: 29
Joined: Wed Oct 04, 2006 4:44 pm
Location: California

Post by Darrel Taylor » Mon Dec 25, 2006 9:11 am

Here's 37 bytes. Assuming we're only talking Program space.

Code: Select all

Device = 18F452 
Clock = 20 
Config WDT = ON, 
       WDTPS = 4 

EEPROM = (1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,1)

Dim EEread As EECON1.booleans(0)

TRISB = 0 
While True 
    EEread = true
    LATB = EEDATA
    Inc(EEADR)
    ASM
      sleep
    End ASM   
Wend
Best regards,
DT

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Mon Dec 25, 2006 6:37 pm

Darrel,

That's very innovative... :D I am wondering, how does it land at the end if the 1's in the middle are not repreated....creating the same symmetry as what happens with 128? I think it's pretty close.

I hope you don't mind but I am using this concept on another forum....I'll give you credit for it.

User avatar
Darrel Taylor
Posts: 29
Joined: Wed Oct 04, 2006 4:44 pm
Location: California

Post by Darrel Taylor » Tue Dec 26, 2006 4:39 am

Yeah, you're right. It's not exactly symmetrical . I was paying more attention to the challenge, than the look.

So, here's a symmetrical data sequence.

Code: Select all

EEPROM = (1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1,
          1,2,4,8,16,32,64,128,128,64,32,16,8,4,2,1)
Here's a sequence with 2 lights at different speeds...

Code: Select all

' --- 2 lights different speed ---
EEPROM = (1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3,
          1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3,
          1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3,
          1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3,
          1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3,
          1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3,
          1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3,
          1,3,5,9,18,34,68,132,136,72,48,16,40,36,66,65,
          129,130,132,136,80,96,96,160,144,80,40,24,12,4,2,3)
and, this one's a Marquee. It would look best with several sets of 8 leds strung end to end.

Code: Select all

' --- marquee ---
EEPROM = (17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136,
          17,34,68,136,17,34,68,136,17,34,68,136,17,34,68,136)
Happy holiday's,
-- DT --

P.S. I don't mind at all, use it any way you wish :)

TimB
Posts: 262
Joined: Wed Oct 04, 2006 7:25 am
Location: London UK

Post by TimB » Tue Dec 26, 2006 11:22 am

Hats off to you Darrel

Very very small ~ 7 words with fantastic flexibility

CLRF TRISB,0
WHILE_0
BSF EECON1,0,0
MOVFF EEDATA,LATB
INCF EEADR,1,0
SLEEP
BRA WHILE_0

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Tue Dec 26, 2006 5:15 pm

Tim,

It is possible that the WHILE_0, BRA WHILE_0, and SLEEP are not necessary since the processor will reset with the WDT when at the end of the program doing nothing.

4 Instructions:

Code: Select all

TRISB = 0
EECON1.0 = 1
LATB = EEDATA
INC(EEADR)

User avatar
Darrel Taylor
Posts: 29
Joined: Wed Oct 04, 2006 4:44 pm
Location: California

Post by Darrel Taylor » Wed Dec 27, 2006 1:02 am

Tim,

Thanks, I got lucky with that, since I had actually given up trying to beat your example. But after Bruce came up with something better, I figured maybe I quit too soon. :?


XOR,

Thought you had it! But after trying it, I found that Swordfish automatically puts ...

Code: Select all

SBGLB2
        CLRWDT
        SLEEP
        BRA SBGLB2
at the end of every program.

So I put a

Code: Select all

Stop: GoTo Stop
at the end to make it reset on the watchdog timeout, and then found that the EEADR register get's zeroed on any reset. So it just sits there, and doesn't scan.

Good thought though.
Best regards,
DT

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Wed Dec 27, 2006 4:21 am

EEADR will remain intact with P16's...I see that's not the case with P18's. Always something new to learn....thanks for pointing it out.

Bruce
Posts: 16
Joined: Sun Oct 29, 2006 5:54 pm
Contact:

Post by Bruce » Wed Dec 27, 2006 2:22 pm

Nice work Darrel. One thing I noticed is it needs one additional instruction
to clear EECON1 before it works reliably.

The POR/BOR value of EECON1 bits EEPGD and CFGS are unkonwn, and
both have to be clear prior to setting RD. It was a hit & miss until I added
EECON1=0. After that, it was bullet-proof. It does add one instruction, but
it's still short & sweet. Nice job.

Code: Select all

Device = 18F452 
Clock = 20 
Config WDT = ON, 
       WDTPS = 8 

Dim TAddress As EEADR
      
EEPROM = (1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1, 
          1,2,4,8,16,32,64,128,64,32,16,8,4,2,1,1)

Dim RD As EECON1.Booleans(0)

Sub GoToSleep()
    ASM
     SLEEP
    End ASM
End Sub

TRISD = 0
EECON1 = $00        ' EECON1 bits EEPGD & CFGS must be cleared first
                    ' These bits are unknown at POR & BOR reset
While TRUE
    RD = TRUE       ' Set RD to start EEPROM read (cleared by hardware after read)
    LATD = EEDATA   ' Place EEPROM contents (EEDATA) on PORTD
    Inc(EEADR)      ' Increment EEPROM address pointer to next byte pattern
    GoToSleep       ' Sleep until watchdog timeout, then repeat
Wend
Regards,

Bruce
http://www.rentron.com

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Wed Dec 27, 2006 3:43 pm

I don't have access to the compiler since I forgot my USB key but what about this. ADRESL does not reset after WDT reset and it sits at the end with the Branch Always until WDT reset:

Code: Select all

  TRISB = 0
  inc(ADRESL)
  EEADR = ADRESL
  EECON1 = 1
  LATB = EEDATA
  ASM
     bra     0
  END ASM

User avatar
Darrel Taylor
Posts: 29
Joined: Wed Oct 04, 2006 4:44 pm
Location: California

Post by Darrel Taylor » Wed Dec 27, 2006 9:08 pm

Hi Bruce,

Indeed it does.
Nice catch. I don't think I turned the power off the whole time I was playing with it.
But sure enough, it only works some of the time when you do.

It doesn't add much, weighs in at 39 bytes now.


XOR,

That works, although it runs a little bit slower. Possibly from the power on timer. And, it comes in at 41 bytes according to Swordfish.

Added: Nope, turned off the power-up timer and it still runs slower. Hmmm.

Added again: Doh! I'm using the MCS bootloader. That's where the extra delay comes from.

-- DT --

P.S. This is Fun!

P.P.S.
How many programmers does it take to blink an LED?
Apparently, All of them, if you want it to work right. :)
Last edited by Darrel Taylor on Wed Dec 27, 2006 9:51 pm, edited 2 times in total.

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Wed Dec 27, 2006 9:23 pm

For those PIC's with default CMCON = 7:

Code: Select all

   TRISB = 0
   inc(ADRESL)
   EEADR = ADRESL
   EECON1 = CMCON
   LATB = EEDATA
   ASM
      bra     0
   END ASM

xor
Posts: 286
Joined: Sun Nov 05, 2006 1:15 pm
Location: NYC
Contact:

Post by xor » Sat Dec 30, 2006 8:43 pm

Here is another novel approach I adapted from Bruno on another forum. It is not perfect in that the 7th bit stays on for 6 extra cycles while the LED goes back and forth. It uses only 15 EEPROM addresses and compiles to 39 program bytes:

Code: Select all

Device = 18F452
Clock = 8
Config WDT = ON
Config WDTPS = 16

EEPROM = (1,2,4,0,8,0,0,0,16,0,0,0,0,0,0,0, 
          32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          192,0,1,0,130,0,0,0,132,0,0,0,0,0,0,0, 
          136,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          144,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 
          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) 

TRISB = 0
EEADR = PORTB
EECON1 = 1
LATB = EEDATA
Repeat Until 0=1
This also works to 39 bytes:

Code: Select all

Dim RD As EECON1.Booleans(0) 

TRISB = 0
EECON1 = 0
EEADR = PORTB
RD = True
LATB = EEDATA
Repeat Until 0=1
This also works for me without having to clear EECON1 first...37 bytes:

Code: Select all

TRISB = 0
EEADR = PORTB
Inc(EECON1)
LATB = EEDATA
Repeat Until 0=1

Post Reply