80-Bus News

  

Spring 1985, Volume 4, Issue 1

Page 8 of 31

SUBMIT file, to PIP the indexes back and forth, but I don’t like SUBMIT files for uneducated use, and anyway, they’re messy. No the answer is to make dBASE do the job as part of the program.

Now dBASE can copy data files around with impunity, and it can create new files all over the place, but can it copy index files from one drive to another, no way! The same applies to .CMD, .FMT and .MEM files as well, but I can’t see why anyone would want to copy these.

The simplest answer is a ‘mini-PIP’ program which will transfer the indexes to the RAM disk and back again. A very simple little program was written to open an input file, open an output file and copy it sector by sector. Dead simple you might think! Let’s have a look at the snags which could befall the unwary.

We need two file control block for a start, and because the program is to be used generally, we need a space to transfer the names of the files to be copied into. No problem there. You can see from the first bit of the progam the ‘to’ drive name, and the ‘from’ drive name and file name space. I put them at the front of the program as that’s easy to find when POKEing around to fill in the names. The POKE location for the names is always three bytes in from the start of the program no matter how I hack the program around and change its length. Note that there is no check to see if you’re trying to write to the same drive. As the program is going to get it’s parameters from the dBASE program, and no user intervention is required, that sort of mistake can’t happen. Can it?

The program starts off by clearing the space behind the ‘from’ name as this is the file control block for the following ‘search for first’. If you forget to clear this fcb, then CP/M does strange things with the ‘search for first’.

The ‘search for first’ is to check for the presence of the named files, if they’re not found, then the program returns home immediately. Here comes the first snag! The ‘search for first’ returns 0ffh if there are no files present, otherwise, it copies the sector of the directory where it found the first entry into the current DMA workspace and returns with A set to the number of the entry in that sector. Checking for 0ffh is dead easy, anything else in A assumes that at least one file was found. Having established the presence of the files, where the heck is the current DMA, as dBASE, sure as eggs is eggs, didn’t leave it at the default DMA of 0080h. We need this address as we have to copy the file name we have found to the file workspace buffer, as we intend to make a list of all the files required before we start the copy process.

A little investigation revealed that different versions of dBASE leave the DMA at different addresses. All around 98XXh, but not consistent. So putting a fixed address into the program is not on. The next thought was that CP/M must know where the DMA address is, but there’s no command to return it. Perhaps it could be found in a CP/M workspace someplace? That way I could cheat and calculate a fixed offset from some known location within CP/M. I looked, it appeared twice, and both in the BIOS. Now the notorious thing about BIOSs is that each version is different, so odds on that the DMA pointers will move around between versions, and anyway, which one of the two pointers to use? No forget that approach. The last resort was the obvious, set the DMA pointer myself. My objection to this was, what would dBASE do? Without disassembling large chunks of it, there was (and still is) no way I could be sure that dBASE would reset the DMA pointer correctly before using one of it’s overlays, or whatever. Or whether in fact this would matter. I took a chance and set the DMA to 0080h. dBASE continued to work, and so far nothing odd appears to have happened. But I’m still unhappy about it.

So before the ‘search for first’, there is a ‘set DMA’ so I know where to retrieve the data.

Unfortunately, having found a file name, you can’t use it immediately to copy the file to the new drive, as the copy process causes the ‘search for first’ — ‘search for next’ to forget where it was, so the file names must be found first and stored in a workspace for copying later. Having found the first entry, the position in the DMA buffer is calculated and the name found copied to the file workspace buffer. The program drops through to the ‘search for next’ and loops until all the names are in the buffer. So I know where the end of the buffer is, I stuck a null on the end of it.

The next bit was a piece of cake. Copy the first name found into the first and second fcb’s, open the files and read a sector from the input file into the DMA and then write the DMA out to the output file. When the file was all copied, close the output file and pick up the next name in the list and do it all again until the name in the list was a null, indicating the end of the list. Simple and very quick.

I didn’t bother to check the validity of the files as Winnie to RAM disk copies are always reliable and anyway what could I do if there was an error? The whole process was quite quick, shovelling about 200K of indexes in about 30 seconds.

From the foregoing, you can see I’m all for the KISS philosophy. KISS, ‘Keep It Simple, Stupid’ on the grounds that if it’s simple it should work Ok, anyway, if it didn’t then it should be a doddle to fix.

Having got the routine working, a thought occurred! Why not make the routine make the backup copy disks as the machine shuts down. That’s about 650K from Winnie to disk. I tried it. It took 45 minutes!!! A very much confused DH sat down to


Page 8 of 31