home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 363_01 / object.c < prev    next >
C/C++ Source or Header  |  1991-12-17  |  6KB  |  197 lines

  1. /***********************************************************************
  2.  *
  3.  *      OBJECT.C
  4.  *      Object File Routines for 68000 Assembler
  5.  *
  6.  *    Function: initObj()
  7.  *      Opens the specified object code file for writing. If the file cannot 
  8.  *      be opened, then the routine prints a message and exits. 
  9.  *
  10.  *      outputObj()
  11.  *      Places the data whose size, value, and address are specified in the 
  12.  *      object code file. If the new data would cause the current S-record to 
  13.  *      exceed a certain length, or if the address of the current item doesn't
  14.  *      follow immediately after the address of the previous item, then the 
  15.  *      current S-record is written to the file (using writeObj) and a new 
  16.  *      S-record is started, beginning with the specified data. 
  17.  *
  18.  *      writeObj()
  19.  *      Writes the current S-record to the object code file. The record length 
  20.  *      and checksum fields are filled in before the S-record is written. If 
  21.  *      an error occurs during the writing, the routine prints a message and
  22.  *      exits. 
  23.  *
  24.  *      finishObj()
  25.  *      Flushes the S-record buffer by writing out the data in it (using 
  26.  *      writeObj), if any, then writes a termination S-record and closes the 
  27.  *      object code file. If an error occurs during this write, the routine 
  28.  *      prints a messge and exits.
  29.  *
  30.  *   Usage: initObj(char *name)
  31.  *
  32.  *      int outputObj(long newAddr, int data, int size)
  33.  *
  34.  *      int writeObj(void)
  35.  *
  36.  *      finishint Obj(void)
  37.  *      
  38.  *      Author: Paul McKee
  39.  *      ECE492    North Carolina State University, 12/13/86
  40.  
  41.  *      Modified A.E. Romer     17 March 1991
  42.  *      Version 1.0
  43.  ************************************************************************/
  44.  
  45.  
  46. #include <stdio.h>
  47. #include <ctype.h>
  48. #include "asm.h"
  49.  
  50. /* Define the maximum number of bytes (address, data, 
  51.    and checksum) that can be in one S-record */
  52. #define SRECSIZE  36    
  53.  
  54. extern char line[256];
  55. extern FILE *objFile;
  56.  
  57. static char sRecord[80], *objPtr;
  58. static char byteCount, checksum, lineFlag;
  59. static long objAddr;
  60. static char objErrorMsg[] = "Error writing to object file\n";
  61.  
  62. int initObj(char *name)
  63.     {
  64.  
  65.     objFile = fopen(name, "w");
  66.     if (!objFile)
  67.         {
  68.         puts("Can't open object file");
  69.         exit(0);
  70.         }
  71.     /* Output S-record file header */
  72.  
  73. /*  fputs("Here comes an S-record...\n", objFile); */
  74.  
  75.     fputs("S004000020DB\n", objFile);
  76.     lineFlag = FALSE;
  77.  
  78.     return NORMAL;
  79.     }
  80.  
  81.  
  82. int outputObj(long newAddr, long data, int size)
  83.     {
  84.     /* If the new data doesn't follow the previous data, or if the S-record
  85.        would be too long, then write out this S-record and start a new one */
  86.  
  87.     if ((lineFlag && (newAddr != objAddr)) || (byteCount + size > SRECSIZE))
  88.         {
  89.         writeObj();
  90.         lineFlag = FALSE;
  91.         }
  92.  
  93.     /* If no S-record is already being assembled, then start making one */
  94.     if (!lineFlag)
  95.         {
  96.         if ((newAddr & 0xFFFF) == newAddr)
  97.             {
  98.             sprintf(sRecord, "S1  %04X", newAddr);
  99.             byteCount = 2;
  100.             }
  101.         else if ((newAddr & 0xFFFFFF) == newAddr)
  102.             {
  103.             sprintf(sRecord, "S2  %06X", newAddr);
  104.             byteCount = 3;
  105.             }
  106.         else
  107.             {
  108.             sprintf(sRecord, "S3  %08lX", newAddr);
  109.             byteCount = 4;
  110.             }
  111.         objPtr = sRecord + 4 + byteCount*2;
  112.         checksum = (char) (checkValue(newAddr) & 0xff);
  113.         objAddr = newAddr;
  114.         lineFlag = TRUE;
  115.         }
  116.     
  117.     /* Add the new data to the S-record */
  118.     switch (size)
  119.         {
  120.         case BYTE : data &= 0xFF;
  121.                     sprintf(objPtr, "%02X", data);
  122.                     byteCount++;
  123.                     checksum += (char) (data & 0xff);
  124.                     break;
  125.         case WORD : data &= 0xFFFF;
  126.                     sprintf(objPtr, "%04X", data); 
  127.                     byteCount += 2;
  128.                     checksum += (char) (checkValue(data) & 0xff);
  129.                     break;
  130.         case LONG : sprintf(objPtr, "%08lX", data);
  131.                     byteCount += 4;
  132.                     checksum += (char) (checkValue(data) & 0xff);
  133.                     break;
  134.         default   : printf("outputObj: INVALID SIZE CODE!\n");
  135.                     exit(0);
  136.         }
  137.     objPtr += size*2;
  138.     objAddr += (long) size;
  139.  
  140.     return NORMAL;
  141.     }   
  142.  
  143.  
  144. long checkValue(long data)
  145.     {
  146.     return (data + (data >> 8) + (data >> 16) + (data >> 24)) & 0xFF;
  147.     }
  148.  
  149.  
  150. int writeObj(void)
  151.     {
  152.     char recLen[3];
  153.  
  154.                     /* Fill in the record length
  155.                      * (including the checksum in the record length */
  156.     sprintf(recLen, "%02X", ++byteCount);
  157.     strncpy(sRecord+2, recLen, 2);
  158.  
  159.                     /* Add the checksum
  160.                      * (including in the checksum the record length) */
  161.     checksum += byteCount;
  162.     sprintf(objPtr, "%02X\n", (~checksum & 0xFF));
  163.     
  164.                     /* Output the S-record to the object file */
  165.  
  166. /*  fputs("Here comes an S-record...\n", objFile); */
  167.  
  168.     fputs(sRecord, objFile);
  169.     if ferror(objFile)
  170.         {
  171.         fputs(objErrorMsg, stderr);
  172.         exit(0);
  173.         }
  174.  
  175.     return NORMAL;
  176.     }
  177.  
  178.  
  179. int finishObj(void)
  180.     {
  181.     /* Write out the last real S-record, if present */
  182.     if (lineFlag)
  183.         writeObj();
  184.  
  185.     /* Write out a termination S-record and close the file*/
  186.     fputs("S9030000FC\n", objFile);
  187.     if ferror(objFile)
  188.         {
  189.         fputs(objErrorMsg, stderr);
  190.         exit(0);
  191.         }
  192.     fclose(objFile);
  193.  
  194.     return NORMAL;
  195.     }
  196.  
  197.