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?
Announcement
Collapse
No announcement yet.
Data Overwrite Problem
Collapse
X
-
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 (retired)
Port Washington WI USA
[email protected]
http://www.talsystems.com
-
Please post some compilable code that demonstrates your problem.
-------------
Lance
PowerBASIC Support
( mailto:[email protected][email protected]</A> )
Lance
mailto:[email protected]
Comment
-
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
[email protected]Michael Mattias
Tal Systems (retired)
Port Washington WI USA
[email protected]
http://www.talsystems.com
Comment
-
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
Comment