/* hdx.c */ /* * Atari Hard Disk Installation Utility * Copyright 1988 Atari Corp. * * Associated files * hdx.rsc resource file * wincap hard disk database (text file) * * hdx.h object tree definitions * defs.h constant definitions * part.h ST structure definitions * ipart.h IBM structure definitions * * hdx.c top level, user interface (this file) * epart.c edit partition sizes * fmt.c disk formatting * part.c partition reading/writing * sect.c sector reading, writing, zeroing * string.c string functions (matching, concat, ...) * assist.c markbad(), zero() * wincap.c hard disk parameter / partition size database * st.c random ST functions (delay, reboot, ...) * *---- * 11-May-1988 ml. Cleaned up the memory management in the program * (ie. for all files). Memory chunks which are for * sure will be < 32k is allocated using malloc(), * whereas chunks >= 32k is allocated using Malloc(). * When using malloc(), you will get the 'Stack Over- * flow message if you are in Supervisor mode and * you have your own supervisor stack. To get around * this, have to use mymalloc() (in mymalloc.s). * 15-Mar-1988 ml. Changed interface to Markbad. * 11-Jan-1988 ml. Modified dialogue boxes. * 07-Dec-1987 ml. Started to add in concept of Bad Sector List. * ??-Oct-1987 ml. Partition and Disk type menu now has 15 entries * instead of 16. * 30-Sep-1987 ml. Inherited 'this' from Landon Dyer. * 24-Mar-1986 lmd Released to software test. * 15-Mar-1986 lmd Hacked up from earlier version by Jim Tittsler. * 8-Nov-1988 jye. change and add some codes so that can be used for extended * and big partition. * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with * acsi and scsi drives. * 22-Jan-1990 jye. Change the HDX so that we don't have to put a informations * of a drive into the Wincap file. * 13-Mar-1990 jye. change the HDX to a genetic one so that the user don't * need know what kind of drive. * 20-Jul-1990 jye. change the interface about the unit select. In the new * interface, user tells the type of drive is acsi or scsi, * then selects unit. * 01-Aug-1990 jye. Change hard disk size request from mdsence to readcap. * 25-Jul-1991 jye. Change the Hdx so that can be used for IDE-AT drive. * 11-Nov-1991 jye. change the hdx so that can got the hard disk size from * page 0, or 3, or 4, or from the wincap. For the SCSI drive, * getting the disk size from wincap or readcap. * 7-Jul-1992 jye. Change the hdx so that can be used for the sparrow scsi. * Feb-3-1993 jye. Fixed a bug which is when format a hard disk with no wincap * file, then the HDX will bomb out. Now, you can still format * the hard disk without the wincap, because the wincap file * is used when HDX can't get the hard disk's informations. * Apr-9-1993 jye. To fixed a problem for the Conner CP2088 drive, which HDX * can't Markbad it in Format, because this kind of drive has * the different values of head, cylinder, and spt between the * physical and logical parameters, so I added a inqury() call * right after the 'fmtunt()' in 'dodiform()' to up date the * table, because 'fmtunt()' changes the physical parameters * to the logical parameters. */ #include "obdefs.h" #include "gemdefs.h" #include "osbind.h" #include "mydefs.h" #include "part.h" #include "bsl.h" #include "hdx.h" #include "ipart.h" #include "addr.h" #include "myerror.h" #define MFM 17 extern char sbuf[]; extern int rebootp; extern long gbslsiz(); extern long get3bytes(); extern long get4bytes(); extern long bslsiz; extern BYTE *bsl; extern int uplim; /* the number of partitions */ extern long sptrk; extern long spcyl; extern int ibmpart; extern int yesscan; extern long disksiz; extern long ratio; extern int typedev; extern int typedrv; extern int prevnpart; extern int atexst; /* set for AT drive exist */ /* Globals */ int rebootp = 0; /* 1: must reboot (not return to desktop) */ int tformat; /* TRUE: just formatted disk */ int running; /* 1: continue evnt_multi() loop */ char sbuf[512]; /* error message buffer */ long extsiz; /* the size of extened partition */ long ostack; /* old stack pointer */ int toibm; /* the flag of partition to ibm format */ int ibm2st; /* the flag for IBM partition to ST */ long bps; /* bytes per sector */ int npart; /* number of partition */ int ext; /* the index of extended partition */ int extend; /* the index of end extended partition */ int showmany; /* the flag that show the too much device alert box */ char ttscsi; /* SCSI hard disk drive */ char spscsixst; /* set for sparrow scsi drive exist */ int noacsi; /* set for no ACSI dirve in the system */ int needscan; /* TRUE: if info in the LOGMAP update */ int noinfo=1; /* 1: no informations in the wincap */ int athead; /* the # of data heads on the AT drive */ int atcyl; /* the # of cylinders on the AT drive */ int atspt; /* the # of sectors per track on the AT drive */ int ok2draw; /* go ahead to draw the change part of dialog box */ int ndevs; /* the # of devices */ char *drvid[] ={ /* for the id of the drives */ "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "123456789012345678901234567", "Identification unavaliable", "Not responding", "ACSI 0", /* index is 19 */ "ACSI 1", "ACSI 2", "ACSI 3", "ACSI 4", "ACSI 5", "ACSI 6", "ACSI 7", "SCSI 0", /* index is 27 */ "SCSI 1", "SCSI 2", "SCSI 3", "SCSI 4", "SCSI 5", "SCSI 6", "SCSI 7", "IDE 0", /* index is 35 */ " " }; DEVSET devid[17]; /* Logical-to-dev+partition mapping table. */ extern int nlogdevs; /* #logical devs found */ extern LOGMAP logmap[]; /* logical dev map */ extern int livedevs[]; /* live physical dev flag */ extern int idevs[]; /* the devise have a id */ extern char cachexst; /* 0: no cache. 1: with cache */ /* Partition related variables */ long mxpsiz = MAXPSIZ; /* AES (windows and messages) related variables */ int gl_hchar; /* height of system font (pixels) */ int gl_wchar; /* width of system font (pixels) */ int gl_wbox; /* width of box able to hold system font */ int gl_hbox; /* height of box able to hold system font */ int phys_handle; /* physical workstation handle */ int handle; /* virtual workstation handle */ int wi_handle; /* window handle */ int formw, formh, sx, sy, lx, ly; /* dialogue box dimensions */ int xdesk, ydesk, hdesk, wdesk; /* window X, Y, width, height */ int xwork, ywork, hwork, wwork; /* desktop and work areas */ int msgbuff[8]; /* event message buffer */ int keycode; /* keycode returned by event-keyboard */ int mx, my; /* mouse x and y pos. */ int butdown; /* button state tested for, UP/DOWN */ int ret; /* dummy return variable */ int pnf; /* 1: partition or format; 0: zero or markbad */ int hidden; /* current state of cursor */ int contrl[12]; int intin[128]; int ptsin[128]; int intout[128]; int ptsout[128]; /* storage wasted for idiotic bindings */ int work_in[11]; /* Input to GSX parameter array */ int work_out[57]; /* Output from GSX parameter array */ int pxyarray[10]; /* input point array */ int blitxst; /* the flag for check the BLiTTER */ /* * Top level; * we get control from the desktop. */ main() { pnf = 0; /* set the flag to it isn't partition yet */ appl_init(); phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox); wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk); open_vwork(); wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk); hidden = FALSE; butdown = TRUE; /* doing a checking see if the cache in the system */ cachexst = (char) chkcache(); /* check the existence of the BLiTTER */ blitxst = chkblit(); if (!rsrc_load(RESOURCEFILE)) { errs("[2][|", RESOURCEFILE, "][ EXIT ]"); goto punt; } /* Get all addresses of dialogues from resource file */ if (getalladdr() != OK) { errs("[2][|", RESOURCEFILE, "][ EXIT ]"); goto punt; } /* * Get maximum partition size from * wincap "@@" entry. */ /* if (wgetent("Parameters", "@@") == OK) { if (wgetnum("ms", &mxpsiz) != OK) mxpsiz = MAXPSIZ; } else { goto punt; } */ needscan = TRUE; redomul: ARROW_MOUSE; /* display menu bar */ menu_bar(menuobj, 1); running = TRUE; while (running) { domulti(); } /* * If nothing has been done to the hard disks * then just get out, back to the desktop. * Otherwise reboot the system. */ menu_bar(menuobj, 0); /* erase menu bar */ punt: /* * If we have to reboot, * tell the user and then do it. * */ if (rebootp) { if (form_alert(2, autoboot) == 1) { reboot(); } else { goto redomul; } } wind_delete(wi_handle); v_clsvwk(handle); appl_exit(); } /* * Get a single event, process it, and return. * */ domulti(){ int event; event = evnt_multi(MU_MESAG, 1,1,butdown, 0,0,0,0,0, 0,0,0,0,0, msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret); if (event & MU_MESAG) { wind_update(TRUE); switch (msgbuff[0]) { case WM_REDRAW: do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]); break; case MN_SELECTED: BEE_MOUSE; switch(msgbuff[3]) { case MNDISK: switch (msgbuff[4]) { case DIFORM: if ((needscan) && (rescan(0,1) == ERROR)) { break; /* don't report medium changed */ } tformat = TRUE; needscan = FALSE; dodiform(); tformat = FALSE; break; case DIPART: if ((needscan)&&(rescan(0,2) == ERROR)) { break; /* don't report medium changed */ } needscan = FALSE; dodipart(-1, NULL, NULL); break; case DIZERO: if (pnf) { err(needboot); } else { if ((needscan)&&(rescan(0,0) == ERROR)) { break; /* don't report medium changed */ } needscan = FALSE; dodizero(); } break; case DIMARK: if (pnf) { err(needboot); } else { if ((needscan)&&(rescan(0,0) == ERROR)) { break; /* don't report medium changed */ } needscan = FALSE; dodimark(); } break; /* case DISHIP: if ((needscan)&&(rescan(0,1) == ERROR)) { break; don't report medium changed } needscan = FALSE; dodiship(); break; */ default: break; } break; case MNFILE: switch (msgbuff[4]) { case FIQUIT: running = 0; break; default: break; } break; case MNDESK: if(msgbuff[4] == DEABOUT) { strcpy(abtdial[ABVERSN].ob_spec, "Version 5.04"); abtdial[ABOK].ob_state = NORMAL; execform(abtdial); } break; /* "cannot happen" */ } menu_tnormal(menuobj, msgbuff[3], 1); /* back to normal */ ARROW_MOUSE; break; case WM_NEWTOP: case WM_TOPPED: wind_set(wi_handle, WF_TOP, 0, 0, 0, 0); break; case WM_CLOSED: running = FALSE; break; default: break; } wind_update(FALSE); } } /* * Default partition name (no "pt" entry). */ #define DEF_PARTNAME "4-6-10" /* * Map from button in format dial. */ int pfmt[] = { PFMT0, PFMT1, PFMT2, PFMT3, PFMT4, PFMT5, PFMT6, PFMT7, PFMT8, PFMT9, PFMT10, PFMT11, PFMT12, PFMT13, PFMT14, PFMT15 }; /* * Handle [FORMAT] item. * */ dodiform() { extern char bootstop; extern char bootend; int dev, v, w, i, br; int modesel; /* flag for mode select */ long cnt, hdsiz; char *s, *d, *wgetstr(); char buf[10], bs[512], sendata[32]; char pnam[128]; char *seldev = "ACSI unit 0", *id = "XXXXX"; char *seldv = "IDE unit 0"; HINFO hinfo; char devnames[NAMSIZ]; /* device type name buffer */ long nbad; extern long gbslsiz(), nument(), dsmarkbad(); long pattern, temp, cyl; long longrandom(); char pr_id[10]; /* partition scheme id */ int mask = 0x0001; int set, scsidrv, bsiz, other = 0; int page=4, spt, ret; int head=0, domark=YESMK; /* * Throw up generic formatting/partition warning, * then get physical dev they want to clobber. */ yesscan = 0; noinfo = 1; for (i = 0; i < NAMSIZ; i++) devnames[i] = "\0"; fwarning[FWARNCN].ob_state = NORMAL; fwarning[FWARNOK].ob_state = NORMAL; if (execform(fwarning) != FWARNOK) return BAILOUT; if ((dev = gphysdev()) < 0) { return BAILOUT; } strcpy(id, "mn"); br = 0; /* display doing SCSI massage */ inqfmt: /* Get all available disk types from wincap 'mn' entries */ if (wallents(devnames, id) != OK) { goto stfm; } if (!*devnames) {/* no informations */ goto stfm; } noinfo = 0; /* Shove format name text into buttons */ for (i = 0, s = devnames; i < 14 && *s; ++i) { dsknames[pfmt[i]].ob_type = G_BUTTON; /* button */ dsknames[pfmt[i]].ob_spec = (long)s; dsknames[pfmt[i]].ob_state = NORMAL; dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON; while (*s++) ; } other = i; /* the other button */ dsknames[pfmt[i]].ob_type = G_BUTTON; /* button */ dsknames[pfmt[i]].ob_spec = "OTHER"; dsknames[pfmt[i]].ob_state = NORMAL; dsknames[pfmt[i]].ob_flags = SELECTABLE | RBUTTON; i++; /* rest of buttons are invisible and untouchable */ for (; i < 16; ++i) { dsknames[pfmt[i]].ob_type = G_IBOX; /* invisible box */ dsknames[pfmt[i]].ob_spec = 0; /* no thickness */ dsknames[pfmt[i]].ob_state = DISABLED; /* nobody home */ dsknames[pfmt[i]].ob_flags = NONE; /* disabled */ } /* clean up rest of the form and throw it up */ dsknames[PFOK].ob_state = NORMAL; dsknames[PFCN].ob_state = NORMAL; if (execform(dsknames) != PFOK) return BAILOUT; /* search for format they picked */ for (i = 0; i < 18; ++i) if (dsknames[pfmt[i]].ob_state & SELECTED) break; if (i >= 18) { /* nothing picked */ return BAILOUT; } else if (other == i) { /* the OTHER button was selected */ noinfo = 1; goto stfm; } if ((!br) && (dev < 8)) { if (wgetent(dsknames[pfmt[i]].ob_spec, "mn") == ERROR) { strcpy(id, "mn"); noinfo = 1; goto stfm; /* nofmt[NOSCHFMT].ob_spec = dsknames[pfmt[i]].ob_spec; nofmt[NOSCHFMT].ob_state = NORMAL; execform(nofmt, 0); return ERROR; */ } if ((s = wgetstr("br")) != NULL) { strcpy(id, s); br = 1; /* processing the branch */ goto inqfmt; /* start over */ } } stfm: modesel = 1; if(gfparm(dev, &noinfo, &modesel, &hinfo, dsknames[pfmt[i]].ob_spec,id)!= 0) { return ERROR; } /* get data pattern to test the disk */ if (wgetnum("dp", &pattern) != OK) { pattern = longrandom(); /* can't find pattern from wincap, make one */ } else { temp = pattern; pattern <<= 16; /* shift pattern to hi word */ pattern |= temp; } if (dev > 15) { /* IDE-AT drive */ br = dev - 16; } else { /* it is a scsi or acsi drive */ br = (dev > 7) ? (dev-8) : (dev); /* minus 8 for the scsi drive number */ } /* asking the user do the marking bad or not */ mkornot[YESMK].ob_state = NORMAL; mkornot[NOTMK].ob_state = NORMAL; domark = execform(mkornot); /* * One last chance to bail out. */ *seldev = 'A'; if (dev > 15) { /* it is a IDE-AT drive */ seldev = seldv; } else if (dev > 7) { /* it is a SCSI drive */ *seldev = 'S'; } *(seldev + 10) = br + '0'; (fmtfnl[FUNIT].ob_spec)->te_ptext = seldev; fmtfnl[FMTYES].ob_state = NORMAL; fmtfnl[FMTNO].ob_state = NORMAL; if (execform(fmtfnl) != FMTYES) return BAILOUT; /* For REAL !! */ dsplymsg(fmtmsg); bsl = 0L; if ((dev > 15) && (!(athead*atcyl*atspt))) { formaterr(dev); ret = ERROR; goto formend; } /* Get size of Bad Sector List */ if ((bslsiz = gbslsiz(dev)) > 0L) { /* Allocate memory for existing BSL */ if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) { ret = err(nomemory); goto formend; } /* Read in BSL */ if ((ret = rdbsl(dev)) != OK) { /* Create a new BSL if current one is unusable */ if (creabsl(dev, NEW, 0L) != OK) { ret = ERROR; goto formend; } } else { /* Remove USER BSL */ if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) { ret = ERROR; goto formend; } } } else if (bslsiz == 0L || bslsiz == ERROR) { /* no bsl or read error */ if (creabsl(dev, NEW, 0L) != OK) { ret = ERROR; goto formend; } } else { /* bslsiz == MDMERR; medium changed error */ ret = ERROR; goto formend; } /* * In supervisor mode * set disk format parameters * and format the disk. */ ostack = Super(NULL); delay(); if (dev > 15) { /* do the IDE-AT format */ if ((ret = fmtunt(dev)) != OK) { delay(); Super(ostack); ret = errcode(dev); if (tsterr(ret) != OK) formaterr(dev); ret = ERROR; } else { /* Apr-7-93 jye: This is a farmware bug, so have to recall identify()*/ /* to update the head, cylinder, and spt */ if (identify(16, bs) == OK) { delay(); gparmfc(&atcyl, &athead, &atspt, bs); } else { ret = ERROR; goto formend; } if (dev == 16) {/* it is a master IDE-AT */ hdsiz = athead*atcyl*atspt; } disksiz = hdsiz; delay(); Super(ostack); } goto formend; } set = typedev & (mask << dev); scsidrv = typedrv & (mask << dev); bsiz = ((set) || (scsidrv)) ? (16) : (22); if (!noinfo) { /* there are info in the wincap */ if ((set) || (scsidrv)) { v = mdsense(dev, 4, 0, 32, sendata); delay(); /* kludge delay */ sqms(dev, sendata); } else { if (modesel) { v = ms(dev, &hinfo); /* Yes, do noprmal mode set */ } } /* Find formatted capacity of drive */ hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt; } else if (dev < 8) { /* No, do special mode set */ for (i = 0; i < 32; i++) sendata[i] = 0; if ((set) || (scsidrv)) { if (mdsense(dev, 0, 0, bsiz, sendata) == OK) { if (hdsiz = get3bytes(sendata+5)) { delay(); /* kludge delay */ sqms(dev, sendata); v = OK; goto kkk; } } redopg: for (i = 0; i < 32; i++) sendata[i] = 0; v = mdsense(dev, page, 0, 32, sendata); for (i = 0; i < 32; i++) /* the lenght of sendata */ if (sendata[i]) break; if ((i == 32) && (page == 4)) { /* no informations returned */ page = 3; goto redopg; } else if (i == 32) { ret = 111; delay(); /* kludge delay */ Super(ostack); goto formend; } if (page == 4) { if (!(hdsiz = get3bytes(sendata+5))) { page = 3; /* cyl = get3bytes(sendata+14); head = *(sendata+17); if ((!cyl) || (!head)) { ret = 111; delay(); Super(ostack); goto formend; } */ sqms(dev, sendata); goto redopg; } sqms(dev, sendata); goto kkk; } if (!(hdsiz = get3bytes(sendata+5))) { /* spt = getword(sendata+22); hdsiz = cyl*head*spt; */ if (!hdsiz) { ret = 111; delay(); /* kludge delay */ Super(ostack); goto formend; } } goto kkk; } else { /* it is the acsi drivers */ hdsiz = (long)hinfo.hi_cc * (long)hinfo.hi_dhc * (long)hinfo.hi_spt; delay(); /* kludge delay */ v = ms(dev, &hinfo); /* Yes, do noprmal mode set */ } } else { if ((v = readcap(dev, 0, (long)0, buf)) == OK) { if ((hdsiz = get4bytes(buf))) { hdsiz += 1; ret = OK; goto kkk; } } delay(); /* kludge delay */ for (i = 0; i < 32; i++) sendata[i] = 0; if ((v=mdsense(dev, 0, 0, bsiz, sendata)) == OK) { if (hdsiz = get3bytes(sendata+5)) { ret = OK; goto kkk; } } for (i = 0; i < 32; i++) sendata[i] = 0; delay(); /* kludge delay */ if ((v=mdsense(dev, 4, 0, 32, sendata)) == OK) { if (hdsiz = get3bytes(sendata+5)) { ret = OK; goto kkk; } } for (i = 0; i < 32; i++) sendata[i] = 0; delay(); /* kludge delay */ if ((v=mdsense(dev, 3, 0, 32, sendata)) == OK) { if (hdsiz = get3bytes(sendata+5)) { ret = OK; goto kkk; } } ret = 111; delay(); /* kludge delay */ Super(ostack); goto formend; } kkk: disksiz = hdsiz; delay(); /* kludge delay */ if (v == OK) { v = format(dev, (UWORD)hinfo.hi_in); /*format*/ } lll: delay(); /* kludge delay */ Super(ostack); if (v != 0) { ret = errcode(dev); if (tsterr(ret) != OK) formaterr(dev); ret = ERROR; goto formend; } ret = OK; rebootp = 1; formend: erasemsg(); /* Erase formatting box */ if (ret == 111) /* HDX may not support this drive */ ret = err(needinfo); if (ret < 0) { if (bsl > 0) free(bsl); return ERROR; } /*------------------------------------------* * Markbad the device destructively. * * Bad Sectors found are added to the BSL. * * Write BSL to device. * *------------------------------------------*/ if (domark == YESMK) { /* need to do the markbad */ if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) { free(bsl); return ERROR; } } if (wrbsl(dev) != OK) { free(bsl); return ERROR; } free(bsl); /* * Install boot-stopper in sector image; * write root sector to device. * 6-13-88 Setting of soft format parameters in root sector sets * the hard disk size only. */ fillbuf(bs, 512L, 0L); /* create new root sector */ sbslparm(bs); /* set BSL parameters */ if (modesel) { sfmtparm(bs, &hinfo); } else { sdisksiz(bs, disksiz); } for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;) *d++ = *s++; Protobt(bs, -1L, -1, 1); /* make root sector executable */ if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) { if (tsterr(ret) != OK) err(rootwrit); return ERROR; } /* * Make a copy of the default partition name. * Figure out the partition scheme id. */ if (!noinfo) { s = wgetstr("pt"); strcpy(pnam, s); } /* ?? figprid(disksiz, pr_id); */ dodipart(dev, pnam, disksiz); return OK; } /* * Handle [PARTITION] item; * if `xdev' is -1, throw up dialog boxes; * if `xdev' >= 0, just partition the dev, * using `pnam' as the partition type, * and `pr_id' to search for the type. * */ dodipart(xdev, pnam, hsize) int xdev; char *pnam; long hsize; { int dev, i, ret =OK, fine; int choice; char *seldev = "ACSI unit 0"; char *seldv = "IDE unit 0"; char *s; char bs[512]; PART *pinfo; int tem1, tem2; long disksiz; int mask = 0x0001; if (xdev < 0) { /* * Throw up warning saying that partition is dangerous; * then get physical dev they want to clobber. */ pwarning[PWARNCN].ob_state = NORMAL; pwarning[PWARNOK].ob_state = NORMAL; if (execform(pwarning) != PWARNOK) return BAILOUT; tformat = FALSE; if ((dev = gphysdev()) < 0) { return BAILOUT; } /* * Let the user edit/pick partitions. */ fine = 0; while (!fine) { if (sfigpart(bs, dev, (PART *)&pinfo) != OK) { if (pinfo > 0) Mfree(pinfo); return BAILOUT; } if ((ret = chkpart(dev, pinfo)) != OK) { if (ret < 0) { /* size too big */ err(nexsmem); } else { /* some other errors */ if (pinfo > 0) Mfree(pinfo); return BAILOUT; } } else { fine = 1; } } fine = dev; /* default for the acsi unit */ *seldev = 'A'; if (dev > 15) { /* it is a IDE-AT drive */ fine = dev - 16; seldev = seldv; } else if (dev > 7) { /* minus 8 for the scsi drive number */ fine = dev - 8; *seldev = 'S'; } *(seldev + 10) = fine + '0'; /* Last chance to bail out */ (partfnl[PUNIT].ob_spec)->te_ptext = seldev; partfnl[PARTYES].ob_state = NORMAL; partfnl[PARTNO].ob_state = NORMAL; if (execform(partfnl) != PARTYES) { if (pinfo > 0) Mfree(pinfo); return BAILOUT; } } else { /* ?? if ((!noinfo) && (!ttscsi) && (wgetent(pnam, pr_id) != OK)) { nopart[NOSCHPOK].ob_state = NORMAL; (nopart[NOSCHPR].ob_spec)->te_ptext = pnam; execform(nopart); return ERROR; } */ npart = 4; ext = NO_EXT; /* set the extended partition flag to not exists */ dev = xdev; if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0) { err(nomemory); if (pinfo > 0) Mfree(pinfo); return ERROR; } inipart(pinfo, npart); npart = 0; setpart(pinfo, pnam, hsize); /* ?? if (ttscsi) { SCSI bus drive setpart(pinfo, hsize); } else { regular drvie for (i = 0; i < 4; ++i) fillpart(i, &pinfo[i]); } */ } /* For REAL!! */ dsplymsg(partmsg); bsl = 0L; /* Get size of BSL */ if ((bslsiz = gbslsiz(dev)) > 0L) { /* Allocate memory for existing BSL */ if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) { ret = err(nomemory); goto partend; } /* Read in BSL */ if ((ret = rdbsl(dev)) != OK) { if (ret == INVALID) err(cruptbsl); ret = ERROR; goto partend; } } else if (bslsiz == 0) { ret = err(oldfmt); goto partend; } else if (bslsiz == ERROR) { ret = err(rootread); goto partend; } else { ret = ERROR; goto partend; } /* Lay out partition headers */ if (spheader(dev, &pinfo[0]) != OK) { ret = ERROR; goto partend; } if (wrbsl(dev) != OK) { /* write BSL */ ret = ERROR; goto partend; } /* check and change the structure's id after 'spheader()' */ changeid(pinfo); /* Shove partition parms into root sector */ if ((ret = getroot(dev, bs, (SECTOR)0)) != 0) { if (tsterr(ret) != OK) err(rootread); ret = ERROR; goto partend; } if ((ret = stlayroot(bs, dev, pinfo)) != OK) { goto partend; } tem1 = npart; /* save the number of partitions */ tem2 = ext; /* save the index of extended partition */ if (rescan(1,2)) { /* has to be here because map changed */ ret = ERROR; /* after partitions are moved around, */ goto partend; /* report medium change error. */ } npart = tem1; ext = tem2; /* Partition the device with parameters given in pinfo */ if (stlaybs(dev, &pinfo[0]) != OK) ret = ERROR; else ret = OK; rebootp = 1; /* add on Jul 2, 90 for removable drive if ((typedev & (mask << dev))) it is a removable drive if (npart <= prevnpart) if less or equal than prevous rebootp = 0; partition, don't reboot change and add over on Jul 2, 90 for the removable drive on Oct 1, 90 if ((typedev & (mask << dev))) { it is a removable drive for (i = 0; i < 10; i++) { if (!mediach(dev)) break; if (i == 10) rebootp = 1; else rebootp = 0; } } */ pnf = 1; /* set the flag to just doing the partition */ partend: if (bsl > 0) free(bsl); inipart(pinfo, npart); if (pinfo > 0) Mfree(pinfo); erasemsg(); return (ret); } /* * get root sector informations and write them into that sector */ stlayroot(bs, dev, part) char *bs; int dev; PART *part; { int i; UWORD sum = 0x1234; long cnt, disksiz, prvst; char *d, *s; extern char bootstop; extern char bootend; /* do the prime partition */ spart(bs, part, 0, &prvst); /* set ST partition parameters */ /* sfmtparm(bs, &hinfo); for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;) *d++ = *s++; */ sbslparm(bs); /* set bsl parameters */ Protobt(bs, -1L, -1, 1); /* make root sector executable */ if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) { if (tsterr(ret) != OK) err(rootwrit); return(ERROR); } if (ext == NO_EXT) return OK; /* no extended partition */ /* do the extended partitions */ extsiz = part[ext].p_siz; for (i = 4; i < npart; i++) { if (!(part[i].p_flg & P_EXISTS)) { /* skip if not exists */ return OK; } spart(bs, part, i, &prvst); /* set IBM partition parameters */ if ((ret = putroot(dev, bs, part[i].p_st)) != OK) { if (tsterr(ret) != OK) err(rootwrit); return(ERROR); } } return OK; } /* * Put information into the root structure */ spart(image, pinfo, pnm, prvst) char *image; /* root sector buffer */ register PART *pinfo; /* partition information */ int pnm; /* partition number */ long *prvst; /* The previous partition start sector */ { PART *rpart; long numcyl; int i, j; if (pnm) { fillbuf(image, 512L, 0L); } rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0]; if (pnm < 4) { for (i = 0; i < NPARTS; i++, rpart++) { if (pinfo->p_flg & P_EXISTS) { rpart->p_flg = P_EXISTS; for (j = 0; j < 3; j++) rpart->p_id[j] = pinfo->p_id[j]; rpart->p_st = pinfo->p_st; rpart->p_siz = pinfo->p_siz; } else { rpart->p_flg = 0; for (j = 0; j < 3; j++) rpart->p_id[j] = 0; rpart->p_st = 0L; rpart->p_siz = 0L; } pinfo++; } } else { /* pnm => 4 */ rpart->p_flg = pinfo[pnm].p_flg; for (j = 0; j < 3; j++) rpart->p_id[j] = pinfo[pnm].p_id[j]; rpart->p_st = ROOTSECT; rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT; rpart++; if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { /* need extened partition */ rpart->p_flg = P_EXISTS; rpart->p_id[0] = 'X'; rpart->p_id[1] = 'G'; rpart->p_id[2] = 'M'; rpart->p_siz = pinfo[pnm+1].p_siz; rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) : (pinfo[pnm].p_siz + *prvst); *prvst = rpart->p_st; } } } /* * Setup partitions on the disk; * write boot sectors and zero FATs and root directories. * */ stlaybs(physdev, pinfo) int physdev; register PART *pinfo; { int i, ldev, ret; int kindfat; SECTOR data, nsect; char *devno="X"; long ndirs; UWORD fatsiz; BOOT *bs; long serialno; extern long longrandom(); extern long cell(); char *buf, *buf1; long size, remsect; long datsect; long datclst; long fatclst; long entsect; if ((bslsiz = gbslsiz(physdev)) < 0L) { if (bslsiz == ERROR) err(rootread); return ERROR; } /* SCAN_BS: pinfo is for scan() and laybs() use */ if (ext != NO_EXT) sortpart(pinfo, SCAN_BS); for (i = 0; i < npart; ++i, ++pinfo) { /* don't care if partition does not exist */ if (!(pinfo->p_flg & P_EXISTS)) { return OK; } /* * Compute boot sector parameters. */ if (pinfo->p_siz > disksiz) { /* partition >? disk size */ *devno = i + '0'; (part2big[BGPART].ob_spec)->te_ptext = devno; part2big[BGPARTOK].ob_state = NORMAL; execform(part2big); return ERROR; } /* estimat the bps */ /* MAXSECT = 16MB - 8 */ bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT); /* the real bps */ bps = BPS * n2power((UWORD)cell(bps, (long)BPS)); ratio = bps / BPS; nsect = pinfo->p_siz / ratio; size = (long)BPS * ratio; if ((buf = (char *)Malloc(size)) <= 0) { err(nomemory); if (buf > 0) Mfree((long)buf); return ERROR; } /* * Install entries in boot sector image; * force sector checksum to zero (non-executable); * write boot sector to media. * * 512 bytes/sector * 2 or 4 sectors/cluster (partition > 16Mb has 4 spc) * 1 reserved sector (for boot) * 2 FATs * ... dir slots * ... # sectors * F8 means media is a hard disk * ... FAT size * */ /* Make a clean boot sector */ fillbuf(buf, bps, 0L); bs = (BOOT *)buf; /* bytes per sector */ iw((UWORD *)&bs->b_bps[0], (UWORD)bps); /* sectors per cluster */ bs->b_spc = SPC; /* number of reserved sectors */ iw((UWORD *)&bs->b_res[0], (UWORD)1); /* number of FATs */ bs->b_nfats = 2; /* * Compute root directory size * 256 entries, plus fudge on devs > 10Mb */ if (pinfo->p_siz < 0x5000L) ndirs = NUMEN; else ndirs = nsect / 80; /* 1 dir entry per 80 sectors */ /* round to nearest sector */ ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1); iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs); /* number of sectors on media (partition) */ iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect); /* media descriptor */ bs->b_media = 0xf8; /*--------------------------------------------------------------* * Compute FAT size * * * * Num entries to map the entire partition * * = partition's size in clusters * * = partition's size in sectors / spc * * * * Num entries in FAT * * = Num entries to map partition + reserved entries * * = (partition's size in sectors / spc) + 2 * * * * Num sectors FAT occupies * * = Num entries in FAT / Num entries of FAT per sector * * = Num entries in FAT / (bps / 2) <16-bit FAT> * * = ((partition's size in sectors / spc) + 2) / (bps/2) + 1 * * <+1 to round up> * *--------------------------------------------------------------*/ fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;/*bps ?? 512 or 1024*/ iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz); /* write the serial number to the bs */ Protobt(bs, 0x01000000, -1, -1); /* * Write partition's boot sector */ forcesum((UWORD *)buf, (UWORD)0); /* force image checksum */ if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) { if (tsterr(ret) != OK) err(bootwrit); return ERROR; } /* * Zero the fat tables directory entry */ if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio), ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) { if (tsterr(ret) != OK) err(hdrwrite); return ERROR; } /* Apr-23-93 jye: To fixed the same bug in the Gemdos. * Num entries in FAT * * = Num entries to map partition + reserved entries * * = (partition's size in sectors / spc) + 2 * * * * Num sectors FAT occupies * * = Num entries in FAT / Num entries of FAT per sector * * = Num entries in FAT / (bps / 2) <16-bit FAT> * * * Num entries in the last sector of FAT * = (nsect/spc + 2) % (bps/2) * * The pointer(or counter in byte)after the last entries in the FAT * = ((nsect/spc + 2) % (bps/2))*ratio*2 (16bit fat is 2 bytes) */ /* # of sectors in datas: * datsect = nsect - boot - 2*fatsiz - size of dir * = nsect-boot-2*fatsiz-(ndirs*32)/bps * # of clusters in datas: * datclst = # of sectors in datas / SPC * # of clusters(entries) in Fat: * fatclst = fatsiz * (bps/2) * # of sectors need in fat talbe for datclst: * entsect = datclst / (bps/2) * # of sectors need to remodify to 0xffff: * remsect = fatsiz - entsect */ datsect = nsect - 1 - 2*fatsiz - (ndirs*32)/bps; datclst = datsect / SPC; fatclst = fatsiz * (bps/2); entsect = datclst / (bps/2); remsect = (fatsiz - entsect)*size; /* # of sectors need to remodify to 0xffff */ if ((buf1 = (char *)Malloc(remsect)) <= 0) { err(nomemory); if (buf > 0) Mfree((long)buf); if (buf1 > 0) Mfree((long)buf1); return ERROR; } /* * Apr-23-93 jye: To fixed the write over to next partitiona in the Gemdos * , here just set those entries in Fat table, which don't * correspond to the availble date sectors in the partition. * The pointers should be: * p_st+(boot+datclst/(bps/2))*ratio and * p_st+(boot+fatsiz+datclst/(bps/2))*ratio */ if ((ret = rdsects(physdev, (UWORD)(remsect/BPS), buf1, (SECTOR)pinfo->p_st+(1+datclst/(bps/2))*ratio)) != OK) { if (tsterr(ret) != OK) err(bootwrit); return ERROR; } /* fill the last sectors of FAT start at last entry with the 0xffff */ /* +2 is for two reserved entries in the fat table */ fillfat(buf1, ((datclst%(bps/2))+2)*2, remsect, 0xffff); if ((ret = wrsects(physdev,(UWORD)(remsect/BPS),buf1, (SECTOR)pinfo->p_st+(1+datclst/(bps/2))*ratio) != OK) || (ret = wrsects(physdev,(UWORD)(remsect/BPS),buf1, (SECTOR)pinfo->p_st+(1+fatsiz+datclst/(bps/2))*ratio) != OK)) { if (tsterr(ret) != OK) err(bootwrit); return ERROR; } /* Apr-23-93 jye: Add above codes to fix the Gemdos over write next * partition. */ /* * Make first 2 entries in FATs more IBM-like. */ if ((ret = rdsects(physdev,(UWORD)ratio,buf, (SECTOR)(pinfo->p_st+ratio)))!= 0){ if (tsterr(ret) != OK) err(fatread); return ERROR; } *(UWORD *)&buf[0] = 0xf8ff; *(UWORD *)&buf[2] = 0xffff; if ((ret = wrsects(physdev,(UWORD)ratio, buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 || (ret = wrsects(physdev,(UWORD)ratio,buf, (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio))) != 0) { if (tsterr(ret) != OK) err(fatwrite); return ERROR; } /* * Mark bad sectors recorded in the BSL into the FATs. * Calculating parameters: * ldev - from physdev and i. * fat0 - always equals 1. * fatsiz - calculated above. * data - starts after the boot sector, 2 FATs and rootdir. */ if (bslsiz > 0) { if ((ldev = phys2log(physdev, i)) == ERROR) return parterr(physdev); data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps); bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), data*ratio, MEDIA); } if (buf > 0) Mfree((long)buf); if (buf1 > 0) Mfree((long)buf1); } return OK; } /* * Handle [ZERO] item. * */ dodizero() { int ldev, ret; char *seldev = "X"; int i; zwarning[ZWOK].ob_state = NORMAL; zwarning[ZWCN].ob_state = NORMAL; if (execform(zwarning) != ZWOK) return BAILOUT; if (showmany) err(manyldev); if ((ldev = glogdev()) < 0) return BAILOUT; /* Find out if logical device has assumed parameters */ if (chkparm(ldev) != OK) { wronparm[WRONOK].ob_state = NORMAL; execform(wronparm); return ERROR; } *seldev = ldev; (zerofnl[ZDRV].ob_spec)->te_ptext = seldev; strcat((zerofnl[ZDRV].ob_spec)->te_ptext, ":"); zerofnl[ZYES].ob_state = NORMAL; zerofnl[ZNO].ob_state = NORMAL; if (execform(zerofnl) != ZYES) return BAILOUT; dsplymsg(zeromsg); if (zero(ldev) == OK) { if (!rebootp) { for (i = 0; i < 10; i++) { if (!mediach(ldev-'A')) break; } if (i == 10) { rebootp = 1; err(mdach); } } } erasemsg(); } /* * Handle [MARKBAD] item. * */ dodimark() { int ldev, ret; int i; mwarning[MWARNOK].ob_state = NORMAL; mwarning[MWARNCN].ob_state = NORMAL; if (execform(mwarning) == MWARNCN) return BAILOUT; if (showmany) err(manyldev); if ((ldev = glogdev()) < 0) return BAILOUT; /* Find out if logical device has assumed parameters */ if (chkparm(ldev) != OK) { wronparm[WRONOK].ob_state = NORMAL; execform(wronparm); return ERROR; } dsplymsg(lmrkmsg); if (markbad(ldev) != OK) { erasemsg(); } else { if (!rebootp) { for (i = 0; i < 10; i++) { if (!mediach(ldev-'A')) break; } if (i == 10) { rebootp = 1; err(mdach); } } } } /* * Translate unit number to tree index. * */ static int physxlat[] = { UNIT0, UNIT1, UNIT2, UNIT3 }; static int physid[] = { DRVID0, DRVID1, DRVID2, DRVID3 }; #define ROLL1 1 /* move the bar one step */ #define ROLL4 4 /* move the bar four steps */ /* * Ship selected devices. */ dodiship() { int xrun = 1; int index=0, i, ret; linkdev(); /* link all live devices into a list */ /* set form for first display */ physdial[PHYSOK].ob_state = NORMAL; physdial[PHYSCN].ob_state = NORMAL; physdial[SLBOX].ob_y = 0; if (ndevs <= 4) { physdial[SLBOX].ob_height = physdial[SLTRK].ob_height; } else { physdial[SLBOX].ob_height = physdial[SLTRK].ob_height / (ndevs/4.0); } ok2draw = 0; drawdev(index); /* draw the devices into the dialog box */ ARROW_MOUSE; dsplymsg(physdial); ++ok2draw; while (xrun) { switch (form_do(physdial, -1)) { case PHYSOK:xrun = 0; break; case PHYSCN:xrun = 0; /* return */ break; case SLTRK: if (ndevs > 5) { scrupdn(ROLL4, &index); } break; case SLUP: if (index != 0) { scrupdn(ROLL1, &index); } break; case SLDN: if ((index < 12) && (index+4 < ndevs)) { scrupdn(ROLL1, &index); } break; case SLBOX: if (ndevs > 5) { slidebox(physdial, &index); } break; } } /* * Draw shrinking box and cleanup the screen; * return thing that caused our exit. */ erasemsg(); if (ret == PHYSCN) { return BAILOUT; } /* search for the selected unit */ for (i=0; i < 4; i++) { if (physdial[physxlat[i]].ob_state & SELECTED) { /* Throw up final shipping warning. */ shipfnl[SFNLCN].ob_state = NORMAL; shipfnl[SFNLOK].ob_state = NORMAL; if (execform(shipfnl) != SFNLOK) return BAILOUT; ship(devid[index+i].dev); /* Put out final message about turning off hard disks */ scommand[TRNOFFOK].ob_state = NORMAL; execform(scommand); } } return BAILOUT; } /* * Get physical device#, * return devno or -1. * */ gphysdev() { int xrun = 1, tpdev=0; int index=0, i, ret; linkdev(); /* link all live devices into a list */ if (tformat) { /* when format, enable all devices in dialog box */ if ((spscsixst) || (atexst)) { /* sparrow or notebook */ ndevs = 9; tpdev = 8; } else if (ttscsi) { ndevs = 16; } else { /* if ((!ttscsi) && (!noacsi)) Mega ST */ ndevs = 8; } } /* set form for first display */ physdial[PHYSOK].ob_state = NORMAL; physdial[PHYSCN].ob_state = NORMAL; physdial[SLBOX].ob_y = 0; if (ndevs <= 4) { physdial[SLBOX].ob_height = physdial[SLTRK].ob_height; } else { physdial[SLBOX].ob_height = physdial[SLTRK].ob_height / (ndevs/4.0); } for (i=0; i < 4; i++) { physdial[physxlat[i]].ob_state = NORMAL; physdial[physid[i]].ob_state = NORMAL; } ok2draw = 0; drawdev(index); /* draw the devices into the dialog box */ ARROW_MOUSE; dsplymsg(physdial); ++ok2draw; while (xrun) { switch (ret=form_do(physdial, -1)) { case PHYSOK:xrun = 0; break; case PHYSCN:xrun = 0; /* return */ break; case SLTRK: if (ndevs > 5) { scrupdn(ROLL4, &index); } break; case SLUP: if (index != 0) { scrupdn(ROLL1, &index); } break; case SLDN: if ((index < 12) && (index+4 < ndevs)) { scrupdn(ROLL1, &index); } break; case SLBOX: if (ndevs > 5) { slidebox(physdial, &index); } break; caseDRVID0:physdial[UNIT0].ob_state = SELECTED; objc_draw(physdial,UNIT0, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; case DRVID1:physdial[UNIT1].ob_state = SELECTED; objc_draw(physdial,UNIT1, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; case DRVID2:physdial[UNIT2].ob_state = SELECTED; objc_draw(physdial,UNIT2, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; case DRVID3:physdial[UNIT3].ob_state = SELECTED; objc_draw(physdial,UNIT3, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; case UNIT0:physdial[DRVID0].ob_state = SELECTED; objc_draw(physdial,DRVID0, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; case UNIT1:physdial[DRVID1].ob_state = SELECTED; objc_draw(physdial,DRVID1, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; case UNIT2:physdial[DRVID2].ob_state = SELECTED; objc_draw(physdial,DRVID2, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; case UNIT3:physdial[DRVID3].ob_state = SELECTED; objc_draw(physdial,DRVID3, MAX_DEPTH, 0, 0, wdesk, hdesk); break;; } } /* * Draw shrinking box and cleanup the screen; * return thing that caused our exit. */ erasemsg(); if (ret == PHYSCN) { return ERROR; } /* search for the selected unit */ for (i=0; i < 4; i++) { if (physdial[physxlat[i]].ob_state & SELECTED) { if (tformat) { return(index+tpdev+i); } else { return(devid[index+i].dev); } } } return ERROR; } /* draw the select devices dialog box for the format operation */ fdrawdev(index) int index; { int i, st=0; if ((spscsixst) || (atexst)) { st = 8; } for (i=0; i < 4; i++) { /* (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[36][0]; (physdial[physid[i]].ob_spec)->te_ptext = &drvid[36][0]; */ if (i+index+st < 8) { (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[19+i+index][0]; } else if (i+index+st < 16) { (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[27+i+index+st-8][0]; } else { (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[35][0]; } physdial[physxlat[i]].ob_state = NORMAL; physdial[physid[i]].ob_state = NORMAL; if (i+index+st == 16) { /* it is sparrow */ (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0]; } else if (livedevs[i+index+st]) { if (idevs[i+index+st]) { (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0]; } else { (physdial[physid[i]].ob_spec)->te_ptext = &drvid[17][0]; } } else { if (idevs[i+index+st]) { (physdial[physid[i]].ob_spec)->te_ptext = &drvid[i+index+st][0]; } else { (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0]; } /* physdial[physid[i]].ob_state = NORMAL; */ } if (ok2draw) { /* objc_draw(physdial,physlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk); */ objc_draw(physdial,physxlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(physdial,physid[i], MAX_DEPTH, 0, 0, wdesk, hdesk); } } } /* draw the select devices dialog box for the partition operation */ drawdev(index) int index; { int i, j; if (tformat) { fdrawdev(index); return OK; } for (i=0; i < 4; i++) { (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[36][0]; (physdial[physid[i]].ob_spec)->te_ptext = &drvid[36][0]; if (devid[i+index].flg) { physdial[physxlat[i]].ob_state = NORMAL; physdial[physid[i]].ob_state = NORMAL; /* if (devid[i+index].flg == 2) { physdial[physxlat[i]].ob_state = NORMAL; } else { physdial[physxlat[i]].ob_state = NORMAL | OUTLINED; } */ j = devid[i+index].dev; if (j < 8) { /* drvid[19][10] = devid[i+index].dev + '0'; */ (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[19+j][0]; } else if (j < 16) { /* drvid[20][10] = devid[i+index].dev - 8 + '0'; */ (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[27+j-8][0]; } else { (physdial[physxlat[i]].ob_spec)->te_ptext = &drvid[35][0]; } /* physdial[physid[i]].ob_state = NORMAL; */ (physdial[physid[i]].ob_spec)->te_ptext = devid[i+index].id; } else { physdial[physxlat[i]].ob_state = DISABLED; physdial[physid[i]].ob_state = DISABLED; /* (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0]; */ } if (ok2draw) { objc_draw(physdial,physxlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk); objc_draw(physdial,physid[i], MAX_DEPTH, 0, 0, wdesk, hdesk); /* objc_draw(physdial,physlat[i], MAX_DEPTH, 0, 0, wdesk, hdesk); */ } } } scrupdn(roll, index) int roll; int *index; { int gr_mkmx, gr_mkmy; int gr_mkmstate, gr_mkkstate; int barht, barx, bary; int eptx, epty, eptht; barht = physdial[SLTRK].ob_height; eptht = physdial[SLBOX].ob_height; graf_mkstate(&gr_mkmx, &gr_mkmy, &gr_mkmstate, &gr_mkkstate); objc_offset(physdial, SLBOX, &eptx, &epty); objc_offset(physdial, SLTRK, &barx, &bary); /* check which part of bar was clicked */ if (gr_mkmy > (epty+eptht)) { /* low part of bar was clicked */ if (roll == ROLL4) { /* if (eptht > (bary+barht-epty-eptht)) { if (((spscsixst)||(atexst)) && (*index+5 >= ndevs)) { *index = ndevs - 4; physdial[SLBOX].ob_y = barht - eptht; } else if (*index+5 >= ndevs) { */ if ((*index+5 >= ndevs) || (eptht > (bary+barht-epty-eptht))) { physdial[SLBOX].ob_y = barht - eptht; *index = ndevs - 4; /* the last 4 to display */ } else if (*index+4 < ndevs) { /* physdial[SLBOX].ob_y += barht / 4; */ physdial[SLBOX].ob_y += eptht; *index += 4; } } else { /* ROLL1 */ if ((*index+5 >= ndevs)||((barht/ndevs)>(bary+barht-epty-eptht))){ physdial[SLBOX].ob_y = barht - eptht; *index = ndevs - 4; /* the last 4 to display */ } else { physdial[SLBOX].ob_y += barht / ndevs; *index += 1; } } } else if (gr_mkmy < epty) { /* upper part of bar was clicked */ if (roll == ROLL4) { if ((eptht > (epty - bary)) || (*index <= 4)) { physdial[SLBOX].ob_y = 0; *index = 0; } else { /* physdial[SLBOX].ob_y -= barht / 4; */ physdial[SLBOX].ob_y -= eptht; *index -= 4; } } else { if (*index <= 1) { physdial[SLBOX].ob_y = 0; *index = 0; } else { physdial[SLBOX].ob_y -= barht / ndevs; *index -= 1; } } } else { return OK; } objc_draw(physdial,SLTRK, MAX_DEPTH, 0, 0, wdesk, hdesk); drawdev(*index); } slidebox(tree, index) OBJECT *tree; int *index; { int gr_wreturn, eptatmax; int ind, tmp; ind = ndevs - 4; eptatmax = tree[SLTRK].ob_height - tree[SLBOX].ob_height; gr_wreturn = graf_slidebox(tree, SLTRK, SLBOX, 1); tmp = (ind * gr_wreturn) / 1000; if (tmp == *index) { /* slide box is in the same place */ return OK; } else { *index = tmp; } if (*index+4 > ndevs) { *index = ndevs-4; } tree[SLBOX].ob_y = (eptatmax * (*index)) / ind; objc_draw(tree, SLTRK, MAX_DEPTH, 0, 0, wdesk, hdesk); drawdev(*index); } /* put the live device into a list */ linkdev() { int i, j=0; for (i=0; i<16; i++) { devid[i].flg = 0; devid[i].id = &drvid[18][0]; if (livedevs[i]) { devid[j].flg = P_EXISTS; devid[j].dev = i; if (idevs[i]) { devid[j++].id = &drvid[i][0]; } else { devid[j++].id = &drvid[17][0]; } } else if (idevs[i]) { devid[j].flg = 2; devid[j].dev = i; devid[j++].id = &drvid[i][0]; } } if ((spscsixst) || (atexst)) { devid[j].flg = P_EXISTS; devid[j].dev = i; devid[j++].id = &drvid[i][0]; } ndevs = j; /* number of live devices */ } ggphysdev() { int i, j, endup, start, index=0; int ret, unit=8; /* Set up the dialog box for SCSI or ACSI or IDE-AT driver selection */ redogphy: typedial[SCSIYES].ob_state = NORMAL; typedial[ACSIYES].ob_state = NORMAL; typedial[IDEYES].ob_state = NORMAL; if (!tformat) { /* check which type of unit was selected */ if ((!ttscsi)&&(!spscsixst)&&(noacsi)) { /* don't need select */ index = 16; unit = 2; } else if ((!ttscsi)&&(!spscsixst)&&(!atexst)) {/* don't need select */ ; } else if ((!atexst) && (noacsi)) { /* don't need select */ index = 8; } else { if ((!ttscsi)&&(!spscsixst)) { typedial[SCSIYES].ob_state = DISABLED; } else if (!atexst) { typedial[IDEYES].ob_state = DISABLED; } else if (noacsi) { typedial[ACSIYES].ob_state = DISABLED; } if ((ret = execform(typedial)) == SCSIYES) { index = 8; } else if (ret == IDEYES) { index = 16; unit = 2; } } } else { /* do format */ if ((ret = execform(typedial)) == SCSIYES) { index = 8; } else if (ret == IDEYES) { index = 16; unit = 2; } } /* * Clean up and exec object; * shadow devs we KNOW are there. */ physdial[PHYSOK].ob_state = NORMAL; physdial[PHYSCN].ob_state = NORMAL; /* if (tformat == TRUE) { start = 1; start initializing at unit 0 physdial[physxlat[0]].ob_state = NORMAL; } else { start = 0; start initializing at unit 1 } */ endup = index + unit; if (index == 16) { physdial[physxlat[0]].ob_state = NORMAL; if ((spscsixst) || (atexst)) { (physdial[physid[0]].ob_spec)->te_ptext = &drvid[16][0]; } else { (physdial[physid[0]].ob_spec)->te_ptext = &drvid[18][0]; } for (i = 1; i < 8; i++) { (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0]; physdial[physid[i]].ob_state = DISABLED; physdial[physxlat[i]].ob_state = DISABLED; } } else { for (i = 0; i < 8; i++) { (physdial[physid[i]].ob_spec)->te_ptext = &drvid[18][0]; if ((spscsixst)&&(tformat)&&(!index)) { physdial[physid[i]].ob_state = DISABLED; physdial[physxlat[i]].ob_state = DISABLED; } else if (tformat) { /* when format, all devices are on */ physdial[physxlat[i]].ob_state = NORMAL; physdial[physid[i]].ob_state = NORMAL; } else { physdial[physid[i]].ob_state = DISABLED; physdial[physxlat[i]].ob_state = DISABLED; } } } /* if (ttscsi) the hard drive is a SCSI drive physdial[physxlat[8]].ob_state = NORMAL; */ for (i = index, j = 0; i < endup; ++i, j++) { if (livedevs[i]) { physdial[physxlat[j]].ob_state = NORMAL | SHADOWED; physdial[physid[j]].ob_state = NORMAL; if ((i < 16) && (idevs[i])) { (physdial[physid[j]].ob_spec)->te_ptext = &drvid[i][0]; } else if ((i < 16) && (!index)) { (physdial[physid[j]].ob_spec)->te_ptext = &drvid[17][0]; } } } if (execform(physdial) != PHYSOK) return ERROR; /* search for the selected unit */ for (i = 0; i < unit; ++i) if (physdial[physxlat[i]].ob_state & SELECTED) { return(index+i); /* if (livedevs[index+i]) return(index+i); else { form_alart(1, nodev); goto redogphy; } */ } return ERROR; /* if no object selected */ } /* * Translate from logical device number * to object number in logical device * dialouge box. */ int logxlat[] = { CCOLON, DCOLON, ECOLON, FCOLON, GCOLON, HCOLON, ICOLON, JCOLON, KCOLON, LCOLON, MCOLON, NCOLON, OCOLON, PCOLON }; /* * Get logical device, * return 'C'...'P' * or -1. * */ glogdev() { int i, flg; /* * Setup tree; selectively enable drive buttons * and so on. */ logdial[LOGOK].ob_state = NORMAL; logdial[LOGCN].ob_state = NORMAL; for (i = 0; i < MAXLOGDEVS; ++i) { if (logmap[i].lm_physdev < 0) flg = DISABLED; else flg = NORMAL; logdial[logxlat[i]].ob_state = flg; } if (execform(logdial) != LOGOK) return -1; for (i = 0; i < MAXLOGDEVS; ++i) if (logdial[logxlat[i]].ob_state & SELECTED) return i + 'C'; return -1; } /* * Open virtual workstation. * */ open_vwork() { int i; for (i = 0; i < 10;) work_in[i++] = 1; work_in[10] = 2; handle = phys_handle; v_opnvwk(work_in, &handle, work_out); } /* * Find and redraw all clipping rectangles * */ Do_redraw(xc, yc, wc, hc) int xc, yc, wc, hc; { GRECT t1, t2; int temp[4]; hide_mouse(); t2.g_x=xc; t2.g_y=yc; t2.g_w=wc; t2.g_h=hc; vsf_interior(handle, 1); vsf_color(handle, 0); wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h); while (t1.g_w && t1.g_h) { if (rc_intersect(&t2, &t1)) { set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h); temp[0] = xwork; temp[1] = ywork; temp[2] = xwork + wwork - 1; temp[3] = ywork + hwork - 1; v_bar(handle, temp); } wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h); } show_mouse(); } /* * Hide the mouse. * */ hide_mouse() { if (!hidden) { graf_mouse(M_OFF, 0L); hidden = TRUE; } } /* * Show the mouse. * */ show_mouse() { if (hidden) { graf_mouse(M_ON, 0L); hidden = FALSE; } } /* * Set clipping rectangle. * */ set_clip(x, y, w, h) int x, y, w, h; { int clip[4]; clip[0] = x; clip[1] = y; clip[2] = x + w; clip[3] = y + h; vs_clip(handle, 1, clip); } /* * "Execute" form, * return thingy that caused the exit. * */ execform(tree) OBJECT tree[]; { int thingy; ARROW_MOUSE; dsplymsg(tree); thingy = form_do(tree, 0); erasemsg(); BEE_MOUSE; return thingy; } /* * Display a dialogue box on the screen. * Input: * tree - object tree for dialogue box to be displayed. * Output: * formw, formh, sx, sy, lx, ly - dimensions of box. */ dsplymsg(tree) OBJECT *tree; { form_center(tree,&lx, &ly, &formw, &formh); /* sx = lx + formw / 2; sy = ly + formh / 2; */ form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh); objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk); } /* * Erase a dialogue box from the screen. * Input: * formw, formh, sx, sy, lx, ly - dimensions of box. */ erasemsg() { form_dial(3, 0, 0, 0, 0, lx, ly, formw, fOrmh); } /* * Make a long (4-byte) random. */ long longrandom() { long pattern; pattern = Random(); pattern <<= 16; pattern ^= Random(); return (pattern); } changeid(part) PART *part; { int i; long psiz; for(i = 0; i < npart; i++) { if (i == ext) continue; if (!(part[i].p_flg & P_EXISTS)) return OK; if (i > 3) { psiz = part[i].p_siz - ROOTSECT; } else { psiz = part[i].p_siz; } if (psiz < MB16) { part[i].p_id[0] = 'G'; part[i].p_id[1] = 'E'; part[i].p_id[2] = 'M'; } else { part[i].p_id[0] = 'B'; part[i].p_id[1] = 'G'; part[i].p_id[2] = 'M'; } } }