Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
Select Case in Native mode

 
Post new topic   Reply to topic    Forum Index -> ZBasic Language
Author Message
spamiam



Joined: 13 Nov 2005
Posts: 689

Posted: 06 October 2008, 2:44 AM    Post subject: Select Case in Native mode Reply with quote

I have a problem with a program I am compiling in Native Mode (ZX24n)

I have the following code snippet

Code:
Select Case True
            Case GetButton(UpButton) 


And other similar Cases. None of them get evaluated as true even if one of them should have been true.

The GetButton function is as follows:

Code:
Public Function GetButton(ByVal ButtonNumber As Byte) As Boolean

    Const ButtonPressed As Byte = 0

    Select Case ButtonNumber
        Case 1
            GetButton = (GetPin(Button1Pin) = ButtonPressed)
        Case 2
            GetButton = (GetPin(Button2Pin) = ButtonPressed)
        Case 3
            GetButton = (GetPin(Button3Pin) = ButtonPressed)
        Case 4
            GetButton = (GetPin(Button4Pin) = ButtonPressed)
        Case Else
            GetButton = False
    End Select
End Function


This function does give correct results when used independently of a Case statement. The Select Case statements work properly when running in the ZVM mode. Is this an inconsistency in the Native Mode function, or do I have some odd software error elsewhere causing the code to fail?

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 06 October 2008, 3:32 AM    Post subject: Re: Select Case in Native mode Reply with quote

spamiam wrote:
Is this an inconsistency in the Native Mode function?
It sounds like there is a code generation error somewhere. I tried to construct a test case similar to what you described but it worked OK.

If you can, try to produce a simplified test case that exhibits the problem. Perhaps a variation of the code below will do it.
Code:
Sub Main()
  Select Case True
  Case test(3)
    Debug.Print "3"
  Case test(5)
    Debug.Print "5"
  End Select
End Sub

Function test(byval mode as byte) as Boolean
  test = (mode = 3)
End Function


Alternately, add --keep-files to your .pjt file and then send me the resulting .c file(s) containing the procedures involved. You'll find them two levels down from the directory containing the .pjt file: zxTempDir/<project-name>.
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 689

Posted: 06 October 2008, 12:30 PM    Post subject: Re: Select Case in Native mode Reply with quote

dkinzer wrote:
It sounds like there is a code generation error somewhere. I tried to construct a test case similar to what you described but it worked OK.


Unfortunately, this is a big, rambling project that I have been trying to update to the newest ZBasic. It was originally written for BasicX. Some of it was written by the BasicX company for some now discontinued hardware.

Since you could not reproduce the error, it is going to get a little harder to reproduce. I will have to move just the Constant declarations (for the button names, etc.) and the GetButton() function, and the Select Case into a new project.

As an attempt to debug the Select Case portion, I added a little code that has a bunch of if-then-else if statements that check all 4 buttons and then puts the button number (or zero) in a variable. I then did the Select Case based on that variable and then it worked.

So, it appears that it is something to do with using the GetButton function and doing the boolean comparison inside the Case statememts. Maybe the Select Case gets optimized away, or maybe the correct boolean value is lost and replaced by a zero. In your test code, the boolean function is effectively a constant, and the optimizer might be able to optimize the code down to something like just the Debug.Print statement, thereby not really reproducing the full complexity of my code.

I have not checked the files to see if there is excessive optimization and to see how the Select Case gets translated into C.

-Tony
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 689

Posted: 06 October 2008, 13:29 PM    Post subject: Reply with quote

I threw the following code together, as best as I can recall, essentially matching the functions of the real code (The actual program is not here at work). I compiled it in Native mode and looked at the C output. It looks fine to me! It ought to work. Now I have to set the Const statements to the correct values and try it again at home on the actual hardware.

-Tony

Code:
Const GoButton      as byte = 1
Const StopButton   as byte = 2
Const UpButton      as byte = 3
Const DownButton   as byte = 4
   
Const Button1Pin   as byte = 5
Const Button2Pin   as byte = 6
Const Button3Pin   as byte = 7
Const Button4Pin   as byte = 8


Sub Main()

   Do
   Select Case True
            Case GetButton(UpButton)
            debug.print "UpButton Pressed"
            
         Case GetButton(DownButton)
            debug.print "DownButton Pressed"
            
         Case GetButton(StopButton)
            debug.print "StopButton Pressed"
            
         Case GetButton(GoButton)
            debug.print "GoButton Pressed"
   End Select
   Loop while (Not GetButton(StopButton))
   
   Debug.print "Test complete"


End Sub


Public Function GetButton(ByVal ButtonNumber As Byte) As Boolean

    Const ButtonPressed As Byte = 0

    Select Case ButtonNumber
        Case 1
            GetButton = (GetPin(Button1Pin) = ButtonPressed)
        Case 2
            GetButton = (GetPin(Button2Pin) = ButtonPressed)
        Case 3
            GetButton = (GetPin(Button3Pin) = ButtonPressed)
        Case 4
            GetButton = (GetPin(Button4Pin) = ButtonPressed)
        Case Else
            GetButton = False
    End Select
End Function
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR

Posted: 06 October 2008, 15:22 PM    Post subject: Reply with quote

spamiam wrote:
I compiled it in Native mode and looked at the C output. It looks fine to me!
You've run into an error that was found and corrected last week (currently being tested for release). The issue arises with the code generated for the button testing code in GetButton(). An excerpt of the generated code appears below.
Code:
uint8_t _zv_selectValTemp01;
_zv_selectValTemp01 = zp_ButtonNumber;
if (_zv_selectValTemp01 == 1)
{
  zr_GetButton = !ZX_BOOL((getPin(7)));
}
else if (_zv_selectValTemp01 == 2)
The problem is the use of the logical negation on the result of the ZX_BOOL() macro. The macro returns either &H00 or &Hff corresponding to ZBasic's False and True values. The logical negation, unfortunately, converts these to 1 and 0, respectively. This causes the comparison with True (back in Main()) to always fail since neither of those values corresponds to True.

The GetButton() function can be rewritten to avoid the problem as shown below.
Code:
Public Function GetButton(ByVal ButtonNumber As Byte) As Boolean
    Const ButtonPressed As Byte = 0
    GetButton = False
    Dim buttonState as Byte
    Select Case ButtonNumber
    Case 1
        buttonState = GetPin(Button1Pin)
    Case 2
        buttonState = GetPin(Button2Pin)
    Case 3
        buttonState = GetPin(Button3Pin)
    Case 4
        buttonState = GetPin(Button4Pin)
    Case Else
        Exit Function
    End Select
    If (buttonState = ButtonPressed) Then
      GetButton = True
    End If
End Function

If the button numbers will always begin with 1 and be sequential, the function can be simplified as shown below.
Code:
Public Function GetButton(ByVal ButtonNumber As Byte) As Boolean
    Const ButtonPressed As Byte = 0
    Dim buttonPins as ByteVectorData({
        Button1Pin, Button2Pin, Button3Pin, Button4Pin
    })

    GetButton = False
    If (ButtonNumber <= CByte(UBound(buttonPins))) And _
            (GetPin(buttonPins(ButtonNumber)) = ButtonPressed) Then
        GetButton = True
    End If
End Function
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 689

Posted: 06 October 2008, 16:17 PM    Post subject: Reply with quote

dkinzer wrote:
You've run into an error that was found and corrected last week (currently being tested for release).


Ah, a week or 2 too late for me to have been helpful!


Quote:
The GetButton() function can be rewritten to avoid the problem as shown below.


That rewritten code looks really good. Actually it is more legible than the code as it currently exists. The GetButton() function is one of the routines that was originally written by Netmedia in their software for this hardware that I never bothered to change. If I were going to write it, it would have ended up looking like what you suggested, but probably not so good.


Quote:
If the button numbers will always begin with 1 and be sequential, the function can be simplified as shown below.
There is no reason the button numbers COULDN'T be starting at 1 and sequential. I believe that they are.

I will await the update, but in the meantime, I will modify the code to work with the existing compiler.

As far as I can tell, this is the only compiler issue (other than it not complaining about an excessively small task stack as discussed in another thread) that I encountered in my conversion of a large BasicX project to Native Mode ZBasic.

-Tony
Back to top
mikep



Joined: 24 Sep 2005
Posts: 771
Location: Austin, TX

Posted: 07 October 2008, 1:56 AM    Post subject: Reply with quote

spamiam wrote:
dkinzer wrote:
You've run into an error that was found and corrected last week (currently being tested for release).


Ah, a week or 2 too late for me to have been helpful!

Here is the thread where I first reported this problem: http://www.zbasic.net/forum/about1031.html

I had a large body of code which made it difficult to isolate the problem. I used a simple workaround for a while. I eventually found time to narrow down the code to a 50 line test case which I sent to Don on 9/22. He was able to quickly diagnose the problem and supply a fix.

So you can blame me for not having this fix earlier Smile
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 689

Posted: 07 October 2008, 3:12 AM    Post subject: Reply with quote

mikep wrote:
Here is the thread where I first reported this problem: http://www.zbasic.net/forum/about1031.html


I had seen that thread. I was not at all sure I understood what it was doing wrong adn what the fix had been. I now can see that the native mode evaluation of boolean results might have played a part in your reported problem.

-Tony
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZBasic Language Time synchro. with the server - Timezone/DST with your computer
Page 1 of 1

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group