Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Checking for disk media... Again

0 views
Skip to first unread message

pe...@nospam.demon.co.uk

unread,
Jul 17, 2009, 1:24:12 AM7/17/09
to
In article <_0u7m.613$eS5...@newsfe25.iad>
aa...@hotSPAM.com "Brian Dude" writes:

[second reply after doing some testing]

> Hello, I posted a little while about difficulties in drive access and
> suppressing/overriding default OS error messages (Subject: Checking for
> disk media), and I got some good advice.
> I'm still getting some odd behavior however. I threw together a quick
> program to play with the things I had just learned (using Borland C 4.52):

[snip sample code]

> Running this on two different systems I get different results. When I
> run it through the Windows XP command prompt, and I try to access the
> CD-ROM drive, and there is no media, the handler executes, no flags seem
> to be set, and the program finishes execution. When I try to access the
> DVD-ROM drive, the handler executes and then the program terminates. So
> I never see that last printf() statement.
> When I run this on an actual Windows 95 machine, and I try to access the
> CD-ROM drive with no media, the handler executes, then just before
> program termination, the default OS message appears again:
>
> Not ready reading drive X:
> Abort? Retry? Fail?
>
> Which is exactly the message I'm trying to override with my handler.
> Could someone help explain what's going on? I'm learning a lot of new
> stuff but having trouble sorting it out.
>
> TIA,
> Brian

Hello Brian,

Following on from before, I discovered two problems with this
code:

1. the call to setdisk() seems to cause a problem, and
2. even setting _AX to zero in the handler is pointless, as BC31
(which I used) preserves *all* regs across the handler.

Here's what I came up with, and which works here:

/*
* isdrive.c
* usage: isdrive [a-z]
* compile in small model
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <dos.h>
#include <dir.h>

extern void interrupt handler(void);

void interrupt (*old)(void);
union REGS in,out;

int main(int argc, char *argv[])
{
int r;
int drv = 0;
/* void interrupt handler(void); */

if (argc > 1)
{
drv = toupper(*argv[1]);
if (drv < 'A' || drv > 'Z')
drv = 0; /* current drive */
else
drv -= ('A'- 1);
}
printf("drv = %d\n", drv);

/*Save the original Critical Error handler*/
old=getvect(0x24);
/*Redirect it to my own*/
setvect(0x24,handler);
/*Use service 36h - get free disk space*/
in.h.ah=0x36;
/* 0=default, 1=A, 2=B etc.*/
in.h.dl=drv;
int86(0x21,&in,&out);
/*Restore the previous Critical Error handler.*/
setvect(0x24,old);

r=out.x.ax;

printf("r = %x\n",r);

return 0;
}

;
; int24.asm
; assemble with: tasm /mx int24;
:
_TEXT segment byte public 'CODE'

public _handler

_handler proc far
xor ax, ax
iret
_handler endp

_TEXT ends

end

Link these together:

bcc -ms -wall isdrive.c int24.obj

The resulting isdrive.exe works as expected here...

Hope it helps
Pete
--
"We have not inherited the earth from our ancestors,
we have borrowed it from our descendants."

Brian Dude

unread,
Jul 17, 2009, 8:00:24 PM7/17/09
to
pe...@nospam.demon.co.uk wrote:
> In article <_0u7m.613$eS5...@newsfe25.iad>
> aa...@hotSPAM.com "Brian Dude" writes:
>
> [second reply after doing some testing]
>
[snip]

>
> Hello Brian,
>
> Following on from before, I discovered two problems with this
> code:
>
> 1. the call to setdisk() seems to cause a problem, and
> 2. even setting _AX to zero in the handler is pointless, as BC31
> (which I used) preserves *all* regs across the handler.
>

(Regarding _AX) Yes, I found this out too from experimenting, but I'm
glad to hear your explanation because I just would have assumed I did
something incorrectly.

I'll be glad to try this at my nearest opportunity. (I'll be busy the
next several days.) I've had some problems compiling assembly code
lately. Hopefully it won't be a problem!

Thanks,
Brian

pe...@nospam.demon.co.uk

unread,
Jul 18, 2009, 3:32:56 AM7/18/09
to
In article <tg88m.6295$0z7....@newsfe07.iad>
aa...@hotSPAM.com "Brian Dude" writes:

> pe...@nospam.demon.co.uk wrote:
> > In article <_0u7m.613$eS5...@newsfe25.iad>
> > aa...@hotSPAM.com "Brian Dude" writes:
> >
> > [second reply after doing some testing]
> >
> [snip]
> >
> > Hello Brian,
> >
> > Following on from before, I discovered two problems with this
> > code:
> >
> > 1. the call to setdisk() seems to cause a problem, and
> > 2. even setting _AX to zero in the handler is pointless, as BC31
> > (which I used) preserves *all* regs across the handler.
> >
>
> (Regarding _AX) Yes, I found this out too from experimenting, but I'm
> glad to hear your explanation because I just would have assumed I did
> something incorrectly.

In fairness, preserving the cpu state is what is needed 99.99% of
the time in an interrupt handler -- just not in this case. It
might be possible e.g. via a pragma to change this behaviour, but
I haven't checked that out.

And thinking further about setdisk(), it wasn't the call to it
per se that caused the problem, rather that if the drive was
invalid it would still be invalid even if the program terminated
normally. A prior call to getdisk() to save the existing drive,
and a further call to setdisk() to reset it would probably have
worked (given that the critical error handler worked, of course).
But setting the drive into the DOS drivespace call is simpler!

[snip]

> I'll be glad to try this at my nearest opportunity. (I'll be busy the
> next several days.) I've had some problems compiling assembly code
> lately. Hopefully it won't be a problem!

I'd be surprised if tasm complains about that two line proc!

0 new messages