Announcement

Collapse
No announcement yet.

Data Overwrite Problem

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

  • Data Overwrite Problem

    I'v just begun exploring PB and I've been having trouble with data overwrite. Just as an experiment I've used pointers to fill an array of type BYTE with data. Once I get past 57600 bytes additional data seems to overwrite the first 11520 bytes the seems to randomly corrupt parts of each following 11520 byte segment. I've used DIM HUGE ... AS BYTE with no effect. Are there any suggestions as to why this occurs?
    Walt Decker

  • #2
    If the array is HUGE, your pointers change at each segment boundary and you may not just increment your pointer anymore.

    Since PB allocates arrays with an offset of 0 in the current segment (undocumented but well known behavior), you should neve have a problem using ponters as long the array stays within 64K - that is, the range of a non-HUGE array.

    However, when you DIM HUGE, you will cross a segment boundary and when you do, your pointer becomes invalid (unless you take specific steps to adjust it).

    Why this is happening at 57K rather than at 64K is a mystery to me, but if the offset portion of your pointer - a DWORD - is going over 64K, I'll bet that's why it's overwriting. (MS-DOS pointer DWORD = Segment*64K + Offset)

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

    Comment


    • #3
      Where the pointer goes past a data segment boundry should have no effect since I use VARPTR32 to get the 32 bit address of each 11520 segment. In otherwords, I continually update the pointer target address.
      Walt Decker

      Comment


      • #4
        Please post some compilable code that demonstrates your problem.

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

        Comment


        • #5
          As Lance says, some code would be useful.

          However, if you are only getting the VARPTR32 at 11520-byte increments, I would expect problems at the highest multiple of 11520 which is still under 64K, say, right around 5 * 11520, which is, by golly, 57600, which is, by golly, the exact number at which you are having problems!

          The sixth block of 11520 bytes does not fit in the same segment and a new pointer must be obtained.

          One of the internal procedures available in PB/DOS is ArrayInfo&, which will give you the number of elements per page (segment).




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

          Comment


          • #6
            The following code illustrates the problem. 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.

            Code:
            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

            Comment

            Working...
            X