s37txt.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,685 行 · 第 1/4 页

C
1,685
字号
                break;
            default:
                Zoiks( ZOIKS_061 );
            }
            current = current->next;
            if(  obj->opts & LST_ASM ){
                obj->asm->sep1[0] = '=';
            }
        }
        current = bead->end; /* main loop gets next */
        obj->opts = curr_opts;
    }
    return( current );
}

static bool FormatQueue( txt_obj *obj, unsigned num ) {
/******************************************************************/

    if( CGSrcGet( obj->srcfi, &obj->line[7], num, 73 ) ){
        obj->line[0] = '*';
        fmt_rdec( &obj->line[1], num );
        obj->line[6] = ':';
        return( TRUE );
    }else{
        return( FALSE);
    }
}

static void DmpQueue( txt_obj *obj, bead_queue *bead ) {
/****************************************************************/

    bead_queue  *next_queue;
    unsigned    last_line;
    unsigned    i;

    if( !( obj->opts & LST_ASM ) ){
        return;
    }
    if( !( obj->opts & LST_SRC ) ){
        obj->asm->label[0] = '*';
        fmt_str( obj->asm->code, "LINE" );
        fmt_dec( obj->asm->ops, bead->num );
        PutAsm( obj );
        return;
    }
    next_queue = (bead_queue *)bead->common.next;
    for(;;){
        if( next_queue == NULL ) {
            last_line = bead->num;
            break;
        }
        if( next_queue->common.class == BEAD_EPILOGUE) {
            last_line = bead->num;
            break;
        }
        if( next_queue->common.class == BEAD_QUEUE ) {
            last_line = next_queue->num - 1;
            break;
        }
        next_queue = (bead_queue *)next_queue->common.next;
    }
    for( i = bead->num; i <= last_line; ++i ) {
        if( !FormatQueue( obj, i ) ) break;
        PutAsm( obj );
    }
    return;
}


static void DmpSeg( txt_obj *obj, bead_seg *bead ) {
/*********************************/
    char *cur;
    char const cd[] = "*XH?F???D";

    if( obj->opts & LST_ASM ) {
        cur = fmt_str( obj->asm->code, "DS" );
        obj->asm->ops[0] = '0';
        obj->asm->ops[1] = cd[ bead->align ];
        cur =  fmt_str( &obj->asm->ops[12], "SEG " );
        cur =  fmt_str( cur, bead->str );
        ++cur;
        fmt_dec( cur, bead->id );
    }

}

static void DmpMsg( txt_obj *obj, char *msg ) {
/*********************************/

    if( obj->opts & LST_ASM ) {
        obj->asm->label[0] = '*';
        fmt_str( obj->asm->code, msg );
    }

}
static void InitRldObj ( rld_obj *obj ) {
/*************************************/

    memset( &obj->rec, 0x40, sizeof( obj->rec ) );
    obj->rec.tag = tag_RLD;
    obj->rem = RLD_MAX;
    obj->curr = obj->rec.info;
}

static void RldFlush( rld_obj *obj ) {
/*************************************/

    int size;

    size = RLD_MAX - obj->rem;
    if( size != 0 ) {
        Stick16( obj->rec.size, size );
        PutObjRec( ObjFile, &obj->rec, 80 );
        obj->rem = RLD_MAX;
        obj->curr = obj->rec.info;
        memset( obj->rec.info, 0x40, sizeof( obj->rec.info ) );
    }
}


static void RldOut( rld_obj *obj, offset addr,
                    short rel_esdid, char flag ) {
/*****************************************************/
    rld_entry *pos;

    if( obj->rem < sizeof( *pos ) ) {
        RldFlush( obj );
    }
    pos = (rld_entry *)obj->curr;
    Stick16( &pos->relesdid, rel_esdid );
    Stick16( &pos->posesdid, obj->csect );
    Stick24( pos->faddr.addr, addr );
    pos->faddr.flag = flag;
    obj->curr += sizeof( *pos );
    obj->rem -= sizeof( *pos );
}

static void RldRecs(  txtseg_rec *rec ) {
    rld_obj     rld;
    bead_def   *bead;

    bead = rec->first;
    InitRldObj( &rld );
    while( bead != NULL ) {
        switch( bead->class ) {
        case BEAD_ADDR:
            RldAddr( &rld, (bead_addr*)bead );
            break;
        case BEAD_XSYM:
           RldXsym( &rld, (bead_xsym*)bead );
           break;
        }
        bead = bead->next;
    }
    RldFlush( &rld );
}

static short GetRelEsdid( rld_obj *obj, hw_sym  *sym ){
/**** get the relesdid************/
    short      rel_esdid;
    bead_xsym *ref;

    if( sym->def != NULL ) {
        if( sym->def->class == BEAD_XSYM ) {
             ref= (bead_xsym *)sym->def;
             rel_esdid = ref->id;
        } else {
            rel_esdid = obj->csect;
        }
    } else {
        rel_esdid = obj->csect;
    }
    return( rel_esdid );
}

static void RldAddr( rld_obj *obj, bead_addr *bead ) {
/**************************************/
    short    rel_esdid;
    char     flag;

    rel_esdid = GetRelEsdid( obj, bead->ref );
    flag = _RLD_FLAG( RLD_AY, 4, RLD_ADD );
    RldOut( obj, bead->common.address, rel_esdid, flag );
    if( bead->rel != NULL ) {
        rel_esdid = GetRelEsdid( obj, bead->rel );
        flag = _RLD_FLAG( RLD_AY, 4, RLD_SUB );
        RldOut( obj, bead->common.address, rel_esdid, flag );
    }
}

static void RldXsym( rld_obj *obj, bead_xsym *bead ) {
/*********************************/

    if( bead->class == XSYM_CSECT ) {
        obj->csect = bead->id;
    }

}

static void  EndRecs(  bead_xsym *entry, txtseg_rec *rec ) {
/*** Generate end card with optional entry point **********/
    bead_def *bead;
    end_record end;

    rec = NULL;
    memset( &end, 0x40, sizeof( end ) );
    if( entry != NULL ) {
        bead = entry->sym->def;
        Stick16( &end.esdid, entry->id );
        Stick24( &end.entpt, bead->address );
    }
    end.tag = tag_END;
    end._12 = 0xF1;
    end.pgmid[0] = 0xE6;
    end.pgmid[1] = 0xC3;
    end.pgmid[2] = 0xC3;
    PutObjRec( ObjFile, &end, 80 );
}

static void Stick32( char *in, offset num ) {
/** format 32 bit into 4byte number ********/
    in[0] = num>>24 & 0xff;
    in[1] = num>>16 & 0xff;
    in[2] = num>>8  & 0xff;
    in[3] = num     & 0xff;
}

static void Stick24( char *in, offset num ) {
/** format 32 bit into 3byte number ********/
    in[0] = num>>16 & 0xff;
    in[1] = num>>8  & 0xff;
    in[2] = num     & 0xff;
}

static void Stick16( char *in, short num ) {
/** format 16 bit into 2byte number ********/
    in[0] = num>>8  & 0xff;
    in[1] = num     & 0xff;
}

static char *OutSym( char *to, const hw_sym *sym, int flag ) {
/**** Put a symbol out in a list or ASM file*******/
    char const *from;
    char curr;

    from = sym->name;
    if( *from == '\0' ){
        Zoiks( ZOIKS_065 ); /* unamed symbol */
    }
    curr = *from;
    while( curr != '\0' ) {
        if( flag ) {
            curr = curr == '_' ? '$' :  toupper( curr );
        }
        *to++ = curr;
        curr = *++from;
   }
   return( to );
}

static char *TXTSym( char *to, const hw_sym *sym, int flag ) {
/*Put symbol out in 370 TEXT file ************/
  #if( ' ' == 0x20 ) /*ASCII HOST ? */
    extern char const atoetbl[];
  #endif
    char const *from;
    char curr;

    from = sym->name;
    if( *from == '\0' ){
        Zoiks( ZOIKS_065 ); /* unamed symbol */
    }
    curr = *from;
    while( curr != '\0' ) {
        if( flag ) {
            curr = curr == '_' ? '$' :  toupper( curr );
        }
      #if( ' ' == 0x20 ) /*ASCII HOST ? */
        *to++ =  atoetbl[curr];
      #else
        *to++ = curr;
      #endif
        curr = *++from;
   }
   return( to );
}

static char *fmt_str( char *to, const char *from ) {
/*** char copy from to***************************/
    while( *from != '\0' ) {
        *to = *from;
        from++;
        to++;
   }
   return( to );
}

static char *fmt_lxstr( char *to, char *from, int len ) {
/*** copy len hexchar from to ***************r*********/
//  static char const con[16] = "0123456789ABCDEF";
    auto char const con[16] = "0123456789ABCDEF";

    for( ;len > 0;len--) {
        to[0] = con[ *from >> 4  ];
        to[1] = con[ *from & 0x0f ];
        to += 2;
        from++;
   }
   return( to );
}

static char *fmt_dec( char *to, offset num ) {
/*** convert num to dec and  copy **************/
    char buff[33];
    char *from;

    from = buff;
    ltoa( num, from, 10 );
    while( *from != '\0' ) {
        *to = *from;
        from++;
        to++;
   }
   return( to );
}

static char *fmt_rdec( char *to, offset num ) {
/*** convert num to dec right justified **************/
    char buff[33];
    char *from;
    int  len;

    from = buff;
    ltoa( num, from, 10 );
    len = Length( from );
    len = 5-len;
    if( len < 0 ) {
        len = 5;
    }
    to = &to[len];
    while( *from != '\0' ) {
        *to = *from;
        from++;
        to++;
   }
   return( to );
}

static char *fmt_hex( char *to, offset num, int len ) {
/*** convert num to hex and copy len char*********/
    char buff[4];
    char hex[8];
    char *from;

    from = buff;
    Stick32( from, num );
    fmt_lxstr( hex, buff, 4 );
    from = &hex[8-len];
    for( ;len > 0;len--) {
        *to++ = *from++;
   }
   return( to );
}


#if  _HOST == _IBM_370
static void fmt_double( char *to, double num ) {
/*** convert num to IBM370 DOUBLE and  copy *******/
    *(double *)to = num;
}
#else
static void fmt_double( char *to, double num ) {
/*** convert num to IBM370 DOUBLE and  copy *******/
    union { double num; unsigned long i[2]; } image;
    int exp;
    int shift;
    unsigned long high;
    unsigned long low;
    image.num = num;
    high = image.i[1];
    low  = image.i[0];
    if( high == 0 && low == 0 ){ /* if  true 0 */
        exp = 0;
    }else{
        high >>= 20;    /* get sign / exp */
        high &= 0x000007ff; /* get rid of sign */
        exp = high;
        exp -= 1023;       /* un-excess exp    */
        shift = exp % 4 ;  /*  rem from base 16 */
        exp   = exp / 4;   /* turn into base 16 */
        if( shift < 0 ){   /* negative pow2 exponent */
            exp += 64;
            shift+= 4;
        }else{
            exp += 65;        /* excess 64         */
        }
        if( exp < 0 ){
            printf( "underflow" );
        }else if( exp > 127 ){
            printf( "overflow" );
        }
        high = image.i[1];  /* get high halve again */
        if( high & 0x80000000 ){  /* set sign bit */
            exp |= 0x80;
        }
        low = image.i[0];
        high &= 0x000fffff; /*knock off exponent */
        high |= 0x00100000; /*dink in MSB        */
        /*normalize base 16 and leave 8 bit exp/sign free */
        high <<= shift;
        high |= low >>( 32-shift);
        low <<= shift;
    }
    Stick32( to, high );
    to[0] = exp;
    Stick32( &to[4], low );
}
#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?