Re: [cc65] dio density detection

From: Christian Groessler <chris1groessler.org>
Date: 2005-02-18 12:26:02
Hi,

On Wed, 16 Feb 2005, Shawn Jefferson wrote:
> 
> --- Christian Groessler <chris@groessler.org> wrote: 
> 
> > Does the buffer need to be set to $2EA? I know of  
> > http://www2.asw.cz/~kubecj/asio.htm as SIO reference
> > and
> > there is nothing mentioned about a specific buffer
> > address
> > for the $53 function.
> >
> > I get the same results regardless whether I set the
> > buffer
> > to $2EA or something else.
> 
> I don't think it matters, but the buffer already
> exists for this information at $2EA, so you wouldn't
> have to take up 4 bytes of memory elsewhere.

Yes, makes sense. I was confused since it didn't work for me.

> 
> > But it doesn't seem to work for me on a real machine
> > :-(
>
> I found the same thing.  Putting DCB.status ($303) =
> 0x40; into the code fixes it.  From what I understand
> that sets the Read direction.  The emuluator doesn't

Oops, I should have known this :-/
I knew this once since I'm setting the status field in siocall.s.


> seem to be paying attention to it, but the real drive
> does (as does APE.)  I read something somewhere that
> the XF551 might give weird results... (?)

Do you have some pointers about this?

What I found out:

It seems that the xf551 needs to have the disk been accessed before
the $53 request gets issued in order for the return values of be correct.

If the (newly inserted) disk hasn't beed accessed yet, the drive
returns the old status from the last disk access. It doesn't access
the disk for the $53 command.


I once read somewhere that the first three sectors of a disk are
always 128 bytes. Now if I read the first sector of a disk before
doing the $53 request, I get a 128 bytes sector status even for a
DD disk.

Therefore I changed my test program to read sector #4 (with
128 bytes read length which gives an error on a DD disk but
this doesn't matter here) before issueing the $53 command.

Unless someone has a better idea, I will implement this density
detection in dio_open.

I don't know how to handle the first 3 sectors of a DD disk though.
Probably the dio_read and dio_write functions should automatically
DTRT (use 128 bytes length), but then an unillumined user might be
unaware that he has read/written only half of his buffer.

Also there is the question how other DD capable hardware handles the
first 3 sectors. Maybe a xf551 detection needs to be implemented - ugh
:-(

regards,
chris


-----------------------------
/* $Id: density.c,v 1.4 2005/02/17 21:58:40 chris Exp $
 *
 * detect disk density / test
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <atari.h>

static void (*sio)(void) = (void (*)(void))0xe459;

unsigned char *DVSTAT = (unsigned char *)0x2ea;

char buf[5];
char dstr[][4] = {
    "D1:","D2:","D3:","D4:"
};

char sectbuf[128];

int main(int argc,char **argv)
{
    char *dnumstr;
    int drvnum;

    if (argc > 1) {
        dnumstr = *(argv+1);
        drvnum = atoi(dnumstr);
        if (! drvnum) ++drvnum;
    }
    else {
      loop:
        printf("\nEnter drive# (0-exit,1-D1,2-D2,...): ");
        dnumstr = fgets(buf, 5, stdin);
        printf("\n");
        drvnum = atoi(dnumstr);
    }
    if (! drvnum) return(0);
    if (drvnum > 4) drvnum = 1;

    printf("Using %s...\n", dstr[drvnum - 1]);

    /* read the 4th block of the disk to update the drive's idea of the disk */

    memset(&DCB, 0, sizeof(DCB));
    DCB.command = 0x52;       /* read sector */
    DCB.device = 0x31;        /* disk drive */
    DCB.unit = drvnum;        /* sub unit */
    DCB.timeout = 15;         /* from DOS source */
    DCB.status = 0x40;        /* direction: read */
    DCB.buffer = sectbuf;
    DCB.xfersize = 128;
    DCB.aux1 = 4;
    /*DCB.aux2 = 0;*/

    sio();
    if (DCB.status != 1)
        printf("SIO returned %d (read sect)\n", DCB.status);

    memset(&DCB, 0, sizeof(DCB));
    *DVSTAT = 0xaa;  /* does the buffer get changed? */

    DCB.command = 0x53;       /* status */
    DCB.device = 0x31;        /* disk drive */
    DCB.unit = drvnum;        /* sub unit */
    DCB.timeout = 15;         /* from DOS source */
    DCB.status = 0x40;        /* direction: read */
    DCB.buffer = DVSTAT;
    DCB.xfersize = 4;

    sio();
    printf("SIO returned %d\n", DCB.status);

    if (DCB.status == 1)
        printf("device status: %u ($%02X)\n", *DVSTAT, *DVSTAT);

    if (argc <= 1) goto loop;
    return(0);
}
/* Local Variables: */
/* c-file-style: "cpg" */
/* c-basic-offset: 4 */
/* End: */
-----------------------------

----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Fri Feb 18 12:25:48 2005

This archive was generated by hypermail 2.1.8 : 2005-02-18 12:25:59 CET