home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1987
/
12
/
naro
/
outhex.c
< prev
next >
Wrap
Text File
|
1987-12-21
|
22KB
|
233 lines
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>
#include <malloc.h>
#include <dos.h>
#include "loc.h"
#include "externs.h"
void output_hex_OMF(hex_file, seg_list, entry_point)
int hex_file ;
SEG_DESCRIPTOR *seg_list ;
unsigned char *entry_point ;
{
unsigned int offset, i, count ;
unsigned char *seg_start, *text ;
SEG_DESCRIPTOR *p ;
/*
This function controls the sequencing of the Intel extended hex
output using the Intel hex output routines.
*/
/* Run through the segment list and output all ROMable segments */
p = seg_list ;
while (p != NULL) {
if (p->romable == TRUE) {
/* Allocate enough memory to hold the segment (up to 64K) */
if ((text = get_mem((unsigned long) p->len)) == NULL) {
perror(__FILE__) ;
exit(1) ;
}
/* Locate the position of the segment in the load module file */
if (lseek(tmp_file, p->position, SEEK_SET) == -1L) {
perror(__FILE__) ;
exit(1) ;
}
/* Read in the segment and pad with zero if necessary */
count = read(tmp_file, text, p->len) ;
if (count != p->len) {
if (count == -1) {
perror(__FILE__) ;
exit(1) ;
}
else
memset(text + count, '\0', p->len - count) ;
}
/* Write the segment number out in an address record */
write_ADDR_record(hex_file, p->pseg) ;
/* Output the segment as a series of 16 byte data records */
offset = p->offset ;
seg_start = text ;
for (i = 0; i < p->len / 16; i++) {
write_DATA_record(hex_file, offset, seg_start, 16) ;
offset += 16 ;
seg_start += 16 ;
}
/* Handle any remaining data */
if ((p->len % 16) != 0)
write_DATA_record(hex_file, offset, seg_start, p->len % 16) ;
free_mem(text) ;
}
p = p->next ;
}
/* Write the START and EOF records */
write_START_record(hex_file, entry_point) ;
write_EOF_record(hex_file) ;
return ;
}
void write_ADDR_record(file, usba)
int file ;
unsigned int usba ;
{
unsigned char buf[16], *p ;
unsigned char len_field = 2 ;
/*
This function writes an Intel extended hex Address record to the
output file. Inputs are the file handle and the USBA (segment
base address).
*/
p = buf ;
*p++ = high_byte(usba) ;
*p++ = low_byte(usba) ;
output_hex_record(file, ADDR_RECORD, 0, buf, p - buf) ;
return ;
}
void write_EOF_record(file)
int file ;
{
/*
This function writes an Intel extended hex EOF record to the
output file.
*/
output_hex_record(file, EOF_RECORD, 0, NULL, 0) ;
return ;
}
void write_DATA_record(file, offset, text, len)
int file ;
unsigned int offset ;
unsigned char *text ;
unsigned int len ;
{
/*
This function writes an Intel extended hex Data record to the
specified output file.
*/
output_hex_record(file, DATA_RECORD, offset, text, len) ;
return ;
}
void write_START_record(file, entry)
int file ;
unsigned char *entry ;
{
unsigned char *buf, *p ;
unsigned int count ;
unsigned char len_field = 4;
unsigned int addr_field = 0 ;
unsigned char rec_type = START_RECORD ;
/*
This function writes an Intel extended hex Start record to the
output file.
*/
/* Allocate some memory to build the data field in */
if ((p = buf = (unsigned char *) malloc(32)) == NULL) {
perror(__FILE__) ;
exit(1) ;
}
/* Store the start address in the data field (segment first) */
*p++ = high_byte(FP_SEG(entry)) ;
*p++ = low_byte(FP_SEG(entry)) ;
/* And then the offset */
*p++ = high_byte(FP_OFF(entry)) ;
*p++ = low_byte(FP_OFF(entry)) ;
/* Output the record */
output_hex_record(file, START_RECORD, 0, buf, p - buf) ;
free(buf) ;
return ;
}
void output_hex_record(file, type, addr, data, length)
int file ;
unsigned char type ;
unsigned int addr ;
unsigned char *data ;
unsigned char length ;
{
char *p, *buf ;
unsigned int size, count ;
unsigned char chksum, digit ;
/*
This function does all of the work of writing an Intel extended
hex output record. The inputs to this routine are:
file output file handle
type record type
addr address field value
data data field contents
length size of the data field
*/
/* Allocate some memory to build the output record in */
if ((p = buf = malloc(550)) == NULL) {
perror(__FILE__);
exit(1) ;
}
/* Build the prefix for the data field */
p += sprintf(p, ":%02X%02X%02X%02X", length, high_byte(addr), \
low_byte(addr), type) ;
/* Compute the checksum on the prefix */
chksum = length + high_byte(addr) + low_byte(addr) + type ;
/* Build the data field byte by byte */
while (length--) {
digit = (*data >> 4) & 0x0f ;
*p++ = (digit > 9) ? digit + 0x37 : digit + '0' ;
digit = *data & 0x0f ;
*p++ = (digit > 9) ? digit + 0x37 : digit + '0' ;
chksum += *data++ ;
}
/* Compute the complement of the checksum and output */
chksum = ~chksum + 1 ;
p += sprintf(p, "%02X\r\n",chksum) ;
/* Compute the size of the output record and output */
size = p - buf ;
count = write(file, buf, size) ;
if (count != size) {
perror(__FILE__) ;
exit(1) ;
}
free(buf) ;
return ;
}