/* ---------------------------------------------------------------------- */
/*                   Copyright (C) 1991 by Natrlich!                  */
/*                      This file is copyrighted!                         */
/*                Refer to the documentation for details.                 */
/* ---------------------------------------------------------------------- */
#include "defines.h"
#include "nasm.h"
#include "debug.h"
#include OSBIND
#include NMALLOC_H
#include "code.h"
#include "seg.h"

seg huge  *h_seg = 0,
    huge  *sp = 0;

make_mallocer( seg, SEGMAX, seg_alloc)


/* ---------------------------------------------------------- */
/* The old segment style was a bit more efficient, but it got */
/* really too complicated for my worn-out neurons. So we use  */
/* the way normal people would have written this.             */
/* ---------------------------------------------------------- */
#if LINKER
word   plus1;

void  build_seg( index, type, size)
word  index, size;
{
   static word       offset;
   extern seg huge   *l_seg;
   extern int        bootable;
   register seg huge *p = seg_alloc();

   p->size   = size;
   p->index  = index + plus1;
   if( ! offset)
      offset = index;
   p->offset = offset;
   offset    = offset + p->size;

   if( ! h_seg)                     /* set head pointer  */
      h_seg = p;
   else
      sp->next = p;

   if( (p->type = type) == S_DS)
      plus1 += 4;
   (sp = p)->next = 0;
}

#else

char  ovf_loss[] = "Too much code";

void  build_rseg( type, size)
word  size;
{
   register seg huge *p = seg_alloc();
   register lword    tmp;

   if( (tmp = __p - __program) >= MAXMODULE)
      nferror( ovf_loss);

   if( ! h_seg)                     /* set head pointer  */
      h_seg = p;
   else                             /* calc segment size */
   {
      register seg huge *q = sp;

      q->next = p;
      if( sis_code( q))
         q->size = calc_index();
   }
   (sp = p)->next = 0;
   p->type  = type;
   p->index = (word) tmp;
   p->size  = size;
}

#endif

#if ! VERSION && ! LINKER
extern int  runnable;

void  check_fseg( p, t)       
seg huge *p;
{
   if( runnable)                 
   {                             
      if( sis_unknown( p))       
         p->type = S_SDATA;
   }                             
   else                          
      if( (t) != p->type)        
         if( sis_unknown( p))    
            p->type = t;         
         else                    
            build_rseg( t, 0);
}

void check_dseg( p, t, val)  
seg huge *p;
word     val;
{
   if( runnable)                 
   {                             
      if( sis_unknown( p))       
         p->type = S_SDATA;      
   }                             
   else                          
      if( (t) != p->type)        
         if( sis_unknown( p))    
         {                       
            p->type = t;         
            p->size = val;       
         }                       
         else                    
            build_rseg( t, val); 
      else                       
         p->size += val;
}
#endif
