Posts: 3
Threads: 1
Joined: Sep 2003
Hello
I want to make a three dimensional array with a large number of indicies. I am using the following code:
DIM a(100,100,100)
I keep getting an error message (error code 9) stating, I think, that the array is too large.
I tried to change the array indicies from static to variable, but this did not work.
Does anyone know what I can do?
tk
Posts: 1,272
Threads: 36
Joined: Feb 2003
Your array is 100*100*100*2 bytes (assuming it's an integer array), or 2 megabytes. That's way too big for real mode memory. With dos you usually have somewhere between 550k and 605k free, and after QB it's more like 300k.
You'll have to either switch languages, or think of a diffrent way to represent your data that doesn't use as much memory.
Posts: 3,368
Threads: 195
Joined: Jan 2003
*STAB*
Or use UGL.
Peace cannot be obtained without war. Why? If there is already peace, it is unnecessary for war. If there is no peace, there is already war."
Visit www.neobasic.net to see rubbish in all its finest.
Posts: 1,272
Threads: 36
Joined: Feb 2003
Or a small simple EMS lib. UGL is probably overkill for what he needs.
Posts: 3
Threads: 1
Joined: Sep 2003
Remeber, I'm a newbie. I have no idea what UGL or an EMS lib are...?
tk
I've actually had some success using the ERASE command...will keep you posted.
Posts: 1,272
Threads: 36
Joined: Feb 2003
UGL is a full features game programming library. It lets your program have sound and high resolution graphics.
A EMS library lets you use EMS memory. UGL can do this too, but UGL may be more than you need.
Does anybody know of a good EMS tutorial for this guy?
Posts: 1,752
Threads: 21
Joined: Jun 2002
Here's some code I wrote a while ago for somebody else having a similar problem:
Code: DEFINT A-Z
'$DYNAMIC
TYPE ArrayEMS
Handle AS INTEGER
ElementLen AS INTEGER
NumElements AS LONG
END TYPE
DECLARE SUB EMS.Array.Dim (Array AS ArrayEMS)
DECLARE SUB EMS.Array.Set (Array AS ArrayEMS, Element&, SrcSegment, SrcOffset)
DECLARE SUB EMS.Array.Get (Array AS ArrayEMS, Element&, DstSegment, DstOffset)
DECLARE SUB EMS.Array.Erase (Array AS ArrayEMS)
CLS
IF NOT EMS.Init THEN 'make sure EMS is available
PRINT "No EMM detected."
END
END IF
DIM TestArray AS ArrayEMS 'set up an EMS array called TestArray
TestArray.ElementLen = 2 '2 = integer, 4 = long integer
TestArray.NumElements = 1000000 'element range = 1 to 1,000,000
EMS.Array.Dim TestArray 'allocate EMS memory for the array
a = 12345 'just some random numbers
b = 3210
'put the value of 'a' into element #1 of the EMS array TestArray
EMS.Array.Set TestArray, 1, VARSEG(a), VARPTR(a)
'put the value of 'b' into element #1,000,000 of the EMS array TestArray
EMS.Array.Set TestArray, 1000000, VARSEG(b), VARPTR(b)
a = 0 'now clear 'a' and 'b' so we can test if it worked
b = 0
'get the value element #1 of the EMS array TestArray and store it in 'a'
EMS.Array.Get TestArray, 1, VARSEG(a), VARPTR(a)
'get the value element #1,000,000 of the EMS array TestArray and store it in 'b'
EMS.Array.Get TestArray, 1000000, VARSEG(b), VARPTR(b)
PRINT a 'check 'em
PRINT b
EMS.Array.Erase TestArray 'deallocate the array (you *must* do this before
'your program ends, or the EMS memory will not be
'released!)
END
SUB EMS.Array.Dim (Array AS ArrayEMS)
IF EMS.FreeHandles = 0 THEN
PRINT "EMS.Array.Dim: No free handles!"
EXIT SUB
END IF
BytesNeeded& = Array.NumElements * Array.ElementLen
PagesNeeded = BytesNeeded& / 16384 + .5
IF EMS.FreePages < PagesNeeded THEN
PRINT "EMS.Array.Dim: Not enough free pages! ("; EMS.FreePages; "available,"; PagesNeeded; "needed)"
EXIT SUB
END IF
Handle = EMS.AllocPages(PagesNeeded)
Array.Handle = Handle
END SUB
SUB EMS.Array.Set (Array AS ArrayEMS, Element&, SrcSegment, SrcOffset)
IF Element& < 1 OR Element& > Array.NumElements THEN
PRINT "EMS.Array.Set: Subscript out of range ("; Element&; "given; must be between 1 and"; Array.NumElements; ")"
EXIT SUB
END IF
Offset& = (Element& - 1) * Array.ElementLen
Page = Offset& \ 16384
PageOffset = Offset& - (Page * 16384&)
EMS.CopyMem CLNG(Array.ElementLen), 0, SrcSegment, SrcOffset, Array.Handle, Page, PageOffset
END SUB
SUB EMS.Array.Get (Array AS ArrayEMS, Element&, DstSegment, DstOffset)
IF Element& < 1 OR Element& > Array.NumElements THEN
PRINT "EMS.Array.Get: Subscript out of range ("; Element&; "given; must be between 1 and"; Array.NumElements; ")"
EXIT SUB
END IF
Offset& = (Element& - 1) * Array.ElementLen
Page = Offset& \ 16384
PageOffset = Offset& - (Page * 16384&)
EMS.CopyMem CLNG(Array.ElementLen), Array.Handle, Page, PageOffset, 0, DstSegment, DstOffset
END SUB
SUB EMS.Array.Erase (Array AS ArrayEMS)
EMS.DeallocPages Array.Handle
END SUB
Needs EMS.BAS (you can probably remove some functions
Code: DEFINT A-Z
'$DYNAMIC
'$INCLUDE: 'QB.BI'
DIM SHARED Regs AS RegTypeX
DIM SHARED EMS.Error 'Holds the error code of the last operation
DECLARE FUNCTION EMS.ErrorMsg$ ()
DECLARE FUNCTION EMS.Init ()
DECLARE FUNCTION EMS.Version$ ()
DECLARE FUNCTION EMS.PageFrame ()
DECLARE FUNCTION EMS.FreeHandles ()
DECLARE FUNCTION EMS.FreePages ()
DECLARE FUNCTION EMS.TotalPages ()
DECLARE FUNCTION EMS.AllocPages (NumPages)
DECLARE SUB EMS.DeallocPages (Handle)
DECLARE SUB EMS.MapPage (Physical, Logical, Handle)
DECLARE SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle)
DECLARE SUB EMS.CopyMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)
DECLARE SUB EMS.ExchMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)
FUNCTION EMS.AllocPages (NumPages)
'Allocates the number of pages in [NumPages] and
'returns the EMS handle the memory is allocated to.
Regs.ax = &H4300 'Allocate [NumPages] pages of EMS
Regs.bx = NumPages
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
EMS.AllocPages = Regs.dx 'Return the handle
END FUNCTION
SUB EMS.CopyMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)
'Copies memory from EMS or base memory to EMS or base memory, where:
'
'Length& = Length of memory to copy in bytes
'SrcHandle = EMS handle of source memory (use 0 if source is base memory)
'SrcSegment = Segment of source memory (or page number if source is EMS)
'SrcOffset = Offset of source memory
'DstHandle = EMS handle of destination memory (use 0 if destination is base memory)
'DstSegment = Segment of destination memory (or page number if destination is EMS)
'DstOffset = Offset of destination memory
'Determine the source and destination memory types by checking the handles
IF SrcHandle = 0 THEN SrcType$ = CHR$(0) ELSE SrcType$ = CHR$(1)
IF DstHandle = 0 THEN DstType$ = CHR$(0) ELSE DstType$ = CHR$(1)
'Create a buffer containing the copy information
CopyInfo$ = MKL$(Length&) + SrcType$ + MKI$(SrcHandle) + MKI$(SrcOffset) + MKI$(SrcSegment) + DstType$ + MKI$(DstHandle) + MKI$(DstOffset) + MKI$(DstSegment)
Regs.ax = &H5700 'Copy the memory region
Regs.ds = VARSEG(CopyInfo$) 'described in the buffer
Regs.si = SADD(CopyInfo$)
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
END SUB
SUB EMS.DeallocPages (Handle)
'Deallocates the EMS pages allocated the EMS handle [Handle].
'You MUST remember to call the sub before your program ends
'if you allocate any memory!
Regs.ax = &H4500 'Release the pages allocated to [Handle]
Regs.dx = Handle
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
END SUB
FUNCTION EMS.ErrorMsg$
'Returns a text string describing the error code in EMS.Error.
SELECT CASE EMS.Error
CASE &H0: Msg$ = "successful"
CASE &H80: Msg$ = "internal error"
CASE &H81: Msg$ = "hardware malfunction"
CASE &H82: Msg$ = "busy -- retry later"
CASE &H83: Msg$ = "invalid handle"
CASE &H84: Msg$ = "undefined function requested by application"
CASE &H85: Msg$ = "no more handles available"
CASE &H86: Msg$ = "error in save or restore of mapping context"
CASE &H87: Msg$ = "insufficient memory pages in system"
CASE &H88: Msg$ = "insufficient memory pages available"
CASE &H89: Msg$ = "zero pages requested"
CASE &H8A: Msg$ = "invalid logical page number encountered"
CASE &H8B: Msg$ = "invalid physical page number encountered"
CASE &H8C: Msg$ = "page-mapping hardware state save area is full"
CASE &H8D: Msg$ = "save of mapping context failed"
CASE &H8E: Msg$ = "restore of mapping context failed"
CASE &H8F: Msg$ = "undefined subfunction"
CASE &H90: Msg$ = "undefined attribute type"
CASE &H91: Msg$ = "feature not supported"
CASE &H92: Msg$ = "successful, but a portion of the source region has been overwritten"
CASE &H93: Msg$ = "length of source or destination region exceeds length of region allocated to either source or destination handle"
CASE &H94: Msg$ = "conventional and expanded memory regions overlap"
CASE &H95: Msg$ = "offset within logical page exceeds size of logical page"
CASE &H96: Msg$ = "region length exceeds 1 MB"
CASE &H97: Msg$ = "source and destination EMS regions have same handle and overlap"
CASE &H98: Msg$ = "memory source or destination type undefined"
CASE &H9A: Msg$ = "specified alternate map register or DMA register set not supported"
CASE &H9B: Msg$ = "all alternate map register or DMA register sets currently allocated"
CASE &H9C: Msg$ = "alternate map register or DMA register sets not supported"
CASE &H9D: Msg$ = "undefined or unallocated alternate map register or DMA register set"
CASE &H9E: Msg$ = "dedicated DMA channels not supported"
CASE &H9F: Msg$ = "specified dedicated DMA channel not supported"
CASE &HA0: Msg$ = "no such handle name"
CASE &HA1: Msg$ = "a handle found had no name, or duplicate handle name"
CASE &HA2: Msg$ = "attempted to wrap around 1M conventional address space"
CASE &HA3: Msg$ = "source array corrupted"
CASE &HA4: Msg$ = "operating system denied access"
CASE ELSE: Msg$ = HEX$(EMS.Error) '"undefined error"
END SELECT
EMS.ErrorMsg$ = Msg$
END FUNCTION
SUB EMS.ExchMem (Length&, SrcHandle, SrcSegment, SrcOffset, DstHandle, DstSegment, DstOffset)
'Exhanges memory from EMS or base memory to EMS or base memory, where:
'
'Length& = Length of memory to exchange in bytes
'SrcHandle = EMS handle of source memory (use 0 if source is base memory)
'SrcSegment = Segment of source memory (or page number if source is EMS)
'SrcOffset = Offset of source memory
'DstHandle = EMS handle of destination memory (use 0 if destination is base memory)
'DstSegment = Segment of destination memory (or page number if destination is EMS)
'DstOffset = Offset of destination memory
'Determine the source and destination memory types by checking the handles
IF SrcHandle = 0 THEN SrcType$ = CHR$(0) ELSE SrcType$ = CHR$(1)
IF DstHandle = 0 THEN DstType$ = CHR$(0) ELSE DstType$ = CHR$(1)
'Create a buffer containing the copy information
ExchInfo$ = MKL$(Length&) + SrcType$ + MKI$(SrcHandle) + MKI$(SrcOffset) + MKI$(SrcSegment) + DstType$ + MKI$(DstHandle) + MKI$(DstOffset) + MKI$(DstSegment)
Regs.ax = &H5701 'Exchange the memory region
Regs.ds = VARSEG(ExchInfo$) 'described in the buffer
Regs.si = SADD(ExchInfo$)
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
END SUB
FUNCTION EMS.FreeHandles
'Returns the number of free (available) EMS handles.
Regs.ax = &H4B00 'Get the # of handles in use
InterruptX &H67, Regs, Regs
UsedHandles = Regs.bx
Regs.ax = &H5402 'Get the total # of handles
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
TotalHandles = Regs.bx
EMS.FreeHandles = TotalHandles - UsedHandles 'Subtract to get the # of free handles
END FUNCTION
FUNCTION EMS.FreePages
'Returns the number of free (available) EMS pages
'(Multiply by 16 to get the amount free EMS in KB.)
Regs.ax = &H4200 'Get the # of free pages
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
EMS.FreePages = Regs.bx
END FUNCTION
FUNCTION EMS.Init
'Returns true (-1) if an EMM is installed
'or false (0) if an EMM is not installed.
Regs.ax = &H3567 'Get the interrupt vector for int 67h
InterruptX &H21, Regs, Regs
DEF SEG = Regs.es 'Point to the interrupt segment
FOR x = 10 TO 17 'Store the 8 bytes at ES:0A in EMM$
EMM$ = EMM$ + CHR$(PEEK(x))
NEXT
IF EMM$ <> "EMMXXXX0" THEN
EMS.Init = 0 'EMM not installed
ELSE
EMS.Init = -1 'EMM installed
END IF
END FUNCTION
SUB EMS.MapPage (Physical, Logical, Handle)
'Maps the logical EMS page [Logical] (allocated to the handle [Handle])
'to the physical page [Physical] in the EMS page frame.
Regs.ax = &H4400 + Physical 'Map the logical page [Logical]
Regs.bx = Logical 'to the physical page [Physical]
Regs.dx = Handle
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
END SUB
SUB EMS.MapXPages (PhysicalStart, LogicalStart, NumPages, Handle)
'Maps up to 4 logical EMS pages to physical pages in the page frame, where:
'
'PhysicalStart = Physical page first logical page is mapped to
'LogicalStart = First logical page to map
'NumPages = Number of pages to map (1 to 4)
'Handle = EMS handle logical pages are allocated to
'Create a buffer containing the page information
FOR x = 0 TO NumPages - 1
MapInfo$ = MapInfo$ + MKI$(LogicalStart + x) + MKI$(PhysicalStart + x)
NEXT
Regs.ax = &H5000 'Map the pages in the buffer
Regs.cx = NumPages 'to the pageframe
Regs.dx = Handle
Regs.ds = VARSEG(MapInfo$)
Regs.si = SADD(MapInfo$)
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
END SUB
FUNCTION EMS.PageFrame
'Returns the segment of the EMS page frame
Regs.ax = &H4100 'Get the segment of the page frame
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Save the status code
EMS.PageFrame = Regs.bx
END FUNCTION
FUNCTION EMS.TotalPages
'Returns the total number of EMS pages
'(Multiply by 16 to get the total amount of EMS in KB.)
Regs.ax = &H4200 'Get the # of total pages
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Store the status code
EMS.TotalPages = Regs.dx
END FUNCTION
FUNCTION EMS.Version$
'Returns a string containing the EMM version.
'(Must be "4.0" or greater to use our routines.)
Regs.ax = &H4600 'Get the EMM version
InterruptX &H67, Regs, Regs
EMS.Error = (Regs.ax AND &HFF00&) \ &H100 'Save the status code
Version = Regs.ax AND &HFF 'Split the version number into
Major = (Version AND &HF0) \ &H10 'its major and minor counterparts
Minor = Version AND &HF
EMS.Version$ = LTRIM$(STR$(Major)) + "." + LTRIM$(STR$(Minor))
END FUNCTION
Posts: 3
Threads: 1
Joined: Sep 2003
Wow!
I really appreciate all the help. I certainly have found a place to go when I am at sticking points.
I think I found a way around my conundrum; now I realize I was using up way too much memory for the computation I was doing (thanks to lots of you who posted).
I will certainly look through the code if I ever REALLY need a 100x100x100 block of data.
Thanks, you guys.
tk
|