[comp.sys.amiga.tech] dos_stuff

rogers@iris.ucdavis.edu (Brewski Rogers) (10/10/89)

Hi, I am working on a videogame that needs to load lots of data (~120-150k)
periodically. (Every time a new map gets loaded.) My question: Is it possible
to get AmigaDOS to approach the speed of simply using the trackdisk device?

The 120K getting loaded usually consists of about 15 files (~8K each.)
Would using AddBuffers help much? Are there any other things to try that
might help?

I assume that writing the files out to a fresh disk in the order I plan
to read them should put them as close together as possible. Is this true?

I *REALLY* want to keep the game dos-compatible (Easier, hard-drive installable
etc.) but there is a maximum to how long loading a new map should take...

Any help on this would be greatly appreciated!

------------------------------------------------------          Quantum _\/_
2727 Eel                   Bruce (6502 RULES!) Rogers        |\  Duck  ( 0 0)
Davis, Ca 95616            Quantum Duck Software,           |\ \______/ / \\\
916-756-2684               rogers@iris.ucdavis.edu         |\ <  <     |   \/
"It's better to be the real thing than the right thing."     \________/  Quark!

usenet@cps3xx.UUCP (Usenet file owner) (10/10/89)

In article <5546@ucdavis.ucdavis.edu> rogers@iris.ucdavis.edu (Brewski Rogers) writes:
>Hi, I am working on a videogame that needs to load lots of data (~120-150k)
>periodically. (Every time a new map gets loaded.) My question: Is it possible
>to get AmigaDOS to approach the speed of simply using the trackdisk device?

Have you considered async IO?
IF the data you load off of disk needs to be messed with after loading
(like, uncompressing), then async can help a lot.
To do it, get an example program (dospackets.c by somebody, on fish
disks somplace).

Basically it goes like this.
fh=Open("filename",x);
asendpacket(firstpacket)
wait()
do {
	asendpacket(nextpacket)
	processpreviouspacket();
	wait(for packet);
} while (!eof);
 Joe Porkka   porkka@frith.egr.msu.edu

cmcmanis%pepper@Sun.COM (Chuck McManis) (10/11/89)

In article <5546@ucdavis.ucdavis.edu> (Brewski Rogers) writes:
>Hi, I am working on a videogame that needs to load lots of data (~120-150k)
>periodically. (Every time a new map gets loaded.) My question: Is it possible
>to get AmigaDOS to approach the speed of simply using the trackdisk device?

Yes, with some fancy disk optimizing.

>The 120K getting loaded usually consists of about 15 files (~8K each.)
>Would using AddBuffers help much? Are there any other things to try that
>might help?

First, put all of the files in one big file, this will help a bit. Then
layout the file so that the FileHeader block in on some track, and then
all of the data blocks for that file are on that track and the next one
over, then on the third track over, put your final set of blocks and
the FileExtensionBlock, and then the some more data blocks. Basically,
by putting the directory entry on the same track as the data, and the
extension block on the same track as it's data the heads won't seek at
all and you will get essentially full bandwidth. Now the only way to do
this is to format a disk. Use a custom program to lay down the data file,
let AmigaDOS revalidate the disk and then add the rest of your files. 
After laying down this fast access file, do not ever delete/rename/copy
it or your work will be undone. 

Also check for the existence of extra ram that you could copy those files
into. That would speed things up tremendously.

>I assume that writing the files out to a fresh disk in the order I plan
>to read them should put them as close together as possible. Is this true?

Generally this will help but you won't get the max speed out of the system
because A-Dos still bunches the directory entries together (so that the
dir command is faster) and the data blocks, and for your appplication this
is exactly the wrong thing to do.

>I *REALLY* want to keep the game dos-compatible (Easier, hard-drive installable
>etc.) but there is a maximum to how long loading a new map should take...

Copying to the fresh disk will help, custom layouts will help more. 


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.
"If I were driving a Macintosh, I'd have to stop before I could turn the wheel."

mks@cbmvax.UUCP (Michael Sinz - CATS) (10/11/89)

In article <5546@ucdavis.ucdavis.edu> rogers@iris.ucdavis.edu (Brewski Rogers) writes:
>Hi, I am working on a videogame that needs to load lots of data (~120-150k)
>periodically. (Every time a new map gets loaded.) My question: Is it possible
>to get AmigaDOS to approach the speed of simply using the trackdisk device?
>
>The 120K getting loaded usually consists of about 15 files (~8K each.)
>Would using AddBuffers help much? Are there any other things to try that
>might help?

It would help much if it was one file.  Via AmigaDOS reads, the fastest you
will see is about 9000 bytes/second when reading at 4000 bytes per gulp.

>I assume that writing the files out to a fresh disk in the order I plan
>to read them should put them as close together as possible. Is this true?

For the most part.  You may wish to look into a disk optimizer for your
distribution floppy.  It would organize the disk as best it could.  Again,
if the 15 files were all in one, things would be MUCH faster as the overhead
for Open() is rather large.

>I *REALLY* want to keep the game dos-compatible (Easier, hard-drive installable
>etc.) but there is a maximum to how long loading a new map should take...

I'm glad to see that I'm not the only one that feels this way.  (Both that it
should be AmigaDOS safe and should not take long...)  A little playing
with it will help.  (One thing to do, if you can not make the 15 files
a single file would be to open them all first and then read them.  This
will help since the directory information is usually right near the center
of the disk and thus the multiple Open()s would go a bit faster...

>2727 Eel                   Bruce (6502 RULES!) Rogers        |\  Duck  ( 0 0)
>Davis, Ca 95616            Quantum Duck Software,           |\ \______/ / \\\
>916-756-2684               rogers@iris.ucdavis.edu         |\ <  <     |   \/
>"It's better to be the real thing than the right thing."     \________/  Quark!


/----------------------------------------------------------------------\
|      /// Michael Sinz -- CATS/Amiga Software Engineer                |
|     ///  PHONE 215-431-9422  UUCP ( uunet | rutgers ) !cbmvax!mks    |
|    ///                                                               |
|\\\///          When people are free to do as they please,            |
| \XX/                they usually imitate each other.                 |
\----------------------------------------------------------------------/

rogers@iris.ucdavis.edu (Brewski Rogers) (10/11/89)

mail bounced, so:

In article <126083@sun.Eng.Sun.COM> you write:
>First, put all of the files in one big file, this will help a bit. Then
>layout the file so that the FileHeader block in on some track, and then
>all of the data blocks for that file are on that track and the next one
>over, then on the third track over, put your final set of blocks and
>the FileExtensionBlock, and then the some more data blocks. Basically,
>by putting the directory entry on the same track as the data, and the
>extension block on the same track as it's data the heads won't seek at
>all and you will get essentially full bandwidth. Now the only way to do
>this is to format a disk. Use a custom program to lay down the data file,
>let AmigaDOS revalidate the disk and then add the rest of your files. 
>into. That would speed things up tremendously.
>

How would I go about writing out this special file? Is there some
utility that would do it? I haven't had much experience with amigados
other than Read/Write/Seek.  

So putting all my little files into one big file should help too?
the big file would be about 500K in that case, and a typical load
of a map would need to go through just about the whole thing reading
in the 120K of data it wanted.

thanks for the reply, that super-file sounds cool!
	-Bruce


------------------------------------------------------          Quantum _\/_
2727 Eel                   Bruce (6502 RULES!) Rogers        |\  Duck  ( 0 0)
Davis, Ca 95616            Quantum Duck Software,           |\ \______/ / \\\
916-756-2684               rogers@iris.ucdavis.edu         |\ <  <     |   \/
"It's better to be the real thing than the right thing."     \________/  Quark!

peter@sugar.hackercorp.com (Peter da Silva) (10/11/89)

In article <126083@sun.Eng.Sun.COM> cmcmanis@sun.UUCP (Chuck McManis) writes:
> Generally this will help but you won't get the max speed out of the system
> because A-Dos still bunches the directory entries together (so that the
> dir command is faster) and the data blocks, and for your appplication this
> is exactly the wrong thing to do.

Is this a significant problem with only one file to open? That is, once the
file is open, will it continue to slow things down to have the header block
on a different track?
-- 
Peter "Have you hugged your wolf today" da Silva      `-_-'
...texbell!sugar!peter, or peter@sugar.hackercorp.com  'U`
``Back off dude! I'm a topologist!''
	-- Andrew Molitor <amolitor@eagle.wesleyan.edu>

rap@peck.ardent.com (Rob Peck) (10/12/89)

In article <5571@ucdavis.ucdavis.edu> rogers@iris.ucdavis.edu (Brewski Rogers) writes:
>
>So putting all my little files into one big file should help too?
>the big file would be about 500K in that case, and a typical load
>of a map would need to go through just about the whole thing reading
>in the 120K of data it wanted.


Somehow I believe that if you are using this superfile thing and using
seek commands from AmigaDOS or fseek() from a compiler would retrieve the
file quite a bit more quickly than "go through just about the whole thing".
Presumably you maintain an index of  what data it needs at a particular
point, and can therefore build a table of indexes off of which to seek
to get there.  I never found out quite HOW AmigaDOS finds a particular
sector, but I doubt that it would have to read an entire file each time
just to do a seek to a particular position.

Rob Peck

cmcmanis%pepper@Sun.COM (Chuck McManis) (10/14/89)

In article <4339@sugar.hackercorp.com> (Peter da Silva) writes:
>Is this a significant problem with only one file to open? That is, once the
>file is open, will it continue to slow things down to have the header block
>on a different track?

Last time I checked the floppy file system did not cache the header blocks
specially (unlike FFS which does). Thus if the file itself was bigger than
your addbuffers command you could find yourself rereading the directory and
header blocks. 

On the question of exactly what do you have to do to make this happen,
the answer is straightforward, but not exactly simple. 

You have to use the trackdisk.device to circumvent DOS being helpful
in laying the blocks down for you. But the cheap way goes something
like this :

Format a fresh floppy, use Leo's used block display program (Fm) from 
Fish Disk 36 to note which blocks are used and not used. You should be
able to find several tracks that are not used. Then declare an array
in your code that looks something like :

/* Note that the ExtensionBlock and DataBlock structures can be derived
 * from information in the DOS Technical Reference manual (or the Bantam
 * AmigaDOS manual), or from some structures Carolyn posted on BIX.
 * NOTE: Must be in CHIP Ram for floppies. 
 */

	struct HeaderBlock 	*HB;
	struct ExtensionBlock	*EB;
	struct DataBlock	*DB;
	ULONG			*RawData;
	
	...
	/* Number of blocks needed to hold the data */
	DataBlockNum = ((FileDataSize + 487)/488);

	/* Number of extension blocks that will be needed */
	Extension_Blocks = (DataBlockNum - BLOCKS_IN_HEADR)/BLOCKS_IN_EXT;
	
	/* Total blocks (1 == Header block) */
	FileSize = DataBlockNum + Extension_Blocks + 1;

	RawData = (ULONG *)AllocMem(FileSize*512, MEMF_CHIP+MEMF_CLEAR);

	InitializeHB(RawData); /* Fill in the header block */
	for (i=0; i<Extension_Blocks; i++)
		InitializeEB(RawData +			/* Data Pointer */
			((BLOCKS_IN_HEADR+1) * 128) +	/* Skip over headr */
			((BLOCKS_IN_EXT + 1) * 128) * i); /* each extension */

	/* Note the define/function MAPBLOCK which should figure out where
  	 * in the rawdata array the blocks should be placed
	 */
	for (i=0; i<DataBlockNum; i++)
		InitializeDB(MAPBLOCK(RawData, i)); /* and the data blocks. */

	mp = CreatePort(0,0);
	ior.ReplyPort = mp;
	OpenDevice("trackdisk.device", ...);
	ior.io_Command = TD_WRITE;
	ior.io_Length = FileSize*512;
	ior.io_Data = RawData;
	ior.io_Offset = Sector_0_of_Track_nn;
	DoIO(ior);


Now this is only a rough sketch and you should really do error checking and
for a general tool you should be able to deal with low chip memory situations
such that you might only be able to write one sector at a time. 

After writing the track, you need to read in the rootblock, add an entry in
it's hash table for your file. Then set the Bitmap invalid flag and exit.
now do either a DiskChange or pop the disk out and re-insert it. To update
the bitmap. Now when A-DOS reads your file it will be as efficient as 
possible because the heads will always be over the track they need to be
on to read the data.


--Chuck McManis
uucp: {anywhere}!sun!cmcmanis   BIX: cmcmanis  ARPAnet: cmcmanis@sun.com
These opinions are my own and no one elses, but you knew that didn't you.
"If I were driving a Macintosh, I'd have to stop before I could turn the wheel."