Announcement

Collapse
No announcement yet.

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

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

  • ESPsupport
    replied
    We have noted this for resolving in the compiler.

    Leave a comment:


  • Miroslav Kovar
    replied
    The same problem is not only in #DATA block, but in #constant too (see a31).
    Why is there in #constant and #DATA blocks other evaluation than in program code?
    The clear solution will be to use standard & operator for addreses like "#constant a31 &(varC[1])".
    (And it would be safer everywhere so that there can be no confusion between the address and the value of the constant, variable, indexed variable, function, which the compiler itself does not evaluate and does not warn the user ...)

    Yes, I understand, this is only a problem of the first pass of compilation and is related to the evaluation of constants in subsequent passes, because it is not the same universal processing procedure ...
    And we are at the same point again that not everything is treated the same, which again brings possible complications and potential errors...

    Miroslav

    PS: The fact that no one has not yet pointed out this does not mean that no one has encountered the same problem. Anyone who has any experience with a "support team" knows very well that it is often faster as a result to cough up the solution or find a solution yourself and not hesitate to explain the problem and create generic examples for support. In the same way, we practiced it for several years before the cup of patience overflowed, and I came across bugs that simply could not be avoided (PWM updates without double buffering). And unfortunately I find out that we will come across similar ones all the time ...
    Last edited by Miroslav Kovar; 23 March 2021, 09:58 PM.

    Leave a comment:


  • ESPsupport
    replied
    Sorry, I did try it, but now I see I tried the sample you sent which has your fix in it.

    The compiler has to manage the different addressing schemes between RAM and Flash (#DATA).

    This can become impossible for the compiler if you use other than a simple variable it assumes byte addressability, as it can't work out what it should be doing. Which is why it is correct for varC, but not varC+1.

    This issue is usually only seen in #DATA statements.

    Not sure why a detailed compiler listing would be easier to understand than a simple print, it certainly wouldn't be quicker.

    Also, the compiler has been around for 10 years now and you are the first to mention this, not saying it isn't an issue, perhaps it is showing a unique coding style that was never considered.

    Leave a comment:


  • Miroslav Kovar
    replied
    Please try to compile this example and you can see that address of (varC+1) is evaluated as two times more than varC only.
    There is an easy comparison between produced lines (first is correct, second is wrong and third say why).
    Or you can look into .aux file: [DATA] 0007: 01 01 03 01 05 02 02 01 05 02
    After a few hours I found a workaround for correctly evaluated address as "word dta (varC/2+1 + idx)", where idx is an array index from 0 to ...
    (Do you understand why assembly listing of a compiled program is important to me for debugging?)

    Haven't you use constant address evaluation and address arrays in you programs? It can give you very easy grouping of a lot of variables (their addresses) into corresponding blocks. This lets you to make universal subroutines for data manipulation, visualisation and user interaction.

    And so every standard compiler accepts to create arrays of variable's addresses. Standard construction to get address of anything is &myvar or addr(myvar) or @myvar. And any part of a variable can be addressed, like addr(myvar[2].xyz[3]). And address evaluation is accepted too, like (&myvar)+2. The only one requirement is that final evaluation must be a constant (when you create constant array) ...

    The only 4DGL compiler didn't accept additional parenthesis and standard Address Modifier & ... Why?

    Regards
    Miroslav

    Leave a comment:


  • ESPsupport
    replied
    I'm a bit confused here, the only error I see is when you put a ram address into a constant and then 'back' into a data statement. I don't know of any compiler that could handle such a thing.

    When you used the "word dta ..... (varC+1)" format you got the right address didn't you?

    Leave a comment:


  • Miroslav Kovar
    replied
    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.

    Leave a comment:


  • ESPsupport
    replied
    In your HexDump8 I think you want
    putnum(HEX2, str_GetByte(a++));

    Leave a comment:


  • Miroslav Kovar
    replied
    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.

    Leave a comment:


  • ESPsupport
    replied
    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.

    Leave a comment:


  • Miroslav Kovar
    replied
    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.

    Leave a comment:


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

    Leave a comment:


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

    Leave a comment:


  • joeblow
    replied
    thanks for the appnote mark

    Leave a comment:


  • ESPsupport
    replied
    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/

    Leave a comment:


  • joeblow
    replied
    why would you have byte indexing and word indexing on the same system??

    Leave a comment:

Working...
X