home *** CD-ROM | disk | FTP | other *** search
- /* fmt.c */
-
- #include "obdefs.h"
- #include "osbind.h"
- #include "mydefs.h"
- #include "part.h"
- #include "hdx.h"
- #include "addr.h"
- #include "error.h"
-
- #define MFM 17 /* sectors per track of MFM */
- #define RLL 26 /* sectors per track of RLL */
-
- extern long ostack;
- extern int typedev;
- extern int typedrv;
- extern char sbuf[];
-
- /*
- * These constants are used in a heuristic that determines
- * if the format parameter information in the boot sector
- * is intact. (See fmtpok()).
- */
- #define MAXCYLS 4096 /* max number of cylinders */
- #define MINCYLS 100 /* minimum number of cylinders */
- #define MAXHEADS 16 /* max number of heads */
- #define MINHEADS 2 /* minimum number of heads */
- #define MAXLZ 16 /* max landing zone value */
- #define MAXRT 2 /* max step-rate code */
-
-
- /*
- * These are the default format parameters;
- * they are for a 20Mb Mutsubuishi drive.
- *
- * @ If we change drives, this might have to be changed.
- *
- */
- HINFO deffmt = {
- 0x264, /* 612 cylinders */
- 4, /* 4 heads */
- 0x264, /* no reduced write-current cylinder */
- 0x264, /* no write precomp cylinder */
- 10, /* landing zone position = 10 */
- 2, /* 2 use buffered seeks */
- 1, /* 2 interleave = 1 */
- 17 /* 17 sectors per track */
- };
-
-
- /*
- * Report format error.
- *
- */
- formaterr(dev)
- int dev;
- {
- char *pdev="X";
-
- if (dev > 7) dev -= 8;
- *pdev = dev + '0';
- (cantform[FMTDEV].ob_spec)->te_ptext = pdev;
- cantform[FMTERROK].ob_state = NORMAL;
- execform(cantform);
- return ERROR;
- }
-
-
- /*
- * Set format parameters in a
- * root sector image.
- * 6-13-88 only set size of hard disk.
- *
- */
-
- sdisksiz(image, hdsiz)
- char *image;
- long hdsiz;
- {
- ((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_siz = hdsiz;
-
- }
-
-
- /*
- * Set format parameters in a
- * root sector image.
- *
- */
- sfmtparm(image, fmtparm)
- char *image;
- HINFO *fmtparm;
- {
- register HINFO *rinfo;
- register long siz;
-
- rinfo = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_info;
- rinfo->hi_cc = fmtparm->hi_cc;
- rinfo->hi_dhc = fmtparm->hi_dhc;
- rinfo->hi_rwcc = fmtparm->hi_rwcc;
- rinfo->hi_wpc = fmtparm->hi_wpc;
- rinfo->hi_lz = fmtparm->hi_lz;
- rinfo->hi_rt = fmtparm->hi_rt;
- rinfo->hi_in = fmtparm->hi_in;
- rinfo->hi_spt = fmtparm->hi_spt;
-
- /* Compute total disk size
- * = <#cyls> * <#heads> * <#sectors / track>
- */
- ((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_siz =
- (long)fmtparm->hi_cc *
- (long)fmtparm->hi_dhc *
- (long)fmtparm->hi_spt;
-
- }
-
-
- /*
- * Determine if format parameters are good;
- * return OK if they appear to be,
- * ERROR if they don't appear to be.
- *
- */
- fmtpok(fmtparm)
- HINFO *fmtparm;
- {
- if (fmtparm->hi_cc > MAXCYLS ||
- fmtparm->hi_cc < MINCYLS ||
- fmtparm->hi_dhc > MAXHEADS ||
- fmtparm->hi_dhc < MINHEADS ||
- fmtparm->hi_lz > MAXLZ ||
- fmtparm->hi_rt > MAXRT)
- return ERROR;
-
- return OK;
- }
-
-
- /*
- * Setup default format parameters in hinfo;
- * (REAL C compilers do this with a structure assignment...)
- *
- */
- fdefault(hinfop)
- HINFO *hinfop;
- {
- hinfop->hi_cc = deffmt.hi_cc;
- hinfop->hi_dhc = deffmt.hi_dhc;
- hinfop->hi_rwcc = deffmt.hi_rwcc;
- hinfop->hi_wpc = deffmt.hi_wpc;
- hinfop->hi_lz = deffmt.hi_lz;
- hinfop->hi_rt = deffmt.hi_rt;
- hinfop->hi_in = deffmt.hi_in;
- hinfop->hi_spt = deffmt.hi_spt;
- }
-
-
- /*
- * Set mode information on drive.
- *
- */
- ms(dev, hinfo)
- int dev;
- HINFO *hinfo;
- {
- int i;
- char *p;
- SETMODE mb;
- extern long mdselect();
-
- /* initialize parameter structure */
- p = (char *)&mb;
- for (i = sizeof(SETMODE); i--;)
- *p++ = 0;
- mb.smd_8 = 0x08;
- mb.smd_1 = 0x01;
- mb.smd_bs[1] = 0x02; /* block size = 512 */
-
- cpw(&mb.smd_cc[0], hinfo->hi_cc);
- mb.smd_dhc = hinfo->hi_dhc;
- cpw(&mb.smd_rwc[0], hinfo->hi_rwcc);
- cpw(&mb.smd_wpc[0], hinfo->hi_wpc);
- mb.smd_lz = hinfo->hi_lz;
- mb.smd_rt = hinfo->hi_rt;
-
- return (int)mdselect(dev, 22, &mb);
- }
-
-
- /*
- * Move `w' to unaligned location.
- *
- */
- cpw(d, w)
- char *d;
- WORD w;
- {
- char *s;
-
- s = (char *)&w;
- d[0] = s[0];
- d[1] = s[1];
- }
-
-
- /*
- * Return format parameters in `hinfo', based on
- * the format parameter name `fpnam'.
- *
- * return 0 on OK,
- * -1 on [CANCEL].
- *
- */
- gfparm(dev, noinfo, modesel, hinfop, fpnam, id)
- int dev;
- int noinfo; /* 1: no information inside the wincap file */
- int *modesel;
- HINFO *hinfop;
- char *fpnam, *id;
- {
- long num;
- char name[128];
- int mask=0x0001;
- int scsidrv, set, ret = OK;
- UWORD cyl;
- BYTE nhead, sptrk;
-
- set = typedev & (mask << dev);
- scsidrv = typedrv & (mask << dev);
- fdefault(hinfop);
- if ((set) || (scsidrv)) {
- *modesel = 0;
- } else if (noinfo) {
- ret = cyhdsp(dev, &cyl, &nhead, &sptrk);
- hinfop->hi_cc = cyl;
- hinfop->hi_dhc = nhead;
- hinfop->hi_rwcc = cyl;
- hinfop->hi_wpc = cyl;
- hinfop->hi_spt = sptrk;
- } else {
-
- strcpy(name, fpnam);
- if (wgetent(fpnam, id) == ERROR) {
- nofmt[NOSCHFOK].ob_state = NORMAL;
- (nofmt[NOSCHFMT].ob_spec)->te_ptext = name;
- execform(nofmt);
- return ERROR;
- }
-
- if (wgetnum("cy", &num) == OK) hinfop->hi_cc = (UWORD)num;
- if (wgetnum("hd", &num) == OK) hinfop->hi_dhc = (BYTE)num;
- if (wgetnum("rw", &num) == OK) hinfop->hi_rwcc = (UWORD)num;
- if (wgetnum("wp", &num) == OK) hinfop->hi_wpc = (UWORD)num;
- if (wgetnum("lz", &num) == OK) hinfop->hi_lz = (BYTE)num;
- if (wgetnum("rt", &num) == OK) hinfop->hi_rt = (BYTE)num;
- if (wgetnum("in", &num) == OK) hinfop->hi_in = (BYTE)num;
- if (wgetnum("sp", &num) == OK) hinfop->hi_spt = (BYTE)num;
- if (wgetnum("md", &num) == OK) *modesel = (UWORD)num;
- }
- return(ret);
- }
-
-
- /*
- * Set mode information on a SYQUEST drive.
- *
- */
-
- sqms(dev, sendata)
- int dev; /* physical device number */
- char sendata[];
- {
- extern long mdselect();
- char buf[32];
-
- inquiry(dev, (WORD)16, buf);
- if (buf[8] == 'Q' & buf[9] == 'U' & buf[10] == 'A' & buf[11] == 'N')
- /* It is a QUANTUM hard disk. So don't need to set the page one. */
- return OK;
- sendata[0] = sendata[2] = 0; /* reserved */
- sendata[3] = 0x08; /* block descriptor length */
- sendata[12] = 0; /* Reserved = 0; Page Code = 0 */
- sendata[13] = 0x02;
- sendata[14] = 0x10; /* set inhst bit in page 00 */
- sendata[15] = 0; /* Device type qualifier */
- return (int)mdselect(dev, 16, sendata);
- }
-
-
-
-
- /*
- * get cylinder, # of head, and sector per track for ST
- */
-
- cyhdsp(dev, cyl, nhead, sptk)
-
- int dev;
- UWORD *cyl;
- BYTE *nhead, *sptk;
-
- {
- char *num;
- BYTE sptrk,numhead;
- int i, ret, totcyl, numtrack;
- extern long get3bytes();
- SETMODE *mb;
- SECTOR size, msiz; /* size of media */
- char buf[512], sendata[32];
- long dmaptr, tmpptr, spcyl;
- char *dmahigh=0xffff8609,
- *dmamid=0xffff860b,
- *dmalow=0xffff860d;
-
- for (i = 0; i < 22; i++)
- sendata[i] = 0;
- ostack = Super(NULL);
- /* get format parameters/ disk size from emdia */
- ret = mdsense(dev, 0, 0, 22, sendata);
- delay();
- Super(ostack);
- if (ret != 0) {
- return ERROR;
- }
- for (i=0; i<22; i++) {
- if (sendata[i])
- break;
- }
- if (i == 22) /* no info return in the buf 'sendata' */
- err(needinfo);
-
- get3bytes(sendata+5); /* it's adaptec's. Interpret as SETMODE structure */
- mb = (SETMODE *)sendata;
- /* get number of cylinders */
- totcyl = mb->smd_cc[0];
- totcyl <<= 8;
- totcyl |= mb->smd_cc[1];
- *cyl = (UWORD)totcyl;
-
- /* get number of heads */
- numhead = mb->smd_dhc;
- *nhead = numhead;
-
- sptrk = (long)MFM;
- msiz = (SECTOR)numhead * (SECTOR)totcyl * sptrk;
-
- for (i = 0; i < 20; i++) {
- if ((ret = rdsects(dev, 1, buf, msiz+i)) == OK) {
-
- /* find out whether data has been transferred, by
- checking if dma pointer has been moved. */
-
- ostack = Super(NULL); /* get into Supervisor mode */
-
- dmaptr = *dmahigh;
- dmaptr &= 0x0000003f;
- dmaptr <<= 16;
- tmpptr = *dmamid;
- tmpptr &= 0x000000ff;
- tmpptr <<= 8;
- dmaptr |= tmpptr;
- tmpptr = *dmalow;
- tmpptr &= 0x000000ff;
- dmaptr |= tmpptr;
-
- delay();
- Super(ostack); /* back to user mode */
-
- if (dmaptr != buf)
- break;
- } else { /* rdsects return an error */
- if (tsterr(ret) == OK) {
- break;
- }
- }
- }
-
- if (ret == MDMCHGD) /* check if error occurred */
- return err(cruptfmt);
-
- /* Determine if media is MFM or RLL */
- if (i < 20) {
- *sptk = RLL;
- } else {
- *sptk = MFM;
- }
- return OK;
- }
-
-
-
-