home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1987 / 12 / naro / outhex.c < prev    next >
Text File  |  1987-12-21  |  22KB  |  233 lines

  1. #include <stdio.h>                                                                           
  2. #include <stdlib.h>                                                                          
  3. #include <io.h>                                                                              
  4. #include <string.h>                                                                          
  5. #include <malloc.h>                                                                          
  6. #include <dos.h>                                                                             
  7.                                                                                              
  8. #include "loc.h"                                                                             
  9. #include "externs.h"                                                                         
  10.                                                                                              
  11.                                                                                              
  12. void  output_hex_OMF(hex_file, seg_list, entry_point)                                        
  13. int   hex_file ;                                                                             
  14. SEG_DESCRIPTOR *seg_list ;                                                                   
  15. unsigned char  *entry_point ;                                                                
  16. {                                                                                            
  17.    unsigned int   offset, i, count ;                                                         
  18.    unsigned char  *seg_start, *text ;                                                        
  19.                                                                                              
  20.    SEG_DESCRIPTOR *p ;                                                                       
  21.                                                                                              
  22.    /*                                                                                        
  23.       This function controls the sequencing of the Intel extended hex                        
  24.       output using the Intel hex output routines.                                            
  25.    */                                                                                        
  26.                                                                                              
  27.    /* Run through the segment list and output all ROMable segments */                        
  28.    p = seg_list ;                                                                            
  29.    while (p != NULL)   {                                                                     
  30.       if (p->romable == TRUE)   {                                                            
  31.                                                                                              
  32.          /* Allocate enough memory to hold the segment (up to 64K) */                        
  33.          if ((text = get_mem((unsigned long) p->len)) == NULL)   {                           
  34.             perror(__FILE__) ;                                                               
  35.             exit(1) ;                                                                        
  36.          }                                                                                   
  37.                                                                                              
  38.          /* Locate the position of the segment in the load module file */                    
  39.          if (lseek(tmp_file, p->position, SEEK_SET) == -1L)   {                              
  40.             perror(__FILE__) ;                                                               
  41.             exit(1) ;                                                                        
  42.          }                                                                                   
  43.                                                                                              
  44.          /* Read in the segment and pad with zero if necessary */                            
  45.          count = read(tmp_file, text, p->len) ;                                              
  46.          if (count != p->len)   {                                                            
  47.             if (count == -1)   {                                                             
  48.                perror(__FILE__) ;                                                            
  49.                exit(1) ;                                                                     
  50.             }                                                                                
  51.             else                                                                             
  52.                memset(text + count, '\0', p->len - count) ;                                  
  53.          }                                                                                   
  54.                                                                                              
  55.          /* Write the segment number out in an address record */                             
  56.          write_ADDR_record(hex_file, p->pseg) ;                                              
  57.                                                                                              
  58.          /* Output the segment as a series of 16 byte data records */                        
  59.          offset = p->offset ;                                                                
  60.          seg_start = text ;                                                                  
  61.          for (i = 0; i < p->len / 16; i++)   {                                               
  62.             write_DATA_record(hex_file, offset, seg_start, 16) ;                             
  63.             offset += 16 ;                                                                   
  64.             seg_start += 16 ;                                                                
  65.          }                                                                                   
  66.                                                                                              
  67.          /* Handle any remaining data */                                                     
  68.          if ((p->len % 16) != 0)                                                             
  69.             write_DATA_record(hex_file, offset, seg_start, p->len % 16) ;                    
  70.                                                                                              
  71.          free_mem(text) ;                                                                    
  72.       }                                                                                      
  73.       p = p->next ;                                                                          
  74.    }                                                                                         
  75.                                                                                              
  76.    /* Write the START and EOF records */                                                     
  77.    write_START_record(hex_file, entry_point) ;                                               
  78.    write_EOF_record(hex_file) ;                                                              
  79.                                                                                              
  80.    return ;                                                                                  
  81. }                                                                                            
  82.                                                                                              
  83.                                                                                              
  84. void  write_ADDR_record(file, usba)                                                          
  85. int   file ;                                                                                 
  86. unsigned int   usba ;                                                                        
  87. {                                                                                            
  88.    unsigned char  buf[16], *p ;                                                              
  89.    unsigned char  len_field = 2 ;                                                            
  90.                                                                                              
  91.    /*                                                                                        
  92.       This function writes an Intel extended hex Address record to the                       
  93.       output file.  Inputs are the file handle and the USBA (segment                         
  94.       base address).                                                                         
  95.    */                                                                                        
  96.                                                                                              
  97.    p = buf ;                                                                                 
  98.    *p++ = high_byte(usba) ;                                                                  
  99.    *p++ = low_byte(usba) ;                                                                   
  100.                                                                                              
  101.    output_hex_record(file, ADDR_RECORD, 0, buf, p - buf) ;                                   
  102.                                                                                              
  103.    return ;                                                                                  
  104. }                                                                                            
  105.                                                                                              
  106.                                                                                              
  107. void  write_EOF_record(file)                                                                 
  108. int   file ;                                                                                 
  109. {                                                                                            
  110.    /*                                                                                        
  111.       This function writes an Intel extended hex EOF record to the                           
  112.       output file.                                                                           
  113.    */                                                                                        
  114.                                                                                              
  115.    output_hex_record(file, EOF_RECORD, 0, NULL, 0) ;                                         
  116.    return ;                                                                                  
  117. }                                                                                            
  118.                                                                                              
  119.                                                                                              
  120. void  write_DATA_record(file, offset, text, len)                                             
  121. int   file ;                                                                                 
  122. unsigned int   offset ;                                                                      
  123. unsigned char  *text ;                                                                       
  124. unsigned int   len ;                                                                         
  125. {                                                                                            
  126.                                                                                              
  127.    /*                                                                                        
  128.       This function writes an Intel extended hex Data record to the                          
  129.       specified output file.                                                                 
  130.    */                                                                                        
  131.                                                                                              
  132.    output_hex_record(file, DATA_RECORD, offset, text, len) ;                                 
  133.                                                                                              
  134.    return ;                                                                                  
  135. }                                                                                            
  136.                                                                                              
  137.                                                                                              
  138. void  write_START_record(file, entry)                                                        
  139. int   file ;                                                                                 
  140. unsigned char  *entry ;                                                                      
  141. {                                                                                            
  142.    unsigned char  *buf, *p ;                                                                 
  143.    unsigned int   count ;                                                                    
  144.                                                                                              
  145.    unsigned char  len_field = 4;                                                             
  146.    unsigned int   addr_field = 0 ;                                                           
  147.    unsigned char  rec_type = START_RECORD ;                                                  
  148.                                                                                              
  149.    /*                                                                                        
  150.       This function writes an Intel extended hex Start record to the                         
  151.       output file.                                                                           
  152.    */                                                                                        
  153.                                                                                              
  154.    /* Allocate some memory to build the data field in */                                     
  155.    if ((p = buf = (unsigned char *) malloc(32)) == NULL)   {                                 
  156.       perror(__FILE__) ;                                                                     
  157.       exit(1) ;                                                                              
  158.    }                                                                                         
  159.                                                                                              
  160.    /* Store the start address in the data field (segment first) */                           
  161.    *p++ = high_byte(FP_SEG(entry)) ;                                                         
  162.    *p++ = low_byte(FP_SEG(entry)) ;                                                          
  163.                                                                                              
  164.    /* And then the offset */                                                                 
  165.    *p++ = high_byte(FP_OFF(entry)) ;                                                         
  166.    *p++ = low_byte(FP_OFF(entry)) ;                                                          
  167.                                                                                              
  168.    /* Output the record */                                                                   
  169.    output_hex_record(file, START_RECORD, 0, buf, p - buf) ;                                  
  170.                                                                                              
  171.    free(buf) ;                                                                               
  172.    return ;                                                                                  
  173. }                                                                                            
  174.                                                                                              
  175.                                                                                              
  176. void  output_hex_record(file, type, addr, data, length)                                      
  177. int   file ;                                                                                 
  178. unsigned char  type ;                                                                        
  179. unsigned int   addr ;                                                                        
  180. unsigned char  *data ;                                                                       
  181. unsigned char  length ;                                                                      
  182. {                                                                                            
  183.    char  *p, *buf ;                                                                          
  184.    unsigned int   size, count ;                                                              
  185.    unsigned char  chksum, digit ;                                                            
  186.                                                                                              
  187.    /*                                                                                        
  188.       This function does all of the work of writing an Intel extended                        
  189.       hex output record.  The inputs to this routine are:                                    
  190.          file     output file handle                                                         
  191.          type     record type                                                                
  192.          addr     address field value                                                        
  193.          data     data field contents                                                        
  194.          length   size of the data field                                                     
  195.    */                                                                                        
  196.                                                                                              
  197.    /* Allocate some memory to build the output record in */                                  
  198.    if ((p = buf = malloc(550)) == NULL)   {                                                  
  199.       perror(__FILE__);                                                                      
  200.       exit(1) ;                                                                              
  201.    }                                                                                         
  202.                                                                                              
  203.    /* Build the prefix for the data field */                                                 
  204.    p += sprintf(p, ":%02X%02X%02X%02X", length, high_byte(addr), \                           
  205.       low_byte(addr), type) ;                                                                
  206.                                                                                              
  207.    /* Compute the checksum on the prefix */                                                  
  208.    chksum = length + high_byte(addr) + low_byte(addr) + type ;                               
  209.                                                                                              
  210.    /* Build the data field byte by byte */                                                   
  211.    while (length--)   {                                                                      
  212.       digit = (*data >> 4) & 0x0f ;                                                          
  213.       *p++ = (digit > 9) ? digit + 0x37 : digit + '0' ;                                      
  214.       digit = *data & 0x0f ;                                                                 
  215.       *p++ = (digit > 9) ? digit + 0x37 : digit + '0' ;                                      
  216.       chksum += *data++ ;                                                                    
  217.    }                                                                                         
  218.                                                                                              
  219.    /* Compute the complement of the checksum and output */                                   
  220.    chksum = ~chksum + 1 ;                                                                    
  221.    p += sprintf(p, "%02X\r\n",chksum) ;                                                      
  222.                                                                                              
  223.    /* Compute the size of the output record and output */                                    
  224.    size = p - buf ;                                                                          
  225.    count = write(file, buf, size) ;                                                          
  226.    if (count != size)   {                                                                    
  227.       perror(__FILE__) ;                                                                     
  228.       exit(1) ;                                                                              
  229.    }                                                                                         
  230.                                                                                              
  231.    free(buf) ;                                                                               
  232.    return ;                                                                                  
  233. }