Issue with booleans?

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
matherp
Registered User
Registered User
Posts: 31
Joined: Tue May 31, 2011 2:59 pm
Location: Cambridge

Issue with booleans?

Post by matherp » Thu Dec 01, 2011 12:27 pm

Hi all

I'm using 2.2.1.3 registered and have had an issue using booleans. I had defined three booleans

Dim a,b,c as boolean

was using them through the code e.g.

a=true

if a then

...

endif

The definition was the last of my variable definitions.

I was getting results which indicated that one of the booleans was being overwritten somewhere in the code.

I changed the booleans to bytes and used 0 and 1 as the coded values and of course changed the "if" statements to

If a=1 then

...

endif

The code then worked perfectly.

Is there any known issue with booleans I should be aware of?

I can post the code if required.

Thanks

Peter

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Dec 01, 2011 12:42 pm

Peter -

It's probably something code-specific, so posting what you've got would be a good idea.

matherp
Registered User
Registered User
Posts: 31
Joined: Tue May 31, 2011 2:59 pm
Location: Cambridge

Post by matherp » Thu Dec 01, 2011 1:19 pm

As requested.

The variables that were booleans are StepDirection,stepactive,Decayout
and the changes in the code are just replacement of "x=true" and "if x" wherever they appear.

Best regards

Peter

Code: Select all

// if device and clock are omitted, then the compiler defaults to 
// 18F452 @ 20MHz - they are just used here for clarity...
Device = 18F26K22
Clock = 64

Include "utils.bas"
dim DirectionPin as portc.0
Dim StepPin as portc.1
dim OutputEnablePin as portc.2
dim DecayPin as Portc.3
Dim Enable1Pin as PortC.5
Dim Enable2Pin as Portc.6
Dim StepMode As byte // default is 23 chars SetAllDigital
Dim ModeinUse(64)  as byte
Dim i,Position as byte
Dim StepPulse, EnablePulse, ForwardReversePulse as byte
Dim StepDirection,stepactive,Decayout as byte
const DecayMask as byte = 8
Const DirectionMask as Byte = 4
Const EnableMask as byte = 4
Const EnableShift as byte =2
const StepMask as byte = 2
Const StepShift as byte =1
const ForwardReverseMask as byte = 1
Const PortB4WI2(64) as Byte = (79,79,207,46,173,108,235,26,153,88,215,54,181,116,243,242,241,242,243,116,181,54,215,88,153,26,235,108,173,46,207,79,79,79,207,46,173,108,235,26,153,88,215,54,181,116,243,242,241,242,243,116,181,54,215,88,153,26,235,108,173,46,207,79)
Const PortC4WI2(64) As byte = (64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,208,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,160,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128)
Const D4W12(64) as Byte = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63)
Const D2W12(64) as byte= (0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62)
Const D1W12(64) As Byte = (0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60)
Const D0W12(64) AS bYTE = (0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56)
setalldigital()
input(porta.0)
input(porta.1)
input(porta.2)
input(porta.3)
trisb=0  //All pins on B are outputs
trisc=%00000111 // c0, c1, c2 inputs
StepMode=porta AND 15
if (stepmode and  DecayMask) = DecayMask then
   decayout=1
 else
	decayout=0
endif
if (stepmode and  DirectionMask) = DirectionMask then
   StepDirection=1
else
	StepDirection=0
endif
stepmode=stepmode and 3
select stepmode
case 3
  for i = 0 to 63
  	  Modeinuse(i)= D4W12(i)
  next
case 2
  for i = 0 to 63
  	  Modeinuse(i)= D2W12(i)
  next
case 1
  for i = 0 to 63
  	  Modeinuse(i)= D1W12(i)
  next
case 0
  for i = 0 to 63
  	  Modeinuse(i)= D0W12(i)
  next
endselect
position=0
Stepactive=0
portb=PortB4WI2(modeinuse(position))
if decayout=1 then
   portc=(Portc4WI2(modeinuse(position)) Or Decaymask)
else
	portc=Portc4WI2(modeinuse(position))
endif
While true
   StepMode=portC AND 7 //Get the enable, step and direction inputs
   Enablepulse=(StepMode AND EnableMask) >> EnableShift
   stepPulse=(Stepmode AND Stepmask) >> Stepshift
   ForwardReversePulse=stepmode and  ForwardReverseMask
   if stepdirection=1 then 
   	  ForwardReversePulse= (NOT ForwardReversePulse) and 1
   endif
   if (enablepulse=1) then
   	  high(enable1pin)
   	  high(enable2pin)
   else
   	   if (stepactive=0) and (steppulse=1) then
   	   	  stepactive=1
   	   	  if (ForwardReversePulse=1) then 
				position=position+1
				position=position mod 64
          else
          	  	position=position-1
				position=position mod 64
	  	  endif
 		  portb=PortB4WI2(modeinuse(position))
		  if decayout=1 then
   		  	 portc=(Portc4WI2(modeinuse(position)) Or Decaymask)
 		  else
  	 	 	 portc=Portc4WI2(modeinuse(position))
		  endif
		  delayus(5)
  	   endif
       if stepactive=1 and (steppulse=0) then
       	  stepactive=0
   	   endif
   endif

Wend


Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Thu Dec 01, 2011 3:59 pm

I can't find any issue in that code with changing it to use booleans.
Granted, I just did an inspection of the asm code generated, so I might have missed something, but the code is pretty simple.

This is what I used:

Code: Select all

// if device and clock are omitted, then the compiler defaults to
// 18F452 @ 20MHz - they are just used here for clarity...
Device = 18F26K22
Clock = 64

Include "utils.bas"

dim DirectionPin as portc.0
Dim StepPin as portc.1
dim OutputEnablePin as portc.2
dim DecayPin as Portc.3
Dim Enable1Pin as PortC.5
Dim Enable2Pin as Portc.6
Dim StepMode As byte // default is 23 chars SetAllDigital
Dim ModeinUse(64)  as byte
Dim i,Position as byte
Dim StepPulse, EnablePulse, ForwardReversePulse as byte

// comment/uncomment to select either booleans or bytes
'{
Dim StepDirection,stepactive,Decayout as boolean
const bTRUE = true
const bFALSE = false
'}
{
Dim StepDirection,stepactive,Decayout as byte
const bTRUE = 1
const bFALSE = 0
}

const DecayMask as byte = 8
Const DirectionMask as Byte = 4
Const EnableMask as byte = 4
Const EnableShift as byte =2
const StepMask as byte = 2
Const StepShift as byte =1
const ForwardReverseMask as byte = 1
Const PortB4WI2(64) as Byte = (79,79,207,46,173,108,235,26,153,88,215,54,181,116,243,242,241,242,243,116,181,54,215,88,153,26,235,108,173,46,207,79,79,79,207,46,173,108,235,26,153,88,215,54,181,116,243,242,241,242,243,116,181,54,215,88,153,26,235,108,173,46,207,79)
Const PortC4WI2(64) As byte = (64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,208,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,160,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128)
Const D4W12(64) as Byte = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63)
Const D2W12(64) as byte= (0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62)
Const D1W12(64) As Byte = (0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60)
Const D0W12(64) AS bYTE = (0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56)


setalldigital()
input(porta.0)
input(porta.1)
input(porta.2)
input(porta.3)
trisb=0  //All pins on B are outputs
trisc=%00000111 // c0, c1, c2 inputs
StepMode=porta AND 15
if (stepmode and  DecayMask) = DecayMask then
   decayout=bTRUE   
 else
   decayout=bFALSE
endif
if (stepmode and  DirectionMask) = DirectionMask then
   StepDirection= bTRUE 'true   '1
else
   StepDirection= bFALSE 'false  '0
endif
stepmode=stepmode and 3
select stepmode
case 3
  for i = 0 to 63
       Modeinuse(i)= D4W12(i)
  next
case 2
  for i = 0 to 63
       Modeinuse(i)= D2W12(i)
  next
case 1
  for i = 0 to 63
       Modeinuse(i)= D1W12(i)
  next
case 0
  for i = 0 to 63
       Modeinuse(i)= D0W12(i)
  next
endselect

position=0
Stepactive=bFALSE
portb=PortB4WI2(modeinuse(position))
if decayout=bTRUE then
   portc=(Portc4WI2(modeinuse(position)) Or Decaymask)
else
   portc=Portc4WI2(modeinuse(position))
endif

While true
   StepMode=portC AND 7 //Get the enable, step and direction inputs
   Enablepulse=(StepMode AND EnableMask) >> EnableShift
   stepPulse=(Stepmode AND Stepmask) >> Stepshift
   ForwardReversePulse=stepmode and  ForwardReverseMask
   if stepdirection=bTRUE then
        ForwardReversePulse= (NOT ForwardReversePulse) and 1
   endif
   if (enablepulse=1) then
        high(enable1pin)
        high(enable2pin)
   else
        if (stepactive=bFALSE) and (steppulse=1) then
            stepactive=bTRUE
            if (ForwardReversePulse=1) then
                position=position+1
                position=position mod 64
            else
                position=position-1
                position=position mod 64
            endif
            portb=PortB4WI2(modeinuse(position))
            if decayout=bTRUE then
                portc=(Portc4WI2(modeinuse(position)) Or Decaymask)
            else
                portc=Portc4WI2(modeinuse(position))
            endif
            delayus(5)
        endif
        if stepactive=bTRUE and (steppulse=0) then
            stepactive=bFALSE
        endif
   endif
Wend
So that I could swap between bools and bytes, I wrote the boolean tests longhand as "if stepactive=bTRUE" and "if (stepactive=bFALSE)" instead of the shorter form "if stepactive",
but that doesn't make any difference in the resulting code.

I'm not sure what you're seeing.

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Dec 02, 2011 11:53 am

Peter -

Are you using a bootloader by chance?

User avatar
Senacharim
Posts: 139
Joined: Tue Aug 10, 2010 5:19 pm
Location: Ventura, CA

Post by Senacharim » Fri Dec 02, 2011 2:56 pm

While I don't have any explanative for this one (sorry) in my experience when using booleans in Swordfish, it works better all round like so:

Code: Select all

'example -- not real code.
Dim
    BitsByte as Byte,
    Bool1 as BitsByte.Booleans(0),
    Bool2 as BitsByte.Booleans(1),
    Bool3 as BitsByte.Booleans(2),
    Bool4 as BitsByte.Booleans(3),
    Bool5 as BitsByte.Booleans(4),
    Bool6 as BitsByte.Booleans(5),
    Bool7 as BitsByte.Booleans(6),
    Bool8 as BitsByte.Booleans(7)
for some reason...

You could always give this kinda thing a shot and see if you get different results.
Surviving Member
Bermuda Triangle Battalion
from 2026 to 1992

Voted "Most likely to time travel"--Class of 2024.

matherp
Registered User
Registered User
Posts: 31
Joined: Tue May 31, 2011 2:59 pm
Location: Cambridge

Post by matherp » Fri Dec 02, 2011 3:54 pm

Jerry

I'm using a version of DS30 which I have modified to use a software uart on the picaxe 28x2 pins (quite pleased with myself on this!).

The problem was the software executing the "not enabled" code when the inputs were set as "enabled" and correctly read as such.

Senacharim - thanks for the idea - I'll try that.

Best regards

Peter

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Dec 02, 2011 5:50 pm

I've seen issues with bit allocations before (and have used Senacharim's method to fix it), but that was many, many versions ago.

Since you're using a bootloader, try the mod to system.bas we talked about in http://www.sfcompiler.co.uk/forum/viewtopic.php?t=1478 and see if that fixes it.

matherp
Registered User
Registered User
Posts: 31
Joined: Tue May 31, 2011 2:59 pm
Location: Cambridge

Post by matherp » Sat Dec 03, 2011 9:51 am

Jerry

I've now got to the bottom of the issue but don't understand the problem.

I had got that code in the version of system.bas in my user library.
I'm fairly certain that I had previously found that you don't need to explicitly "include system.bas" which is why it wasn't in my code.

However, by examining the .lst files I found that even if I included system.bas the code was not appearing. I then edited the version of system.bas in the central library to include the code and it then appeared in the lst file.

Thus for some reason the local "userlibrary" version of system.bas is not being picked up.

However, and this is the really strange bit, the local copy of utils.bas which includes your version of setalldigital is being correctly used. I haven't touched the central version.

I don't know if for some reason system.bas is a special case in this latest release or what is happening. I have re-organised my PC somewhat since this worked but can't find any obvious issues

Best Regards

Peter

Jerry Messina
Swordfish Developer
Posts: 1473
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sat Dec 03, 2011 8:51 pm

That is a little mysterious. I don't know if that's OS dependent, but on my machines (XP) it searches:
- the project directory
- SF/UserLibrary
- SF/Library
but I also don't have SF installed in its default location.
I'm fairly certain that I had previously found that you don't need to explicitly "include system.bas" which is why it wasn't in my code
From my experience, it's a lot better if you do. While system.bas is included by some of the other modules, it's not in all of them. Also, you really want to make sure it's the very first thing done, and explicitly placing it as the first include is the best way for this to happen.

SF adds very little in the way of "startup" code, and assumes that the program is running from reset. A lot of bootloaders don't restore the registers they muck around with so this is an issue with a number of them.

You could always fix ds30 to do the right thing.

Post Reply