Announcement

Collapse
No announcement yet.

cant figure out #DATA....#END use

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

  • cant figure out #DATA....#END use

    Hi i cant get my head around the data section use

    in the below code the first const section has to be indexed in increments of 2 to work right.
    but in the second data section refereing to the p1_buttons members in increments of 1 works ok,.

    could someone tell me
    1. why this is and
    2. how to use the sizeof() function, it doesnt seem to work how i would expect and
    3. what exactly ARE data members, pointers, aliases, ???

    please see the code below

    /**
    * page 1 touch areas for buttons, in the format
    * X0, Y0, X1, Y1 ( left, top, right, bottom )
    */
    #DATA // L T R B
    word p1_bt_new 285, 77, 365, 127
    word p1_bt_same 370, 77, 470, 127
    word p1_bt_stick 160, 143, 260, 193
    word p1_bt_adjust 265, 143, 385, 193
    word p1_bt_cut 390, 143, 470, 193
    word p1_bt_settings 115, 209, 265, 259
    word p1_bt_dxf 270, 209, 350, 259
    word p1_bt_tip 355, 209, 415, 259
    word p1_bt_help 420, 209, 470, 259
    #END
    // touch area access
    #CONST
    X0_DIM 0
    Y0_DIM 2
    X1_DIM 4
    Y1_DIM 6
    #END

    // button group to make searching touch areas easier
    #DATA
    word p1_buttons p1_bt_new, p1_bt_same, p1_bt_stick, p1_bt_adjust, p1_bt_cut, p1_bt_settings, p1_bt_dxf, p1_bt_tip, p1_bt_help

    #END
    // button ids to access button group pointers
    #CONST
    bt_new 0
    bt_same 1
    bt_stick 2
    bt_adjust 3
    bt_cut 4
    bt_settings 5
    bt_dxf 6
    bt_tip 7
    bt_help 8
    bt_total 9
    #END

    func test_ptrs()
    var ptr;
    var i;

    for( i := 0; i < bt_total; i++ )
    ptr := p1_buttons[ i ];

    print ( "X0 = ", ptr[ X0_DIM ],", Y0 = ", ptr[ Y0_DIM ],", X1 = ", ptr[ X1_DIM ],", Y1 = ", ptr[ Y1_DIM ], "\n" );

    next

    endfunc

  • #2
    Hello Joeblow,

    It would be helpful if you check the chapter about data blocks in the 4DGL_Programmers Reference PDF manual found in pages 14 and 15, where you can see some of its applications and examples. The definition for data blocks is:

    #DATA blocks reside in the CODE space and can be bytes or words. Data cannot be changed during run-time (i.e. it is read only). A block of data can be indexed like an array. Every data entry is declared with a unique name which must be a valid identifier.

    Comment


    • #3
      As for
      Code:
      has to be indexed in increments of 2 to work right
      this is because you have placed the address of 'DATA' in a pointer. RAM is word indexed and 'DATA' is byte indexed. The compiler will 'do the right thing' if you access DATA directly, but once you put it inside a pointer it loses the ability to detect that the address in the pointer is 'DATA' and not RAM. So you need to 'help' it.
      Mark

      Comment


      • #4
        thanks mark
        the same seems to happen when "DATA" is passed as argument

        /** */
        ie.
        #DATA
        word rect_w i_dim_width, WIN_LEFT_ALL, WIN_3_TOP, DIM_TXT_R_ALL, (WIN_3_TOP + TXT_OFF_V), shape_data.width
        #END

        /** */
        func pass_data( var data )
        print("\nDIM_IMAG = ", data[ DIM_IMAGE * 2 ] );
        print("\nDIM_IMG_L = ", data[ DIM_IMG_L * 2 ] );
        print("\nDIM_IMG_T = ", data[ DIM_IMG_T * 2 ] );
        print("\nDIM_TXT_R = ", data[ DIM_TXT_R * 2 ] );
        print("\nDIM_TXT_T = ", data[ DIM_TXT_T * 2 ] );
        stop();
        endfunc

        doesnt work like if you were to..
        /** */
        func pass_data()
        print("\nDIM_IMAG = ", data[ DIM_IMAGE * 2 ] );
        print("\nDIM_IMG_L = ", data[ DIM_IMG_L * 2 ] );
        print("\nDIM_IMG_T = ", data[ DIM_IMG_T * 2 ] );
        print("\nDIM_TXT_R = ", data[ DIM_TXT_R * 2 ] );
        print("\nDIM_TXT_T = ", data[ DIM_TXT_T * 2 ] );
        stop();
        endfunc



        are there any sections in the manual that are specific about memory types locations etc
        cheers

        Comment


        • #5
          See my previous post
          Mark

          Comment


          • #6
            why would you have byte indexing and word indexing on the same system??

            Comment


            • #7
              I think you missed part of what I said.

              It's not the 'indexing', it's the way the memory is.

              RAM is word, so each increment addresses 1 word.

              FLASH is byte, so each increment addresses 1 byte.

              I don't believe this 'idea' is not uncommon.

              When the compiler can work out what is being addressed, i.e. the address is a constant it automatically takes this into account.

              When the compiler cannot work this out, i.e. when the address is passed to a function, it increments by one.

              Also see http://www.4dsystems.com.au/appnote/4D-AN-00047/

              Mark

              Comment


              • #8
                thanks for the appnote mark

                Comment


                • #9
                  is there a way to raise a byte pointer other than by str_Ptr.
                  ie like
                  var d;
                  d = (byte*)( byte array );

                  Comment


                  • #10
                    No, but I don't really understand the question. Why would you need 'another way'?
                    Mark

                    Comment


                    • #11
                      Hi Mark,
                      Can I make universal function to support RAM and FLASH addressing differences? Is there any possibility to change pointer type to word?

                      Here is my vital debugging function:
                      func HexDump16(var* adresa, var delka, var radek)
                      var i;
                      for (i := 0; i < delka; i++)
                      if (!(i % radek))
                      print("\n", [H04] adresa, ":");
                      else
                      putch(' ');
                      endif
                      putnum(H04, *adresa++);
                      next
                      print("\n");
                      endfunc

                      var cfg[cfgsize];
                      #DATA
                      word cfgDefault 0x0010,0x1120,x2230,x3340,x4450,
                      0xAA00,0xBB10,0xCC20,0xDD30,EE40
                      //...
                      #END
                      HexDump16(cfg, sizeof(cfg), 16); //goes correctly by 2
                      HexDump16(cfgDefault, sizeof(cfgDefault), 16); //goes incorrectly by 1

                      It doesn't correspond with your description, does it?
                      Originally posted by ESPsupport View Post
                      When the compiler can work out what is being addressed, i.e. the address is a constant it automatically takes this into account.
                      When the compiler cannot work this out, i.e. when the address is passed to a function, it increments by one.
                      The equivalent problem is with byte addressing, when I hoped that str_Ptr() changes word to byte addressing, but it is not true. There is no difference with or without usage of this function or with direct function parameter usage (adresa in place of a).

                      Here is a similar function for bytes:
                      func HexDump8(var* adresa, var delka, var radek)
                      var i, a;
                      a := str_Ptr(adresa);
                      // a := adresa;
                      for (i := 0; i < delka; i++)
                      if (!(i % radek))
                      print("\n", [H04] a, ":");
                      else
                      putch(' ');
                      endif
                      putnum(H02, *a++);
                      next
                      print("\n");
                      endfunc

                      HexDump8(cfg, 2*sizeof(cfg), 2*16); //goes incorrectly by 2
                      HexDump8(cfgDefault, 2*sizeof(cfgDefault), 2*16); //goes correctly by 1

                      Now I slowly got to know why there are too much problems with internal functions and communication routines when I call them with parameters from tables in RAM or FLASH...

                      Do you have any idea how to solve these problems and how to keep correct processing of functions at all conditions?

                      I think it will be much better to create any possibility to declare pointer as byte or word oriented as usual in other programming languages.
                      For example by this small improvement: var byte* ptrB, word* ptrW;

                      Or let it to be any size oriented defined by a constant (for example one row from #DATA section).
                      var (2*columns) *rowPtr; or var *rowPtr(2*columns);

                      Then it will be possible to create clear constructions like that:
                      for (rowPtr := cfgDefault; rowPtr < &cfgDefault[sizeof(cfgDefault)]; rowPtr++)
                      previous := &rowPtr[-1];
                      oldvalue := previous[column];
                      nextvalue := rowPtr[1][column];
                      next

                      Yes, then it can looks like two dimensional array, so next improvement will be usage directly by this way: cfgDefault[raw,column] ...

                      Thank you
                      Best Regards
                      Miroslav

                      PS: Why are graphical files generated by IDE (.GCI and .GCF) and functions like media_ReadWord() and media_WriteWord() using big-endian encoding, but internal memories (RAM and Flash at Diablo16) are little-endian encoded? It's very uncomfortable ...
                      Last edited by Miroslav Kovar; 7 December 2020, 07:20 AM.

                      Comment


                      • #12
                        It doesn't correspond with your description, does it?
                        Originally posted by ESPsupport View Post
                        When the compiler can work out what is being addressed, i.e. the address is a constant it automatically takes this into account.
                        When the compiler cannot work this out, i.e. when the address is passed to a function, it increments by one.
                        Sure does, you are passing the address to a function, so it increments by 1.

                        Placing
                        Code:
                        if (adresa < 0) adresa++ ; // or adresa & 0x8000, < 0 is 1 byte shorter
                        after the putnum in your function will help it work in both cases.

                        PS: Why are graphical files generated by IDE (.GCI and .GCF) and functions like media_ReadWord() and media_WriteWord() using big-endian encoding, but internal memories (RAM and Flash at Diablo16) are little-endian encoded? It's very uncomfortable ...
                        I don't know, but it shouldn't be uncomfortable. I suspect the person who designed the GCI file format thought that all files on uSD needed to be big-endian to conform to some standard, whereas, of course, in memory endianness is generally fixed by the hardware architecture.

                        Use ByteSwap to change endianness.
                        Mark

                        Comment


                        • #13
                          Ok, this workarround by detection of upper 32k segment (= FLASH memory) is possible,
                          but how to solve HexDump8 to go through bytes in RAM lineary? I hoped for this is the function str_Ptr as a pointer modifier.
                          It is very complicated pointer address computation, where in RAM 1+1 != 2, but 4 (++ after ++ is 4 bytes long way).
                          And offset differences for moving in arrays by index or by pointers from FLASH are very confusing...
                          Miroslav

                          PS: After some other tests I finally found a solution for byte access via str_Ptr and str_GetByte, I have understand how it is with the Byte and Word pointers:
                          the str_Ptr function multiplies the original pointer value by two, and then the str_GetByte function returns a Hi or Lo byte from RAM word (addressed by ptr/2).
                          Why is this not clearly written in any documentation?!!!
                          Or from the beginning: why aren't all pointers byte oriented with LSB = 0 for standard word access in the entire addressable space (RAM + FLASH)?
                          Especially when the RAM is only 32 kB, ie 16 kWords and not 32kWords. For byte access the LSB can be 0 or 1 for Lo or Hi byte part. For word access LSB must be 0. This is common for 16-bit or 32-bit microprocessors ...
                          It would be so easy and clearly understandable ...
                          Last edited by Miroslav Kovar; 7 December 2020, 09:58 AM.

                          Comment


                          • #14
                            In your HexDump8 I think you want
                            putnum(HEX2, str_GetByte(a++));
                            Mark

                            Comment


                            • #15
                              Hi Mark,
                              how to define pointers to array elements in a #DATA section? Direct indexing can't be compiled and offsetting generates wrong address ...

                              It seems that even the compiler is not completely clear about word and byte indexing ...

                              Here is an example:

                              var buf[0x100],varA, varB, varC[2];

                              //#constant a3 varC, a31 varC[1] //error when compiled
                              #constant a2 varB, a3 varC, a31 (varC + 1) //error in address

                              #DATA
                              // word dta varA, varC, varC[1], varB //error when compiled
                              word dta varA, varC, (varC+1), varB, a31 //error in address
                              #END


                              func main()
                              print([HEX] &varA, ",", [HEX] &varC[0], ",", [HEX] &varC[1], ",", [HEX] &varB, ",", [HEX] varC, "\n");
                              print([HEX] dta[0], ",", [HEX] dta[1], ",", [HEX] dta[2], ",", [HEX] dta[3], ",", [HEX] dta[4], "\n");
                              print([HEX] a31, ",", [HEX] str_Ptr(varC), ",", [HEX] str_Ptr(varC)+1);
                              repeat forever
                              endfunc

                              Thank you
                              Regards
                              Miroslav

                              Edit: Functional workarround is "word dta varA, varC, (varC/2+2), varB, a31", but it is terrible to correct wrong computation from compiler ...
                              Last edited by Miroslav Kovar; 23 March 2021, 05:33 AM.

                              Comment

                              Working...
                              X