Announcement

Collapse
No announcement yet.

Diablo 16 Internal 4DGL function for SPE environment

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Diablo 16 Internal 4DGL function for SPE environment

    I needs large flash programs and aren't supported by the diablo, I planned change from GFX to SPE environment. I have microcontroller as host with flash 1MB. My question: What all Internal diablo 4DGL functions that exist when using GFX environment, also available all when use SPE environment? Thanks.

  • #2
    The most commonly used commands from GFX are available in SPE.

    What has happened to calling functions in banks, surely you haven't used all 192KB?
    Mark

    Comment


    • #3
      I've tried and met a lot of errors when trying to split program into slave.

      1. What is the function located in flashbank 1 to 5 (as a slave), can be called directly from the bank 0 (as master), without having to go through a reference to the main function of the slave? If we use the same parameter names for all the different functions, it would be difficult for maintenance process?

      2. Why are the variables with public access is not available in the slave?

      If the compiler can access directly 192kb flash program, of course all the above problems will be solved. Why the compiler can not access flash program directly 192kb?

      Comment


      • #4
        Put the parameter names in an inherited file, that will ensure they always match.

        You mean global variables? Global variables are allocated when a program starts, but functions called in banks never 'start' so there is no opportunity to allocate them with the required persistence.

        To use global variables in a bank pass a pointer to them from the main bank. Either use normal global memory from Bank 0, or use mem_Alloc'd memory. define it as an array and have indexes named and defined in an inherited file.

        The compiler is 16bits, due to the word addressing nature this means each bank an only be 32KB.

        Many people prefer the bank scheme over one huge linear space, you can udpate one bank from another, for example. It also tends to modularise large programs.
        Mark

        Comment


        • #5
          Thank you for point out, I'll try it again.

          Global variables or member variables = allowing all functions in same module/class to access these variables from within the function.

          From here, A 16-bit integer can store 2^16 (or 65,536) distinct values. In an unsigned representation, these values are the integers between 0 and 65,535; using two's complement, possible values range from −32,768 to 32,767. Hence, a processor with 16-bit memory addresses can directly access 64 KB of byte-addressable memory. Why 4D only can directly access 32KB, not 64KB?

          Comment


          • #6
            >Global variables or member variables = allowing all functions in same module/class to access these variables from within the function.
            It's the same as I said before "Global variables are allocated when a program starts, but functions called in banks never 'start' so there is no opportunity to allocate them with the required persistence." Use pointers to access variables across functions and banks

            It does access 64kb, 32kb of Flash + 32kb of RAM
            Mark

            Comment


            • #7
              When the code in bank 0 exceed 32kb then compiler automatically saves the program to the next empty bank. So we can make code up to 192kb, without fear of running out of free space. I think It will make it easier for programmers to focus on completing the work.
              Last edited by rwin; 23rd May 2015, 07:56 AM.

              Comment


              • #8
                It's a LOT more complicated than that.

                We do have plans for a 32bit version but it's quite a long way off.

                ​Once you design how you want to use banks you will find they actually help you write better organised code.

                We have many users with what I would call huge programs, they rarely go past three banks. One uses a 4th bank to enable update of their code on the fly over the internet.
                Mark

                Comment


                • #9
                  I'm not familiar with how to save the program separately, using 0-5 banks, as used diablo.

                  I more often use rcm5600w of rabbit microcontroller, which is also 16 bits microcontroller variant. The difference is, I can make the program more flexible for 1MB flash, without fear running out of flash because the compiler automatically knows, must save the program in a location where it is. Programmers simply add the storage location in front of the function name if we want to save function to different memory, eg: we want to save add() function on the external flash, we just add xmem add(var a, var b). The compiler will automatically save add function to the external memory function, without the programmer having to divide their code and distribute into the empty flash.

                  I'm glad to hear if the 4D-System plans to make 32 bits so that it will add more flash memory, because of the complex graphics applications require it.
                  Last edited by rwin; 23rd May 2015, 02:39 PM.

                  Comment


                  • #10
                    I'm confused, how to split the code into the different bank of flash will save the flash memory. See the example program below.
                    Program A stored in a bank: bank0, code size bank0=91bytes.
                    Program B is stored in two banks: bank0 and bank1. Code size bank0=147bytes.

                    Where is the saving of flash memory when split code into different bank? I see a program that uses single flash(Program A) have code size smaller than if separated as program B.

                    Program A:
                    Code:
                    #platform "uLCD-43DT"
                    #MODE FLASHBANK_0
                    
                    func add(var a, var b)
                        return a + b;
                    endfunc                                              
                    
                    func sub(var a, var b)
                        return a-b;
                    endfunc
                    
                    func main()
                        gfx_ScreenMode(LANDSCAPE) ;
                        print([DEC] add(3, 2), "\n");
                        print([DEC] sub(3, 2), "\n");
                        repeat forever
                    endfunc
                    Program A is divided into two parts with the aim of saving flash memory, be Program B1 and Program B2.

                    Program B1(Slave):
                    Code:
                    #platform "uLCD-43DT"
                    #MODE FLASHBANK_1
                    
                    func add(var a, var b)
                        return a + b;
                    endfunc
                    
                    func sub(var a, var b)
                        return a-b;
                    endfunc
                    
                    func main(var funcId, var a, var b)
                        var f[2];
                        f[0] := add(a, b);
                        f[1] := sub(a, b);
                        return f[funcId];
                    endfunc

                    Program B1(Master):
                    Code:
                    #platform "uLCD-43DT"
                    #MODE FLASHBANK_0
                    
                    #CONST
                        ADD,
                        SUB
                    #END
                    
                    var args[4];
                                                                                    
                    func add(var a, var b)
                        args[0]:=3;        // 3 parameters on slave (funcId, first param and second param)
                        args[1]:=ADD;   // funcId
                        args[2]:=a;        // first params = a
                        args[3]:=b;        // second params = b
                        return flash_Exec(FLASHBANK_1, args);
                    endfunc
                    
                    func sub(var a, var b)
                        args[0]:=3;        // 3 parameters on slave (funcId, first param and second param)
                        args[1]:=SUB;   // funcId
                        args[2]:=a;        // first params = a
                        args[3]:=b;        // second params = b
                        return flash_Exec(FLASHBANK_1, args);
                    endfunc
                    
                    func main()
                        gfx_ScreenMode(LANDSCAPE) ;
                        print([DEC] add(3, 2), "\n");     // call add function in bank1
                        print([DEC] sub(3, 2), "\n");     // call sub function in bank1
                        repeat forever
                    endfunc

                    Comment


                    • #11
                      You example doesn't work well because there is hardly any 'meat' in the functions, if those functions we 100, or even 1000 bytes you would have noticeably removed quite a bit of code from Bank 0

                      Here's another example that shows how to share memory and 'get to' bank functions in a 'better' (for certain uses) manner. It also shows how to return strings. in common memory

                      Bank 0 'master'
                      Code:
                      #platform "uLCD-35DT"
                      
                      #MODE FLASHBANK_0
                      
                      #inherit "xbdefs.inc"
                      
                      var xbstg[xmLimit], args[3] ;
                      
                      func xbcall(var xfunc)
                          args[2] := xfunc ;
                          flash_Exec(FLASHBANK_1, args);
                      endfunc
                      
                      func main()
                          args[0] := 2 ;
                          args[1] := xbstg ;
                      
                          gfx_ScreenMode(LANDSCAPE) ;
                          xbstg[a]:= 3 ;
                          xbstg[b]:= 2 ;
                          xbcall(fADD) ;
                          print([DEC] xbstg[c], "\n");
                          xbstg[a]:= 3 ;
                          xbstg[b]:= 2 ;
                          xbcall(fSUB) ;
                          print([DEC] xbstg[c], "\n");
                          xbstg[a]:= 3 ;
                          xbstg[b]:= 2 ;
                          xbcall(fADDSTR) ;
                          print([STR] &xbstg[d], "\n");
                          repeat forever
                      endfunc
                      Bank 1 'Fucntions'
                      Code:
                      #platform "uLCD-35DT"
                      #MODE FLASHBANK_1
                      
                      #inherit "xbdefs.inc"
                      
                      func main(var *xbstg, var funcId)
                          var ii ;
                          switch (funcId)
                              case fADD :
                                  xbstg[c] := xbstg[a] + xbstg[b] ;
                                  break ;
                              case fSUB :
                                  xbstg[c] := xbstg[a] - xbstg[b] ;
                                  break ;
                              case fADDSTR :
                                  ii := xbstg[a] + xbstg[b] ;
                                  to(&xbstg[d]) ;
                                  print(xbstg[a], " plus ", xbstg[b], " Equals ", ii) ;
                                  break ;
                          endswitch
                      endfunc
                      Inherit file
                      Code:
                      #CONST
                          fADD,
                          fSUB,
                          fADDSTR
                      #END
                      
                      #CONST
                          a,
                          b,
                          c,
                          d,
                          dArray := d +9,     // d becomes an array with 10 elements
                          e,
                          xmLimit
                      #END
                      You keep referring to your rabbit and it's 1MB of flash. Diablo is very efficient in the way it uses flash, it is not uncommon to see programs take up around 1/10th of the space that they do on other processors. Indeed, the 'Piano demo' was written based on a demo for another hardware platform and it ended up using around 2% of the space required on the original platform and had more functionality. An extreme example I'm sure, but nonetheless instructive.
                      Mark

                      Comment


                      • rwin
                        rwin commented
                        Editing a comment
                        @Mark, Thank you for point out. Your example works if all the functions have the same input parameters length (two parameters). How if the function does not have input parameters? I tried to passing null character to function in bank1, and I get Error 29. PC=28856 v1=0 v2=0. What meaning of this error?

                    • #12
                      Error 29 is 'Target of flash_Exec cannot have globals or privates'

                      Somehow it is missing from the manual. (It's in the PmmC release notes, but of course that is no excuse)
                      Mark

                      Comment


                      • #13
                        Yes you are right, thank you.

                        Bank 0 'master'
                        Code:
                        #platform "uLCD-35DT"
                        #MODE FLASHBANK_0
                        #inherit "xbdefs.inc"
                        
                        var xbstg[xmLimit], args[3] ;
                        
                        func xbcall(var xfunc)
                            args[2] := xfunc ;
                            flash_Exec(FLASHBANK_1, args);
                        endfunc
                        
                        func main()
                            args[0] := 2 ;
                            args[1] := xbstg ;
                        
                            gfx_ScreenMode(LANDSCAPE) ;
                            /*
                            xbstg[a]:= 3 ;
                            xbstg[b]:= 2 ;
                            xbcall(fADD) ;
                            print([DEC] xbstg[c], "\n");
                            xbstg[a]:= 3 ;
                            xbstg[b]:= 2 ;
                            xbcall(fSUB) ;
                            print([DEC] xbstg[c], "\n");
                            xbstg[a]:= 3 ;
                            xbstg[b]:= 2 ;
                            xbcall(fADDSTR) ;
                            print([STR] &xbstg[d], "\n");
                            /*
                            
                            // new function
                            xbstg[a]:= '\0' ;
                            xbcall(fNEW) ;
                            print([DEC] &xbstg[a], "\n");
                        
                            repeat forever
                        endfunc
                        Bank 1 'Functions'
                        Code:
                        #platform "uLCD-35DT"
                        #MODE FLASHBANK_1
                        #inherit "xbdefs.inc"
                        
                        func main(var *xbstg, var funcId)
                            var ii ;
                            switch (funcId)
                        
                                // new function
                                case fNEW:
                                    xbstg[a] := 1;
                        
                                case fADD :
                                    xbstg[c] := xbstg[a] + xbstg[b] ;
                                    break ;
                                case fSUB :
                                    xbstg[c] := xbstg[a] - xbstg[b] ;
                                    break ;
                                case fADDSTR :
                                    ii := xbstg[a] + xbstg[b] ;
                                    to(&xbstg[d]) ;
                                    print(xbstg[a], " plus ", xbstg[b], " Equals ", ii) ;
                                    break ;
                            endswitch
                        endfunc
                        Inherit file
                        Code:
                        #CONST
                            fNEW, // new function
                            fADD,
                            fSUB,
                            fADDSTR
                        #END
                        
                        #CONST
                            a,
                            b,
                            c,
                            d,
                            dArray := d +9,     // d becomes an array with 10 elements
                            e,
                            xmLimit
                        #END
                        Last edited by rwin; 20th June 2015, 09:36 AM.

                        Comment


                        • #14
                          Hello Mark,

                          If we are not permitted to use the global variable in the slave, How about kbRoutines.inc solutions that require global variable hndl in slave side?

                          Code:
                          func setkeystate(var key, var idx)
                              img_SetWord(hndl, key, IMAGE_INDEX, idx);
                              img_Show(hndl, key) ;
                          endfunc

                          Comment


                          • #15
                            Hmm, You will need to create a new kbRoutines.inc which receives and passes hndl as a parameter
                            Mark

                            Comment

                            Working...
                            X