home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / assembler / as / src / c / lit < prev    next >
Encoding:
Text File  |  1993-03-07  |  2.7 KB  |  109 lines

  1. /*
  2.  * lit.c
  3.  * Copyright © 1992 Niklas Röjemo
  4.  */
  5.  
  6. #include <stdlib.h>
  7. #include "error.h"
  8. #include "input.h"
  9. #include "area.h"
  10. #include "reloc.h"       
  11. #include "put.h"
  12. #include "fix.h"
  13. #include "lit.h"
  14.  
  15. static LitInfo *litFind(LitInfo *p, RelocTag tag, WORD extra, int notbefore, Value value)
  16. {
  17.   for(; p; p = p->next) {
  18.     if(p->reloc.lineno < 0 && p->reloc.offset < notbefore)
  19.       return 0;
  20.     if(p->reloc.Tag == tag && p->reloc.extra == extra && valueEqual(&p->reloc.value,&value))
  21.       return p;
  22.   }
  23.   return 0;
  24. }
  25.  
  26. static LitList *cache = 0;
  27.  
  28. static LitList *litListNew(LitList *next, int offset)
  29. {
  30.   LitList *new;
  31.   if(cache) {
  32.     new = cache;
  33.     cache = new->next;
  34.   } else
  35.     new = malloc(sizeof(LitList));
  36.   if(new) {
  37.     new->next = next;
  38.     new->offset = offset;
  39.     new->lineno = inputLineNo;
  40.   } else 
  41.     error(ErrorSerious,FALSE,"Out of memory in litListNew.");
  42.   return new;
  43. }
  44.   
  45. static LitInfo *litInfoNew(LitInfo *more, RelocTag tag, WORD extra, Value value)
  46. {
  47.   LitInfo *new = malloc(sizeof(LitInfo));
  48.   if(new) {
  49.     new->next = more;
  50.     new->used = 0;
  51.     new->reloc.Tag = tag;
  52.     new->reloc.lineno = -1;
  53.     new->reloc.offset = -1;
  54.     new->reloc.extra = extra;
  55.     new->reloc.value = valueCopy(value);
  56.   } else 
  57.     error(ErrorSerious,FALSE,"Out of memory in litInfoNew.");
  58.   return new;
  59. }
  60.  
  61. static void litNew(RelocTag tag, WORD extra, int offset, int notbefore, Value value)
  62. {
  63.   LitInfo *p = litFind(areaCurrent->area.info->lits,tag,extra,notbefore,value);
  64.   if(!p) {
  65.     p = litInfoNew(areaCurrent->area.info->lits,tag,extra,value);
  66.     areaCurrent->area.info->lits = p;
  67.   }
  68.   p->used = litListNew(p->used,offset);
  69. }
  70.       
  71. void litInt(int size, Value value)
  72. {
  73.   if(areaCurrent) {
  74.     litNew(RelocImmN,size,areaCurrent->value.ValueInt.i,areaCurrent->value.ValueInt.i-4095,value);
  75.   } else
  76.     error(ErrorError,TRUE,"No area defined.");
  77. }
  78.  
  79. void litOrg(LitInfo *li)
  80. {
  81.   LitList *ll,*nll;
  82.   char *image  = areaCurrent->area.info->image;
  83.  
  84.   for(; li; li = li->next) {
  85.     if(li->reloc.lineno < 0) {
  86.       li->reloc.offset = areaCurrent->value.ValueInt.i;
  87.       relocAdd(&li->reloc);
  88.     }
  89.     for(ll = li->used; ll; ll = nll) {
  90.       WORD w;
  91.       int offset = ll->offset;
  92.       nll = ll->next;
  93.       ll->next = cache;
  94.       cache = ll;
  95.       w = (image[offset+3]<<24)|(image[offset+2]<<16)|(image[offset+1]<<8)|image[offset+0];
  96.       w = fixCpuOffset(ll->lineno,w,li->reloc.offset-ll->offset-8);
  97.       image[offset+3] = (w>>24) & 0xff;
  98.       image[offset+2] = (w>>16) & 0xff;
  99.       image[offset+1] = (w>> 8) & 0xff;
  100.       image[offset+0] =  w      & 0xff;
  101.     }
  102.     if(li->reloc.lineno < 0) {
  103.       li->reloc.lineno = inputLineNo;
  104.       putData(li->reloc.extra,0);
  105.     }
  106.     li->used = 0;
  107.   }
  108. }
  109.