Here's some code for MAXLIB's XMSArray routines, that allows you to
create 2-dimensional arrays of any fixed-length data type. It lets
you DIM, move data in and out, and ERASE the array.
This code can handle arrays of INTEGERS, WORDS, BYTES, DWORDS, LONGS,
QUADS, BCDS, user-defined TYPES, fixed-length STRINGS -- any fixed
length data. If you want to read and write elements large than 100
bytes, you need to change %MAXSIZE to reflect the largest element size
you need to use.
The concept is that the individual elements of the two-dimensional
array are mapped into a single dimensional array, and the array handle
that is passed back becomes a TYPE variable, rather than an integer, so
that a record of how to map the array travels with the handle.
Limitations: The total elements still must not exceed (64K-1).
Calculate total elements by multiplying the elements in the first
dimentsion by the elements in the second dimension. Also, this code
requires PB3.1 or PB3.2. It won't run under PB3.0c or before.
'------------------- START CODE ---------------------------
$LINK ".\MAXLIB.PBL" '<--- current directory - is this right?
$INCLUDE ".\MAXLIB.BI" '<--- current directory - is this right?
TYPE TwoDimHandle
FirstUBound AS INTEGER
SecondUBound AS INTEGER
Multiplier AS WORD
Length AS INTEGER
MaxHandle AS INTEGER
END TYPE
DECLARE SUB Dim2XMS (Handle AS TwoDimHandle, A1%, B1%, A2%, B2%, ElemLen%)
DECLARE SUB In2XMS (Handle AS TwoDimHandle, Index1%, Index2%, ANY)
DECLARE SUB Out2XMS (ANY, Handle AS TwoDimHandle, Index1%, Index2%)
DECLARE SUB Erase2XMS (Handle AS TwoDimHandle)
%ERRORTOOMANY = -5 'MAXLIB's internal "too many elements" error
%MAXSIZE = 100 'individual elements must be <= %MAXSIZE
'/////////////////// START OF MAIN \\\\\\\\\\\\\\\\\\\\\
InitXMSArray 'must have this!
'Create the equivalent of DIM Array2 (1 TO 16000, 1 TO 4) AS WORD
DIM Array2 AS TwoDimHandle ' dim the "handle" variable
Dim2XMS Array2, 1, 16000, 1, 4, 2
IF ErrorCode% = %ERRORTOOMANY THEN
PRINT "Hey! That's too big an array!"
END
END IF
DIM InValue AS WORD
DIM OutValue AS WORD
InValue = 56789
'Do the equivalent of Array2(123, 4) = InValue
In2XMS Array2, 123, 4, InValue
'Do the equivalent of OutValue = Array2(123, 4)
Out2XMS OutValue, Array2, 123, 4
PRINT OutValue 'did it work? should PRINT 56789
IF OutValue = InValue THEN
PRINT "Succeeded."
ELSE
PRINT "Failed."
END IF
Erase2XMS Array2
END
'///////////////////// END OF MAIN \\\\\\\\\\\\\\\\\\\\\
'========================================================================
SUB Dim2XMS (Handle AS TwoDimHandle, A1%, B1%, A2%, B2%, ElementLen%)
'========================================================================
TotalFirstDim& = (B1% - A1%) + 1
TotalSecondDim& = (B2% - A2%) + 1
TotalElements& = TotalFirstDim& * TotalSecondDim&
IF TotalElements& > 65535& THEN
SetErrorCode %ERRORTOOMANY
ELSE
Handle.FirstUBound = A1%
Handle.SecondUBound = A2%
Handle.Length = ElementLen%
Handle.Multiplier = CINT(TotalSecondDim&)
RealStart% = A1% - Handle.FirstUBound - 32768
RealEnd% = CINT(TotalElements& - 32767 + 1)
Handle.MaxHandle = DimXMS%(RealStart%, RealEnd%, ElementLen%)
END IF
END SUB
'======================================================================
SUB In2XMS (Handle AS TwoDimHandle, Index1%, Index2%, ANY)
'======================================================================
' If you are going to use this SUB to access elements longer than
' 100 bytes, you'll need to increase the buffer size.
DIM BUFFER AS STRING * %MAXSIZE
DIM BufSeg AS WORD
DIM BufOff AS WORD
Length% = Handle.Length ' how long is our ANY parameter?
BufSeg = VARSEG(BUFFER) ' where is our buffer?
BufOff = VARPTR(BUFFER)
! Push DS ; save required registers
! Push SI
! Push DI
! Mov AX, BufSeg
! Mov ES, AX
! Mov DI, BufOff ; load ES:DI with address of BUFFER
! Lds SI, [BP+6] ; load DS:SI with address of ANY parameter
! Mov CX, Length% ; load CX with number of bytes to move
! Rep Movsb ; copy CX bytes of ANY into BUFFER
! Pop DI ; restore the required registers
! Pop SI
! Pop DS
FirstPlace% = (Index1% - Handle.FirstUBound) + 1
SecondPlace% = (Index2% - Handle.SecondUBound) + 1
RealIndex% = -32768 + (FirstPlace% * Handle.Multiplier) + SecondPlace%
'move value from BUFFER into XMS array
InXMS Handle.MaxHandle, RealIndex%, BUFFER
END SUB
'======================================================================
SUB Out2XMS (ANY, Handle AS TwoDimHandle, Index1%, Index2%)
'======================================================================
DIM BUFFER AS STRING * %MAXSIZE
DIM BufSeg AS WORD
DIM BufOff AS WORD
>>> Continued to next message
* SLMR 2.1a * MAXLIB For PB v1.2 - Access arrays and files in EMS/XMS!
--- WILDMAIL!/WC v4.12
---------------
* Origin: Com-Dat BBS - Hillsboro, OR. HST DS (1:105/314.0)
|