urjlew@ecsvax.UUCP (Rostyk Lewyckyj) (08/05/87)
[Wisdom for the line eater. For what x is x*x <> x^2 in AMIGABASIC 1.0] Several weeks ago I posted the following note describing a suspected Amiga BASIC problem. Since I did not receive a salvo of fire from the guns of Commodore, I take this as a tacit admision of another bug in this version of BASIC. I know that the article made it out into the network by verifying that it had arrived on the batcomputer at Cornell. ------------ original article follows ---------------------- Included below is an Amiga BASIC program whose purpose is supposed to be to read in a packed record of 8204 integers stored as one record of a random file, and unpack the record into an array. Why I am trying to do this is irrelevant just now. What is relevant is that this program keeps getting visited by the GURU and I don't know why. CLEAR , 1030,1030 CLEAR , 40000&,2048 OPEN "R",1, "matfile", 16410 FIELD 1,16408 AS a$ LSET a$="abcd" DIM ps%(8203) ps%(0)=0 b&=VARPTR(ps%(0)) c&=b& GET #1,1 a&=SADD(a$) FOR i&=a& TO a&+16407 STEP 2 POKEW c&,PEEKW(i&) c&=c&+2 NEXT i& END I would much appreciate an explanation of why its happening. What am I doing wrong, other than trying to program in that stupid BASIC.:-) By the way the values in the record are {640,100,2,0,0,0,....}, but that shouldn't matter. -- Reply-To: Rostyslaw Jarema Lewyckyj urjlew@ecsvax.UUCP , urjlew@tucc.bitnet or post to comp.sys.amiga. Others may also be interested
prm@usl (Patrick Royce Michaud) (08/18/87)
In article <3645@ecsvax.UUCP> urjlew@ecsvax.UUCP (Rostyk Lewyckyj) writes: > >Several weeks ago I posted the following note describing a suspected >Amiga BASIC problem. Since I did not receive a salvo of fire from >the guns of Commodore, I take this as a tacit admision of another >bug in this version of BASIC. Actually, the people at Commodore may not be the ones to ask about it, as AmigaBasic is made by Microsoft :-). At any rate, the bug is not in AmigaBasic, but in your code (see below): >------------ original article follows ---------------------- >Included below is an Amiga BASIC program whose purpose is supposed to be >to read in a packed record of 8204 integers stored as one record of a >random file, and unpack the record into an array. Why I am trying to do >this is irrelevant just now. What is relevant is that this program keeps >getting visited by the GURU and I don't know why. > >CLEAR , 1030,1030 >CLEAR , 40000&,2048 >OPEN "R",1, "matfile", 16410 >FIELD 1,16408 AS a$ >LSET a$="abcd" >DIM ps%(8203) >ps%(0)=0 >b&=VARPTR(ps%(0)) >c&=b& >GET #1,1 >a&=SADD(a$) >FOR i&=a& TO a&+16407 STEP 2 >POKEW c&,PEEKW(i&) >c&=c&+2 >NEXT i& >END > >I would much appreciate an explanation of why its happening. Ok, here's my explanation. The problem statement is the "c&=b&". (really!) Your second CLEAR statement allocates 40000 bytes of space for AmigaBASIC's data segment. This is where all of your variables (simple variables, arrays, etc.) are going to be stored. It turns out that the variables aren't stored helter-skelter as they are declared, but that they do have some semblence of order placed upon them. You can think of the data segment as a table, which grows as new variables are declared within the program. The organization of this table is such that simple variables come first, followed by the array variables. What is happening with your program is this -- you first DIM the ps%() array, so AmigaBASIC goes and allocates space (16408+overhead bytes) for it. Later, your program says "b&=VARPTR(ps%(0))". Since simple variables have to come _before_ array variables in the data segment, AmigaBASIC moves the ps%() array in the data segment to make enough room for b&. It then gets the address of ps%() and puts it in b& -- still no problem. But what is a problem is your next statement-- "c&=b&". Since c& has not been previously declared, AmigaBASIC has to find space for it. Again, following the "simple variable before array" rule, it moves the array AGAIN to make enough room for c&. But, c& is getting the OLD address of the array, and not the new one. Thus, when you finally get down to POKEWing into what c& thinks is the start of the array, you're mucking around in territory that isn't yours, and trashing up the AmigaBASIC data segment. The solution to this problem is easy -- make sure that no other "new" variable declarations occur between the time the VARPTR is done and the actual POKEW takes place. If any new variable declarations do occur, then the VARPTR of the array is gonna change (in this case, c&, a&, and i& all cause the VARPTR of ps%() to change). One solution is to do "c&=0:a&=0:i&=0" before you do the "b&=VARPTR(ps%(0))" statement. Thus, these variables will have already been declared by the time the VARPTR takes place, and it won't move by the time you do the POKEWs. A better solution might be to use one of the following (and avoid VARPTR altogther): a&=SADD(a$) | a&=SADD(a$) FOR i = 0 to 8203 | FOR i = 0 to 8203 ps%(i) = PEEKW(a&+i*2) | ps%(i) = cvi(mid$(a$,i*2,2)) NEXT i | NEXT i These present somewhat cleaner alternatives to PEEKW and POKEW, although I can certainly find reasons why you might want to use PEEKW and POKEW instead of the above examples. At any rate, I hope this helps to solve your problem. Patrick R. Michaud USL NASA Project Member "my opinions are my own" ut-sally!usl!prm