/* epart.c */ /* * Partition edit and pick for MS-DOS * * 08-Oct-1988 jye. change and add this codes to do the partition * editing and picking for MS-DOS * 18-NOV-1988 jye. change and add codes in the partition editing and * picking for the user interface. */ #include "obdefs.h" #include "gemdefs.h" #include "osbind.h" #include "mydefs.h" #include "part.h" #include "ipart.h" #include "bsl.h" #include "hdxpch.h" #include "addr.h" #include "myerror.h" extern int typedev; extern int typedrv; extern char sbuf[]; extern int npart; /* number of partitions */ extern int ext; /* the index of extended partition */ /* * Global variables these routines communicate with * */ static PART *pinfo; /* -> partition block */ static int totcyl; /* total # of cylinder */ static long sizleft; /* size of unused disk in blocks */ static long extleft; /* size of unused extended partition in blocks */ static int formw, formh; static int lx, ly, sx, sy; static int ok2draw; /* 0: don't draw PARTPNL boxes */ static int pnlflg; /* 1: partition scheme comes from panel */ static int along; /* 1: will not redraw and clean the box */ static int lowlim; /* index of dialog box */ static int first; /* flag for add bad and good sectors only one time */ long disksiz; /* size of disk in blocks */ long sumsiz; /* the sum of bytes of root sectors */ long spcyl; /* sector per cylinder */ long sptrk; /* sector per track */ int yesscan; /* the flag for the func. IBMGPART use */ int tolpart; /* the total of number partitions */ int epty; /* the y-coordinate of the moving bar */ int restept; /* 1: rest the moving bar to initial place */ #define MFM 17 /* sectors per track of MFM */ #define RLL 26 /* sectors per track of RLL */ /* * get ST partition information for ST structure */ stgpart(xdev, bs, rpinfo) int xdev; char *bs; PART **rpinfo; { int i, j, linkst, ret; long sect; register PART *ipart; PART *xpinfo; if ((npart = countpart(xdev)) == ERROR) { return ERROR; } if ((*rpinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0) { err(nomemory); if (rpinfo > 0) Mfree(rpinfo); return ERROR; } xpinfo = *rpinfo; inipart(xpinfo, npart); ipart = &((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_p[0]; for (i = 0; i < NPARTS; i++, ipart++) { xpinfo[i].p_flg = ipart->p_flg; xpinfo[i].p_st = ipart->p_st; xpinfo[i].p_siz = ipart->p_siz; if (ipart->p_flg & P_EXISTS) { if (i == ext) { xpinfo[i].p_id[0] = 'X'; xpinfo[i].p_id[1] ='G'; xpinfo[i].p_id[2] = 'M'; } else if (xpinfo[i].p_siz < MB16) { xpinfo[i].p_id[0] = 'G'; xpinfo[i].p_id[1] ='E'; xpinfo[i].p_id[2] = 'M'; } else { xpinfo[i].p_id[0] = 'B'; xpinfo[i].p_id[1] ='G'; xpinfo[i].p_id[2] = 'M'; } } } if (ext != NO_EXT) { /* there are extended partition */ sect = xpinfo[ext].p_st; do { if ((ret = getroot(xdev, bs, sect)) != 0) { if (tsterr(ret) != OK) err(rootread); return ERROR; } ipart = &((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_p[0]; xpinfo[i].p_flg = ipart->p_flg; xpinfo[i].p_st = sect; xpinfo[i].p_siz = ipart->p_siz + ROOTSECT; if (xpinfo[i].p_siz < MB16) { xpinfo[i].p_id[0] = 'G'; xpinfo[i].p_id[1] ='E'; xpinfo[i].p_id[2] = 'M'; } else { xpinfo[i].p_id[0] = 'B'; xpinfo[i].p_id[1] ='G'; xpinfo[i].p_id[2] = 'M'; } ipart++; i++; sect = ipart->p_st + xpinfo[ext].p_st; } while ((ipart->p_id[0] == 'X') && (ipart->p_id[1] == 'G') && (ipart->p_id[2] == 'M')); /* more partition */ } return OK; } inipart(xpart, npart) PART *xpart; int npart; { int i; for (i = 0; i < npart; i++) { xpart[i].p_siz = 0L; xpart[i].p_flg = 0; xpart[i].p_st = 0L; xpart[i].p_id[0] = 0; xpart[i].p_id[1] = 0; xpart[i].p_id[2] = 0; } } countpart(dev) int dev; { char bs[512]; PART *ipart; int ret, count, i; long sect, start; if ((ret = getroot(dev, bs, (SECTOR)0)) != 0) { if (tsterr(ret) != OK) err(rootread); return ERROR; } ipart = &((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_p[0]; ext = NO_EXT; for (i=0; i < NPARTS; i++, ipart++) { if ((ipart->p_flg & P_EXISTS) && (ipart->p_id[0] == 'X') && (ipart->p_id[1] == 'G') && (ipart->p_id[2] == 'M')) { ext = i; start = ipart->p_st; } } count = 4; if (ext != NO_EXT) { sect = start; do { if ((ret = getroot(dev, bs, sect)) != 0) { if (tsterr(ret) != OK) err(rootread); return ERROR; } ipart = &((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_p[0]; count++; ipart++; sect = ipart->p_st + start; } while ((ipart->p_id[0] == 'X') && (ipart->p_id[1] == 'G') && (ipart->p_id[2] == 'M')); /* more partition */ } return (count); } /* * Force checksum of sector image to a value */ forcesum(image, sum) UWORD *image; UWORD sum; { register int i; register UWORD w; w = 0; /* up limit is half of buffer size - 2 */ for (i = 0; i < ((UWORD)BPS/2 - 1); ++i) w += *image++; *image++ = sum - w; } /* * Put word in memory in 8086 byte-reversed format. * */ iw(wp, w) UWORD *wp; UWORD w; { char *p; p = (char *)wp; p[0] = (w & 0xff); p[1] = ((w >> 8) & 0xff); } /* * Put long word in memory in 8086 word-reversed format. * */ ilong(lp, l) long *lp; long l; { UWORD *p; p = (UWORD *)lp; iw(&p[0],(UWORD)(l & 0xffff)); iw(&p[1],(UWORD)((l >> 16) & 0xffff)); } /* * Get long word in memory, from 8086 word-reversed format. * */ glong(al, lp) /* al is a swaped return long word,*/ /* lp is a to be swaped long word */ long *al; long *lp; { char *p, *q; p = (char *)al; q = (char *)lp; p[0] = q[3]; p[1] = q[2]; p[2] = q[1]; p[3] = q[0]; } /* * Get word in memory, from 8086 byte-reversed format. * */ UWORD gw(wp, aw) UWORD *wp; UWORD *aw; { char *p, *q; p = (char *)wp; q = (char *)aw; q[0] = p[1]; q[1] = p[0]; return *aw; } /* * Stupid delay between writes (.01 second); * called in supervisor mode on the ST. * * The hard disk controller cannot keep up with * full-tilt accesses for some reason. * */ delay() { register long hz200v, *p; p = (long *)0x4ba; hz200v = *p + 2L; /* compute future value */ while (*p < hz200v) /* wait for it to reach that */ ; } /* * Throw up an alert box * with the given text. * */ err(s) char *s; { ARROW_MOUSE; form_alert(1, s); BEE_MOUSE; return ERROR; } /* * Error, concatenate the three strings * and throw up an alert box. * */ errs(s1, s2, s3) char *s1, *s2, *s3; { strcpy(sbuf, s1); strcat(sbuf, s2); strcat(sbuf, s3); return err(sbuf); } /* * Errcode() * Find error code for previous instruction which returned Check * Condition Status. * * Input: * pdev - the physical device number (0 -> 7). * Return: * errnum - the error code. */ errcode(pdev) int pdev; { char data[128]; extern long rqsense(), ostack; UWORD errnum; int mask = 0x0001; int set, scsidrv; if (pdev > 15) return ERROR; ostack = Super(NULL); /* check #pdev device is set or not */ set = typedev & (mask << pdev); scsidrv = typedrv & (mask << pdev); if ((set)||(scsidrv)) { /* if set, it is a removable driver */ errnum = rqsense(pdev, 16, data); } else { /* if not set, it is a not removable driver */ errnum = rqsense(pdev, 4, data); } delay(); Super(ostack); if (errnum != 0) return err("[1][Fatal error][OK]"); if ((set)||(scsidrv)) { /* if set, it is a removable driver */ errnum = (UWORD)data[12]; } else { /* if not set, it is a not removable driver */ data[0] &= 0x7f; /* mask out advalid bit */ errnum = (UWORD)data[0]; } return errnum; /* return it */ } /* * Tsterr() * Given an error code, test if it is a medium change error * or a write protection error. Put up the appropiate box if * it is either one of those, and return OK. * If it is not either of those, return ERROR. * */ tsterr(errnum) UWORD errnum; { switch(errnum) { case MDMCHGD: err(mdmchng); break; case WRTPRTD: err(wrprotct); break; case DEVNRDY: err(drvnrdy); break; default: return ERROR; } return OK; }