home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX302.ST / BSL.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  19.1 KB  |  674 lines

  1. /*
  2.  * BSL.C
  3.  *
  4.  *     Functions to manipulate the Bad Sector List.
  5.  *
  6.  * 25-Nov-87    ml.    Started this mess.
  7.  * 04-Dec-87    ml.    Hmmm, looks OK.
  8.  * 11-Dec-87    ml.    Added bsl2fat().
  9.  * 14-Dec-87    ml.    Structure of BSL is changed (_again_!).
  10.  *            Now, first entry in BSL contains number VENDOR
  11.  *            entries.  First byte of 2nd entry is the checksum
  12.  *            byte, while 2nd and 3rd bytes are reserved for 
  13.  *            future use.
  14.  * 08-Nov-87    jye. change or add codes so that can be used for MS-DOS
  15.  *
  16.  */
  17.  
  18. #include "obdefs.h"
  19. #include "osbind.h"
  20. #include "mydefs.h"
  21. #include "part.h"
  22. #include "bsl.h" 
  23. #include "hdx.h"
  24. #include "addr.h" 
  25. #include "error.h" 
  26.  
  27. /* Globals */
  28. BYTE *bsl;            /* bad sector list */
  29. long bslsiz;            /* num sectors BSL occupies */
  30. SECTOR badbuf[WARNBADSECTS];    /* bad sectors buffer */
  31. extern int tformat;        /* 1: called by Format */
  32.  
  33.  
  34. /*
  35.  *  Get size of the Bad Sector List (in sectors)
  36.  *    Input:
  37.  *        pdev - physical unit BSL belongs to.
  38.  *    Return:
  39.  *        number of sectors BSL occupies.
  40.  */
  41. long 
  42. gbslsiz(pdev) 
  43. int pdev;    /* physical device number */
  44. {
  45.     char bs[512];    /* boot sector image */
  46.     UWORD  ret;
  47.     
  48.        if ((ret = getroot(pdev, bs, (SECTOR)0)) != 0) {
  49.            if (tsterr(ret) == OK)
  50.             return MDMERR;
  51.         else return ERROR;
  52.        }
  53.        if (((RSECT *)(bs + 0x200 - sizeof(RSECT)))->bsl_st != STBSL)
  54.            return 0L;
  55.        return(((RSECT *)(bs + 0x200 - sizeof(RSECT)))->bsl_cnt);
  56. }
  57.  
  58.  
  59. /*
  60.  *  Set BSL parameters (starting sector and size of BSL) into
  61.  *  root sector image.
  62.  *    Input:
  63.  *        image - root sector image.
  64.  */
  65.  
  66. sbslparm(image)
  67. char *image;
  68. {
  69.     ((RSECT *)(image + 0x200 - sizeof(RSECT)))->bsl_st = STBSL;
  70.     ((RSECT *)(image + 0x200 - sizeof(RSECT)))->bsl_cnt = bslsiz;
  71. }
  72.  
  73.  
  74. /* 
  75.  *  Create a BSL in memory.
  76.  *    Input:
  77.  *        pdev - physical unit BSL will belong to.
  78.  *        type - kind of BSL to be created. NEW or EXPAND.
  79.  *        nents - number of VENDOR entries BSL should hold.
  80.  *    Output:
  81.  *        bsl - pointer to the BSL. (in bsl.h)
  82.  *    Return:
  83.  *        OK - everything is fine.
  84.  *        ERROR - anything is wrong.
  85.  *    Comment:
  86.  *        "NEW" means to create a totally new BSL.
  87.  *        "EXPAND" means to expand an existing BSL.
  88.  */
  89. creabsl(pdev, type, nents)
  90. int  pdev;    /* physical unit number */
  91. int  type;    /* kind of BSL to be created */
  92. long  nents;    /* num VENDOR entries in BSL */
  93. {
  94.     BYTE *newbsl;  /* BSL just created */
  95.     long l, size;  /* l - index into BSL;  size - size of BSL in bytes */ 
  96.     long start;       /* where to start initializing entries to zeroes */
  97.     long nument();
  98.  
  99.     if (nents == 0) {    /* no VENDOR entries specified */
  100.         size = 512L;    /* default size of BSL to 1 sector */
  101.     } else {       /* num VENDOR entries is specified */
  102.         /*------------------------------------------------------*/
  103.         /* Calculate length of BSL in bytes.            */
  104.         /* Have to add space for reserved entries and USER list    */
  105.         /* (note: (+1) to round up)                */
  106.         /*------------------------------------------------------*/
  107.     size = (((nents + RENT + WARNBADSECTS)/EPS) + 1) * 512L;
  108.     }
  109.     
  110.     /* allocate enough memory for new BSL */
  111.     if ((newbsl = (BYTE *)mymalloc((int)size)) <= 0)
  112.         return err(nomemory);
  113.     
  114.     if (type == NEW) {    /* a new BSL */
  115.         start = 0;    /* start at 0th entry, i.e. init whole BSL to 0s */
  116.     }    
  117.     else {        /* expand the BSL */
  118.         /* start init to 0s after VENDOR list */
  119.     start = (nument(VENDOR) + RENT) * BPE;
  120.     
  121.         /* copy original BSL into this expanded memory */
  122.         for (l = 0; l < start; l++)
  123.             newbsl[l] = bsl[l];
  124.     }
  125.         
  126.             
  127.     /* free up old BSL */
  128.     if (bsl > 0) free(bsl);
  129.     bsl = newbsl;
  130.     
  131.     /* init BSL to zeroes beginning at 'start'th entry */
  132.     for (l = start; l < size; l++)
  133.         bsl[l] = 0;
  134.         
  135.     /* install BSL info */
  136.     bslsiz = size/512;    /* current num sectors BSL occupies */
  137.     put3bytes(bsl, nents);  /* num VENDOR entries */
  138.     mkmagic();    /* make the BSL checks sum to BSLMAGIC byte-wise */
  139.                           
  140.     return OK;
  141. }
  142.  
  143.  
  144. /*
  145.  *  Read the BSL into memory.
  146.  *    Input:
  147.  *        pdev - physical unit that contains the BSL.
  148.  *    Output:
  149.  *        bsl - pointer to the BSL.  (in bsl.h)
  150.  *    Return:
  151.  *        OK - everything is fine.
  152.  *        INVALID - BSL doesn't checksum correctly.
  153.  *        ERROR - can't read BSL.
  154.  */
  155. rdbsl(pdev)
  156. int pdev;    /* physical unit to read from */
  157. {
  158.     int ret;
  159.     
  160.     if ((ret = rdsects(pdev, (UWORD)bslsiz, bsl, (SECTOR)STBSL)) != 0) {
  161.         if (tsterr(ret) != OK) {
  162.             if (tformat == FALSE)
  163.             err(bslread);
  164.         }
  165.     return ERROR;
  166.     }
  167.         
  168.     return(sumbsl());    /* Checksum BSL and return */
  169. }
  170.  
  171.  
  172. /*
  173.  *  Count number of entries in the requested portion of BSL.
  174.  *    Input:
  175.  *        portion - portion of BSL.  MEDIA, VENDOR, USER or UNUSED.
  176.  *    Return:
  177.  *        Number of entries of the requested portion.
  178.  *    Comments:
  179.  *        There are 3 bytes per entry (BPE), and the first 2 entries
  180.  *    are reserved (RENT) for BSL info.
  181.  */
  182. long
  183. nument(portion)
  184. int portion;        /* portion of BSL to be counted */
  185. {
  186.     long  vdr, usr;        /* num ent in VENDOR list, num ent in USER list */
  187.     long  nbytes, offset;   /* BSL's len in bytes, index into BSL */
  188.     long  get3bytes();
  189.     
  190.     /* 2nd entry in BSL contains num entries in VENDOR list */
  191.     vdr = get3bytes(bsl);
  192.     
  193.     if (portion == VENDOR)  return (vdr);
  194.     
  195.     nbytes = bslsiz*512;    /* num bytes in BSL */
  196.     
  197.     /* num bytes available for valid entries */
  198.     /* (need this because nbytes may not be divisible by BPE) */
  199.     nbytes -= (nbytes % BPE);
  200.     
  201.     /* find out num entries in USER list */
  202.     usr = 0;
  203.     for (offset = (RENT+vdr)*BPE;  /* index into beginning of USER list */
  204.          (offset < nbytes)       /* while not at end of BSL */
  205.      && get3bytes(bsl+offset); /* and it's a used entry */
  206.          offset += BPE)           /* increment index */
  207.         usr++;        /* increment num entries for USER list */
  208.          
  209.     if (portion == USER)
  210.         return (usr);        /* num entries in USER list */
  211.         
  212.     if (portion == MEDIA)
  213.         return (vdr+usr);    /* num entries in MEDIA list */     
  214.         
  215.     /* portion == UNUSED */
  216.     return ((nbytes/BPE)-RENT-vdr-usr);
  217. }
  218.  
  219.  
  220. /*
  221.  *  Write the BSL into the disk.
  222.  *    Input:
  223.  *        pdev - physical unit number BSL belongs to.
  224.  *        bsl - pointer to buffer containing the BSL. (in bsl.h)
  225.  *    Return:
  226.  *        OK - everything is fine.
  227.  *        ERROR - can't write BSL.
  228.  */
  229. wrbsl(pdev)
  230. int pdev;    /* physical unit number */
  231. {
  232.     int ret;            /* return code */
  233.  
  234.     *((int *)(bsl + 0x4)) = 0;        /* set the 4th & 5th byte to 0 in BSL */
  235.     mkmagic();
  236.     if ((ret = wrsects(pdev, (UWORD)bslsiz, bsl, (SECTOR)STBSL)) != 0) {
  237.         if (tsterr(ret) != OK)
  238.             err(bslwrite);
  239.         return ERROR;
  240.     }
  241.  
  242.     return OK;
  243.  
  244.  
  245. /*
  246.  *  Sort the BSL in memory in ascending order.
  247.  *    Input:
  248.  *        entries - number of used entries in BSL
  249.  *        bsl - pointer to the BSL. (in bsl.h)
  250.  *    Output:
  251.  *        a sorted bsl.
  252.  *    Algorithm:
  253.  *        Bubble sort.
  254.  *    Comments:
  255.  *        The reserved entries won't be sorted.
  256.  */
  257. sortbsl(entries)
  258. long  entries;    /* num entries in BSL */
  259. {
  260.     long  i, e1, e2;
  261.     long  start;    /* beginning byte of entries in BSL */
  262.     long  end;        /* tail byte of BSL */
  263.     int   change;    /* signal if changes have been made in current pass */
  264.     long  get3bytes();
  265.     
  266.     if (entries == 0L || entries == 1L)    /* BSL is empty */
  267.         return;
  268.             
  269.     change = 1;        /* assume list is not in order */
  270.     start = RENT*BPE;    /* beginning of entries in BSL */
  271.     end = entries * BPE;
  272.     while (1) {
  273.         if (change == 0)    /* if no changes made, DONE --> HOME */
  274.         return;
  275.         
  276.         change = 0;    /* assume list is in order */
  277.         for (i = start; i <= end; i += BPE) {
  278.             e1 = get3bytes(bsl+i);
  279.             e2 = get3bytes(bsl+i+BPE);
  280.             if (e1 > e2) {            /* switch if out of order */
  281.                 put3bytes(bsl+i, e2);
  282.                 put3bytes(bsl+i+BPE, e1);
  283.                 change = 1;
  284.             }
  285.         }
  286.         end -= BPE;
  287.     }
  288. }
  289.  
  290.  
  291. /*
  292.  *  Search through a sorted BSL for a given sector number.
  293.  *    Input:
  294.  *        sect - sector number searching for.
  295.  *        entries - number of used entries in the BSL.
  296.  *    Return:
  297.  *        YES - if given sector is found.
  298.  *        NO - if given sector is not found.
  299.  *    Algorithm:
  300.  *        Binary Search.
  301.  */
  302. srchbsl(sect, entries)
  303. SECTOR  sect;    /* sector searching for */
  304. long  entries;    /* num used entries in BSL */
  305. {
  306.     long  start, mid, end; /* start, middle and end indices into list */
  307.     SECTOR  temp;       /* sector number in middle of list */
  308.     long  get3bytes();
  309.  
  310.     start = RENT;        /* start after reserved entries */
  311.     end = entries+RENT-1;    /* end of BSL */ 
  312.     
  313.     while (1) {
  314.          mid = (start + end) / 2;        /* middle entry in list */
  315.         temp = get3bytes(bsl+(mid*BPE));    /* sector num at mid entry */
  316.         
  317.         if (sect == temp)    /* given sector == sector at mid entry */
  318.             return YES;        /* given sector found in list */
  319.         else if (sect < temp)    /* given sector < sector at mid entry */
  320.             end = mid - 1;    /* limit search to smaller sector num */
  321.         else            /* given sector > sector at mid entry */
  322.             start = mid + 1;    /* limit search to larger sector num */
  323.             
  324.         if (end < start)    /* list is exhausted */
  325.             return NO;        /* can't find given sector */    
  326.     }
  327. }
  328.  
  329.  
  330. /*
  331.  *  Checksum (byte-wise) the BSL.
  332.  *    Input:
  333.  *        bsl - pointer to the BSL.  (in bsl.h)
  334.  *    Return:
  335.  *        OK - BSL checksum to BSLMAGIC (0xa5).
  336.  *        INVALID - BSL does not checksum to BSLMAGIC.
  337.  */
  338. sumbsl()
  339. {
  340.     register BYTE sum;    /* byte-wise sum of BSL */
  341.     long i;        /* index into BSL */
  342.     long length;    /* length of BSL in bytes */
  343.  
  344.     length = bslsiz*512;    /* length of entire BSL */
  345.     sum = 0;    /* initialize the sum */
  346.     
  347.     /* Sum up values in the BSL by byte */
  348.     for (i = 0; i < length; i++) {
  349.         sum += bsl[i];
  350.     }
  351.     if (sum != BSLMAGIC) {    /* doesn't checksum correctly */
  352.         return INVALID;
  353.     }
  354.     return OK;    /* checksum correctly */
  355. }
  356.  
  357.  
  358. /*
  359.  *  Make the BSL checks sum to BSLMAGIC.
  360.  */
  361. mkmagic()
  362. {
  363.     register BYTE diff;    /* difference to make BSL checks sum correctly */
  364.     long i;        /* index into BSL */
  365.     long len;        /* length of BSL in bytes */
  366.     
  367.     len = bslsiz*512;    /* length of entire BSl */
  368.     diff = BSLMAGIC;    /* initialize the difference */
  369.     
  370.     /* find out what number would make BSL checks sum to BSLMAGIC */
  371.     for (i = 0; i < len; i++) {
  372.         diff -= bsl[i];
  373.     }
  374.     
  375.     /* add that difference to checksum byte (1st byte of 2nd entry of BSL) */
  376.     bsl[BPE] += diff;
  377. }
  378.  
  379.  
  380. /*
  381.  *  Add bad sectors found to the Bad Sector List.
  382.  *    Input:
  383.  *        pdev - physical unit BSL belongs to.
  384.  *        portion - portion of BSL to add to.  VENDOR or USER.
  385.  *        nbad - number of bad sectors to be added.
  386.  *    Return:
  387.  *        toadd - number of new bad sectors added to the BSL.
  388.  *        USRFULL - user part of the BSL is filled up.
  389.  *        NOMEM - not enough memory for add buffer or BSL.
  390.  *        ERROR - something is wrong.
  391.  *    Comment:
  392.  *        The entry will be added only if it is not already on the
  393.  *    bad sector list.  Binary search is performed to guarantee this.
  394.  *        If the VENDOR list is full, this routine will take care
  395.  *    of the expansion of the list also.
  396.  */
  397. addbsl(pdev, portion, nbad) 
  398. int pdev;        /* physical unit number */
  399. int portion;        /* portion of BSL */
  400. int nbad;        /* num of bad sectors to be added */
  401. {
  402.     long  entries;    /* num entries to be retained in BSL */
  403.     long  empty;    /* num empty slots available for adding entries */
  404.     long  end;        /* address of end of BSL */
  405.     int  i, toadd;    /* index to badbuf, num of bad sectors to be added */
  406.     int  ret = 0;    /* return code */
  407.     SECTOR *addbuf;    /* bad sectors to be added to BSL */
  408.     long  nument();
  409.     
  410.     /* Allocate memory for sector numbers of bad sectors to be added */
  411.     if ((addbuf = (SECTOR *)mymalloc(nbad*4)) <= 0) {
  412.         err(nomemory);
  413.         return NOMEM;
  414.     }
  415.     
  416.     if (portion == VENDOR) {    /* adding to VENDOR list */
  417.         entries = nument(VENDOR);   /* only keep the VENDOR list */
  418.         empty = 0;            /* there's no unused slot for VENDOR ent */
  419.     } else {            /* adding to USER list */
  420.         entries = nument(MEDIA);    /* keep entire list */
  421.         empty = nument(UNUSED);     /* slots left unused */
  422.     }
  423.     sortbsl(entries);        /* sort BSL in ascending order */
  424.     toadd = 0;            /* none is to be added to BSL yet */
  425.  
  426.     /* For all bad sectors found, search for them in the current BSL.
  427.        Add them to the list only when they are not already recorded.  */    
  428.     if (entries) {    /* only search if BSL is not empty */
  429.     for (i = 0; i < nbad; i++) {
  430.         if (srchbsl(badbuf[i], entries) == NO) {
  431.         addbuf[toadd] = badbuf[i];
  432.         toadd++;
  433.         }
  434.         }
  435.     } else {  /* add in all bad sectors found */
  436.     for (i = 0; i < nbad; i++)
  437.         addbuf[i] = badbuf[i];
  438.         toadd = nbad;
  439.     }
  440.     
  441.     /* All bad sectors found have been recorded.  Nothing is added to BSL */
  442.     if (toadd == 0) {
  443.         if (portion == USER && (ret = rdbsl(pdev)) != OK) {
  444.             if (ret == INVALID)
  445.                 err(cruptbsl);
  446.         goto togo;
  447.     }
  448.         ret = toadd;
  449.     }
  450.     
  451.     /*------------------------------------------------------------------*/
  452.     /* Check if there are enough empty slots for new entries.  If not,    */
  453.     /* determine what kind of entries we are adding, VENDOR or USER.    */    
  454.     /* Expand the BSL if we are adding to VENDOR list.  Give warning    */
  455.     /* if we are adding to USER list.                          */
  456.     /*------------------------------------------------------------------*/
  457.     if (toadd > empty) {
  458.         if (portion == VENDOR) {    /* this only happens at format time */
  459.         /* expanded BSL should hold (entries + toadd) VENDOR entries */
  460.         if (creabsl(pdev, EXPAND, entries+toadd) != OK)
  461.             goto togo;
  462.         } else {            /* We are adding to USER list */
  463.             err(manybad);
  464.             toadd = empty;    /* num ent to add = empty slots available */
  465.         }
  466.     }
  467.     
  468.     /* Read in orig unsorted list if adding USER entries */
  469.     if (portion == USER) {
  470.         if ((ret = rdbsl(pdev)) != OK) {
  471.             if (ret == INVALID)
  472.                 err(cruptbsl);
  473.             goto togo;
  474.         }
  475.     }
  476.                 
  477.     /* Append new entries to end of BSL */
  478.     end = bsl + (RENT + entries)*BPE;    /* end of BSL */
  479.     for (i = 0; i < toadd; i++) {
  480.         put3bytes((end + i*BPE), addbuf[i]);
  481.     }
  482.     
  483.     /* make BSL checks sum to magic number */
  484.     mkmagic();
  485.  
  486.     if (portion == USER && toadd == empty) {
  487.         ret = USRFULL;
  488.         goto togo;
  489.     }
  490.         
  491.     ret = toadd;
  492.     
  493. togo:
  494.     if (addbuf > 0) free(addbuf);            
  495.     return(ret);
  496. }
  497.  
  498.  
  499. /*
  500.  *  Mark bad sectors from the BSL to FATs of a partition.
  501.  *    Input:
  502.  *        ldev - logical device the FATs belong to.
  503.  *        fat0 - logical sector number of where FAT 0 starts.
  504.  *        fatsiz - size of FAT in sectors.
  505.  *        data - logical sector number of where data clusters start.
  506.  *        portion - part of BSL to mark from.
  507.  */
  508. bsl2fat(ldev, fat0, fatsiz, data, portion)
  509. int  ldev;    /* logical device number */
  510. SECTOR fat0;    /* starting sector number (logical) of FAT 0 */ 
  511. UWORD fatsiz;    /* FAT size */
  512. SECTOR data;    /* starting sector number (logical) of data clusters */
  513. int portion;    /* part of BSL to mark from, VENDOR or MEDIA */
  514. {
  515.     long nument(), entries;    /* num entries in the list to be considered */
  516.     long i, end;        /* indices to the list to be considered */
  517.     long get3bytes();
  518.     SECTOR badsect;        /* a bad sector in the list */
  519.     SECTOR pstart;        /* phys sector num where partition starts */
  520.     SECTOR pdata;        /* phys sector num where data block starts */
  521.     SECTOR pend;        /* phys sector num where data block ends */
  522.     SECTOR logstart(), logend();
  523.     int nbad;
  524.     
  525.     nbad = 0;            /* assume none to be marked */
  526.     pstart = logstart(ldev);    /* find where partition starts */
  527.     pdata = pstart + data;    /* find where data block starts */
  528.     pend = logend(ldev);    /* find where data block ends */    
  529.     entries = nument(portion);    /* find num entries in given portion */
  530.     sortbsl(entries);        /* sort given portion of BSL */
  531.     
  532.     end = (RENT + entries) * BPE;
  533.     
  534.     /* Store vendor bad sectors of the logical device in badbuf */
  535.     for (i = BPE*RENT; i < end; i += BPE) {
  536.         if ((badsect = get3bytes(bsl+i)) > pend)
  537.             break;
  538.             
  539.         if (badsect >= pdata) {
  540.             badbuf[nbad++] = badsect;
  541.             
  542.             /* if badbuf overflows, mark what we have so far in the FAT */
  543.             if (nbad == WARNBADSECTS) {
  544.                 if (fixbadcls(ldev, fat0, fatsiz, data, nbad) < 0) {
  545.                     return ERROR;
  546.                 }
  547.                 nbad = 0;    /* reinit num bad sectors in partition to 0 */
  548.             }
  549.         }
  550.     }
  551.     
  552.     /* Bad sectors in partition not marked in FAT yet */
  553.     if (nbad) {
  554.         if (fixbadcls(ldev, fat0, fatsiz, data, nbad) < 0) {
  555.             return ERROR;
  556.         }
  557.     }
  558.     
  559.     return OK;
  560. }
  561.  
  562.  
  563. /*
  564.  *  Count number of bad sectors on a logical drive recorded in BSL.
  565.  *    Input:
  566.  *        ldev - logical drive to be considered.
  567.  *    Return:
  568.  *        nbad - number of bad sectors found.
  569.  */
  570. long
  571. cntbad(ldev)
  572. int  ldev;    /* logical drive number */
  573. {
  574.     SECTOR pstart, pend;    /* phys starting and ending block of ldev */
  575.     extern SECTOR logstart(), logend();
  576.     long nbad=0L;        /* num bad sectors on ldev */
  577.     long entries, nument(), bslend;
  578.     long curr, get3bytes();
  579.     int done, i;
  580.     
  581.     pstart = logstart(ldev);    /* starting block # of partition */
  582.     pend = logend(ldev);    /* ending block # of partition */
  583.     entries = nument(MEDIA);    /* num entries in BSL */
  584.     sortbsl(entries);        /* sort BSL */
  585.     
  586.     done = 0;
  587.     bslend = (RENT+entries) * BPE;
  588.     for (i = RENT*BPE; (!done) && (i < bslend); i += BPE) {
  589.         curr = get3bytes(bsl+i);  /* get next entry in BSL */
  590.         if (curr < pstart)      /* not within logical drive's range yet */
  591.             continue;
  592.         if (curr <= pend)      /* within logical drive's range */
  593.             nbad++;
  594.         else done = 1;          /* pass logical drive's range */
  595.     }
  596.     return (nbad);
  597. }
  598.  
  599.  
  600. /*
  601.  *  Put a word into memory in 68000 format.
  602.  *    Input:
  603.  *        p - pointer to memory.
  604.  *        i - word to be put.
  605.  */
  606. putword(p, i)
  607. BYTE *p;
  608. UWORD i;
  609. {
  610.     *p = i >> 8;
  611.     *(p+1) = i;
  612. }
  613.  
  614.  
  615. /*
  616.  *  Get a 68000 format word from memory.
  617.  *    Input:
  618.  *        p - pointer to memory.
  619.  *    Return:
  620.  *        i - word read from memory.
  621.  */        
  622. getword(p)
  623. BYTE *p;
  624. {
  625.     UWORD i;
  626.     
  627.     i = *p;
  628.     i <<= 8;
  629.     i |= *(p+1);
  630.     return (i);
  631. }
  632.  
  633.  
  634. /*
  635.  *  Put 3 bytes (68000 format) into memory.
  636.  *    Input:
  637.  *        p - pointer to memory.
  638.  *        l - long which contains the 3 bytes at the low-bit end.
  639.  */
  640. put3bytes(p, l)
  641. BYTE *p;
  642. long l;
  643. {
  644.     *p = l >> 16;
  645.     *(p+1) = l >> 8;
  646.     *(p+2) = l;
  647. }    
  648.  
  649.  
  650. /*
  651.  *  Get 3 bytes (68000 format) from memory.
  652.  *    Input:
  653.  *        p - pointer to memory.
  654.  *    Return:
  655.  *        l - a long which contains the 3 bytes read in last 3 bytes.
  656.  */
  657. long
  658. get3bytes(p)
  659. BYTE *p;
  660. {
  661.     long  k=0x000000ff, l=0x000000ff;
  662.     
  663.     l &= *p;        /* first byte */
  664.     l <<= 16;
  665.     k &= *(p+1);    /* second byte */
  666.     k <<= 8;
  667.     l |= k;
  668.     k = 0x000000ff;
  669.     k &= *(p+2);    /* third byte */
  670.     l |= k;
  671.     return (l);
  672. }
  673.