extern bool CGOpenf() { /*************************/ CopyStr( FEAuxInfo( NULL, OBJECT_FILE_NAME ), ObjName ); if( (int)FEAuxInfo( NULL, REVISION_NUMBER ) != II_REVISION ) { FatalError( "Incompatible code generator" ); } ObjFile = OpenObj( ObjName ); if( ObjFile == 0 ) return( FALSE ); return( TRUE ); }
extern unsigned DepthAlign( unsigned depth ) /******************************************/ { static unsigned char AlignArray[10] = { 0 }; if( AlignArray[0] == 0 || depth == PROC_ALIGN ) { unsigned char *align_info_bytes = FEAuxInfo( NULL, CODE_LABEL_ALIGNMENT ); Copy( align_info_bytes, AlignArray, align_info_bytes[0] + 1 ); } if( OptForSize ) return( 1 ); if( _CPULevel( CPU_486 ) ) { if( depth == PROC_ALIGN || depth == DEEP_LOOP_ALIGN ) return( 16 ); return( 1 ); } if( _CPULevel( CPU_386 ) ) { if( depth == PROC_ALIGN || depth == DEEP_LOOP_ALIGN ) return( 4 ); return( 1 ); } if( depth == PROC_ALIGN || depth == DEEP_LOOP_ALIGN ) { return( AlignArray[1] ); } if( depth == 0 ) depth = 1; if( depth >= AlignArray[0] ) { depth = AlignArray[0] - 1; } return( AlignArray[depth + 1] ); }
void CVProEnd( dbg_rtn *rtn, offset lc ) /*****************************************/ { cg_sym_handle sym; dbg_type tipe; fe_attr attr; const char *name; cs_gproc *ptr; sg_index kind; cv_out out[1]; /* unused parameters */ (void)lc; sym = AskForLblSym( CurrProc->label ); attr = FEAttr( sym ); if( attr & FE_GLOBAL ){ kind = SG_GPROC; }else{ kind = SG_LPROC; } NewBuff( out, CVSyms ); ptr = StartSym( out, kind ); ptr->pParent = 0; ptr->pEnd = 0; ptr->pNext = 0; ptr->proc_length = 0; ptr->debug_start = rtn->pro_size; ptr->debug_end = 0; ptr->offset = 0; ptr->segment = 0; tipe = FEDbgType( sym ); ptr->proctype = tipe; ptr->flags.s = 0; #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( *(call_class *)FindAuxInfoSym( sym, CALL_CLASS ) & FAR_CALL ) { ptr->flags.f.far_ret = true; } #endif if( rtn->obj_type != DBG_NIL_TYPE ) { name = FEAuxInfo( sym, CLASS_APPENDED_NAME ); } else { name = FEName( sym ); } CVPutStr( out, name ); EndSym( out ); BuffPatchSet( CVSyms, RtnPatch ); BuffWrite( out, &ptr->offset ); SymReloc( CVSyms, sym, 0 ); BuffSkip( out, &ptr->proctype ); buffEnd( out ); DBLocFini( rtn->reeturn ); DBLocFini( rtn->obj_loc ); if( rtn->parms != NULL ){ DumpParms( rtn->parms, &rtn->rtn_blk->locals ); } DumpLocals( rtn->rtn_blk->locals ); }
static void dumpAutoLocn( void ) { AUTO_LOCN* curr; if( auto_locations ) { for( ; ; ) { curr = auto_locations; if( ! curr ) break; auto_locations = curr->next; if( ((pointer)TEMP_LOC_YES) == FEAuxInfo( curr->s, TEMP_LOC_NAME ) ) { Action( "TEMP_LOC_TELL offset=%h symbol=%s%n" , curr->offset , Name( curr->s ) ); FEAuxInfo( (sym_handle)curr->offset, TEMP_LOC_TELL ); } CGFree( curr ); } Action( "%n" ); } }
static const char *SetDwarfProducer( void ) { const char *name; #if 0 // disable this feature for now, to have compatibility with OW 1.9 name = (const char *)FEAuxInfo( NULL, DBG_DWARF_PRODUCER ); if( name == NULL ) name = ""; #else name = ""; #endif return( name ); }
static int SetLang( void ){ int ret; char *name; int index; ret = DWLANG_C; name = FEAuxInfo( NULL, SOURCE_LANGUAGE ); for( index = 0; index < MAX_LANG; ++index ){ if( strcmp( name, LangNames[index].name ) == 0 ){ ret = LangNames[index].lang; break; } } return( ret ); }
type_class_def CallState( aux_handle aux, type_def *tipe, call_state *state ) /****************************************************************************/ { type_class_def class; uint i; hw_reg_set parms[24]; hw_reg_set *parm_src; hw_reg_set *parm_dst; state->unalterable = FixedRegs(); HW_CAsgn( state->modify, HW_FULL ); HW_TurnOff( state->modify, SavedRegs() ); HW_CTurnOff( state->modify, HW_UNUSED ); state->used = state->modify; /* anything not saved is used*/ state->attr = 0; i = 0; parm_src = ParmRegs(); parm_dst = &parms[0]; for(;;) { *parm_dst = *parm_src; if( HW_CEqual( *parm_dst, HW_EMPTY ) ) break; if( HW_Ovlap( *parm_dst, state->unalterable ) ) { FEMessage( MSG_BAD_SAVE, aux ); } HW_CTurnOff( *parm_dst, HW_UNUSED ); parm_dst++; parm_src++; i++; } i++; state->parm.table = CGAlloc( i*sizeof( hw_reg_set ) ); Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) ); HW_CAsgn( state->parm.used, HW_EMPTY ); state->parm.curr_entry = state->parm.table; state->parm.offset = 0; InitPPCParmState( state ); class = ReturnClass( tipe, state->attr ); if( *(call_class *)FEAuxInfo( aux, CALL_CLASS ) & HAS_VARARGS ) { state->attr |= ROUTINE_HAS_VARARGS; } UpdateReturn( state, tipe, class, aux ); return( class ); }
extern void InitBlip() { /**************************/ #if 0 char *src_name; BlipsOn = FALSE; blipHandle = OpenFileMapping( FILE_MAP_WRITE, FALSE, SHMEM_NAME ); if( blipHandle != NULL ) { fileMapping = MapViewOfFile( blipHandle, FILE_MAP_WRITE, 0, 0, 0 ); if( fileMapping == NULL ) { _Zoiks( ZOIKS_110 ); return; } BlipsOn = TRUE; src_name = FEAuxInfo( NULL, SOURCE_NAME ); strncpy( &fileMapping->file_name[ 0 ], src_name, _MAX_PATH ); strcpy( &fileMapping->rtn_name[ 0 ], "" ); fileMapping->debug.debug_info = FALSE; } #endif }
void CVGenStatic( cg_sym_handle sym, dbg_loc loc, bool mem ) /*************************************************************/ { dbg_type tipe; cv_out out[1]; fe_attr attr; cs_gdata *ptr; sg_index kind; const char *name; attr = FEAttr( sym ); tipe = FEDbgType( sym ); NewBuff( out, CVSyms ); attr = FEAttr( sym ); if( attr & FE_GLOBAL ) { kind = SG_GDATA; } else { kind = SG_LDATA; } ptr = StartSym( out, kind ); ptr->offset = 0; ptr->segment = 0; ptr->type = tipe; if( mem ){ name = FEAuxInfo( sym, CLASS_APPENDED_NAME ); } else { name = FEName( sym ); } CVPutStr( out, name ); EndSym( out ); if( LocSimpStatic( loc ) == sym ) { BuffWrite( out, &ptr->offset ); SymReloc( CVSyms, sym, 0 ); BuffSkip( out, &ptr->type ); } else { /*TODO:can't handle locs */ } buffEnd( out ); }
type_class_def CallState( aux_handle aux, type_def *tipe, call_state *state ) /****************************************************************************/ { call_class cclass; type_class_def type_class; uint i; hw_reg_set parms[10]; hw_reg_set *parm_src; hw_reg_set *parm_dst; hw_reg_set *pregs; hw_reg_set tmp; state->unalterable = FixedRegs(); pregs = FEAuxInfo( aux, SAVE_REGS ); HW_CAsgn( state->modify, HW_FULL ); HW_TurnOff( state->modify, *pregs ); HW_CTurnOff( state->modify, HW_UNUSED ); state->used = state->modify; /* anything not saved is used*/ tmp = state->used; HW_TurnOff( tmp, StackReg() ); HW_CTurnOff( tmp, HW_BP ); // should be able to call routine which modifies BP if( HW_Ovlap( state->unalterable, tmp ) ) { FEMessage( MSG_BAD_SAVE, aux ); } state->attr = ROUTINE_REMOVES_PARMS; cclass = *(call_class *)FEAuxInfo( aux, CALL_CLASS ); if( cclass & INTERRUPT ) { state->attr |= ROUTINE_INTERRUPT; } else if( cclass & FAR_CALL ) { state->attr |= ROUTINE_LONG; } else if( cclass & FAR16_CALL ) { state->attr |= ROUTINE_FAR16; } if( cclass & CALLER_POPS ) { state->attr &= ~ROUTINE_REMOVES_PARMS; } if( cclass & SUICIDAL ) { state->attr |= ROUTINE_NEVER_RETURNS; } if( cclass & ROUTINE_RETURN ) { state->attr |= ROUTINE_ALLOCS_RETURN; } if( cclass & NO_STRUCT_REG_RETURNS ) { state->attr |= ROUTINE_NO_STRUCT_REG_RETURNS; } if( cclass & NO_FLOAT_REG_RETURNS ) { state->attr |= ROUTINE_NO_FLOAT_REG_RETURNS; state->attr |= ROUTINE_NO_8087_RETURNS; } if( cclass & NO_8087_RETURNS ) { state->attr |= ROUTINE_NO_8087_RETURNS; } if( cclass & MODIFY_EXACT ) { state->attr |= ROUTINE_MODIFY_EXACT; } if( cclass & NO_MEMORY_CHANGED ) { state->attr |= ROUTINE_MODIFIES_NO_MEMORY; } if( cclass & NO_MEMORY_READ ) { state->attr |= ROUTINE_READS_NO_MEMORY; } if( cclass & LOAD_DS_ON_ENTRY ) { state->attr |= ROUTINE_LOADS_DS; } if( cclass & LOAD_DS_ON_CALL ) { state->attr |= ROUTINE_NEEDS_DS_LOADED; } if( cclass & PARMS_STACK_RESERVE ) { state->attr |= ROUTINE_STACK_RESERVE; } if( cclass & PARMS_PREFER_REGS ) { state->attr |= ROUTINE_PREFER_REGS; } if( cclass & FARSS ) { state->attr |= ROUTINE_FARSS; } if( state == &CurrProc->state ) { if( cclass & ( GENERATE_STACK_FRAME | PROLOG_HOOKS | EPILOG_HOOKS ) ) { CurrProc->prolog_state |= GENERATE_FAT_PROLOG; state->attr |= ROUTINE_NEEDS_PROLOG; } if( cclass & PROLOG_HOOKS ) { CurrProc->prolog_state |= GENERATE_PROLOG_HOOKS; } if( cclass & EPILOG_HOOKS ) { CurrProc->prolog_state |= GENERATE_EPILOG_HOOKS; } if( cclass & FAT_WINDOWS_PROLOG ) { CurrProc->prolog_state |= GENERATE_FAT_PROLOG; } if( cclass & EMIT_FUNCTION_NAME ) { CurrProc->prolog_state |= GENERATE_FUNCTION_NAME; } if( cclass & THUNK_PROLOG ) { CurrProc->prolog_state |= GENERATE_THUNK_PROLOG; } if( cclass & GROW_STACK ) { CurrProc->prolog_state |= GENERATE_GROW_STACK; } if( cclass & TOUCH_STACK ) { CurrProc->prolog_state |= GENERATE_TOUCH_STACK; } if( cclass & LOAD_RDOSDEV_ON_ENTRY ) { CurrProc->prolog_state |= GENERATE_RDOSDEV_PROLOG; } } type_class = ReturnClass( tipe, state->attr ); i = 0; parm_dst = &parms[0]; for( parm_src = FEAuxInfo( aux, PARM_REGS ); !HW_CEqual( *parm_src, HW_EMPTY ); ++parm_src ) { *parm_dst = *parm_src; if( HW_Ovlap( *parm_dst, state->unalterable ) ) { FEMessage( MSG_BAD_SAVE, aux ); } HW_CTurnOff( *parm_dst, HW_UNUSED ); parm_dst++; i++; } *parm_dst = *parm_src; i++; state->parm.table = CGAlloc( i*sizeof( hw_reg_set ) ); Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) ); HW_CAsgn( state->parm.used, HW_EMPTY ); state->parm.curr_entry = state->parm.table; state->parm.offset = 0; if( tipe == TypeNone ) { HW_CAsgn( state->return_reg, HW_EMPTY ); } else if( type_class == XX ) { if( cclass & SPECIAL_STRUCT_RETURN ) { pregs = FEAuxInfo( aux, STRETURN_REG ); state->return_reg = *pregs; state->attr |= ROUTINE_HAS_SPECIAL_RETURN; } else { state->return_reg = StructReg(); } if( (state->attr & ROUTINE_ALLOCS_RETURN) == 0 ) { tmp = ReturnReg( WD, false ); HW_TurnOn( state->modify, tmp ); } } else { if( cclass & SPECIAL_RETURN ) { pregs = FEAuxInfo( aux, RETURN_REG ); state->return_reg = *pregs; state->attr |= ROUTINE_HAS_SPECIAL_RETURN; } else { state->return_reg = ReturnReg( type_class, _NPX( state->attr ) ); } } UpdateReturn( state, tipe, type_class, aux ); return( type_class ); }
extern void DFObjLineInitDbgInfo( void ) { /*****************************************************/ /* called by objinit to init segments and dwarf writing library */ static const dw_funcs cli_funcs = { CLIReloc, CLIWrite, CLISeek, CLITell, CLIAlloc, CLIFree }; dw_init_info info; dw_cu_info cu; type_def *tipe_addr; info.language = DWLANG_C; info.compiler_options = DW_CM_DEBUGGER; info.abbrev_sym = 0; info.producer_name = SetDwarfProducer(); info.language = SetLang(); if( setjmp( info.exception_handler ) == 0 ) { info.funcs = cli_funcs; InitLineSegBck(); // start each seg with a ref label Client = DWInit( &info ); if( Client == NULL ) { Zoiks( ZOIKS_107 ); /* Bad */ } cu.source_filename = FEAuxInfo( NULL, SOURCE_NAME ); cu.directory = ""; cu.dbg_pch = NULL; cu.inc_list = NULL; cu.inc_list_len = 0; #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( _IsTargetModel( FLAT_MODEL ) ) { cu.flags = true; cu.segment_size = 0; }else{ cu.flags = false; cu.segment_size = 2; } #else cu.flags = true; cu.segment_size = 0; #endif tipe_addr = TypeAddress( TY_NEAR_POINTER ); cu.offset_size = tipe_addr->length; switch( GetMemModel() ){ case 'h': cu.model = DW_MODEL_HUGE; break; case 'l': cu.model = DW_MODEL_LARGE; break; case 'f': cu.model = DW_MODEL_FLAT; break; case 's': cu.model = DW_MODEL_SMALL; break; default: cu.model = DW_MODEL_NONE; break; } DWInitDebugLine( Client, &cu ); } else { Zoiks( ZOIKS_107 ); /* Big Error */ } }
extern void DFObjInitDbgInfo( void ) { /*****************************************************/ /* called by objinit to init segments and dwarf writing library */ static const dw_funcs cli_funcs = { CLIReloc, CLIWrite, CLISeek, CLITell, CLIAlloc, CLIFree }; dw_init_info info; cg_sym_handle abbrev_sym; cg_sym_handle debug_pch; fe_attr attr; if( _IsntModel( DBG_LOCALS | DBG_TYPES ) ){ return; } info.compiler_options = DW_CM_DEBUGGER; info.abbrev_sym = 0; info.producer_name = SetDwarfProducer(); info.language = SetLang(); if( setjmp( info.exception_handler ) == 0 ) { info.funcs = cli_funcs; InitSegBck(); // start each seg with a ref label if( _IsModel( DBG_PREDEF ) ) { abbrev_sym = FEAuxInfo( NULL, DBG_PREDEF_SYM ); info.abbrev_sym = (dw_sym_handle)abbrev_sym; attr = FEAttr( abbrev_sym ); if( (attr & FE_IMPORT) ) { info.compiler_options |= DW_CM_ABBREV_PRE; }else{ back_handle bck; segment_id old; info.compiler_options |= DW_CM_ABBREV_GEN; bck = FEBack( abbrev_sym ); // dump out export label bck->seg = DwarfSegs[DW_DEBUG_ABBREV].seg; old = SetOP( DwarfSegs[DW_DEBUG_ABBREV].seg ); DataLabel( bck->lbl ); SetOP( old ); } } debug_pch = FEAuxInfo( NULL, DBG_PCH_SYM ); if( debug_pch != NULL ){ attr = FEAttr( debug_pch ); if( !(attr & FE_IMPORT) ) { back_handle bck; segment_id old; bck = FEBack( debug_pch ); bck->seg = DwarfSegs[DW_DEBUG_INFO].seg; old = SetOP( DwarfSegs[DW_DEBUG_INFO].seg ); DataLabel( bck->lbl ); SetOP( old ); debug_pch = NULL; } } Client = DWInit( &info ); if( Client == NULL ) { Zoiks( ZOIKS_107 ); /* Bad */ } DFBegCCU( AskCodeSeg(), (dw_sym_handle)debug_pch ); } else { Zoiks( ZOIKS_107 ); /* Big Error */ } }
extern void DFBegCCU( segment_id code, dw_sym_handle dbg_pch ) /****************************************************************/ // Call when codeseg hase been defined { dw_cu_info cu; back_handle bck; segment_id old; type_def *tipe_addr; if( _IsntModel( DBG_LOCALS | DBG_TYPES ) ) { return; } if( CcuDef ) { cu.source_filename = FEAuxInfo( NULL, SOURCE_NAME ); cu.directory = ""; cu.dbg_pch = dbg_pch; cu.inc_list = NULL; cu.inc_list_len = 0; old = SetOP( code ); #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( _IsTargetModel( FLAT_MODEL ) ) { bck = MakeLabel(); OutLabel( bck->lbl ); Pc_Low = bck; Pc_High = MakeLabel(); // Emitting DW_AT_low_pc and DW_AT_high_pc is valid *only* if the // compilation unit's code is in a single contiguous block (see // DWARF 2, section 3.1). // I don't know how to find out at the time of this call if there's // only one code segment or not, hence these attributes are always // disabled. The low/high pc attribs should probably be handled by // the linker. cu.flags = false; cu.segment_size = 0; } else { bck = NULL; cu.flags = false; Pc_Low = NULL; Pc_High = NULL; cu.segment_size = 2; } #else bck = MakeLabel(); OutLabel( bck->lbl ); Pc_Low = bck; Pc_High = MakeLabel(); cu.flags = true; cu.segment_size = 0; #endif SetOP( old ); Comp_High = Pc_High; tipe_addr = TypeAddress( TY_NEAR_POINTER ); cu.offset_size = tipe_addr->length; switch( GetMemModel() ) { case 'h': cu.model = DW_MODEL_HUGE; break; case 'l': cu.model = DW_MODEL_LARGE; break; case 'f': cu.model = DW_MODEL_FLAT; break; case 's': cu.model = DW_MODEL_SMALL; break; default: cu.model = DW_MODEL_NONE; break; } DWBeginCompileUnit( Client, &cu ); if( cu.flags ) { BEFreeBack( bck ); } } else { CcuDef = true; } }
extern type_class_def CallState( aux_handle aux, type_def *tipe, call_state *state ) /*******************************************************************/ { type_class_def class; uint i; hw_reg_set parms[20]; hw_reg_set *parm_src; hw_reg_set *parm_dst; hw_reg_set *pregs; call_class cclass; call_class *pcclass; risc_byte_seq *code; bool have_aux_code = FALSE; state->unalterable = FixedRegs(); if( FEAttr( AskForLblSym( CurrProc->label ) ) & FE_VARARGS ) { HW_TurnOn( state->unalterable, VarargsHomePtr() ); } // For code bursts only, query the #pragma aux instead of using // hardcoded calling convention. If it ever turns out that we need // to support more than a single calling convention, this will need // to change to work more like x86 if( !AskIfRTLabel( CurrProc->label ) ) { code = FEAuxInfo( aux, CALL_BYTES ); if( code != NULL ) { have_aux_code = TRUE; } } pregs = FEAuxInfo( aux, SAVE_REGS ); HW_CAsgn( state->modify, HW_FULL ); if( have_aux_code ) { HW_TurnOff( state->modify, *pregs ); } else { HW_TurnOff( state->modify, SavedRegs() ); } HW_CTurnOff( state->modify, HW_UNUSED ); state->used = state->modify; /* anything not saved is used */ state->attr = 0; pcclass = FEAuxInfo( aux, CALL_CLASS ); cclass = *pcclass; if( cclass & SETJMP_KLUGE ) { state->attr |= ROUTINE_IS_SETJMP; } if( cclass & SUICIDAL ) { state->attr |= ROUTINE_NEVER_RETURNS; } if( cclass & NO_MEMORY_CHANGED ) { state->attr |= ROUTINE_MODIFIES_NO_MEMORY; } if( cclass & NO_MEMORY_READ ) { state->attr |= ROUTINE_READS_NO_MEMORY; } i = 0; if( have_aux_code ) { parm_src = FEAuxInfo( aux, PARM_REGS ); } else { parm_src = ParmRegs(); } parm_dst = &parms[0]; for( ;; ) { *parm_dst = *parm_src; if( HW_CEqual( *parm_dst, HW_EMPTY ) ) break; if( HW_Ovlap( *parm_dst, state->unalterable ) ) { FEMessage( MSG_BAD_SAVE, aux ); } HW_CTurnOff( *parm_dst, HW_UNUSED ); parm_dst++; parm_src++; i++; } i++; state->parm.table = CGAlloc( i * sizeof( hw_reg_set ) ); Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) ); HW_CAsgn( state->parm.used, HW_EMPTY ); state->parm.curr_entry = state->parm.table; state->parm.offset = 0; class = ReturnClass( tipe, state->attr ); UpdateReturn( state, tipe, class, aux ); return( class ); }
HW_CAsgn( state->return_reg, HW_EMPTY ); } else if( class == XX ) { if( cclass & SPECIAL_STRUCT_RETURN ) { pregs = FEAuxInfo( aux, STRETURN_REG ); state->return_reg = *pregs; state->attr |= ROUTINE_HAS_SPECIAL_RETURN; } else { state->return_reg = StructReg(); } if( !( state->attr & ROUTINE_ALLOCS_RETURN ) ) { tmp = ReturnReg( WD, FALSE ); HW_TurnOn( state->modify, tmp ); } } else { if( cclass & SPECIAL_RETURN ) { pregs = FEAuxInfo( aux, RETURN_REG ); state->return_reg = *pregs; state->attr |= ROUTINE_HAS_SPECIAL_RETURN; } else { state->return_reg = ReturnReg( class, _NPX( state->attr ) ); } } UpdateReturn( state, tipe, class, aux ); return( class ); } extern void UpdateReturn( call_state *state, type_def *tipe, type_class_def class, aux_handle aux ) { /********************************************************************/
void CVObjInitDbgInfo( void ) /******************************/ /* called by objinit to init segments and for codeview */ { cv_out out[1]; cs_objname *optr; cs_compile *cptr; char *name; InitSegBck(); if( _IsModel( DBG_LOCALS ) ) { NewBuff( out, CVSyms ); optr = StartSym( out, SG_OBJNAME ); optr->signature = 0; name = FEAuxInfo( NULL, OBJECT_FILE_NAME ); CVPutStr( out, name ); EndSym( out ); buffEnd( out ); NewBuff( out, CVSyms ); cptr = StartSym( out, SG_COMPILE ); cptr->language = SetLang(); cptr->flags.s = 0; /* set default */ #if _TARGET & _TARG_IAPX86 cptr->flags.f.Mode32 = false; cptr->machine = MACH_INTEL_8080; #elif _TARGET & _TARG_80386 cptr->machine = MACH_INTEL_80386; cptr->flags.f.Mode32 = true; #elif _TARGET & _TARG_AXP cptr->machine = MACH_DECALPHA; cptr->flags.f.Mode32 = true; cptr->flags.f.FloatPrecision = 1; #endif switch( GetMemModel() ){ case 'h': cptr->flags.f.AmbientData = AMBIENT_HUGE; cptr->flags.f.AmbientCode = AMBIENT_FAR; break; case 'l': cptr->flags.f.AmbientData = AMBIENT_FAR; cptr->flags.f.AmbientCode = AMBIENT_FAR; break; case 'f': case 's': cptr->flags.f.AmbientData = AMBIENT_NEAR; cptr->flags.f.AmbientCode = AMBIENT_NEAR; break; case 'c': cptr->flags.f.AmbientData = AMBIENT_FAR; cptr->flags.f.AmbientCode = AMBIENT_NEAR; break; case 'm': cptr->flags.f.AmbientData = AMBIENT_NEAR; cptr->flags.f.AmbientCode = AMBIENT_FAR; break; default: break; } CVPutStr( out, "WATCOM CV 10.5 " ); EndSym( out ); buffEnd( out ); } }