/* C -language version of test program to determine whether CPU board
    is capable of shutting off NEC floppy controller chip by hardware
    or whether it needs an "in 03" to do it.

Synopsis of procedure:
    Do a regular floppy read to set up DMA address
    Look at the DMA vector to find DMAFdone routine
    Search DMAFdone to find "in 03", and NOP it out
    Do another floppy read -- if it hangs, the
	  board is one of the old kind.

Compilation:
    The Aztec CII (Manx) compiler was used to generate this program, by a
    sequence like:
			cii modtest.c
			as modtest.asm
			ln modtest.o libc.lib

    However the program isn't too fancy and will probably compile fine under
    the BDS or various other compilers.


Revision history:

    1.1  05/04/83  Check assignment on A: to make sure it's a floppy
		    before doing any of the rest ot it.
		   Don't allow use on Net Master.
		   (response to SCR #0021)		-- DSB
 */

#define version  1
#define revision 1

#define IN	0xDB
#define NOP	0x00
#define PUSHPSW 0xF5

#define SDtype	0x00
#define DDtype	0x20
#define MINItype 0xA0

#define modeplatz 0x004E
#define usernum   0x0047

main()
{
    char a,*DMAFdone;

    chkuser();		/* can't run this on the master   */

    logmsg();
    waitkey();		     /* give chance to abort */

    chkdrive(); 	/* make sure drive A: is a floppy */

/*  plugretry();	    disable auto retries in BIOS */
    doread();		 /* do a floppy read */
    
    warning();
    waitkey();		 /* give chance to abort */

    DMAFdone = findDMA();   /* grab the DMA vector */
    plugin03(DMAFdone);    /* (exit if not found) */
    a = doread();

    fixin03(DMAFdone);	   /* restore DMA stuff  */
/*  fixretry(); 	      restore BIOS retry */
 
    if (a)
	printf("\nError code %d -- this is an old revision board!",a);
    else
	printf("\n\nOK- this is a new-type board.\n");
    exit();
}

chkuser()
{
    char *unum = usernum;
    if (*unum == 0)
    {
	printf("\nThis program can't be run on the HiNet Master.");
	bye();
    }
}

chkdrive()
{
    char *devtype;	    /* call cpmMAP for ptr to unit no, */

    bios(9,0);		    /* (having selected disk A: for sure) */
    devtype = (bioshl(33)-1); /* decrement it for ptr to dev type */
    if ((*devtype != SDtype) && (*devtype != DDtype) && (*devtype != MINItype))
    {	    
	printf("\n\nDrive A: is not assigned to a floppy!");
	bye();
    }
}

bye()
{
    printf("\ngoodbye\n");
    exit();
}

char *findDMA()
{
    unsigned *wbootaddr;	/* 1 is a pointer to wboot */
    unsigned *DMAvect;		/* DMAvect is a pointer to DMAFdone */
    char *DMAFdone;		/* DMAFdone is a ptr to its instructions */
    char *wboot;		/* wboot is a ptr to the BIOS jump table */


    wbootaddr = 1;
    wboot = *wbootaddr;
    DMAvect = wboot + 0x55;  /* point at DMAFdone!	  */
    DMAFdone = *DMAvect;

    if ((*DMAFdone != PUSHPSW) || (*(DMAFdone+1) != IN) || (*(DMAFdone+2) !=3))
    {
	printf("\n%x %x %x",*DMAFdone,*(DMAFdone+1),*(DMAFdone+2));
	printf("\nCannot find DMAFdone");
	printf("\n(Make sure drive A: is a floppy)");
	bye();
    }

    return(DMAFdone);
}

plugin03(vect)
char *vect;
{
    vect++;
    if (*vect == IN)
	*vect = NOP;

    vect++;
    if (*vect == 03)
	*vect = NOP;
} /* plugin03 -- overwrite w/ NOPs */

fixin03(vect)
char *vect;
{
    *(vect+1) = IN;
    *(vect+2) = 03;
} /* fixin03 -- restore old code */

doread()
{
	char filbuf[128];

	bios(9,0);	/* select disk A:  */
	bios(10,0);	/* set track 0	 */
	bios(11,1);	/* set sector 1  */
	bios(12,filbuf);/* set DMA address */
	return(bios(13,0));	/* do the read!    */
} /* doread */

logmsg()
{
    printf("\n\n");
    printf("MODTEST ver. %d.%d\n",version,revision);
    printf("\nThis program test the floppy disk controller on the CPU board.");
    printf("\nTo do the test, you must have drive A: assigned to a floppy.");
    printf("\nThis will automatically be true if you have booted from a");
    printf("\nfloppy, otherwise you will need to run ASSIGN (for example,");
    printf("\nASSIGN A D0 to assign A: to a double-density floppy.)  The");
    printf("\nassignment must be correct before this program will run.");
    printf("\n\nHit control-C to abort now, anything else to continue:");
}
warning()
{
    printf("\n\n");
    printf("\nThe program will now do a modified floppy read function to ");
    printf("\ndetermine the revision of the CPU board.  If the CPU board ");
    printf("\nis of the new type, this read will be successful and this");
    printf("\nprogram will print an 'ok' message and return to CP/M.  If ");
    printf("\nthe CPU board of the older type, the floppy controller will");
    printf("\nhang and you may have to do a cold-boot to recover.");
    printf("\n\nHit control-C to abort now, anything else to continue:");
}

plugretry()	  /* set retry bit to 0 */
{
    char *mode;
    char curmode;

    mode = modeplatz;
    curmode = *mode;
    *mode = (curmode & 0xFE);
}

fixretry()	  /* set retry bit to 1 */
{
    char *mode;
    char curmode;

    mode = modeplatz;
    curmode = *mode;
    *mode = (curmode | 0x01);
}

waitkey()	  /* get a key, abort if ^C */
{
    char a;
    if ((a=bios(3)) == 3)
	bye();
    return(a);
}


1);
}

waitkey()	  /* get a key, abort if ^C */
{
    char a;
    if ((a=bios(3)) == 3)
	bye();
   