loadraw.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 396 行 · 第 1/2 页
C
396 行
i = 0;
while( bufOfs ) { // Do data bytes, leaving BufOfs 0 at end
sprintf( str_buf + 9 + 2 * i, "%02x", lineBuf[i] );
checksum += lineBuf[i++];
--bufOfs;
}
sprintf( str_buf + 9 + 2 * i, "%02x\r\n", (-checksum) & 0xFF );
WriteLoad( str_buf, 13 + 2 * i );
}
static bool WriteHexData( void *_sdata, void *_addr )
/***************************************************/
{
segdata *sdata = _sdata;
unsigned_32 pieceAddr = *(unsigned long *)_addr + sdata->a.delta;
unsigned_16 len = sdata->length;
unsigned_16 offset;
unsigned_16 piece;
if( !sdata->isuninit && !sdata->isdead && len > 0 ) {
if( pieceAddr != nextAddr + bufOfs ) { // Must start new record if address not contiguous
if( pieceAddr < nextAddr + bufOfs ) {
LnkMsg( ERR + MSG_FIXED_LOC_BEFORE_CUR_LOC, "a", (targ_addr*)_addr);
}
if( bufOfs ) { // If partial record in buffer, flush
WriteHexLine();
}
nextAddr = pieceAddr;
}
offset = 0;
while( len ) { // Now lob out records
piece = HEXLEN - bufOfs; // Handle partially filled buffer
if( piece > len ) { // Handle not enough to fill buffer
piece = len;
}
ReadInfo( sdata->data + offset, lineBuf + bufOfs, piece );
bufOfs += piece;
if( bufOfs == HEXLEN ) {
WriteHexLine(); // Only write full buffers
nextAddr += HEXLEN; // NextAddr reflects start of line
} // Partial records will be written later
offset += piece; // if address is not contiguous
len -= piece;
}
}
return( FALSE );
}
static bool DoHexLeader( void *seg, void *addr )
/**********************************************/
{
if ( !(((seg_leader *)seg)->class->flags & CLASS_NOEMIT ||
((seg_leader *)seg)->segflags & SEG_NOEMIT) ) {
unsigned long segaddr = *(unsigned long *)addr + GetLeaderDelta( seg );
RingLookup( ((seg_leader *)seg)->pieces, WriteHexData, &segaddr );
}
return( FALSE );
}
static bool DoHexDupLeader( void *seg, void *addr )
/************************************************/
{
unsigned_32 segaddr = *(unsigned long *)addr + GetLeaderDelta( seg );
RingLookup( ((seg_leader *)seg)->pieces, WriteHexData, &segaddr );
return( FALSE );
}
void WriteStart( void )
/*********************/
{
char str_buf[22];
if( StartInfo.addr.off > 0xffff ) {
sprintf( str_buf, ":04000005%08lx%02x\r\n", StartInfo.addr.off,
(-(9 + (StartInfo.addr.off >> 24) + ((StartInfo.addr.off >> 16) & 0xFF) +
((StartInfo.addr.off >> 8) & 0xFF) + (StartInfo.addr.off & 0xFF) )) & 0xFF );
} else {
sprintf( str_buf, ":04000003%04lx%04lx%02x\r\n", StartInfo.addr.seg, StartInfo.addr.off,
(-(7 + (StartInfo.addr.seg >> 8) + (StartInfo.addr.seg & 0xFF) +
(StartInfo.addr.off >> 8) + (StartInfo.addr.off & 0xFF) )) & 0xFF );
}
WriteLoad( str_buf, 21 );
}
typedef struct {
unsigned_32 addr;
group_entry *lastgrp; // used only for copy classes
} grpwriteinfo;
static bool WriteHexCopyGroups( void *_seg, void *_info )
/************************************************/
{
// This is called by the outer level iteration looking for classes
// that have more than one group in them
seg_leader * seg = _seg;
grpwriteinfo *info = _info;
if( info->lastgrp != seg->group ) { // Only interate new groups
info->lastgrp = seg->group;
// Check each initialized segment in group
Ring2Lookup( seg->group->leaders, DoHexDupLeader, &info->addr);
info->addr += seg->group->totalsize;
}
return FALSE;
}
extern void HexOutput( void )
/***************************/
{
outfilelist *fnode;
group_entry *group;
group_entry *wrkgrp;
section *sect;
outfilelist *finfo;
unsigned_32 size;
class_entry *class;
grpwriteinfo info;
nextAddr = 0L; // Start at absolute linear address 0
linear = 0; // in segmented mode
seg = 0;
bufOfs = 0;
if( FmtData.type & (MK_PE | MK_QNX_FLAT | MK_OS2_FLAT | MK_ELF) ) {
CurrSect = Root; // needed for WriteInfo.
Root->sect_addr = Groups->grp_addr;
fnode = Root->outfile;
fnode->file_loc = 0;
Root->u.file_loc = Root->sect_addr.off - FmtData.output_offset;
/* write groups */
for( group = Groups; group != NULL; group = group->next_group ) {
class = group->leaders->class;
if( class->flags & CLASS_COPY ) {
wrkgrp = class->DupClass->segs->group;
} else {
wrkgrp = group;
}
size = CalcGroupSize( wrkgrp );
if( size != 0 ) {
info.addr = (group->grp_addr.off + group->linear - FmtData.output_offset);
sect = wrkgrp->section;
CurrSect = sect;
finfo = sect->outfile;
DEBUG((DBG_LOADDOS, "group %a section %d to %l in %s",
&group->grp_addr, sect->ovl_num, info.addr, finfo->fname ));
if( group->leaders->class->flags & CLASS_COPY ) {
Ring2Lookup( wrkgrp->leaders, DoHexDupLeader, &info.addr );
} else {
Ring2Lookup( wrkgrp->leaders, DoHexLeader, &info.addr );
}
}
}
}
else {
OrderGroups( CompareDosSegments );
CurrSect = Root; // needed for WriteInfo.
Root->sect_addr = Groups->grp_addr;
fnode = Root->outfile;
fnode->file_loc = 0;
Root->u.file_loc = (Root->sect_addr.seg << FmtData.SegShift) + Root->sect_addr.off - FmtData.output_offset;
/* write groups */
for( group = Groups; group != NULL; group = group->next_group ) {
class = group->leaders->class;
if( class->flags & CLASS_COPY ) {
sect = group->section;
CurrSect = sect;
finfo = sect->outfile;
info.addr = SUB_ADDR( group->grp_addr, sect->sect_addr ) + sect->u.file_loc;
DEBUG((DBG_LOADDOS, "group %a section %d to %l in %s",
&group->grp_addr, sect->ovl_num, info.addr, finfo->fname ));
info.lastgrp = NULL;
RingLookup( class->DupClass->segs->group->leaders, WriteHexCopyGroups, &info);
} else {
if( group->size != 0 ) {
sect = group->section;
CurrSect = sect;
finfo = sect->outfile;
info.addr = SUB_ADDR( group->grp_addr, sect->sect_addr ) + sect->u.file_loc;
DEBUG((DBG_LOADDOS, "group %a section %d to %l in %s",
&group->grp_addr, sect->ovl_num, info.addr, finfo->fname ));
Ring2Lookup( group->leaders, DoHexLeader, &info.addr );
}
}
}
}
if( bufOfs ) { // If partial record in buffer, flush
WriteHexLine();
}
if( FmtData.output_start ) {
WriteStart();
}
WriteLoad( ":00000001ff\r\n", 13 );
WriteDBI();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?