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
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