home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 195_01 / doctor.c < prev    next >
Text File  |  1987-10-05  |  8KB  |  389 lines

  1. /* [DOCTOR.C of JUGPDS Vol.18]
  2. *****************************************************************
  3. *                                *
  4. *    Written by  Hakuo Katayose (JUG-CP/M No.179)        *
  5. *            49-114 Kawauchi-Sanjuunin-machi        *
  6. *            Sendai, Miyagi 980                          *
  7. *            Phone: 0222-61-3219                *
  8. *                                *
  9. *    Edited & tested by Y. Monma (JUG-C/M Disk Editor)       * 
  10. *                                *
  11. *****************************************************************
  12. */
  13.  
  14. /* doctor - disk doctor */
  15.  
  16. #define BIOS_CALL(n,bc,de,a)    biosh((n),(bc),(de))
  17.  
  18.  
  19. #define UP        0x05    /* Screen_Edit mode Cursole_up        */
  20. #define DOWN        0x18    /*        --II--    Cursole_down    */
  21. #define LEFT        0x13    /*        --II--    Cursole_letf    */
  22. #define RIGHT        0x04    /*        --II--    Cursole_right    */
  23. #define ESC_CH        '@'    /* Special command sequence code    */
  24. #define ENDINPUT    'Z'    /* Screen_Edit mode exit        */
  25. #define ABORT        'X'    /* Screen_Edit mode exit without Write */
  26.  
  27. /*
  28.  ************************************************************************
  29.  *    HOME        Cursor Home Positioning                    *
  30.  *    CLRS        Clear Screen and Cursor Home Positioning    *
  31.  *    POS(x,y)    Set Cursor position (x,y)            *
  32.  ************************************************************************
  33. */
  34. #define ESC        0x1b
  35. #define    HOME        bios(4,ESC); bios(4,'H')
  36. #define    CLRS        bios(4,ESC); bios(4,'E')
  37. #define    POS(x,y)    bios(4,ESC); bios(4,'Y'); bios(4,y+32); bios(4,x+32)
  38.  
  39.  
  40. /*
  41.  *    Global DATA defintion
  42.  */
  43.  
  44. unsigned    tpd, bpd, No_Of_Track, No_Of_Sector, No_Of_Block, Block_Length;
  45.  
  46. /*
  47.  *    DPB (disk parameter block) definition for CP/M 2.x
  48.  */
  49.  
  50. struct    dpb {
  51.     int    spt;        /* logical sector per track */
  52.     char    bsh,        /* block shift factor       */
  53.         blm,        /* block mask            */
  54.         exm;        /* extent mask            */
  55.     int    dsm,        /* disk storage (reacord)   */
  56.         drm;        /* total directory entry - 1*/
  57.     char    al0,al1;    /* allocation bit mask        */
  58.     int    cks;        /* size of directory check  */
  59.     int    off;        /* offset (system track)    */
  60. };
  61.  
  62. /*
  63.  *    DPH (disk parameter header) definition for CP/M 2.x
  64.  */
  65.  
  66.  
  67. struct    dph {
  68.     char        *xltp;        /* logical to physical trans  */
  69.     char        dmy1[6];    /* system use            */
  70.     char        *dirb;        /* pointer for DIR_BUFFER   */
  71.     struct dpb    *dpbp;        /* pointer for DPB        */
  72.     char        *csvp,        /* pointer for check_size   */
  73.             *alvp;        /* pointer for allocation   */
  74. };
  75.  
  76.  
  77. struct    dph    *DPH;
  78. struct    dpb    *DPB;
  79.  
  80. int        bn, bufcnt, es;
  81. char        vflag, logflag, blkflag;
  82. char        queflag, *quep;
  83. char        *hexdigit;
  84.  
  85. main()
  86.  
  87. {
  88.     char    *p, c, comnd, buf[2048], w[128], *wp;
  89.     int    d, i, j, v, len, t, s, n, sc;
  90.  
  91.     hexdigit = "0123456789ABCDEFabcdef";
  92.     queflag = 0;
  93.     vflag = 0;
  94.     logflag = 1;
  95.     blkflag = 0;
  96.     bn = 0;
  97.     s = 1;
  98.     p = buf;
  99.     CLRS;
  100.     POS(0, 0); printf("Disk: "); d = toupper(bios(3, 0)) - 'A';
  101.     seldisk(d);
  102.     t = 0;
  103.     while ( GetSector(d, t, s, p) == 0 ) {
  104. loopd:        POS(0, 4);
  105.         Display(p);
  106.         c = getchr();
  107.         switch ((comnd = tolower(c))) {
  108.         case 'a' :
  109.             Modify(t, s, p, comnd, p);
  110.             break;
  111.         case 'b' :
  112.             POS(57, 0);    scanf("%d", &bn);
  113.             if (bn < 0 || bn > DPB->dsm)
  114.                 break;
  115.             blkflag = (blkflag) ? 0 : 1;
  116.             logflag = 1;
  117.             sc = bn * ( DPB->blm + 1);
  118.             t  = sc / DPB->spt;
  119.             s  = sc % DPB->spt + 1;
  120.             break;
  121.         case 'c' :
  122.             setmem(p, 128, 0);
  123.             PutSector(t, s, p);
  124.             break;
  125.         case 'd' :
  126.             POS(5, 0); d = toupper(bios(3, 0)) - 'A';
  127.             seldisk(d);
  128.             break;
  129.         case 'e' :
  130.             exit();
  131.         case 'h' :
  132.             Modify(t, s, p, comnd, p);
  133.             break;
  134.         case 'i' :
  135.             setmem(p, 128, 0x0e5);
  136.             PutSector(t, s, p);
  137.             break;
  138.         case 'l' :
  139.             logflag = logflag ? 0 : 1;
  140.             seldisk(d);
  141.             break;
  142.         case 'q' :
  143.             queflag = queflag ? 0 : 1;
  144.             quep = "++++++++++++++++";
  145.             goto loopd;
  146.         case 't' :
  147.             POS(16,0);    scanf("%d", &t);
  148.             break;
  149.         case 's' :
  150.             POS(37,0);    scanf("%d", &s);
  151.             break;
  152.         case '+' :
  153.         case ';' :
  154.             if ( ++s > DPB->spt ) {s = 1; t++;}
  155.             break;
  156.         case '-' :
  157.         case '=' :
  158.             if ( --s < 1 ) {s = DPB->spt; t--;}
  159.             break;
  160.         case '>' :
  161.         case '.' :
  162.             t++;
  163.             break;
  164.         case '<' :
  165.         case ',' :
  166.             t--;
  167.             break;
  168.         case ']' :
  169.         case '}' :
  170.             bn++;
  171.             if (bn < 0 || bn > DPB->dsm)
  172.                 break;
  173.             blkflag = (blkflag) ? 0 : 1;
  174.             logflag = 1;
  175.             sc = bn * ( DPB->blm + 1);
  176.             t  = sc / DPB->spt;
  177.             s  = sc % DPB->spt + 1;
  178.             break;
  179.         case '[' :
  180.         case '{' :
  181.             bn--;
  182.             if (bn < 0 || bn > DPB->dsm)
  183.                 break;
  184.             blkflag = (blkflag) ? 0 : 1;
  185.             logflag = 1;
  186.             sc = bn * ( DPB->blm + 1);
  187.             t  = sc / DPB->spt;
  188.             s  = sc % DPB->spt + 1;
  189.             break;
  190.         default :
  191.             goto loopd;
  192.         }
  193.         s = max(1, s);
  194.         s = min(DPB->spt, s);
  195.         t = max(0, t);
  196.         t = min(tpd + DPB->off*logflag, t);
  197.         bn = (t * DPB->spt + s -1)/(DPB->blm+1);
  198.     }
  199.     POS(0,23);
  200. }
  201.  
  202.  
  203. GetSector(d, t, s, p)
  204. char    *p;
  205. {
  206.     int    bn;
  207.  
  208.     bn = (t * DPB->spt + s -1)/(DPB->blm+1);
  209.     POS(16,0);    printf("%4d      ", t);
  210.     POS(37,0);    printf("%3d      ", s);
  211.     POS(56,0);    printf("%4d      ", bn);
  212.     BIOS_CALL(10, t+logflag*DPB->off, 0, 0);    /* set Track No  */
  213.     BIOS_CALL(11, s-1, 0, 0);            /* set Sector No */
  214.     BIOS_CALL(12, p, 0, 0);                /* set DMA       */
  215. /*
  216.     BIOS_CALL(28, 0, 0, 1);                /* for CP/M 3.x  */
  217. */
  218.     BIOS_CALL(13, 0, 0, 0);
  219.     return 0;
  220. }
  221.  
  222.  
  223. PutSector(t, s, p)
  224. int     t, s;
  225. char    *p;
  226. {
  227.     BIOS_CALL(10,t+logflag*DPB->off, 0, 0);        /* set track no */
  228.     BIOS_CALL(11, s-1, 0, 0);            /* set Sector No */
  229.     BIOS_CALL(12, p, 0, 0);                /* set dma      */
  230. /*
  231.     BIOS_CALL(28, 0, 0, 1);                /* for CP/M Plus  */
  232. */
  233.     BIOS_CALL(14, 1, 0, 0);
  234. }
  235.  
  236.  
  237. getchr()
  238. {
  239.     if (queflag) {
  240.         if (*(quep+1) == '\0')
  241.             queflag = 0;
  242.         return *quep++;
  243.         }
  244.     return bios(3, 0);
  245. }
  246.  
  247.  
  248. Modify(t, s, p, mode, bp)
  249. char    *p, *bp, mode;
  250. {
  251.     int    j, x, y, c, c1, end_flag;
  252.  
  253.     j = 0;
  254.     x = 0;    y = 0;
  255.  
  256.     POS(0,12);
  257.     printf("                                                  ");
  258.     POS(0,12);
  259.     printf("%s mode Modify-Data :", mode == 'a' ? "Ascii" : "Hexdec");
  260.     end_flag = 0;
  261.     while (!end_flag) {
  262.         POS(x+x, (mode == 'a' ? y+y+5 : y+y+4));
  263.         switch (c = bios(3,0)) {
  264.             case UP :
  265.                 if (y)
  266.                     y--;
  267.                 break;
  268.             case DOWN :
  269.                 if (y < 4)
  270.                     y++;
  271.                 break;
  272.             case LEFT :
  273.                 if (x)
  274.                     x--;
  275.                 else if (y) {
  276.                     x = 31;
  277.                     y--;
  278.                     }
  279.                 break;
  280.             case RIGHT :
  281.                 if (x < 31)
  282.                     x++;
  283.                 else if (y < 3) {
  284.                     x = 0;
  285.                     y++;
  286.                     }
  287.                 break;
  288.             default :
  289.                 if (c == ESC_CH) {
  290.                     if ((c = toupper(bios(3,0))) == ENDINPUT) {
  291.                         end_flag = 1;
  292.                         break;
  293.                         }
  294.                     else if (c == ABORT) {
  295.                         end_flag = 1;
  296.                         break;
  297.                         }
  298.                     }
  299.                 if (mode == 'h') {
  300.                     c1 = bios(3, 0);
  301.                     c1 = toupper(c1);
  302.                     c  = toupper(c);
  303.                     if ((c1 = index_(hexdigit, c1)) >= 0
  304.                      && (c = index_(hexdigit, c)) >= 0) {
  305.                         *(p + j) = c*16+c1;
  306.                     }
  307.                 }
  308.                 else
  309.                     *(p + j) = c;
  310.                 POS(0, 4);
  311.                 Display(p);
  312.                 if (x < 31)
  313.                     x++;
  314.                 else if (y < 3) {
  315.                     x = 0;
  316.                     y++;
  317.                     }
  318.             }
  319.         j = (y << 5) + x;
  320.         }
  321.     if (c != ABORT)
  322.         PutSector(t, s, bp);
  323.     POS(0, 12);
  324.     printf("                                                  ");
  325. }
  326.  
  327.  
  328. seldisk(d)
  329. int d;
  330. {
  331.     unsigned    x,y,z;
  332.  
  333.     DPH = BIOS_CALL(9, d, 0, 0);        /* select disk  */
  334.     DPB = DPH->dpbp;
  335.     x = DPB->blm+1;
  336.     y = DPB->dsm;
  337.     z = DPB->spt;
  338.     No_Of_Sector  = z;
  339.     No_Of_Track   = (x * y + z - 1)/ z + DPB->off;
  340.     No_Of_Block   = y + 1;
  341.     Block_Length  = x * 128;
  342.  
  343.     POS(0,21);
  344.      printf("Track_No :=%6d       Sector_No :=%6d       Block_No   :=%6d\n",
  345.                  No_Of_Track, No_Of_Sector, No_Of_Block);
  346.     printf("Offset   :=%6u       Directry  :=%6u       Block_size :=%6d",
  347.             DPB->off, DPB->drm+1, Block_Length);
  348.     POS(0,0);
  349.     printf("Disk:     Track:              Sector:              Block:");
  350.     POS(5 ,0);    putchar(d+'A');
  351.     POS(0 ,2);    printf(logflag ? "(  Log" : "( Phys");
  352.     POS(6 ,2);    printf("ical-CP/M-Sector )");
  353.     tpd = No_Of_Track-1;
  354.     bpd = No_Of_Block-1;
  355.     return DPB->off*logflag;
  356. }
  357.  
  358.  
  359. setmem(p, l, d)
  360. char *p, d;
  361. int  l;
  362. {
  363.     while (l--) *p++ = d;
  364. }
  365.  
  366.  
  367. index_(s, c)
  368. char *s, c;
  369. {
  370.     char *p;
  371.  
  372.     for (p = s; *s != c; s++)
  373.         if (!*s)
  374.             return -1;
  375.     return s-p;
  376. }
  377.  
  378.  
  379. /*    for CP/M Plus
  380. BIOS_CALL(fn, bcreg, dereg, areg)
  381. {
  382.     biospb.BIOS_NO = fn;
  383.      biospb.BC_REG  = bcreg;
  384.      biospb.DE_REG  = dereg;
  385.      biospb.A_REG  = areg;
  386.     return bdos(50, &biospb);
  387. }
  388. */
  389.