13 January 2010

Swap Arrays by ArrPtr()

Didn't GFABASIC for Atari ST support swapping (or passing) arrays by pointer? I picked up my copy of the book 'GFABASIC' by Frank Ostrowski (1987) to check if I remembered correctly. Indeed, some kind of swapping by pointer is supported. The QuickSort program FO presented on page 22 passes a string array to the sort routine by using *a$(), which is equal to ArrPtr(a$()). To access the array locally in the procedure, the array descriptor passed is swapped with a the descriptor of array a$(). Given a pointer to an array descriptor the Atari ST Swap command supported the following syntax:

Swap *ardescriptor%, a$()   ! Atari ST GFABASIC

Unfortunately, the Swap command of GB32 isn't that flexible. The arguments of the Swap command need to be of the same kind. For instance:

Swap a%(), b%()
Swap f#, g#
Swap udt1, udt2

Even a user-defined type can be swapped! Swap works well as long as the data type of both operands is the same. But I have a need to store a pointer (Long Integer) to an array of data and later on use that pointer to access the array's data. So, I want to store an ArrPtr() and swap that pointer with an (empty) array. For instance:

Swap arrdesc%, d()    // not supported

After disassembling the code GB32 generates for Swap a(), b() it is easy to see, that GB32 implements the array swap by passing the pointers of the descriptors of these arrays. Internally, a Swap a(), b() is actually a Swap ArrPtr(a()), ArrPtr(b()).

Also, the disassembly reveals the Asm scall name for the library function. Strangely, the name is pgMinBottom, obviously an error in the naming. It is now easy to create a custom routine to swap two arrays by descriptor.

Proc ArrPtrSwap(ArrPtr1%, ArrPtr2%)
  . push [ArrPtr1%], [ArrPtr2%]
  . scall pgMinBottom   ' GB32 naming error
EndProc

Given some arrays, the procedure might be invoked like this:

Dim g%(2), a%(5)
Dim ptrToa% = *a()
Dim ptrTog% = ArrPtr(g())

ArrPtrSwap(ptrToa%, *g%())
ArrPtrSwap *a%(), *g%()
ArrPtrSwap *a%(), ptrTog%

Now you can initialize an array, store a pointer to it in the .WhatsThisHelpID property of an OCX control, and use it later on by swapping it with an empty array. I now can finally conclude my series on custom drawing of single SubItems of a ListView.Listitem object.

No comments:

Post a Comment