Announcement

Collapse
No announcement yet.

Data Overwrite Code

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

  • Data Overwrite Code

    The following code illustrates the data overwrite problem when using pointers to store data in a byte array. Beginning at about the 57600 byte, additional data seems to overwrite the first part of the array. There are no comments; however, I've tried to use variable names that are fairly descriptive. This code creates a random terrain cross-section, then displays the data in screen mode 13. To view the problem, increase the value of NumImages.

    DEFINT A - Z

    DIM Posn AS DWORD
    DIM ScnAdr AS DWORD
    DIM ScnPtr AS BYTE PTR
    DIM GndAdr AS DWORD
    DIM GndPtr AS BYTE PTR
    DIM HUGE Gnd(MAX, 1) AS BYTE
    DIM Colour AS BYTE
    DIM Kolor AS BYTE
    DIM BytesPerImage AS WORD
    DIM Counter AS WORD
    DIM GndCounter AS BYTE
    DIM Rad AS SHARED SINGLE
    DIM Deg AS SHARED SINGLE

    Pi! = 4 * ATN(1)

    Deg = 180 / Pi!
    Rad = Pi! / 180

    GndWide = 320
    GndHigh = 36

    Colour = 8
    NumImages = 4
    BytesPerImage = GndWide * GndHigh
    TotalBytes& = BytesPerImage * NumImages + NumImages
    PRINT TotalBytes&
    REDIM Gnd(TotalBytes&)

    RANDOMIZE TIMER

    GndCounter = 0
    ScnAdr = &HA000 * 65536

    Ly = RND(0, 9)

    DO
    Counter = 0
    Lx = 0
    X = 7
    Posn = GndCounter * BytesPerImage
    GndAdr = VARPTR32(Gnd(Posn))

    DO
    Elvn = RND(0, 9)
    Y = RND(0, Elvn)
    Azi# = Az(Lx, Ly, X, Y) * Rad
    Dist = SQR((Lx - X) ^ 2 + (Ly - Y) ^ 2)
    FOR I = 0 TO DIST
    XX = Lx + I * SIN(Azi#)
    YY = Ly - I * COS(Azi#)
    FOR J = YY TO GndHigh - 1
    Posn = J * 320 + XX
    GndPtr = GndAdr + Posn
    @GndPtr = Colour
    NEXT J
    NEXT I

    Lx = X
    Ly = Y
    X = Lx + 8
    Counter = X
    IF X > 319 THEN X = 319
    LOOP UNTIL Counter > 319
    INCR GndCounter
    INCR Colour
    LOOP UNTIL GndCounter > NumImages - 1

    ! mov AX, &H13
    ! int &H10

    Y = 0
    GndCounter = 0

    DO
    Posn = GndCounter * BytesPerImage
    GndAdr = VARPTR32(Gnd(Posn))
    GndPtr = GndAdr

    FOR I = 0 TO GndHigh - 1
    Posn = I * 320
    ScnPtr = ScnAdr + Posn
    FOR J = 0 TO GndWide - 1
    Kolor = @GndPtr
    @ScnPtr = Kolor
    INCR ScnPtr
    INCR GndPtr
    NEXT J
    NEXT I
    INCR GndCounter
    SLEEP 3
    LOOP UNTIL GndCounter > NumImages - 1
    END

    FUNCTION Az# (BYVAL X1#, BYVAL Y1#, BYVAL X2#, BYVAL Y2#)
    X = X2# - X1#
    Y = Y2# - Y1#
    SELECT CASE Y
    CASE < 0
    Az# = -ATN(X / Y) * Deg!
    IF X < 0 THEN Az# = 360 - ATN(X / Y) * Deg!

    CASE > 0
    Az# = 180 - ATN(X / Y) * Deg!

    CASE 0
    IF X > 0 THEN Az# = 90
    IF X < 0 THEN Az# = 270
    END SELECT
    END FUNCTION
    Walt Decker

  • #2
    Hey Walt, nice to see you took my suggestion to come here.
    Glad to have you. Buff
    Client Writeup for the CPA

    buffs.proboards2.com

    Links Page

    Comment


    • #3
      Thanks, Fred. So far I've not received a good answer to why my data is overwritten. Hopefully someone out there will respond. I'd like to be able to use PB to do real-time geologic modeling. I can't do that if data gets corrupted.
      Walt Decker

      Comment


      • #4
        I tried running your program, but...

        1. The change to mode 13 video and back seems difficult for my computer

        2. I can't tell that the image is incorrect! What is it supposed to look like?

        I did notice that you get a new pointer for each image, but the sample you supplied did not have enough images to go over the 57600-byte then across the 64K boundary I mentioned when you asked this same question in another thread. (I don't think. It would have been easier had you used the "code" UBB tag and preserved the indents).

        Basically, if your array is over 64K in size (that is, HUGE), you cannot use pointer access on any element beyond 64K, if that pointer was obtained in the prior 64K segment. You *may* get lucky, or, if your array elements are powers of two in size (one is a power of two) you may get lucky again; but when incrementing unsigned data(i.e., DWORDS or Pointers), PB does not return the expected overflow error: it will just return MOD 65556 of the incremented value (binary truncation). This will result in a return to previous values if you are just incrementing the low word of the pointer value.

        I would look there for problems.




        -------------
        Michael Mattias
        Racine WI USA
        [email protected]
        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Michael,

          The data is supposed to look like a terrain cross-section, i.e., the silloette of a mountain range. I'm an engineering geologist and I thought I'd look into PB as a possible viable alternative to HTbasic/Rocky Mountian Basic/PDS 7x for modeling geologic data.

          What you are telling me then, is that once the pointer passes the 65536 mark, it can't find the next 64K segment and, therefore, I'll have to continually use VARPTR32 to find where the data is. That seems like it will severly slow the display of data, especially if it is continually being fed in via telecummications lines for real-time modeling.

          Since your computer doe not display MODE 13 well, I've modified the display to use MODE 12. Perhaps that will enable you to see the problem more clearly. Place the following code above:

          ! mov AX, &H13

          SCREEN 12
          Y = 0
          GndCounter = 0
          DO
          Posn = GndCounter * BytesPerImage
          GndAdr = VARPTR32(Gnd(posn))
          GndPtr = GndAdr
          FOR I = 0 TO GndHigh - 1
          FOR J = 0 TO GndWide - 1
          Kolor = @GndPtr
          PSET(J, I + Y), Kolor
          INCR GndPtr
          NEXT J
          NEXT I
          Y = Y + GndHigh + 2
          INCR GndCounter
          LOOP UNTIL GndCounter > NumImages - 1

          END
          Walt Decker

          Comment


          • #6
            Walt, if you actually do perform a VARPTR32() call for each 'byte', does the "corruption" problem disappear? (I've not had time to examine your code in depth, sorry!)

            -------------
            Lance
            PowerBASIC Support
            ( mailto:[email protected][email protected]</A> )
            Lance
            mailto:[email protected]

            Comment


            • #7
              Lance, yes, the problem disappears when using VARPTR32() for each byte. By placing a boundry query in the code I've also ascertained that Michael is correct that the problem occurs at (or near) the 64K data boundry. This suggests that I should be able to reset the value of GndAdr to the point where the data is beyond the 64K boundry then increment the GndPtr pointer with the GndAdr + Posn value. That works except that other problems appear. The bottom half of the last image is cut off and a shadow of the top half of the last image appears in the first image.

              The query I used is:

              DIM GndPosn AS DWORD
              DIM Boundry AS DWORD
              Boundry = 65536
              ......
              ......
              GndPosn = Posn
              DO
              Elvn = RND(0, 9)
              Y = RND(0, Elvn)
              Azi# = Az(Lx, Ly, X, Y) * Rad
              Dist = SQR((Lx - X) ^ 2 + (Ly - Y) ^ 2)
              FOR I = 0 TO DIST
              XX = Lx + I * SIN(Azi#)
              YY = Ly - I * COS(Azi#)
              FOR J = YY TO GndHigh - 1
              IF GndPosn + J * 320 + XX > Boundry THEN
              Posn = GndCounter * BytesPerImage
              Posn = Posn + J * 320 + XX
              GndAdr = VARPTR32(Gnd(Posn))
              GndPosn = Posn
              Boundry = Boundry + 65535
              END IF
              Posn = J * 320 + XX
              GndPtr = GndAdr + Posn
              @GndPtr = Colour
              NEXT J
              NEXT I
              Walt Decker

              Comment

              Working...
              X