home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / info / spartan.lha / Spartan / Low-Level / SFormat.c < prev    next >
C/C++ Source or Header  |  1992-05-16  |  8KB  |  370 lines

  1. /*   SFormat version 2.0 by Paul Harker....written in Manx C v3.6    */
  2.        
  3.  
  4. #include stdio.h
  5. #include ctype.h
  6.  
  7. typedef unsigned char byte;
  8.  
  9. byte RESET  = 128;        /*define CONTROL flags*/
  10. byte BUSY    = 64;
  11. byte REQUEST = 32;
  12. byte MSG     = 16;
  13. byte COMMAND  = 8;
  14. byte INPUT    = 4;
  15.  
  16. byte ACK     = 16;        /*define cmd flags*/
  17. byte PHASE    = 8;
  18. byte SELECT   = 4;
  19. byte BUS      = 1;
  20.  
  21. byte *data = 0x000001;          /*pointer to SCSI data register*/
  22. byte *initCMD = 0x000003;       /*pointer to SCSI ICR register*/
  23. byte *targetCMD = 0x000007;     /*pointer to SCSI TCR register*/
  24. byte *control = 0x000009;       /*pointer to SCSI control register*/
  25. byte *status = 0x00000B;        /*pointer to SCSI status register*/
  26.  
  27. byte inbuff[100], outbuff[100], cmdbuff[10], statin, msg; /* SCSI IO storage */
  28.  
  29. unsigned int address, intrlv;
  30.  
  31. main()
  32. {
  33. int dummy;
  34.  
  35.  
  36.     printf("\n\n                               SFormat V2.0\n");
  37.     printf("                          Spartan-SCSI Formatter\n");
  38.     printf("                            ⌐ 1991 Paul Harker\n");
  39.     printf("\n  This utility will perform a low-level format of the hard");
  40.     printf(" drive. ALL data\n  will be destroyed.\n\n  Continue? (Y/N) :");
  41.         if (toupper(getchar()) != 'Y')
  42.           exit(200);
  43.  
  44.     printf("\n   Base Address of interface :");
  45.       doBASE();
  46.  
  47.     gets(dummy);      /*  Toss a Null  */
  48.  
  49.     printf("\n  SCSI address :");
  50.       address = getNumber(0,6);
  51.  
  52.     printf("  Interleave :");
  53.       intrlv = getNumber(1,27); 
  54.  
  55.     printf("\n  Ready to format.\n\n  Continue? (Y/N) :");
  56.         if (toupper(getchar()) != 'Y')
  57.           exit(200);
  58.  
  59.      printf("  Zeroing Drive..........");
  60.      fflush(stdout);    
  61.      reZERO();
  62.      errorCHECK();
  63.  
  64.      printf("  Checking Drive Ready...");
  65.      fflush(stdout);
  66.      unitRDY();
  67.      errorCHECK();
  68.  
  69.      printf("  Selecting Mode.........");
  70.      fflush(stdout);
  71.      modeSEL();
  72.      errorCHECK();
  73.  
  74.      printf("  Formatting.............");
  75.      fflush(stdout);
  76.      doFORMAT();
  77.      errorCHECK();
  78.      printf("\n Format Complete.\n");
  79. }
  80.  
  81. errorCHECK()    /* Check Status Byte and Report Error Data */
  82. {
  83. int count;
  84.  
  85. if (statin)
  86.     {  
  87.     if (statin == 8)
  88.        printf("\n SCSI Device Busy Error\n");
  89.     else 
  90.        {
  91.        readERROR();
  92.        printf("\n Completion Status Error #%d:",statin);
  93.        for (count = 0;count < 27 ;count ++) 
  94.            if (inbuff[count])
  95.                printf("\n Sense Error Byte #%d: %d",count,inbuff[count]);
  96.        }
  97.     exit(700);
  98.     }
  99. printf("OK\n");
  100. }
  101.  
  102. readERROR()   /* Request Sense Command */
  103. {
  104. clearCMD();
  105. clearIN();
  106. cmdbuff[0] = 3;
  107. cmdbuff[4] = 27;       /* Read all possible sense data */
  108. scsi();
  109. }
  110.  
  111. /*  
  112.    future stuff eh dude?
  113. clearBUFF(&buff,elements)    /  Clear Specified Buffer  /
  114. int elements;
  115. byte buff[elements];
  116. {
  117. int count;
  118.  
  119. while (count = 0; count < elements; count++)
  120.     buff[count] = 0;
  121. }
  122. */
  123.  
  124. getNumber(lower,upper)   /* get a number between -32k to 32k  */
  125.  
  126. int lower, upper;
  127. {
  128. char input[10];
  129. int test = 0xffff;
  130.  
  131. while((test > upper) || (test < lower)){
  132.       gets(input);
  133.         test = atoi(input);
  134.           if ((test > upper) || (test < lower))
  135.              printf("\n  Bad Entry. Please try again  :");
  136.       }
  137. return test;
  138. }
  139.  
  140.  
  141.  
  142. reZERO()
  143. {
  144.     clearCMD();
  145.     cmdbuff[0] = 1;
  146.     scsi();
  147. }    
  148.  
  149.  
  150. unitRDY()
  151. {
  152.     clearCMD();
  153.     scsi();
  154. }
  155.  
  156.  
  157. modeSEL()
  158. {
  159.     clearCMD();
  160.     clearOUT();
  161.  
  162.     cmdbuff[0] = 21;
  163.     cmdbuff[4] = 12;  /* parameter list length */
  164.  
  165.     outbuff[3] = 8;
  166.     outbuff[10] = 2;  /* high byte of block size -512 bytes- */
  167.  
  168.     scsi();
  169. }
  170.  
  171.  
  172. doFORMAT()
  173. {
  174.  
  175.     clearCMD();
  176.     clearOUT();
  177.  
  178.     cmdbuff[0] = 4;
  179.     cmdbuff[4] = (byte) intrlv;
  180.  
  181.     scsi();   
  182. }
  183.  
  184.  
  185.  
  186. clearCMD()   /*   Clear command buffer   */
  187. {
  188. int count;
  189.  
  190.    for(count=0;count <= 10 ;count++)
  191.        cmdbuff[count] = 0;
  192.  
  193. }
  194.  
  195.  
  196. clearOUT()      /*   Clear output buffer    */
  197. {
  198. int count;
  199.  
  200.   for(count=0;count <= 100;count++)
  201.        outbuff[count] = 0;
  202. }
  203.  
  204.  
  205. clearIN()       /*   Clear Input Data Buffer    */
  206. {
  207. int count;
  208.  
  209.    for(count = 0;count < 100;count++)
  210.       inbuff[count] = 0;
  211. }
  212.  
  213. goodmorning()    /*wake up the controller*/
  214. {
  215. byte initiator = 128, target = (1 << address);
  216. long count;
  217.         
  218.     *initCMD = 0;                            /*clear the controller chip*/
  219.     *(initCMD + 2) = 0;
  220.     *control = 0;
  221.  
  222.     for(count = 0; *control & BUSY; count++){  /*if bus is busy, wait*/
  223.        if (count >= 100000){                /*wait for bus*/
  224.            printf("\n  SCSI bus BUSY error.\n\n");   
  225.            exit(100);
  226.            }
  227.        }
  228.  
  229.     *data = initiator | target;                   /*load scsi addresses */
  230.     *initCMD |= BUS;                         /*assert bus*/
  231.  
  232.     for(count = 0;count <60;count++);        /*wait 2 * 45 nanoseconds*/
  233.  
  234.     *initCMD |= SELECT;                      /*assert select*/
  235.  
  236.     for(count = 0; !(*control & BUSY); count++){
  237.         if (count >= 100000){            /*wait for busy from controller*/
  238.            printf("\n  No response from SCSI address #%d.\n\n",address);   
  239.              exit(100);
  240.            }
  241.         }
  242.     for(count = 0;count < 60;count++);
  243.     *initCMD &= ~SELECT;                     /*deassert select*/
  244. }
  245.  
  246.  
  247.  
  248.  
  249. scsi()          /* send Command and handle I/O */
  250. {
  251. byte dataout = 0, datain = 1, cmdout = 2,
  252.      instat = 3, msgin = 7;
  253.  
  254.     goodmorning();
  255.  
  256.     while (*control & BUSY){
  257.  
  258.        waitREQ();
  259.  
  260.        if (*control & COMMAND){                    /*cmd I/O?*/
  261.            if (*control & MSG){                    /*message?*/
  262.                if (*control & INPUT)              /*if message in*/
  263.                    doIO(msgin,&msg);             /*read it..msg out invalid*/
  264.            }
  265.  
  266.            else {                                 /*not msg..status or cmd*/
  267.                if (*control & INPUT)
  268.                    doIO(instat,&statin);          /*get status*/
  269.                else
  270.                    doIO(cmdout,cmdbuff);            /*send command*/
  271.           }
  272.        }
  273.  
  274.        else {                                    /*controller requests data I/O*/
  275.            if (*control & INPUT)                    /* input or output? */
  276.               doIO(datain,inbuff);                  /* input */
  277.            else
  278.               doIO(dataout,outbuff);                /* output */
  279.        }
  280.     }
  281. }
  282.  
  283.  
  284.  
  285. doIO(mode,buffer)        /* Read-Send whatever the controller desires */
  286. byte mode, buffer[];
  287. {
  288. int index, count;
  289.  
  290.     *targetCMD = mode;                             /*what mode are we in*/
  291.  
  292.     for (index = 0;(*status & PHASE);index++){    /*while phase unchanged*/
  293.  
  294.          waitREQ();
  295.  
  296.          if (mode == 1 || mode == 3 || mode == 7)             /*if input*/
  297.             *(buffer + index) = *data;       /*get data*/
  298.  
  299.          else                                /*if output*/
  300.             *data = *(buffer + index);       /*write it*/
  301.  
  302.          *initCMD |= ACK;                  /*Perform ack*/
  303.  
  304.          while(*control & REQUEST);        /*wait for dropped req*/
  305.  
  306.          *initCMD &= ~ACK;                 /*drop ack*/
  307.  
  308.          for(count=0;count<4000;count++);  /*kill some time*/
  309.     }
  310.    *targetCMD = 0;
  311. }
  312.  
  313.  
  314. waitREQ()           /* Wait for REQ to be asserted */
  315. {
  316.     while(!(*control & REQUEST))
  317.         if(!(*control & BUSY) || !(*control & PHASE))
  318.             return();
  319. }
  320.             
  321. getADD(hex)
  322. char *hex;
  323. {
  324. int low, high, address;
  325.  
  326. high = unhex(*hex);
  327. low = unhex(*(hex+1));
  328. address = (high*16 + low);
  329. if (high < 0 || low < 0)
  330.     address = -1;
  331. return address;
  332. }
  333.  
  334. doBASE()
  335. {
  336. char hex[20];
  337. int address = -1;
  338. unsigned long base;
  339.  
  340. while (address < 0)
  341.     {
  342.     scanf("%s",hex);
  343.     address = getADD(hex);
  344.     if (address < 0)
  345.         printf("\n  Bad Entry. Please try again  :");
  346.     }
  347. base = (address * 0x10000);
  348. data += base;          /*pointer to SCSI data register*/
  349. initCMD += base;       /*pointer to SCSI ICR register*/
  350. targetCMD += base;     /*pointer to SCSI TCR register*/
  351. control += base;       /*pointer to SCSI control register*/
  352. status += base;        /*pointer to SCSI status register*/
  353. }
  354.  
  355. unhex(ascii)
  356. char ascii;
  357. {
  358. int value;
  359. char tmp;
  360.  
  361. tmp = toupper(ascii);
  362. if (isalpha(tmp))
  363.     value = tmp-55;
  364. else if (isdigit(tmp))
  365.     value = tmp - 48;
  366. if (value > 15 || value < 0)
  367.     value = -1;
  368. return value;
  369. }
  370.