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 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 (nreadi'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 - 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