ts heap

(354 min. left) PASCAL        (1639) Conference Command? TS HEAP
Msg # to Begin Search from (18836-23747)? 25000
Scanning PASCAL        (1639) Conference
Searching for HEAP
(353 min. left) PASCAL        (1639) Conference Command? TS HEAP
Msg # to Begin Search from (18836-23747)? 25000-
Scanning PASCAL        (1639) Conference
Searching for HEAPDate: 01-19-95 (18:34)              Number: 23739 of 23747 (Refer# NONE)
  To: MAYNARD PHILBROOK
From: FRANK BUTERA
Subj: Re: Huge Constant Arrays
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

MP>  ML> I'm working on converting some .C code to pascal and I've run into a
MP>  ML> problem.  I have a HUGE constant array ( array[1..31900] of integer )
MP>  ML> and it says the data segment is too large.  How can I patch this up so
MP>  ML> I can use it?  The array is for a picture, if you need to know. Thanks
MP>
MP>
MP>  Type MyArray = Array[1..31900] of interger;
MP>
MP> var
MP> MyTable :^Myarray;
MP>
MP> Begin
MP>  new(MyTable);

My guess is that he doesn't understand memory pointers.  If he did, he
would've known that that would let him get around the data segment limit.
(353 min left), (H)elp, More?
Don't forget to tell him that to access this array, he must use:
MyTable^[???] to access it.  Any pointer variable must contain the carret
after its name or an error in compiling will give an invalid variable.

You can also free up this memory when you are through with it by:
dispose(MyTable);
You can also manuever your heap space for these pointers
with compiler directives, just to give you something else to play with.

There.  Now if he didn't know, he does now.  :)

Frank Butera

--- GEcho 1.01+
 * Origin: T.W.B. BBS - Lockport, IL - 2 Nodes - 708.301.2948 (1:2235/90)
(353 min left), (H)elp, End of Message Command? Date: 01-16-95 (09:53)              Number: 23677 of 23747 (Refer# NONE)
  To: JENS HANSEN
From: KRIS VANDERMOTTEN
Subj: Compiler
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

On (12 Jan 95) Jens Hansen wrote to Kris Vandermotten...

 KV> (Furthermore, a case statement is very bad for cache
 KV> performance, but that's another issue.)

 JH> What do you actually mean by that ??

A large case statement tends to trash the processor cache.

Since a case satement actually is a nested if then statement:

Case i of
 1: ...;
 2: ...;
 3: ...;
 else ...;
(353 min left), (H)elp, More? end;

compiles to (approx.) the same code as:

if i=1 then ...
else if i=2 then ...
else if i=3 then ...
else ...;

(The compiled code of the case is more efficient since i is evaluated
and loaded only once.)

In the assembly you'll see:

mov al,i
cmp al,1
(353 min left), (H)elp, More? jne @case2
...;
jmp @endcase
@case2
cmp al,2
jne @case3
...;
jmp @endcase
@case3
.......

As you can see, the search code is spread around between the actual
procedures. Therefore, all this memory must be loaded into the
processor's cache, replacing other information. If you place the search
code in one place, and the routines in another, then the search code
might be kept in the cache until the next loop through.
(353 min left), (H)elp, More? The reason for this is the granularity of the cache. The primary cache
of a 486 works per 16 byte 'page'. So you want the search to occupy as
less pages as possible. Therefore it should be localised in one block of
memory, in stead of spread around. (Hope I make myself clear - have some
doubts ;-)

 KV> If you need more information on this completely different
 KV> method, write me back and I'll explain.

 JH> Could you in short terms, try to explain what this "different method" is ?


This "different method" is two step evaluation: instead of reading a
line of source code and executing it, you first read and parse the
whole file. The result of this parsing step is stored in binary form
(typically a set of tagged records or objects on the heap). The second
(353 min left), (H)elp, More? step is the actual execution of the code, using the binary
representation. In this way, lines inside loops don't have to be
translated twice (or more).

Of course, this method is most well suited to block structured
languages. I believe you wanted to do something like Salt, which is a C
like language, wright?

Because you are doing things in two steps, the first step being executed
only once, you want to move as much work into the first step as
possible. In the binary representation of your program, there will not
be any names of procedures or variables (or labels). The jumps will be
resolved in the first step, as will the locations of variables. So
taking a jump in the binary rep is only folowing a pointer.

I suggest, if you use this method, that you do it in OOP. That will be
(353 min left), (H)elp, More? much easier then using tagged records. You start from BNF notation of
your language. Every non terminal will become an object. Every object
will have a virtual execute routine. (This is the same as storing a
pointer to a procedure in a non-OOP implementation).

BTW: BNF example:

if-then-else-statement ::=
  'if' condition 'then' statement 'else' statement

So you would need at least an if-then-else-statement object, a condition
object, and a statement object. In another rule, you would probably see
that if-than-else-statement is a statement, and therefore inherits from
it.
Your if-then... object would probably look something like this:

(353 min left), (H)elp, More? Type
 PIfThenElseStatement = ^TIfThenElseStatement;
 TIfThenElseStatement =
  Object (TStatement)
   condition: PCondition;
   thenstatement,
   elsestatement: PStatement;
   Procedure Execute; Virtual;
  End;

You would also need a constructor and a destructor etc...
The constructors will contain some of the parsing code.

procedure TIfThenElseStatement.Execute;
Begin
 if condition^.evaluate then thenstatement^.execute
(353 min left), (H)elp, More?  else elsestaement^.execute;
End;

 JH> Could you in short terms, try to explain what this "different method" is ?

I think this is far enough for 'in short terms'. I also realise it was
a bit 'filosophical'. If you need help on a real implementation, write
me back. Tell me your exact problem and include some BNF.

Greetings,
Kris

--- PPoint 1.86
 * Origin: *** (2:292/600.14)

(353 min left), (H)elp, End of Message Command? Date: 01-18-95 (00:19)              Number: 23665 of 23747 (Refer# NONE)
  To: DAVID RAWSTHORNE
From: HORST KRAEMER
Subj: FreePtr^
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

Hello David,

15 Jan 95  09:44:19, David Rawsthorne wrote to All:

 > Hello All!

 > Can anyone tell me the equivalent of the FreePtr Pointer name
 > using Turbo Pascal 7.0? I know it is a pointer to the 'Fragment
 > List', but I have an old unit that I want to update to TP 7.0 and
 > TP 7.0 barfs when It encounters this pointer.....

There is no equivalent of FreePtr in TP 6.0+, as the heap management has
changed completely. You will have to rewrite the code. Refer to the BP 7.0
documentation, that's all you need.

Regards
(353 min left), (H)elp, More? Horst

--- FMail 1.0g
 * Origin: -= Las orillas del Nahuel Huapi =- (2:2410/121.16)

(353 min left), (H)elp, End of Message Command? Date: 01-18-95 (10:50)              Number: 23657 of 23747 (Refer# NONE)
  To: MARCOS GONZALEZ
From: MIKE COPELAND
Subj: Help
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

>>    I have a very basic question for someone with a little time to
>>    spare. First I'm active duty in the army and I do programming as
>>    a hobby. I run a BBS and I'm working on a door. Now my problem
>>    is since I never had a chance to be assigned close enough to a
>>    college where I can learn Turbo Pascal. All my knowledge comes from
>>    books. What I'm trying to do is a simple record type file with
>>    the user name (string) level (integer) and maybe save the value
>>    of a boolean on a record. Now how do I get Pascal to write this
>>    file, look for a user's name and read their level and boolean
>>    value from the record? Also how do I make a procedure to read the
>>    data file and sort the users from the highest level lowest and
>>    write to a text file (this is to make a top ten bulletin). This
>>    is probably my last resource to get this information since I have
>>    no other way to get this information. I'll be very thankful if
>>    anybody sends me some information on this. Thanks... ---

(352 min left), (H)elp, More? Type UREC = record
              NAME  : string[24];
              LEVEL : integer;
              FLAG  : boolean;
            end;
Var  F    : file of UREC;
     W    : UREC;                                  { working record }
     I    : integer;
begin
  Assign (F,'userfile.dat'); Reset (F);  { open file for read/write }
  I := 0;
  while I < FileSize (F) do                     { sequential access }
    begin
      Seek (F,I); Read (F,W);                       { read a record }
      with W do                    { process the data in the record }
        begin
(352 min left), (H)elp, More?           writeln (NAME,LEVEL:4);
          if LEVEL > 3 then                        { update record? }
            begin
              FLAG := true;
              Seek (F,I); Write (F,W)        { write updated record }
            end;
          etc...
          Inc (I)                            { point to next record }
        end;
      Close (F)
    end  { while }
end.

   The requirement to read/sort the file is predicated on how large the
file is, as well as how much data is in each record: you must be able to
store the entire file's contents in memory, either as Var data or Heap
(352 min left), (H)elp, More? and pointers.  That's a bit complex for a single post, but I can do so
if you ask another question (if this answer works for you...).  Hope
this helps.

... Sex is natural, but not if it's done right!
--- Via Silver Xpress V4.01 BT033
 * Origin: Silver Xpress Mail System (1:114/124)

(352 min left), (H)elp, End of Message Command? Date: 01-17-95 (16:59)              Number: 23652 of 23747 (Refer# NONE)
  To: MARK ROGERS
From: MIKE COPELAND
Subj: More mem..
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

>>    Ok.. Yes I know how to use pointers but I still have memory
>>    probs..
>>     I NEED and Array [320000] Of Byte; And this just will NOT
>>    compile in TP 7.0 as we already know, so, how on earth can I get
>>    all my info into an array that will not compile ?? Come on,
>>    someone out there must have one or two working tricks up his/her
>>    sleave?? Possibly EMS or XMS??

   You're just going to have to use that pointer knowledge - to redesign
your application to use 64K "chunks" of that array, and allocate Heap
pointers to them.  The absolute most amount of _anything_ you can access
is 64K, but there are numerous ways to subdivide larger data into 64K
portions; usually it's some form of "paging"...

... 1024x780x256... Some MEAN woman!
--- Via Silver Xpress V4.01 BT033
(352 min left), (H)elp, More?  * Origin: Silver Xpress Mail System (1:114/124)

(352 min left), (H)elp, End of Message Command? Date: 01-17-95 (16:55)              Number: 23651 of 23747 (Refer# NONE)
  To: BYRON ELLACOTT
From: MIKE COPELAND
Subj: More about pointers.
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 IL>> you use. The memory for them isn't in the EXE but allocated in memory
 IL>> by the EXE with memory allocation calls later. A 4k array doesn't take
 IL>> 4k in the EXE just because it's declared as 4k for use in memory. I
 IL>> think the program just knows to allocate DOS memory in the data segment
 IL>> for it once the program has started.
>>     oops :)  I wrote two programs, one with array[0..1023] of byte
>>     and one with a pointer to [0..1023] of byte..i wrote a value to
>>     the array and read a value from the pointer (no
>>     allocation!)..the .exe produced were exactly the same size..i
>>     didn't know pascal optimized that well...in asm if you define
>>     data you will get space in the .exe allocated for it.. :)

   He is right, and you've verified it by testing: all Var data is
"reserved" for the program when it's loaded/started, and the total Var
space (64K max.) must be available at that time.  Code and constants
belong and are part of the .EXE file, but Var data isn't.  This is (yet)
(352 min left), (H)elp, More? another reason why it's critical to initialize Var data in Pascal,
because the way it's made available to a program, _any_ value is
possible - and none can be assumed.
   Another issue that's been discussed here at times: how "big" is the
program space requirement.  It's a combination of the .EXE size and the
Var space that's going to be used...initially.  Of course, there are
other issues, such as the Stack and Heap requirements (which vary during
execution), as well as overlay space, if used.  I've always felt it's
pretty hard to compute how much space a program will use during
execution...  8<}}

... Keep your children short on pocket money-but long on hugs.
--- Via Silver Xpress V4.01 BT033
 * Origin: Silver Xpress Mail System (1:114/124)

(352 min left), (H)elp, End of Message Command? Date: 01-16-95 (22:38)              Number: 23650 of 23747 (Refer# NONE)
  To: MATT LANGFORD
From: MIKE COPELAND
Subj: Huge Constant Arrays
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 ML> I'm working on converting some .C code to pascal and I've run
 ML> into a problem.  I have a HUGE constant array ( array[1..31900]
 ML> of integer ) and it says the data segment is too large.  How
 ML> can I patch this up so I can use it?  The array is for a
 ML> picture, if you need to know. Thanks in advance.

   You're going to have to declare a pointer to an object of this type,
and allocate/access the data on the Heap:

Type HUGE_STUFF = array[1..31900] of integer;
Var  H_S_PTR    : ^HUGE_STUFF;
begin
  New (H_S_PTR);   { allocate space on Heap }
  H_S_PTR^ := something;  { access the data }
  etc.
end;
(352 min left), (H)elp, More?
... This isn't a tagline.  It's an after-thought....
--- Via Silver Xpress V4.00 BT033
 * Origin: Silver Xpress Mail System (1:114/124)

(352 min left), (H)elp, End of Message Command? Date: 01-17-95 (22:22)              Number: 23634 of 23747 (Refer# NONE)
  To: DJ MURDOCH
From: MATT MOODY
Subj: getmem 65535
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

DM=> IL> Getmem can't take a value that high in its Word size argument but can
  =>take
  => IL> 65535 and it works.

DM=>Really?  Try this:

DM=> type
  =>  big = array[1..65535] of byte;
  => var
  =>  pbig : ^big;
  =>  pbyte : ^byte;
  => begin
  =>  getmem(pbyte,1);   { or just New(pbyte) }
  =>  getmem(pbig,65535);{ or just New(pbig) }

DM=>  pbyte^ := 0;
(352 min left), (H)elp, More?   =>  fillchar(pbig^, 65535, 1);

DM=>  if pbyte^ <> 0 then
  =>    Writeln('Oops, 65535 is too big!!');
  => end.

DM=>You'll find that pbyte^ has been trashed, because the heap manager can only
  =>safely allocate blocks up to 65528 bytes.

Theoretically, each allocated memory range could be an entire segment
with a maximum size of 64K. Through normalization, the lower limit is
set to 15 bytes. Therefore, calling GetMem can allocate memory blocks
with a maximum size of 65521 bytes (65536 - 15).


 * QMPro 1.53 * REALITY.SYS corrupt:  Reboot Universe (Y/N)
(352 min left), (H)elp, More?
--- GOMail v1.2 [92-0585]
 * Origin: Fidonet: Madmen and Maniacs - 706.860.5781 (1:360/12)

(352 min left), (H)elp, End of Message Command? Date: 01-17-95 (00:11)              Number: 23612 of 23747 (Refer# NONE)
  To: DAVID DUNSON
From: GERHARD DALENOORT
Subj: MIDI
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

I saw U asking about MIDI....

The .MID format I don't know... but I was searching for
acces on the midi port for a month or so...

The SB is very cruel on programming the MIDI interface,
ye can't play sound and send/recieve MIDI at the same time.

I have a LogiTech SoundMan Games Card (SB compatible 8-bit) and
the little (read cheap: $30) has a MPU-401 Compatible Chip onboard.

Usually the BASE adress (port) is $330 (don't bother the IRQ (2) )

Now Reset it:    Port[$331]:= $FF  { Reset at Status Port }
Enter UART mode: Port[$331]:= $3F

(352 min left), (H)elp, More?  Al you have to do is read/write to Port[$330].... Tadaa...

But... It is advisable to check for a Byte Avaible because, else you
will get one byte about 10 times if ye continually read Port $330

 GreetZ,
   Gerhard.

---
 * Origin: Hunze-BBS, #1 31-5920-18921, #2 31-5920-14281 (2:2802/216)

(352 min left), (H)elp, End of Message Command? Date: 01-18-95 (15:32)              Number: 23605 of 23747 (Refer# NONE)
  To: MARK ROGERS
From: LEWIN EDWARDS
Subj: More mem..
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 MR>  I NEED and Array [320000] Of Byte; And this just will NOT

You can't have one, sorry. Max size of any data struct in real mode is just
under 64K.

 MR> there must have one or two working tricks up his/her sleave??
 MR> Possibly EMS or XMS??

EMS is even worse, you have to access it in 16K pages (though you can put 4
together and get 64K... but that's no better).

If you want a continuous linear structure which is larger than 64K, you should
declare a huge pointer to char, and point it to a block of memory allocated
from the far heap. How to do this in TP, I have no idea. In BC you would
declare `unsigned char huge *p;' and create the array with `p=(unsigned char
huge *) farmalloc(320000ul)';
(352 min left), (H)elp, More?
Maybe someone else who knows TP better than myself can tell you how to actually
do this in Pas. I suspect it's a compiler directive.

I really do think a little creative thinking about data storage would solve
your problem though. What do you need to store ? I very much doubt you `NEED'
an array of that size.

-- Lewin A.R.W. Edwards (obsessed)
Mobile 015 809 805  *  Pager 132222 #426185  *  Pager (03) 4834444 #173425

--- FreeMail 1.10 alpha-3
 * Origin: ZWSBBS +61-3-8276881 28800bps 24 Hours (3:634/396)

(352 min left), (H)elp, End of Message Command? Date: 01-17-95 (01:28)              Number: 23582 of 23747 (Refer# NONE)
  To: MATT LANGFORD
From: JUD MCCRANIE
Subj: Re: Huge constant arrays
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 ML> into a problem.  I have a HUGE constant array ( array[1..31900]
 ML> of integer ) and it says the data segment is too large.  How

that's not too large for an individual piece of data, but your
total global data must be too large (> 64K).  Yuo need to put
it on the heap or stack (with a subroutine).


Jud McCranie

--- Via Silver Xpress V3.02

--- MsgToss 2.0c
 * Origin: Powerline, Valdosta GA (1:3645/21)

(352 min left), (H)elp, End of Message Command? ...   Date: 01-15-95 (08:06)              Number: 23504 of 23747 (Refer# NONE)
  To: MIKE COPELAND
From: STEVE ROGERS
Subj: Style
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

MC>  >>  for I := 1 to EndOfArray do
  >  >>    YOUTHGROUP[I] := Nil;  { initialize P/A }

MC>>>                            or

MC>>>        fillchar(YOUTHGROUP,sizeof(YOUTHGROUP),0);

MC>>>                 (if you're in a hurry :)

MC>   Perhaps, but I prefer the documentation obtained from the loop and
  >the use of Nil - you can see what's happening.  I didn't (don't?) know
  >that 0 equates to Nil (should it be #0?), and this very problem seems to
  >make my method better, overall...  8<}}

    Step it through the IDE and watch it (and let me know what you find).
  Filling a pointer with 0 shows nil in the watch window. It sure makes
(352 min left), (H)elp, More?   a diff when you have to init thousands of pointers in an array many
  times in a prog.
    Documentation? While I too prefer the code to speak for itself (and
  for me it does in this case), a single line comment should suffice.
    #0 (for chars) = 0 (for bytes) = nil (for pointers). I use fillchar
  regularly to init "empty" data structures. It seems to work for just
  about anything, including pointers, strings, and numerics.


MC>  >>  J := 0;  { # of records stored }
  >  >>  while not EOF(F) do
  >  >>    begin
  >  >>      read (F,WORK); Inc (J);
  >  >>      New (YOUTHGROUP[J]);  { allocate Heap space for new record }
  >  >>      YOUTHGROUP[J]^ := WORK
  >  >>    end;
(352 min left), (H)elp, More?
MC>>>       You're not gaining anything with the temp var. I'd just do

MC>>>       j:= 0;
  >>>       while not eof(f) do begin
  >>>         inc(j);
  >>>         new(youthgroup[j]);
  >>>         read(f,youthgroup[j]^);
  >>>       end;

MC>   Not in this case, I agree.  However, I was showing the basic logic in
  >a simplistic way, and I often like to use the temp variable (with a
  >"with" clause) to do considerable work before storing that actual record
  >- again, it helps to document what's going on, and I don't want to take
  >the chance of inadvertently altering the index/pointer by some other
  >process.  It's certainly unnecessary, but sometimes safety is an
(352 min left), (H)elp, More?   >important issue...  8<}}

  But your temp var adds complexity (in this case), whereas "my" method
  IS more "simplistic". Do you use temp vars every time you do an
  assignment? (of course not) Nobody's advocating anything dangerous
  here. Use a temp when it's needed, and document that necessity in the
  code. Using temps by default is slavish conformation to style for
  style's sake, and confuses the issue, IMHO. Be safe, be sure, but be
  efficient, too. :)

  As the Pascal Lessons moderator your code examples are used by bunches
  of newbies as the basis for a lot of their programming. (And what one
  hell of a fine job you do, too! You've sure showed me a thing or two.)
  Although this is a different echo, a lot of folks read both. It would
  be unfortuneate if someone were to surmise that temp vars were "magic
  bullets" for data safety. IMHO, if someone doesn't understand that a
(352 min left), (H)elp, More?   var is being read from a file into YouthGroup[j]^, they won't
  understand moving the temp var into YouthGroup[j]^ either.


--- WM v3.11/93-0830
 * Origin: D.W.'s Toolbox * 404-471-6636 * Jonesboro Georgia  (1:133/1719.0)

(352 min left), (H)elp, End of Message Command? . Date: 01-16-95 (10:32)              Number: 23431 of 23747 (Refer# NONE)
  To: JOHN HOWARD
From: MATT LANGFORD
Subj: Huge Constant Arrays
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 JH> => Quoting Matt Langford to All on 12 Jan 95  21:10 <=

 JH> ML> I'm working on converting some .C code to pascal and I've run into a
 JH> ML> problem.  I have a HUGE constant array ( array[1..31900] of integer
 JH> )
 JH> ML> and it says the data segment is too large.  How can I patch this up
 JH> so
 JH> ML> I can use it?  The array is for a picture, if you need to know.
 JH> Thanks

 JH> Integer data type is 16 bits wide.  A data segment is
 JH> limited to 64k.
 JH> Use the OS heap instead.  Turbo Pascal programs share one
 JH> data segment!
 JH> With Extended Pascal for OS/2 you could have a HUGE
 JH> constant array.
(352 min left), (H)elp, More?  JH> PROGRAM HeapBigPicture;   { Untested! }
 JH> { Author: John Howard
 JH>   Date: January 15, 1995
I'm not sure that would work.  I don't really want to change the code too much
from its original C, plus I don't know exactly how the array is setup.  But,
thanks anyways.
--- GEcho 1.11+
 * Origin: Knight Mare 405 672 5644 (1:147/3006)

(352 min left), (H)elp, End of Message Command? ..  Date: 01-15-95 (17:20)              Number: 23365 of 23747 (Refer# NONE)
  To: MATT LANGFORD
From: JOHN HOWARD
Subj: Huge Constant Arrays
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 => Quoting Matt Langford to All on 12 Jan 95  21:10 <=

 ML> I'm working on converting some .C code to pascal and I've run into a
 ML> problem.  I have a HUGE constant array ( array[1..31900] of integer )
 ML> and it says the data segment is too large.  How can I patch this up so
 ML> I can use it?  The array is for a picture, if you need to know. Thanks

Integer data type is 16 bits wide.  A data segment is limited to 64k.
Use the OS heap instead.  Turbo Pascal programs share one data segment!
With Extended Pascal for OS/2 you could have a HUGE constant array.
PROGRAM HeapBigPicture;   { Untested! }
{ Author: John Howard
  Date: January 15, 1995
  Version: 1.0
  Note: Demonstrate accessing a HUGE array.
}
(352 min left), (H)elp, More? CONST
  Columns = 640-1;
  Rows = 480-1;  { ImageSize is 307200 bytes }

TYPE
  DataType = byte;
  BigArrayRow  = array[0..Columns] of DataType;
  BigArrayType = array[0..Rows] of ^BigArrayRow;

VAR
  BigArray : BigArrayType;
  Column : byte;
  Row : byte;
  TheColor : DataType;

BEGIN
(352 min left), (H)elp, More?   {
   The largest block that can be safely allocated on the heap at one time
   is 65,528 bytes (64k - $8).
  }
  for Row := 0 to Rows do
    GetMem(BigArray[Row], SizeOf(BigArrayRow));

  {  Show how to assign a color.  }
  TheColor := 2;
  Column := 240;
  Row := 300;
  BigArray[Row]^[Column] := TheColor;

  TheColor := 1;  { assign something completely different for test }

  {  Show how to retrieve a color.  }
(352 min left), (H)elp, More?   Column := 240;
  Row := 300;
  TheColor := BigArray[Row]^[Column];
  writeln('TheColor (should be 2) = ', TheColor);

  for Row := 0 to Rows do
    FreeMem(BigArray[Row], SizeOf(BigArrayRow));
END.

... Remember GERONIMO?
 * Origin: Infinity (1:280/5)

(352 min left), (H)elp, End of Message Command? ...   Date: 01-14-95 (13:22)              Number: 23287 of 23747 (Refer# NONE)
  To: ALL
From: JASON ROTHSTEIN
Subj: umb_heap.pas
Read: (N/A)                         Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

{
    Here is the UMB_Heap unit i found in a copy of PC Magazine a while back...
This code works on my 486DX/2 66mhz with 4meg ram...    so it should (i hope)
run on yourz too....    All you need to do to use this is just call Extend_Heap
in your program someplace to get the extra heap memory, and GetBlockSizes if
you wish to know how large the UMB blocks are that were allocated...

ttylz yallz...

}

Unit
  UMB_Heap;

Interface

(352 min left), (H)elp, More? Const
  Max_Blocks      = 4;

Type
  UMBDataType = Array[1..Max_Blocks] Of Word;

Procedure Extend_Heap;
Procedure GetBlockSizes(Var US : UMBDataType);

Implementation

Type
  PFreeRec        = ^TFreeRec;
  TFreeRec        = Record
    Next          : PFreeRec;
    Size          : Pointer;
(352 min left), (H)elp, More?   End;

Var
  Block_Segments  : UMBDataType;
  Block_Sizes     : UMBDataType;
  SaveExitProc    : Pointer;

Function UMB_Driver_Present : Boolean;

Var
  Flag            : Boolean;

Begin
  Flag := False;
  Asm
    Mov   AX, $4300
(352 min left), (H)elp, More?     Int   $2F
    CMP   AL, $80
    JNE   @Done
    Inc   [Flag]
  @Done:
  End;
  UMB_Driver_Present := Flag;
End;

Procedure Allocate_UMB;

Var
  I,
  Save_Strategy,
  Block_Segment,
  Block_Size      : Word;
(352 min left), (H)elp, More?
Begin
  For I := 1 To Max_Blocks Do
    Begin
      Block_Segments[I] := 0;
      Block_Sizes[I] := 0;
    End;
  Asm
    Mov   AX, $5801
    Mov   BX, $0FFFF
    Int   $21
    Mov   AX, $5803
    Mov   BX, $0001
    Int   $21
  End;
  For I := 1 To Max_Blocks Do
(352 min left), (H)elp, More?     Begin
      Block_Segment := 0;
      Block_Size := 0;
      Asm
        Mov   AX, $4800
        Mov   BX, $0FFFF
        Int   $21
        CMP   BX, 0
        JE    @Fail
        Mov   AX, $4800
        Int   $21
        JC    @Fail
        Mov   [Block_Segment], AX
        Mov   [Block_Size], BX
      @Fail:
      End;
(352 min left), (H)elp, More?       Block_Segments[I] := Block_Segment;
      Block_Sizes[I] := Block_Size;
    End;
End;

Procedure Release_UMB; Far;

Var
  I,
  Segment : Word;

Begin
  ExitProc := SaveExitProc;
  Asm
    Mov   AX, $5803
    Mov   BX, $0000
(352 min left), (H)elp, More?     Int   $21
  End;
  For I := 1 To Max_Blocks Do
    Begin
      Segment := Block_Segments[I];
      If (Segment > 0) Then
        Asm
          Mov   AX, $4901
          Mov   BX, [Segment]
          Mov   ES, BX
          Int   $21
        End;
    End;
End;

Function Pointer_To_LongInt(p : Pointer) : LongInt;
(352 min left), (H)elp, More?
Type
  PtrRec          = Record
    Lo, Hi        : Word;
  End;

Begin
  Pointer_To_LongInt := LongInt(PtrRec(P).Hi * 16 + PtrRec(P).Lo);
End;

Procedure Extend_Heap;

Var
  I               : Word;
  Temp            : PFreeRec;

(352 min left), (H)elp, More? Begin
  If UMB_Driver_Present then
    Begin
      Allocate_UMB;
      Temp := HeapPtr;
      I := 1;
      While ((Block_Sizes[I] > 0) And
             (I <= Max_Blocks)) Do
        Begin
          Temp^.Next := Ptr(Block_Segments[I], 0);
          Temp       := Temp^.Next;
          Temp^.Next := HeapPtr;
          Move(Block_Sizes[I], Temp^.Size, SizeOf(Word));
          Temp^.Size := Pointer(LongInt(Temp^.Size) SHL 16);
          Inc(I);
        End;
(352 min left), (H)elp, More?       If (Block_Sizes[1] > 0) then
        FreeList := Ptr(Block_Segments[1], 0);
    End;
End;

Procedure GetBlockSizes(Var US : UMBDataType);

Begin
  US := Block_Sizes;
End;

Begin
  FillChar(Block_Sizes, SizeOf(Block_Sizes), 0);
  SaveExitProc := ExitProc;
  ExitProc := @Release_UMB;
End.
(352 min left), (H)elp, More?
--- FMail 0.96
 * Origin: Cobra's Point (1:387/31.55)

(352 min left), (H)elp, End of Message Command? ...   Date: 01-11-95 (20:48)              Number: 23246 of 23747 (Refer# NONE)
  To: JOHN BALDWIN
From: MARK OUELLET
Subj: More pointer stuff..
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

Friday December 30 1994 11:11, John Baldwin wrote to Mario Polycarpou:

Hello John!

MP>  BE>> getmem(buf,65521);
MP>  BE>> reset(f1,65521);
MP>  BE>> blockread(f1,buf^,1);
MP>  BE>> freemem(buf,65521);

First this will produce an output file that ISN'T the same size as the original
if the blockwrite call uses the same block size.

MP> BE>> 65521 is the largest size block of memory you can have under real
MP> BE>> mode. If you want more, check up on protected mode (I dont have bp so
MP> BE>> I cant tell u anything about memory allocation under DPMI)..

(352 min left), (H)elp, More? MP>> More like 65535

JB> Nope, DOS has to claim a few bytes for its memory management.  65521 leaves
JB>  14 bytes for DOS, but I think DOS uses 16 bytes, making the max size
JB> 65519. Of course, I could be wrong.  If so, someone please tell me why it's
JB> 14 and not 16 bytes?  Hope this helps.

Actually it's 65536-8 = 65528 or 0-65527;

    The reason for it all is ALLOCATION SIZE. BTW The above is true for TP/BP
7.x. In TP 6.0 and previous the value was different because they used different
allocation sizes.

    TP/BP 7.x allocates memory in 8byte chunks, because you can't be sure that
the offset is 0, it could be 8, then to avoid WRAPING AROUND at the end of the
segment, without checking the offset, the largest value allowable is 65528.
(352 min left), (H)elp, More? Because 65528+8 = 65536. Make that 65529 and, if the offset is 0 you're OK
because the end offset will be 65529+0 = 65529. But if you're unlucky and TP/BP
picked an offset of 8, then it becomes 65529+8 = 65537 ONE BYTE too many and
you've just wrapped around to the start of the segment. Problem is, if *YOU*
have an offset of 8, *WHO'S* residing at the start of the segment at offset
0???? You've just overwritten something else then!!

    By limiting allocations to 65536-8, TP/BP can work faster by not having to
check segment wrap-around on memory access.

Test it yourself. Create a few variables on the heap and check the offset of
each of those. You'll only find offsets of 0 or 8 nothing else.

    Then try allocating variables of different sizes from 1 byte to 17 bytes.
Check memavail after each allocation. You'll find memory reduced by a factor of
8 bytes each time. All allocations from 1 byte to 8 bytes will reduce memory by
(352 min left), (H)elp, More? 8 bytes, then all allocations from 9 to 16 by 16 bytes, then 24 etc...

    Best regards,
    Mark Ouellet.

...The plural of spouse is spice.
--- GoldED/2 2.50.B1016+[45LM2]
 * Origin: Mark's point under OS/2 2.11 Sillery, Qc, Canada (1:240/99.44)

(352 min left), (H)elp, End of Message Command? Date: 01-12-95 (11:49)              Number: 23204 of 23747 (Refer# NONE)
  To: JING SU
From: MIKE COPELAND
Subj: Pointers
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

>>    Let's say I have a pointer which has already been typed WORD.

>>    TYPE
>>    WPRD_PTR = WORD^.

   You need to code it as:

  Type WORD_PTR = ^Word;

>>    How do I change this WORD pointer to a VOID (POINTER) pointer?

   Then you need to declare a variable:

  Var WP : WORD_PTR;

   And explicitly assign it the Nil value:
(352 min left), (H)elp, More?
     WR := Nil;

   Later, you allocate Heap storage for it:

   New(WP);

   And use it this way:

   WP^ := 12345;

   However, the whole issue is somewhat moot, since the pointer consumes
more space in you Data Segment (4 bytes) than the Word variable (2
bytes).  I don't know why you'd want to do this, given the cost of data
and the execution degradation created by pointer referencing...
   Are you trying to make Pascal behave like C?  I don't feel that's a
(352 min left), (H)elp, More? good idea, and it's difficult in such areas as this seems to be...

... It's no longer a crime bill, it's Bill's Crime.
--- Via Silver Xpress V4.01 BT033
 * Origin: Silver Xpress Mail System (1:114/124)

(352 min left), (H)elp, End of Message Command? Date: 01-12-95 (11:03)              Number: 23202 of 23747 (Refer# NONE)
  To: STEVE ROGERS
From: MIKE COPELAND
Subj: Pointers?
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

MC>>Heap (pointer-referenced) data are numerous: (1) individual data
  >>pointers; (2) linked lists (single or double); (3) pointer arrays
  >>(arrays of pointers).

>>        and (4) array pointers (pointers to arrays)

   Yep...

MC>>   Pointer arrays are very useful for applications where a maximum
  >>amount of data can be expressed, and normally all of available Heap
  >>memory can be expressed for P/As, whether it's actually used is
  >>application and execution/data dependent.  In TP/BP, it's possible to
  >>P/As of up to 16,384 items, or even P/As of other 16K P/As - there
  >>really is no limit other than available Heap limits.

>>        I have trouble if I go beyond 16382, do you?
(352 min left), (H)elp, More?
   Yes, and that's why I limit mine to 16380 - this whole business of
mod-8 rounding is enough of a problem, I don't try to "fight it" by
getting the absolute maximum out of each 64K allocation.  Path of least
resistance and all that...

... And... she was wearing this sexy freudian-slip...
--- Via Silver Xpress V4.01 BT033
 * Origin: Silver Xpress Mail System (1:114/124)

(351 min left), (H)elp, End of Message Command? Date: 01-12-95 (11:00)              Number: 23201 of 23747 (Refer# NONE)
  To: STEVE ROGERS
From: MIKE COPELAND
Subj: Out, out, damn nit!  :)
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

  >>  for I := 1 to EndOfArray do
  >>    YOUTHGROUP[I] := Nil;  { initialize P/A }

>>                            or

>>        fillchar(YOUTHGROUP,sizeof(YOUTHGROUP),0);

>>                 (if you're in a hurry :)

   Perhaps, but I prefer the documentation obtained from the loop and
the use of Nil - you can see what's happening.  I didn't (don't?) know
that 0 equates to Nil (should it be #0?), and this very problem seems to
make my method better, overall...  8<}}

  >>  J := 0;  { # of records stored }
  >>  while not EOF(F) do
(351 min left), (H)elp, More?   >>    begin
  >>      read (F,WORK); Inc (J);
  >>      New (YOUTHGROUP[J]);  { allocate Heap space for new record }
  >>      YOUTHGROUP[J]^ := WORK
  >>    end;

>>       You're not gaining anything with the temp var. I'd just do

>>       j:= 0;
>>       while not eof(f) do begin
>>         inc(j);
>>         new(youthgroup[j]);
>>         read(f,youthgroup[j]^);
>>       end;

   Not in this case, I agree.  However, I was showing the basic logic in
(351 min left), (H)elp, More? a simplistic way, and I often like to use the temp variable (with a
"with" clause) to do considerable work before storing that actual record
- again, it helps to document what's going on, and I don't want to take
the chance of inadvertently altering the index/pointer by some other
process.  It's certainly unnecessary, but sometimes safety is an
important issue...  8<}}

... Of the last three presidents named William, two died in office.
--- Via Silver Xpress V4.01 BT033
 * Origin: Silver Xpress Mail System (1:114/124)

(351 min left), (H)elp, End of Message Command? ....    Date: 01-12-95 (21:23)              Number: 23142 of 23747 (Refer# NONE)
  To: CHRIS UNSWORTH
From: CJ CLIFFE
Subj: Re: statbar
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

-> Hi Cj,
->
->   I have just connected to this echo, and would be most interested in your
-> snippet for the status bar.  Would you mind reposting it please.

No Problem!  Here goez:

-----------------------------------------------------------------------------

{
    I've seen a LOT of programs which Say they are doing something like
    Reading/Writing to files, and you wonder if they have crashed or what,
    I think it would be nice to have a nice Status Bar to show the progress
    of what is going on!  so here's my contribution to everyone:

    Statbar:  Highly Accurate Status Bar..
(351 min left), (H)elp, More?
   All Code except for HideCursor and ShowCursor is mine.

                  - Shareware Overload BBS  (613)382-1924

}


Uses crt;


Procedure HideCursor; Assembler;  Asm                 {I forget where I got}
MOV   ax,$0100;  MOV   cx,$2607;  INT   $10 end;    {     these two      }



(351 min left), (H)elp, More? Procedure ShowCursor; Assembler; Asm
MOV   ax,$0100;  MOV   cx,$0506;  INT   $10 end;



Procedure Dupeit(Str: String; Num: Integer);  {Just a little Helper, dupes}
var Cnt: integer;                             {        lines              }
begin
For Cnt := 1 to Num do begin
write(Str);
end;
end;


Procedure Statbar(cnum,enum,xspot,yspot,fullcolor,emptycolor: Integer);
var percentage: Integer;              {Uh-Oh, here comes the Mathematical}
(351 min left), (H)elp, More? begin                                 {                Crap!!            }
Hidecursor;                                 {Kill That Damned Cursor!}
percentage := round(cnum / enum * 100 / 2);   {/2 can be changed for}
  Gotoxy(xspot,yspot);                          {  Shorter Stat Bars  }
 Textcolor(fullcolor);
dupeit(#219,Percentage);                {Can change the Char to whatever}
 Textcolor(emptycolor);
dupeit(#177,50 - Percentage);                    {same as above}

  write('  ',percentage * 2,'%');         {this is not needed, just an extra}
Showcursor;
end;

Procedure WriteXy(x,y: Integer; dstr: String; tcolor: integer);
Begin
Hidecursor;
(351 min left), (H)elp, More? Gotoxy(x,y);                      { Yeah, I now it's Cheap and cheezy}
Textcolor(tcolor);                 { but it gets the job done well! }
write(dstr);
Showcursor;
end;



var B1,B2,B3: integer;

Begin

  Clrscr;
  WriteXy(30,3,'Statbar By CJ Cliffe..',yellow);

Repeat
(351 min left), (H)elp, More?
 Inc(B1,4);
 Inc(B2,1);
 Inc(B3,1);

{ The Statbar procedure works like so:

Statbar(Current Number, Final Number, x location, y location,
                   Color of completed bars, color of empty bars);

Will process (as far as I know) Any pairs of numbers, as long as the Current
Number does not exceed the Final Number, everything should look fine.. }


   Statbar(B1,800,15,5,Lightcyan,Cyan);     {800 Just makes em go nice 'n}
   Statbar(B2,400,15,7,LightRed,Red);       {slow because they are FAST  }
(351 min left), (H)elp, More?    Statbar(B3,300,15,9,LightGreen,Green);

Until B1 = 800;

 WriteXy(30,15,'Press any key to quit...',Lightblue);
 Readkey;

end.

--- InterEcho 1.03a
 * Origin: CrossRoads * Kingston, Ont. Canada (1:249/1)

(351 min left), (H)elp, End of Message Command? . Date: 01-10-95 (07:46)              Number: 23085 of 23747 (Refer# NONE)
  To: DREW PRESTON
From: STEVE ROGERS
Subj: Pascal Overlay Unit
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

DP>Hi, Steve. Thanks for the advice on DPMI. I'm not sure how to use the Dos
  >Protected Mode Interface though, I have some ASM on detecting DPMI and I kno
  >that Windows uses DPMI in its 3.0 and 3.1 versions. I also know that the
  >functions are available through interrupts 2Fh and 31h. I am not sure how to
  >use this feature to overcome my problem though. Any advice would be
  >appreciated.

  Hi Drew,
    I do it the easy way - I let BP handle it for me. Compile and run
    the following using TPC -cp (or compile|target|protected in the IDE):

    begin
      writeln(memavail,' bytes available');
    end.

    It should report much more than 640k (if you have extended memory on
(351 min left), (H)elp, More?     your machine). _Using DPMI_ - well, that's a horse of a different
    color. I had a great idea once to make a BIG file sorter with DPMI.
    I'd put all the strings into a linked list, sorting as I went. RAM
    access went fine, but after a few hundred strings the thing got
    painfully slow. A B-Tree would have been a better choice, I guess.
    The way I use DPMI mostly is I set up arrays of pointers on the heap
    and just fill them up with data. That's how I do it without DPMI,
    for that matter. So I guess I use DPMI just like real mode, but only
    when I have too much data to fit in real mode RAM. DPMI, BTW, is
    slower than real mode (although you probably won't notice without a
    profiler :).


--- WM v3.11/93-0830
 * Origin: D.W.'s Toolbox * 404-471-6636 * Jonesboro Georgia  (1:133/1719.0)

(351 min left), (H)elp, End of Message Command? . Date: 01-11-95 (16:06)              Number: 23023 of 23747 (Refer# NONE)
  To: CHRIS MALO
From: BRAD RYLL
Subj: Re: MOD/S3M Player
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

CM> Does anyone have an example for a MOD or S3M Module player .. Kinda Trying
CM> to do this but is eginning to be rough.. Just wanted to include such
CM> routines in a small dir lister i made so i could do a pick list of Modules
CM> and play them.. Just Been having too much trouble with MOD/S3M routines.

Here ya go..

--- Cut
PROGRAM tpmod;
USES crt;

{$M $4000,0,0}               {16k stack, no heap - adjust as needed }
{$L MOD-OBJ.OBJ}           { Link in Object file }
{$F+}                   { force calls to be 'far'}
procedure modvolume(v1,v2,v3,v4:integer); external ; {Can do while playing}
procedure moddevice(var device:integer); external ;
(351 min left), (H)elp, More? procedure modsetup(var status:integer;device,mixspeed,pro,loop:integer;var
str:string); external ;
procedure modstop; external ;
procedure modinit; external;
{$F-}

var
 dev,mix,stat,pro,loop : integer;
 md : string;
 ch: char;

begin
        modinit;
    moddevice ( dev ); { Returns device number in DEV or 255 if 'no sound' }
        if (dev =255) then halt(1);         { Exit - no sound }
        if (dev = 0 ) then
(351 min left), (H)elp, More?            begin
           writeln;
           writeln('* The PC Speaker is not very good at playing modules');
           writeln('* Why not build a simple resistor D/A converter as');
           writeln('* detailed in HARDWARE.DOC - its really great quality');
           writeln('* and only costs a couple of pounds/dollars');
           writeln;
           end;
         write('Enter module filename             : ');
         readln(md);
        mix := 10000;   {use 10000 normally }
        pro := 0; {Leave at 0}
        loop :=4; {4 means mod will play forever}
        modvolume (255,255,255,255);    { Full volume }
    modsetup ( stat, dev, mix, pro, loop, md );
         case stat of
(351 min left), (H)elp, More?            1: writeln('Not a mod');
           2: writeln('Already playing');
           4: writeln('Out of memory');
         else
           begin
              writeln('Your program does something here! Press a key');
              ch := readkey;
              modstop;
           end;
        end;
end.

--- Cut Here

-Brad

(351 min left), (H)elp, More?  * Origin: Digital Underground  Yardley, PA  215.321.9157 (1:273/206)

(351 min left), (H)elp, End of Message Command? . Date: 01-11-95 (13:54)              Number: 22929 of 23747 (Refer# NONE)
  To: IAN LIN
From: OLAF BARTELT
Subj: Re: > 640k heap
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

Hello Ian!

IL> Oh, OK. I guess I can't do it without that code, though. ;) Oh well.
too bad :)

c'ya,
Olaf
--- Yuppie! v2.11
 * Origin: Home of NEBULA-Software... (2:240/5520.2)

(351 min left), (H)elp, End of Message Command? Date: 01-08-95 (10:07)              Number: 22911 of 23747 (Refer# NONE)
  To: MIKE COPELAND
From: STEVE ROGERS
Subj: Pointers?
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

MC>Heap (pointer-referenced) data are numerous: (1) individual data
  >pointers; (2) linked lists (single or double); (3) pointer arrays
  >(arrays of pointers).

    and (4) array pointers (pointers to arrays)

MC>   Pointer arrays are very useful for applications where a maximum
  >amount of data can be expressed, and normally all of available Heap
  >memory can be expressed for P/As, whether it's actually used is
  >application and execution/data dependent.  In TP/BP, it's possible to
  >P/As of up to 16,384 items, or even P/As of other 16K P/As - there
  >really is no limit other than available Heap limits.

    I have trouble if I go beyond 16382, do you?


(351 min left), (H)elp, More? --- WM v3.11/93-0830
 * Origin: D.W.'s Toolbox * 404-471-6636 * Jonesboro Georgia  (1:133/1719.0)

(351 min left), (H)elp, End of Message Command? Date: 01-08-95 (09:59)              Number: 22910 of 23747 (Refer# NONE)
  To: MIKE COPELAND
From: STEVE ROGERS
Subj: Out, out, damn nit!  :)
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

  >  for I := 1 to EndOfArray do
  >    YOUTHGROUP[I] := Nil;  { initialize P/A }

                        or

    fillchar(YOUTHGROUP,sizeof(YOUTHGROUP),0);

             (if you're in a hurry :)

  >  J := 0;  { # of records stored }
  >  while not EOF(F) do
  >    begin
  >      read (F,WORK); Inc (J);
  >      New (YOUTHGROUP[J]);  { allocate Heap space for new record }
  >      YOUTHGROUP[J]^ := WORK
  >    end;
(351 min left), (H)elp, More?
   You're not gaining anything with the temp var. I'd just do

   j:= 0;
   while not eof(f) do begin
     inc(j);
     new(youthgroup[j]);
     read(f,youthgroup[j]^);
   end;


--- WM v3.11/93-0830
 * Origin: D.W.'s Toolbox * 404-471-6636 * Jonesboro Georgia  (1:133/1719.0)

(351 min left), (H)elp, End of Message Command? Date: 01-09-95 (19:57)              Number: 22900 of 23747 (Refer# NONE)
  To: DREW PRESTON
From: JOHN BALDWIN
Subj: Pascal Overlay Unit
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 On 01-05-95 DREW PRESTON wrote to JOHN BALDWIN...

 DP> *** Quoting John Baldwin to Drew Preston dated 01-01-95 ***
 DP> >  On 12-28-94 DREW PRESTON wrote to RYAN THOMPSON...
 DP> >
 DP> >  DP> Hi, Ryan. I have 2mb of ram but Turbo Pascal 7.0 limits the
 DP> max.
 DP> > heap
 DP> >  DP> space to
 DP> >  DP> 655 Kb. I checked throughout my program for bad $M directives
 DP> but
 DP> >  DP> didn't find
 DP> >  DP> any. I even checked all my units that I created. I really
 DP> > appreciate
 DP> >  DP> the
 DP> >  DP> assisance that you have given me. Thanks alot.
(351 min left), (H)elp, More?  DP> >  DP>
 DP> >  DP> See ya
 DP> >  DP> Drew
 DP> >
 DP> > It's not 655kb.  It's 655360 bytes which is 640 kb (655360/1024).
 DP> > That's the
 DP> > maximum conventional memory on an IBM-compatible.  TP 7 can not
 DP> create
 DP> > programs in Protected Mode, so you can only use the 640 kb for your

 DP> > programs.
 DP> > The other 1 Meg on your Computer is extended memory, you can not
 DP> access
 DP> > it from
 DP> > TP w/o a lot of trouble.  Anyway, in case you were wandering, the
 DP> > missing
(351 min left), (H)elp, More?  DP> > 384kb from the first Meg of your memory is used to store Video
 DP> Memory
 DP> > and ROM.
 DP> > Hope this helps.
 DP>
 DP> Hi, John. Thanks for the information on memory sizes in TP7 and where
 DP> the
 DP> extra memory is in the first meg of my memory. If I don't have enough
 DP> heap to
 DP> allocate my pointers, where should I allocate them and how? Are arrays
 DP> allocated on the heap as well? Could you help me with this?
 DP>
 DP> See ya,
 DP> Drew

I can't help you get any extra memory.  The two things you can do are 1) get
(351 min left), (H)elp, More? BP 7, which can compile for Protected Mode, or 2) use a swap file on disk.
Arrays are allocated in the data segment, not the heap.  Only pointers are
allocated on the heap.  Hope this helps.

John Baldwin


---
 * OFFLINE 1.56 * Politics:  Poly=many, tics=Blood sucking parasites.

--- Olms 2.01 [PCTDG4AB]
 * Origin: The Boot Factory BBS - 804-262-9289 (1:264/19)

(351 min left), (H)elp, End of Message Command? . Date: 01-09-95 (07:32)              Number: 22795 of 23747 (Refer# NONE)
  To: JOHN BALDWIN
From: DAVID MUIR
Subj: Copying
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

 -=> Quoting John Baldwin to David Muir <=-

 JB>
 JB> I assume you are using a pointer, in that case, all of these should be
 JB> changed  to heap.  When you use 'new' or 'getmem', you get memory from
 JB> the heap, not  the stack.  If this pointer was declared in a procedure,
 JB> all that would go onto  the stack would be 4 bytes that hold the
 JB> address of what's being pointed to.  Of course, if you are declaring
 JB> this as an array and you use this in a proc,  then the mem would be
 JB> allocated on the stack.  However, this greatly increases  the risk of
 JB> running out of room on the stack and should be avoided most of the
 JB> time.

     Fact is I rarely use pointers, And I've never need my "copy" to be that
fast as it rarely ever copies files in excess of about 5k. I'm sure I would
reconsider if I needed a faster copy or to copy larger files. However
(351 min left), (H)elp, More? everything I've needed it for to date has fit comfotably in the stack,
although granted in my example, the heap would have been a better destination.
But you still couldn't use 65536, so the general idea still holds. Although
it's much better expressed in my post earlier this morning in regards to the
"fastest copy for the meduium".
     thanks...
Dave...


--- GEcho 1.11+
 * Origin: Forbidden Knights Systems * (905)820-7273 * Dual * (1:259/423.0)

(351 min left), (H)elp, End of Message Command? Date: 01-08-95 (20:46)              Number: 22789 of 23747 (Refer# NONE)
  To: MIKE COPELAND
From: DAVID MUIR
Subj: Fastest copy for the medi
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

{
 -=> Quoting Mike Copeland to David Muir <=-

 MC> That's really important, for what you've tested and shown.
 MC> However, your specific values don't apply to everyone, as smaller HDs
 MC> have smaller sector sizes (4096, 2048, etc.).  In order for your thesis
 MC> to work best, the code/logic should also determine the HD sector size,
 MC> before allocating buffers and trying to maximize performance to this
 MC> degree.  That gets down into some pretty low-level code...

     It wouldn't be "that" tough really (if you wanted to do it). You simply
make the buffer as large as the optimum size for the smallest cluster size
which is 64512 (1024*63). Then do your blockread/blockwrites based on the
optimal number for the current cluster size. It is, after all, the size of the
block to read/write which is adversely affecting the speed, and not the size
of the buffer itself.
(351 min left), (H)elp, More?      It would look something like this.
}

Uses Dos;

Const
maxarray = 64512;

Var
regs        :registers;
buf         :array[1..maxarray] of char;
fil1,
fil2        :file;
maxread,
numread,
numwritten,
(351 min left), (H)elp, More? clustSize   :word;

begin
   regs.cx := 0;                        {set for error-checking}
   regs.ax := $3600;                    {get free space}
   regs.dx := 0;                        {0=current, 1=a:, 2=b:, etc.}
   msDos (regs);
   clustsize := regs.ax * regs.cx;      {cluster size}
   maxread := maxarray - (maxarray mod clustsize);
             {the largest number of bytes ("char"s) evenly divisible
              by the cluster size that will fit in our array}
   assign(fil1,paramstr(1));
   assign(fil2,paramstr(2));
   reset(fil1,1);
   rewrite(fil2,1);
   repeat
(351 min left), (H)elp, More?       blockread(fil1,buf,maxread,numread);
      blockwrite(fil2,buf,numread,numwritten);
      until ((eof(fil1)) or (numwritten=0));
   close(fil1);
   close(fil2);
   end.

Error checking not included!!

     You may wish to redefine "regs.dx" above if the copy drive is other than
current, but you will likely find this gives you the fastest "copy" regardless
of the cluster size of the medium. With the noteable exception that if you
had a medium with 512 byte clusters, the above optimal number "could" be
increased by 512 if the variables were otherwise defined. (Placing the buffer
in the heap for instance.) Not that any drive with a 512 byte cluster is
really worth the trouble <G> but if you were going to put "buf" in the heap
(351 min left), (H)elp, More? then you should consider using maxarray = 65024 (127*512) instead of 64512.

Dave...

--- GEcho 1.11+
 * Origin: Forbidden Knights Systems * (905)820-7273 * Dual * (1:259/423.0)

(351 min left), (H)elp, End of Message Command? Date: 01-06-95 (02:22)              Number: 22783 of 23747 (Refer# NONE)
  To: NICK MANISCALCO
From: ARNON AXELROD
Subj: linked lists
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

Hi Nick!

NM>hey, i am having trouble on finding info on linked lists.
how,
NM>when,
NM>and why do you use them.

The reason to use linked lists is to use as much memory as needed
and not more. when you define variables in a procedure or in the
main program (with VAR), they are allocated in the stack, and
they are disposed automaticly as the procedure/program ends. to
use dynamic memory allocation (in the heap), you use pointers. a
pointer is a variable that you define in the stack and that
variable is used to store an adress of another variable that is
in the heap. when you declare a pointer, you should define what
type it points to. for example:
(350 min left), (H)elp, More?
var p:^integer;

in this example p is a pointer to integer.
  now you have to allocate memory to store the integer that p is
points to. u do it with the New keyword as follow:

new(p);

now an integer variable is allocated in the heap, and p stores
the address of this variable. you can now use the integer
variable by using the carret sign (^). for example:

p^:=5;

when you allocates memory with New, u should free it in the end
(350 min left), (H)elp, More? of the program (or sooner, if you don't need it any more) with
the Dispose keyword:

dispose(p);

if you want a pointer to point to nothing write this:

p:=NIL;


And now, to the main subject: linked lists:
to make a linked list u define a record like this:

type
      link_item=record
        next: ^link_item;
(350 min left), (H)elp, More?         prev: ^link_item;

        var1: integer;   {you can put any variables instead }
        var2: string[5]; {of var1, var2, var3}
        var3: byte;
      end;

var
     item:^link_item;

begin
   new(item);
   item^.prev=Nil;
   new(item^.next);
   ...
   {to move to the next item:}
(350 min left), (H)elp, More?    if item^.next<>NIL then item:=item^.next;
   ...
   {to move to the prev item:}
   if item^.prev<>NIL then item:=item^.prev;
   ...
   {to insert a new item (new_item:^link_item) between 2 items:}
   new_item^.next=item^.next;
   item^.next=new_item;
   new_item^.prev=new_item^.next^.prev;
   new_item^.next^.prev:=new_item;
   ...

   repeat
      item:=item^.prev;
   until item^.prev=Nil;

(350 min left), (H)elp, More?    repeat
item:=item^.next;
dispose(item^.prev);
   until item^.next=Nil;
   dispose(item);
end.

Hope that I helped!




 /\
/-/\rnon
 /--\xelrod
        :-)
(350 min left), (H)elp, More?  * Wave Rider 1.0 [NR] *
... UNREGISTERED EVALUATION COPY
--- Blue Wave/RA
 * Origin: Hitch Hiker's BBS, Home of MenuWiz and QuickEd (2:405/0)

(350 min left), (H)elp, End of Message Command? Date: 01-06-95 (11:56)              Number: 22706 of 23747 (Refer# NONE)
  To: DAVID MUIR
From: STEVE ROGERS
Subj: Copying
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

DM>P.S.
  >     If it's possible to do this without the "stack" limitation, you'll have
  >to talk to someone a little better than myself at playing with memory.
  >Although I imagine that any speed improvement over this would be minimal.

  Sure, just allocate your buffer on the heap. This gets rid of the
  stack problem, but the 64k limit still holds. BTW, your sector size
  idea makes good sense. I though it migh make sense to add code to find
  the right sector size, but 8192 should work well for all smaller ones,
  too, as long as they're powers of 2, huh?

  procedure fcopy(source,dest : string);
  const
    MAX=8192*7;
  var
    buf : pointer;
(350 min left), (H)elp, More?     f1,f2 : file;
    nread : word;

  begin
    getmem(buf,MAX);
    assign(f1,source);
    reset(f1,1);
    assign(f2,dest);
    rewrite(f2,1);

    repeat
      blockread(f1,buf^,MAX,nread);
      blockwrite(f2,buf^,nread);
    until (nread<MAX);

    close(f1);
(350 min left), (H)elp, More?     close(f2);
    freemem(buf,MAX);
  end;


--- WM v3.11/93-0830
 * Origin: D.W.'s Toolbox * 404-471-6636 * Jonesboro Georgia  (1:133/1719.0)

(350 min left), (H)elp, End of Message Command? Date: 01-06-95 (11:48)              Number: 22703 of 23747 (Refer# NONE)
  To: RONEN HOCH
From: STEVE ROGERS
Subj: Big Lists
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

RH>i'm codin' a file viewer now...
RH>welp, i made an array with 200 strings in it, and i think that's the biggest
  >i can get. now, i know i should use Pointers and stuff like that, but i dunn
  >how exactly, so, if any1 can help, it'll be gr8.

  Well, like kewl, dewd! It's like, ya know, you use, like, pointers
  instead of, like, vars, that kinda thang. You could even, like, read
  the manyul 'bout, like, pointers, ya know, and then, like, ask an
  intelligent, like, question, ya know? Then folks could, like, respond
  with, like, helpful suggestyuns, ya know?

  Pointers are very powerful and useful items (I consider them
  indispensible). Using them correctly requires following a few basic
  rules which are best introduced by the manuals. Get your feet wet there
  and ask specific questions here. You'll get all the help you can
  stand...
(350 min left), (H)elp, More?
  BTW, a single array of pointers can access up to 16380 strings on the
  heap. The real limit depends on the sizes of the strings themselves.
  You can also use linked lists and be limited only by your installed
  RAM (I find this slower and a bit more work, but useful in some apps).

  l8tr, g8tr :)


--- WM v3.11/93-0830
 * Origin: D.W.'s Toolbox * 404-471-6636 * Jonesboro Georgia  (1:133/1719.0)

(350 min left), (H)elp, End of Message Command? Date: 01-08-95 (21:43)              Number: 22645 of 23747 (Refer# NONE)
  To: MAARTEN SCHROEDERS
From: MATT RICHARDS
Subj: Scrolling and Graphics
Read: NO                            Status: PUBLIC MESSAGE (Echo)
Conf: PASCAL        (1639)       Read Type: TEXT SCAN (-)

MS> Hello Matt, God has send me to write you a message ....
MS>
MS> This crap was written by Matt Richards, meant for All:
MS>
MS> > I am working on an E-Mag, but I'm still a little new to programming
MS> > graphics in Turbo Pascal. What I need is a small piece of source that
MS> > will show me how to open a file, find a certain place in the text, and
MS> > scroll that text whenevr the user presses the up or down key. I have
MS> > source for the windows and telling if they pressed an up or down key,
MS> but
MS> > I don't understand how I can open a file, pick a spot, and scroll. Thank
MS> > you for ANY help you can offer.
MS>
MS> If the textfile isn't too large, you could load it into an array....
MS> (using pointers or so...).... i dunno what kind of text files you want to
MS> write, though....
(350 min left), (H)elp, More? MS>
MS> TTYL,
MS>
MS> Maarten
MS>
MS> --- GEcho 1.00
MS>  * Origin: And He said to the people: I want Mail! (2:500/275.8)
Actually the text file is 67k so far. I have found some source that is perfect
for it. But I have one problem that you may be able to help me with. When I
use the exec command, change the heap size, and swapvectors I end up not
having enough memory. I think I can find some source on this, but I'd like an
explanation of what the best way to exec a program from my E-Mag is. It works,
just not if I run it over and over from the GUI.

Since I've started this venture, I've learned a *LOT* of TP. In fact I'm
beginning to become an efficient programmer :). You'll be able to see some of
(350 min left), (H)elp, More?  my work on the Internet in a while....when it comes out, I'll give everyone
the site name and directory for it.

The piece of code that I'm working on now is an application for a local
computer art contest...it'll use some of the scrolling techniques I've found
and my toolkit. Pretty well-witten code though. Hope somebody will check out
my program when it's finished  <G>

- Pedit Ver 2.5

--- ProBoard v2.01 [Reg]
 * Origin: The Programmers' Palace  ZyXEL 19.2  (713) 242-4708 (1:106/4708)

(350 min left), (H)elp, End of Message Command? n
